Moh*_*nde 54 c function function-prototypes
我是C的新手(我之前有Java,C#和一些C++经验).在C中,是否有必要声明一个函数原型,或者代码可以在没有它的情况下编译?这样做是很好的编程习惯吗?或者它只是依赖于编译器?(我正在运行Ubuntu 9.10并在Code :: Blocks IDE下使用GNU C编译器或gcc)
AnT*_*AnT 65
永远不需要在C中声明函数的原型,既不在"旧"C(包括C89/90)也不在新C(C99)中.但是,在功能声明方面,C89/90和C99之间存在显着差异.
在C89/90中,根本没有必要声明一个函数.如果函数未在调用时声明,则编译器会从调用中传递的参数类型中隐式地"猜测"(推断)声明,并假定返回类型为int.
例如
int main() {
int i = foo(5);
/* No declaration for `foo`, no prototype for `foo`.
Will work in C89/90. Assumes `int foo(int)` */
return 0;
}
int foo(int i) {
return i;
}
Run Code Online (Sandbox Code Playgroud)
在C99中,您调用的每个函数都必须在调用之前声明.但是,仍然没有必要专门用原型声明它.非原型声明也可以使用.这意味着在C99中,"隐式int"规则不再起作用(对于推断的函数返回类型,在这种情况下),但是如果声明函数没有原型,则仍然可以从参数类型中猜出参数类型.
前面的示例不会在C99中编译,因为foo未在调用时声明.但是,您可以添加非原型声明
int foo(); /* Declares `foo`, but still no prototype */
int main() {
int i = foo(5);
/* No prototype for `foo`, although return type is known.
Will work in C99. Assumes `int foo(int)` */
return 0;
}
...
Run Code Online (Sandbox Code Playgroud)
最终得到有效的C99代码.
然而,在调用函数之前声明函数的原型始终是一个好习惯.
另外一点:我上面说过,永远不需要声明一个函数原型.事实上,对于某些功能来说,这是一项要求.为了在C中正确调用可变参数函数(printf例如),必须在调用点之前使用原型声明函数.否则,行为未定义.这适用于C89/90和C99.
use*_*405 62
在ANSI C(意思是C89或C90)中,您不必声明函数原型; 但是,使用它们是最佳实践.标准允许您不使用它们的唯一原因是为了向后兼容非常旧的代码.
如果您没有原型,并且调用了函数,编译器将根据您传递给函数的参数推断出原型.如果稍后在同一个编译单元中声明该函数,如果函数的签名与编译器猜测的不同,则会出现编译错误.
更糟糕的是,如果函数在另一个编译单元中,则无法获得编译错误,因为没有原型就无法检查.在这种情况下,如果编译器出错,如果函数调用在堆栈上推送的函数不同于函数预期,则可能会得到未定义的行为.
惯例是始终在头文件中声明一个原型,该头文件与包含该函数的源文件同名.
在C99或C11中,标准C在调用任何函数之前需要在范围内进行函数声明.许多编译器在实践中不强制执行此限制,除非您强制它们这样做.