c - 隐含的函数声明

时间:2014-04-29 04:44:19

标签: c header-files

这是我的头文件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文件中,它就可以了。但就目前而言,它不起作用。我该如何解决?

3 个答案:

答案 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.ctree.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定义的第二个保护似乎是不必要的,这是这个问题的原因。后一段只是重​​申其他人所说的内容,如果它无助于说服你这种观点,那么在技术上也是多余的,但是避免虚伪,第一段是你的问题的解决方案,不会影响你的决定。说的意见。