未定义的变量错误
我是C语言编程的新手,我在理解编译程序时出现的错误时遇到了麻烦。 我有以下程序,这很简单,我的教授说的是正确的:
#include #define TRUE 1 #define FALSE 0 #define BOOL int extern int x; extern BOOL do_exp; int exp_or_log(); main() { x = 10; do_exp = TRUE; printf("2^%d = %d\n", x, exp_or_log()); //should print 1024 x = 145; do_exp = FALSE; printf("log(%d) = %d\n", x, exp_or_log()); //should print 7 }
但是当我尝试编译它时,我得到:
"_x", referenced from: _x$non_lazy_ptr in ccWdLlxk.o "_exp_or_log", referenced from: _main in ccWdLlxk.o _main in ccWdLlxk.o "_do_exp", referenced from: _do_exp$non_lazy_ptr in ccWdLlxk.o ld: symbol(s) not found
我甚至没有足够的想法知道这意味着从何处开始试图找出问题。 如果有人有一个有用的解释,或者甚至只是对我应该注意什么来开始问题拍摄的一般概念,我真的很感激。
x
, do_exp
和exp_or_log()
都在另一个文件中定义,我猜是由你的教授提供的。 您需要与该文件链接在一起。 这通常通过在编译行上添加文件名和你的文件名来完成。
您已向编译器声明这些变量和函数可用,但不一定在此特定源文件中定义:
extern int x; extern BOOL do_exp; int exp_or_log();
并且它们未在该源文件中定义。 但是,链接器需要能够解析这些名称,并且您收到的错误消息表明链接器无法在其任何输入文件中找到这些名称。
您需要为链接器( ld
)提供具有这些内容的库,或者您需要一个定义它们的C文件,并且还要编译和链接该C文件。
抱怨的不是编译器:
ld: symbol(s) not found
链接器(ld)找不到引用的符号。 您尚未提供其定义。
首先,请注意您如何在两个变量定义上使用extern
关键字。
extern int x; extern BOOL do_exp;
这意味着:
这些变量是在别处创建的( 外部联盟)。 你应该知道它们存在,但它们存在于其他地方。
如果故意在另一个文件中声明这些变量,则需要将其他文件与您的文件进行链接编译,并将它们链接在一起。
但是,我怀疑你更有可能只是声明它们。
int x; BOOL do_exp;
回过头来报告,然后我们将开始处理你的函数exp_or_log
。
我猜你正在使用输出中的* nix机器,所以你需要:
cc -c Anna_program.c
这应该产生Anna_program.o
。 在您的错误中,乱码.o文件与此文件相同,但是暂时的,因此给出了一个psudo-random名称。 -c标志具有仅编译源文件的效果,并且不再生成可执行文件的链接。
然后你可以这样做:
cc Anna_program.o other_file.o -o Anna_program
并生成可执行文件Anna_program
。 如果您没有使用* nix样式编译器,那么您的集合将不同,您可能需要在最后一个命令的输出文件名末尾添加扩展名。
你可以这样做:
cc Anna_program.c other_file.o -o Anna_program
这将结合前两个步骤。
你应该记住的是cc
(或gcc
)实际上不是编译器,而是一个简单的编译管理器。 在引擎盖下,他们运行其他程序,在构建程序时执行不同的步骤。 默认情况下, cc
将尝试获取您提供的内容并生成可执行文件(a.out),根据您提供的内容,根据需要运行尽可能多的步骤。 你可以传递它的标志,例如-c
,告诉它只是部分方式(在这种情况下编译和汇编)。
C的步骤是预处理(由程序cpp
),编译(由cc1
完成),汇编(由as
完成)和链接(由ld
完成)。
cc
或gcc
命令决定需要做什么,然后运行这些其他程序来执行此操作。
你有链接器问题。
查看代码顶部:
extern int x; extern BOOL do_exp; int exp_or_log();
这三行就像编译器的承诺。 你说,相信我,到时候你将能够找到一个整数x,一个BOOL do_exp和一个函数exp_or_log();
extern对变量做出了这个承诺,并且函数没有正文:{…}使它成为函数。
链接器抱怨,因为你没有履行你的诺言。 您需要exp_or_log()的实现,并声明x和do_exp。
还有更多代码吗? 如果您创建另一个文件,则调用xh,其中包含以下内容:int x; int do_exp; int exp_or_log(){return 6; }
然后将其包含在.c文件中:
#include "xh"
你会得到一些输出。 在这种情况下,它是无意义的,但它会在您修复逻辑问题时进行编译。
$ ./a.out 2^10 = 6 log(145) = 6