《C和指针》笔记25: 函数原型(函数声明)

**函数原型 (functionprototype)**总结了函数定义的起始部分的声明,向编译器提供有关该函数应该如何调用的完整信息。使用原型最方便(且最安全)的方法是把原型置于一个单独的文件,当其他源文件需要这个函数的原型时,就使用#include指令包含该文件。这个技巧避免了错误键入函数原型的可能性,它同时简化了程序的维护任务,因为这样只需要该原型的一份物理拷贝。如果原型需要修改,你只需要修改它的一处拷贝。

例如定义一个头文件func.h,在里面包含函数的原型:

int *func( int *value, int len );

然后在需要使用时包含这个头文件。

#include "func.h"

这个方法的好处:

  1. 现在函数原型具有文件作用域,所以原型的一份拷贝可以作用于整个源文件,不需要函数每次调用前单独书写一份函数原型。
  2. 现在函数原型只书写一次,这样就不会出现多份原型的拷贝之间的不匹配现象。
  3. 如果函数的定义进行了修改,我们只需要修改原型,并重新编译所有包含了该原型的源文件即可。
  4. 如果函数的原型同时也被#include指令包含到定义函数的文件中,编译器就可以确认函数原型与函数定义的匹配。

函数原型是很重要的,当程序调用一个无法见到原型的函数时,编译器便认为该函数返回一个整型值。对于那些并不返回整型值的函数,这种认定可能会引起错误。

假设有一个函数xyz,它返回float值3.14。用于表示这个浮点数的二进制位模式如下:01000000010010001111010111000011

现在假定函数是这样被调用的:

float f;
...
f = xyz();

如果在函数调用之前编译器无法看到它的原型,它便认定这个函数返回一个整型值,并产生指令将这个值转换为float,然后再赋值给变量f。

函数返回的位如上所示。转换指令把它们解释为整型值1078523331,并把这个值转换为float类型,结果存储于变量f中。为什么函数的返回值实际上已经是浮点值的形式时,还要执行类型转换呢?编译器并没有办法知道这个情况,因为没有原型或声明告诉它这些信息。这个例子说明了为什么返回值不是整型的函数具有原型是极为重要的。

参考

  1. 《C和指针》

你可能感兴趣的:(C和C++,c语言,函数,原型,声明)