5

这是一个愚蠢的问题,我承认。代码会更好地解释它。得到这些文件:

你好ç:

#include <stdio.h>

void hello(char * s)
{
    printf("hello, %s\n", s);
}

主.c:

int main()
{
    hello("world!");
    return 0;
}

生成文件:

test : main.o hello.o
    gcc -o test main.o hello.o

main.o : main.c
    gcc -c main.c

hello.o : hello.c
    gcc -c hello.c

.PHONY : clean
clean :
    -rm test
    -rm main.o
    -rm hello.o

我可以“制作”和“./test”它并且它可以工作。我不应该在 main.c 中包含类似 hello.h 的内容,以便编译器知道函数原型吗?

我什至没有在任何地方包含 hello.c,它就可以工作!main.c 怎么知道 hello 函数?

如果可行,我什么时候需要 .h 文件?我是 C 编程的新手,但我认为这个概念很容易掌握,现在我完全糊涂了。

4

2 回答 2

13

如果您使用该-Wall标志(并且应该始终使用它,以及-Werror -Wextra),那么您将收到以下消息:

main.c: In function 'main':
main.c:3: warning: implicit declaration of function 'hello'

并且编译器有效地“猜测”了要做什么,这在许多情况下可能会导致灾难。

正确使用头文件可以避免这种警告。

于 2013-01-14T01:41:24.880 回答
5

你不需要头文件;相反,您的函数需要原型。当您调用hello传递它时"world",C 会发现您正在调用一个单参数函数 take char*,并且一切正常。int但是,如果该函数采用浮点数,并且您决定将其设置为 as (尝试一下,它非常有启发性),则这将不起作用 。出于向后兼容的原因,C 将允许您在没有原型的情况下调用函数,但这很危险。例如,在您调用 的情况下hello,编译器认为您正在调用一个返回int. 从技术上讲,您正在调用未定义的行为,因此您的程序会意外运行。

标头恰好提供了提供原型的最方便的方法,但您可以在代码本身中提供它们,如下所示:

void hello(char*);

int main()
{
    hello("world!");
    return 0;
}
于 2013-01-14T01:43:57.420 回答