事先声明职能

时间:2009-11-25 19:18:47

标签: c function declaration

为什么函数需要事先在C中声明?

6 个答案:

答案 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

现在,目标文件将链接到我的程序而无需重新编译。