为什么函数需要事先在C中声明?
答案 0 :(得分:1)
这样编译器在调用函数时就能检测到类型错误。当然,有很多方法,但这就是他们选择的方式。
答案 1 :(得分:1)
现代C语言中的函数需要事先声明,原因有两个:1)告诉编译器特定名称是函数的名称(而不是其他东西),2)告诉编译器确切的返回函数的类型,以便编译器可以正确处理该返回。
在C中,可以使用或不使用原型声明函数。原型声明为编译器提供了更多信息。它包含有关函数参数的数量和类型(如果有)的信息,从而帮助编译器正确地为函数调用准备参数。
在C语言的C89 / 90版本中,函数不必事先声明,这导致编译器在调用时对函数做出假设。不用说,在许多情况下,这被证明是危险的。
答案 2 :(得分:0)
这样一次通过编译器就知道每个参数要传递多少字节。
考虑:
f(12345);
int f(char input)
{
printf("%c",input);
}
如果没有原型,编译器将假定f
接受整数,并向函数发送sizeof(int)
个字节(通过堆栈或寄存器,具体取决于平台)。但该函数只会查看1个字节,这会产生错误的结果。
答案 3 :(得分:0)
因为旧编译器的速度和内存有限,所以他们希望一切都可以完成(只需从上到下阅读文件,一切都可以理解)。
现代设计的编译器可以向上,向下查找函数,即使在尚未在某一点声明的时候也可以查找不同的文件。
答案 4 :(得分:0)
基本上,你没有......
如果你还没有声明它,许多编译器会假设你正在调用一个int Function()签名。链接器...嗯...可能不会吃那个。
编译器会介意声明的函数的签名是否与调用语句不匹配,但它是第二步出错的地方: - 编码参数传递和返回值预编码
后者实际上必须为每次呼叫确定。在第二个代码生成步骤中,C 编译器确实错过了声明(这是函数签名的原因)。 然后链接器还需要将函数的符号调用转换为实际的...... er ...调用。但是如果函数存在于“某处”(去研究 extern 修饰符),那么链接器将不会是一个显示停止。
所有这些的例外是函数指针机制,在这里您告诉编译器和链接器预期的签名,但调用本身不是由编译器决定的,也不是链接器的“硬编码”调用。检查一下。
答案 5 :(得分:0)
我确信这不是唯一的原因,但是当您只知道函数的声明(例如来自头文件)时,您可以编译调用其他函数的文件。这是可能的,无需重新编译函数本身的定义(可能在另一个文件中)。但是为了验证函数是否被正确调用,编译器必须知道它的声明。然后链接器将处理其余的事情。
这里有一个小例子
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。现在,当我想编译我的main函数时,我不再需要编译我的function.c文件了,我只需要知道头文件和目标文件中的声明:
gcc main.c function.o -o test
现在,目标文件将链接到我的程序而无需重新编译。