CS50 - 制作 helpers.c
CS50 - make helpers.c
也许有人可以给我提示:
几个小时以来,我一直在尝试修复此错误,但不知何故找不到真正的问题。会不会是其他文件之一(filter.c 或 bmp.h)有问题?
我收到以下错误消息:
/usr/bin/ld: /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crt1.o: in function `_start':
(.text+0x24): undefined reference to `main'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [<builtin>: helpers] Error 1**
我做错了什么?
#include <math.h>
#include "helpers.h"
// Convert image to grayscale
void grayscale(int height, int width, RGBTRIPLE image[height][width])
{
for (int i = 0; height > i; i++)
{
for (int j = 0; width > j; j++)
{
//dividing by 3 in order to get average color / grey tone
// using float
// using round
float total = image[i][j].rgbtGreen + image[i][j].rgbtRed + image[i][j].rgbtBlue;
int average = (round)(total / 3); // 3 because of 3 colors RGB / Red, Green, Blue
average = image[i][j].rgbtGreen = image[i][j].rgbtRed = image[i][j].rgbtBlue;
}
}
}
// Convert image to sepia
// Maximalwert von 255 Beachten --> hier am besten if condition > 255 dann etc
// round beachten // siehe hint
void sepia(int height, int width, RGBTRIPLE image[height][width])
{
for (int i = 0; height > i; i++)
{
for (int j = 0; width > j; j++)
{
float green_before = image[i][j].rgbtGreen;
float red_before = image[i][j].rgbtRed;
float blue_before = image[i][j].rgbtBlue;
int green_after = (round)(.349 * red_before + .686 * green_before + .168 * blue_before);
int red_after = (round)(.393 * red_before + .769 * green_before + .189 * blue_before);
int blue_after = (round)(.272 * red_before + .534 * green_before + .131 * blue_before);
if (green_after > 255)
{
green_after = 255;
}
if (red_after > 255)
{
red_after = 255;
}
if (blue_after > 255)
{
blue_after = 255;
}
image[i][j].rgbtGreen = green_after;
image[i][j].rgbtRed = red_after;
image[i][j].rgbtBlue = blue_after;
}
}
}
// Reflect image horizontally
void reflect(int height, int width, RGBTRIPLE image[height][width])
{
for (int i = 0; height > i; i++)
{
for (int j = 0; j < width / 2; j++)
{
RGBTRIPLE temp = image[i][j];
image[i][j] = image[i][width - j - 1];
image[i][width - j - 1] = temp;
}
}
}
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE temp[height][width];
for (int i = 0; height > i; i++)
{
for (int j = 0; width > j; j++)
{
int Green_insg = 0;
int Red_insg = 0;
int Blue_insg = 0;
float counter = 0;
for (int a = -1; 2 > a; a++)
{
for (int b = -1; 2 > b; b++)
{
if (0 > i + a || i + a > height - 1 || 0 > j + b || j + b > width -1)
{
continue;
}
Green_insg += image [i+a][j+b].rgbtGreen;
Red_insg += image [i+a][j+b].rgbtRed;
Blue_insg += image [i+a][j+b].rgbtBlue;
counter++;
}
}
// Durchschnittswerte der Nachbarpixel bilden
temp[i][j].rgbtGreen = round(Green_insg/counter);
temp[i][j].rgbtRed = round(Red_insg/counter);
temp[i][j].rgbtBlue = round(Blue_insg/counter);
}
}
for (int i = 0; height > i; i++)
{
for (int j = 0; width > j; j++)
{
image[i][j].rgbtGreen = temp[i][j].rgbtGreen;
image[i][j].rgbtRed = temp[i][j].rgbtRed;
image[i][j].rgbtBlue = temp[i][j].rgbtBlue;
}
}
return;
}
您编译了一些 C
代码,但没有告诉 gcc
您想要什么样的输出。当您这样做时,gcc
将使用默认设置,认为您需要一个可运行的可执行文件。
所有可运行的可执行文件都必须有一个入口点。该入口点有一个签名(一个非常具体的函数,具有非常具体的类型)。 运行 可执行文件中 main
所需的签名应该这样写:
int main(int argc, char** argv) {
...
}
注意...
不是C语言的一部分,不应该打字;相反,应该在此处键入要执行的代码,而不是键入 ...
如果您不想构建可执行文件,还有其他选项可用。我不会列出所有这些,但常见的是:
-c
这会在链接之前停止编译,并写入一个“.o”文件,这意味着如果您正在编译 hello.c
,您将得到输出 hello.o
(无法执行,但可以可以很容易地合并到另一个可执行文件中(通过链接)或者可以合并到一个存档文件 collection.a
(对于将大量编译的项目传递给其他可执行文件很有用,就像在测试时一样)或一个共享库 collection.so
这是对于专门构建的库非常有用,可以与其他程序共享,或者由您自己的程序选择性地加载。
因为我们不知道你想要gcc
做什么,希望它是上面的掩护;但是,如果上面没有涵盖,请提交一个包含更多详细信息的新问题。
Edwin Buck 的回答据我所知是正确的。在这种来自 CS50 的“过滤器”问题的特定情况下,您应该使用 make filter
进行编译,它使用提供的 Makefile
命令将所有相关文件编译在一起。当您尝试仅编译 helpers.c
文件时,您要求仅编译该文件,该文件没有 main
函数。
也许有人可以给我提示:
几个小时以来,我一直在尝试修复此错误,但不知何故找不到真正的问题。会不会是其他文件之一(filter.c 或 bmp.h)有问题?
我收到以下错误消息:
/usr/bin/ld: /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crt1.o: in function `_start':
(.text+0x24): undefined reference to `main'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [<builtin>: helpers] Error 1**
我做错了什么?
#include <math.h>
#include "helpers.h"
// Convert image to grayscale
void grayscale(int height, int width, RGBTRIPLE image[height][width])
{
for (int i = 0; height > i; i++)
{
for (int j = 0; width > j; j++)
{
//dividing by 3 in order to get average color / grey tone
// using float
// using round
float total = image[i][j].rgbtGreen + image[i][j].rgbtRed + image[i][j].rgbtBlue;
int average = (round)(total / 3); // 3 because of 3 colors RGB / Red, Green, Blue
average = image[i][j].rgbtGreen = image[i][j].rgbtRed = image[i][j].rgbtBlue;
}
}
}
// Convert image to sepia
// Maximalwert von 255 Beachten --> hier am besten if condition > 255 dann etc
// round beachten // siehe hint
void sepia(int height, int width, RGBTRIPLE image[height][width])
{
for (int i = 0; height > i; i++)
{
for (int j = 0; width > j; j++)
{
float green_before = image[i][j].rgbtGreen;
float red_before = image[i][j].rgbtRed;
float blue_before = image[i][j].rgbtBlue;
int green_after = (round)(.349 * red_before + .686 * green_before + .168 * blue_before);
int red_after = (round)(.393 * red_before + .769 * green_before + .189 * blue_before);
int blue_after = (round)(.272 * red_before + .534 * green_before + .131 * blue_before);
if (green_after > 255)
{
green_after = 255;
}
if (red_after > 255)
{
red_after = 255;
}
if (blue_after > 255)
{
blue_after = 255;
}
image[i][j].rgbtGreen = green_after;
image[i][j].rgbtRed = red_after;
image[i][j].rgbtBlue = blue_after;
}
}
}
// Reflect image horizontally
void reflect(int height, int width, RGBTRIPLE image[height][width])
{
for (int i = 0; height > i; i++)
{
for (int j = 0; j < width / 2; j++)
{
RGBTRIPLE temp = image[i][j];
image[i][j] = image[i][width - j - 1];
image[i][width - j - 1] = temp;
}
}
}
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE temp[height][width];
for (int i = 0; height > i; i++)
{
for (int j = 0; width > j; j++)
{
int Green_insg = 0;
int Red_insg = 0;
int Blue_insg = 0;
float counter = 0;
for (int a = -1; 2 > a; a++)
{
for (int b = -1; 2 > b; b++)
{
if (0 > i + a || i + a > height - 1 || 0 > j + b || j + b > width -1)
{
continue;
}
Green_insg += image [i+a][j+b].rgbtGreen;
Red_insg += image [i+a][j+b].rgbtRed;
Blue_insg += image [i+a][j+b].rgbtBlue;
counter++;
}
}
// Durchschnittswerte der Nachbarpixel bilden
temp[i][j].rgbtGreen = round(Green_insg/counter);
temp[i][j].rgbtRed = round(Red_insg/counter);
temp[i][j].rgbtBlue = round(Blue_insg/counter);
}
}
for (int i = 0; height > i; i++)
{
for (int j = 0; width > j; j++)
{
image[i][j].rgbtGreen = temp[i][j].rgbtGreen;
image[i][j].rgbtRed = temp[i][j].rgbtRed;
image[i][j].rgbtBlue = temp[i][j].rgbtBlue;
}
}
return;
}
您编译了一些 C
代码,但没有告诉 gcc
您想要什么样的输出。当您这样做时,gcc
将使用默认设置,认为您需要一个可运行的可执行文件。
所有可运行的可执行文件都必须有一个入口点。该入口点有一个签名(一个非常具体的函数,具有非常具体的类型)。 运行 可执行文件中 main
所需的签名应该这样写:
int main(int argc, char** argv) {
...
}
注意...
不是C语言的一部分,不应该打字;相反,应该在此处键入要执行的代码,而不是键入 ...
如果您不想构建可执行文件,还有其他选项可用。我不会列出所有这些,但常见的是:
-c
这会在链接之前停止编译,并写入一个“.o”文件,这意味着如果您正在编译 hello.c
,您将得到输出 hello.o
(无法执行,但可以可以很容易地合并到另一个可执行文件中(通过链接)或者可以合并到一个存档文件 collection.a
(对于将大量编译的项目传递给其他可执行文件很有用,就像在测试时一样)或一个共享库 collection.so
这是对于专门构建的库非常有用,可以与其他程序共享,或者由您自己的程序选择性地加载。
因为我们不知道你想要gcc
做什么,希望它是上面的掩护;但是,如果上面没有涵盖,请提交一个包含更多详细信息的新问题。
Edwin Buck 的回答据我所知是正确的。在这种来自 CS50 的“过滤器”问题的特定情况下,您应该使用 make filter
进行编译,它使用提供的 Makefile
命令将所有相关文件编译在一起。当您尝试仅编译 helpers.c
文件时,您要求仅编译该文件,该文件没有 main
函数。