2010-10-14 2 views
1

Я новичок в программировании на 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 

я даже не достаточно иметь представление о том, что это значит знать, с чего начать пытаться выяснить проблему. Если у кого-то есть полезное объяснение или даже просто общее представление о том, на что я должен смотреть, чтобы начать пробную съемку, я бы очень признателен.

+3

Где определены 'x',' do_exp' и 'exp_or_log()'? –

+0

Может быть использовано 'boolean' вместо' BOOL' и, вероятно, определено для 'TRUE' и' FALSE' не требуется. – Arun

+0

Использование ** глобальной переменной ** 'do_exp' для управления поведением функции' exp_or_log() ', вероятно,' exp() 'и' log() 'внутри, является странным. – Arun

ответ

1

Это не компилятор, который жалуется:

ld: symbol(s) not found 

Компоновщик (л.д.) не может найти ссылки символов. Вы не указали свои определения.

1

Вы объявили компилятор, что эти переменные и функции доступны, но не обязательно определены в данном исходном файле:

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

И они не определены в этом исходном файле. Однако компоновщик должен иметь возможность разрешать эти имена, а получаемое сообщение об ошибке указывает, что компоновщик не может найти эти имена в любом из своих входных файлов.

Вы должны засохнуть обеспечить линкер (ld) с библиотекой, которая имеет эти вещи, или вам нужен файл C, который определяет их, и ahave файл C и скомпилирован и связанный с.

2

x, do_exp , и exp_or_log() все определены в другом файле, я предполагаю, что ваш профессор. Вам нужно связать с этим файлом. Обычно это делается путем добавления имени файла вместе с вашим на вашей линии компиляции.

0

У вас проблемы с компоновщиком.

Смотрите в верхней части вашего кода:

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

Эти три линии, как обещаниям компилятором. Вы говорите, поверьте мне, когда придет время, вы сможете найти целое число x, BOOL do_exp и функцию exp_or_log();

Внешняя сторона делает это обещание для переменных и тот факт, что функция не имеет тела: {...} делает это для функции.

Компонент жалуется, потому что вы не выполняете свое обещание. Вам нужна реализация exp_or_log() и объявить x и do_exp.

Есть ли еще код? Если вы создадите другой файл, вызовите x.h со следующим содержимым: int x; int do_exp; int exp_or_log() { return 6; }

, а затем включить его в свой файл .c:

#include "x.h" 

Вы получите некоторый вывод.В этом случае это бессмысленно, но он будет компилироваться, пока вы исправляете логические проблемы.

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

Во-первых, обратите внимание, как вы использовали ключевое слово extern в двух определениях переменных.

extern int x; 
extern BOOL do_exp; 

Это означает:

Эти переменные создаются в другом месте (ехЬегп союзника). Вы должны знать , что они существуют, но они существуют где-то в другом месте.

Если эти переменные намеренно объявлены в другом файле, вам необходимо связать их с другим файлом и связать их вместе.

Однако я подозреваю, что более вероятно, что вы просто хотели объявить их.

int x; 
BOOL do_exp; 

Возвращайтесь на это, то мы начнем дело с функцией exp_or_log.

1

Я предполагаю, что вы используете Никс машину * с выхода, так что вам нужно будет:

cc -c Anna_program.c 

Это должно производить Anna_program.o. В вашей ошибке файл табуляции .o был таким же, как этот, но был временным, поэтому ему было присвоено псевдослучайное имя. Флаг -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 являются Preprocessing (сделано программой cpp), составление (сделано по cc1), монтаж (сделано as) и связывание (сделано ld).

Команда cc или gcc решает, что необходимо сделать, а затем запускает эти другие программы, чтобы сделать это.

Смежные вопросы