先前的函数声明
为什么 C 语言中需要预先声明函数?
Why do functions need to be prior declared in C ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

发布评论
评论(6)
旧人2024-08-19 15:21:14
基本上,你不......
很多编译器会假设你正在调用 int Function() 签名,如果你还没有声明它。链接器......嗯......可能不会吃那个。
如果声明的函数的签名与调用语句不匹配,编译器会介意,但第二步就会出现问题:
- 参数传递和返回值预编码的编码
后者实际上必须为每次调用确定。正是在第二个代码生成步骤中,C 编译器真正错过了声明(这就是函数签名的原因)。
然后链接器还需要将函数的符号调用转换为实际的...呃...调用。但是,如果该函数存在于“某处”(去研究extern修饰符),链接器将不会成为一个显示障碍。
所有这一切的例外是函数指针机制,您可以在其中告诉编译器和链接器预期的签名,但调用本身不是由编译器决定的,链接器也没有“硬编码”调用...检查它出来了。
熊抱啵儿2024-08-19 15:21:14
我确信这不是唯一的原因,但是当您只知道函数的声明(例如来自头文件)时,您可以编译包含对其他函数的调用的文件。这是可能的,无需重新编译函数本身的定义(可能位于另一个文件中)。但为了验证函数是否被正确调用,编译器必须知道它的声明。然后链接器将处理剩下的事情。
这里有一个小例子
main.c:
#include "function.h"
int main(){
function();
return 0;
}
function.h:
#ifndef FUNCTION_H
#define FUNCTION_H
void function();
#endif
function.c:
#include "function.h"
void function(){}
我正在使用 gcc 进行编译:
gcc function.c -c
这将生成一个目标文件 function.o。现在,当我想编译我的主函数时,我不必再编译我的 function.c 文件,我只需要知道头文件和目标文件中的声明:
gcc main.c function.o -o test
现在,目标文件将链接到我的程序无需重新编译。
~没有更多了~
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
现代 C 语言中的函数需要预先声明,原因有两个:1)告诉编译器特定名称是函数的名称(而不是其他名称),2)告诉编译器确切的返回类型函数,以便编译器可以正确处理该返回。
在 C 中,可以使用或不使用原型来声明函数。原型声明为编译器提供了更多信息。它包括有关函数参数(如果有)的数量和类型的信息,从而帮助编译器正确准备函数调用的参数。
在 C 语言的 C89/90 版本中,函数不必事先声明,这导致编译器在调用时对函数做出假设。不用说,在许多情况下这被证明是危险的。
Functions in modern C language need to be prior-declared for two reasons: 1) to tell the compiler that a specific name is the name of a function (and not of something else), 2) to tell the compiler the exact return type of the function so that the compiler can handle that return correctly.
In C a function can be declared with or without prototype. A prototype declaration provides more information to the compiler. It includes information about the number and the types of function parameters (if any), thus helping the compiler to prepare the arguments for the function call properly.
In C89/90 version of C language the functions didn't have to be prior declared, which resulted in the compiler making assumptions about the function at the point of the call. Needless to say, in many cases this proved to be dangerous.