未定义的变量错误

时间:2010-10-14 19:00:45

标签: c variables undefined

我是C语言编程的新手,当我尝试编译程序时,我无法理解即将出现的错误。我有以下程序,这很简单,我的教授说的是正确的:

#include <stdio.h>
#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

我甚至没有足够的想法知道这意味着从哪里开始试图找出问题。如果有人有一个有用的解释,或者甚至只是对我应该开始拍摄问题的一般概念,我真的很感激。

6 个答案:

答案 0 :(得分:2)

xdo_expexp_or_log()都在另一个文件中定义,我猜是由你的教授提供的。您需要与该文件链接在一起。这通常是通过在编译行上添加其文件名来完成的。

答案 1 :(得分:1)

抱怨的不是编译器:

ld: symbol(s) not found

链接器(ld)找不到引用的符号。您尚未提供他们的定义。

答案 2 :(得分:1)

您已向编译器声明这些变量和函数可用,但未必在此特定源文件中定义:

extern int x;
extern BOOL do_exp;
int exp_or_log();

并没有在该源文件中定义它们。但是,链接器需要能够解析这些名称,并且您收到的错误消息表明链接器无法在其任何输入文件中找到这些名称。

您需要向链接器(ld)提供具有这些内容的库,或者您需要一个定义它们的C文件,并且还要编译和链接该C文件。

答案 3 :(得分:1)

首先,请注意您在两个变量定义中如何使用extern关键字。

extern int x;
extern BOOL do_exp;

这意味着:

  

这些变量是在别处创建的   ( extern 盟友)。你应该知道   他们存在,但他们存在   在其他地方。

如果故意在另一个文件中声明这些变量,则需要将其他文件与您的文件进行链接编译,并将它们链接在一起。

但是,我怀疑你更有可能只是声明它们。

int x;
BOOL do_exp;

回复此报告,然后我们将开始处理您的函数exp_or_log

答案 4 :(得分:1)

我猜你正在使用输出中的* 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完成)和链接(由{{完成) 1}})。

ldcc命令决定需要做什么,然后运行其他程序来执行此操作。

答案 5 :(得分:0)

你有链接器问题。

请参阅代码顶部:

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。

还有更多代码吗?如果您创建另一个文件,请调用x.h,其中包含以下内容:     int x;     int do_exp;     int exp_or_log(){       返回6;    }

然后将其包含在.c文件中:

#include "x.h"

你会得到一些输出。在这种情况下,它是无意义的,但它会在您修复逻辑问题时进行编译。

$ ./a.out
2^10 = 6
log(145) = 6