这是我的头文件tree.h
#ifndef TREE_H_
#define TREE_H_
#if defined treeItem
extern int totalnode;
treeItem *addItem(treeItem *node, char *w);
void printInOrder(treeItem *node, FILE *output);
void freeTree(treeItem *node);
#endif
#endif
这是main.c中的main(),包括tree.h
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "tree.h"
#define MAX 1024
extern int totalnode;
int main(int argc, char *argv[]){
FILE *input;
FILE *output;
char *filename;
char ch[MAX];
//extern int totalnode;
struct treeItem *element;
element = NULL;
int i;
if (argc > 2){
output = fopen(argv[1], "w");
for(i = 2; i < argc + 1; i++){
filename = argv[i];
input = fopen(filename, "r");
if(input != NULL){
while(getword(ch, MAX, input) != EOF)
if (isalpha(ch[0]))
element = addItem(element, ch);
}
}
printInOrder(element, output);
fprintf(output,"-------------- \n ");
fprintf(output,"%4d Total number of different words",totalnode);
freeTree(element);
fclose(input);
fclose(output);
}
else{
printf("There is no input file.\n");
}
return 0;
}
编译说:
../main.c: In function 'main':
../main.c:57: warning: implicit declaration of function 'addItem'
../main.c:57: warning: assignment makes pointer from integer without a cast
../main.c:60: warning: implicit declaration of function 'printInOrder'
../main.c:64: warning: implicit declaration of function 'freeTree'
另一个错误:架构x86_64的未定义符号:
"_totalnode", referenced from:
_main in main.o
_addItem in tree.o
ld:找不到架构x86_64的符号
collect2:ld返回1退出状态
如果我在不使用头文件的情况下将所有代码放在同一个.c文件中,它就可以了。但就目前而言,它不起作用。我该如何解决?
答案 0 :(得分:3)
行
#if defined treeItem
和匹配的#endif
应该从tree.h
移除
请记住,预处理在概念上发生在实际编译之前(或作为第一步)。
通常,您可以使用
获得main.c
的预处理形式
gcc -C -E main.c > main.i
然后在less
main.i
之类的寻呼机)
我经常使用
删除生成的预处理程序指令gcc -C -E main.c | grep -v '^#' > main.i
gcc -Wall -c main.i
这会在main.i
(不是main.c
或tree.h
)中提供行号引用的错误消息,这有时对调试宏很有用。 gcc
的另一个有用选项是-H
:它显示每个#include
- d文件
答案 1 :(得分:0)
为了“按原样”使用tree.h文件,并让它按照您的意愿定义项目,您必须定义treeItem:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
/* You will need to define 'treeItem' prior to including 'tree.h'. */
typedef /* the defintition here */ treeItem;
#include "tree.h"
#define MAX 1024
extern int totalnode;
如果您可以自由编辑tree.h文件,那么删除该行可能会更好:
#if defined treeItem
和其中一行:
#endif
答案 2 :(得分:0)
因为除非定义了treeItem,否则你有预编译器指令排除了tree.h的实体主体,你必须在main.c中包含tree.h之前#define treeItem,这是由于预编译器指令的方式正在处理中。这将解决眼前的问题。
我在main.c中看到你有一行:struct treeItem * element; 如果我正确地解释你打算满足标题中的#ifdef treeItem行,那么你就会误解这些#行是如何像C / C ++的单独语言一样。这些行称为预编译器指令,或更多随便的宏。宏是预处理程序的命令,它在编译之前对文本文件进行操作,目的是在内存中创建一个完整的源代码,该代码可以编译成一个对象,以后可以与其他对象链接以形成程序。预处理器的定义与C / C ++中的定义不同,它们不直接交互。关于结构的这一行对于预处理器几乎是不可见的,它对C / C ++一无所知。您必须在#ifdef。
之前使用#define定义此treeItem更美观的是,你的头文件不应该像这样保护,因为它是多余的。 main.c模块的#include“tree.h”行足以表明包含tree.h实体主体的意图。你有一个适当的防范重复包含,但关于treeItem定义的第二个保护似乎是不必要的,这是这个问题的原因。后一段只是重申其他人所说的内容,如果它无助于说服你这种观点,那么在技术上也是多余的,但是避免虚伪,第一段是你的问题的解决方案,不会影响你的决定。说的意见。