gpt4 book ai didi

c - 为什么我们应该在函数声明的同一个文件中包含函数原型(prototype)的头文件?

转载 作者:行者123 更新时间:2023-12-03 08:14:59 26 4
gpt4 key购买 nike

可能是一个愚蠢(而且非常简单)的问题,但我想尝试一下,因为我不知道在哪里可以找到答案。我正在意识到一些书,并且我已经开始谷歌搜索一些东西 - 我实际上有点好奇为什么,如果我们有这样的文件:

file1.c

#include <stdio.h>
#include "file2.h"

int main(void){
printf("%s:%s:%d \n", __FILE__, __FUNCTION__, __LINE__);
foo();
return 0;
}

file2.h

void foo(void);

file2.c

#include <stdio.h>
#include "file2.h"

void foo(void) {
printf("%s:%s:%d \n", __FILE__, __func__, __LINE__);
return;
}

编译它:

gcc file1.c file2.c -o file -Wall

为什么包含 file2.h 的头文件是一个好习惯其中包含 foo 的原型(prototype)函数与 foo 位于同一文件中被宣布?我完全理解将其附加到 file1.c ,虽然我们应该使用头文件来定义每个模块的接口(interface),而不是“原始”编写它,但为什么要将带有原型(prototype)的头文件附加到声明它的文件( file2.c )呢? -Wall 选项标志如果我不包含它也不会说什么,那么为什么人们说它是“正确的方法”?它是否有助于避免错误,还是只是为了使代码更清晰?

这些代码示例取自此讨论: Compiling multiple C files in a program

一些用户说这是“正确的方法”。

最佳答案

要回答这个问题,您应该对编译器和链接器之间的区别有基本的了解。简而言之,编译器单独编译每个翻译单元(C 文件),然后链接器的工作是将所有已编译的文件链接在一起。

例如,在上面的代码中,链接器正在搜索从 main() 调用的函数 foo() 存在的位置并链接到它。

首先是编译器步骤,然后是链接器。

让我们演示一个示例,其中将 file2.h 包含在 file2.c 中会很方便:

file2.h
void foo(void);
file2.c
#include <stdio.h>
#include "file2.h"

void foo(int i) {
printf("%s:%s:%d \n", __FILE__, __func__, __LINE__);
return;
}

此处 foo() 的原型(prototype)与其定义不同。

通过在 file2.c 中包含 file2.h,编译器可以检查函数的原型(prototype)是否与其定义相同,如果不相同,则会出现编译器错误。

如果 file2.h 未包含在 file2.c 中会发生什么?

然后编译器不会发现任何问题,我们必须等到链接步骤,链接器会发现从 main 调用的函数 foo() 没有匹配() 并且会出现错误。

如果链接器稍后会发现错误,那为什么还要麻烦呢?

因为在大型解决方案中,可能有数百个源代码需要花费大量时间来编译,因此等待链接器最后引发错误将浪费大量时间。

关于c - 为什么我们应该在函数声明的同一个文件中包含函数原型(prototype)的头文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69689893/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com