C函数语法,参数列表后声明的参数类型
我对C比较陌生。我遇到过一种我从未见过的函数语法形式,其中参数类型在参数列表之后定义。 有人能向我解释它与典型的C函数语法有何不同吗?
例:
int main (argc, argv)
int argc;
char *argv[];
{
return(0);
}
这是参数列表的旧式语法,仍然受支持。 在K&R C中,你也可以不使用类型声明,而是默认为int。 即
main(argc, argv)
char *argv[];
{
return 0;
}
将是相同的功能。
有趣的是,调用约定与功能的区别,以及没有原型的功能。 考虑一个旧式的定义:
void f(a)
float a; {
/* ... */
}
在这种情况下,调用约定是所有参数在传递给函数之前都会被提升。 因此,如果f
接收到double
但参数的类型为float
(这非常有效),那么编译器必须发出代码,以便在执行函数体之前将double转换为float。
如果包含原型,则编译器不再执行此类自动升级,并且任何传递的数据都将转换为原型的参数类型,就像通过赋值一样。 因此,以下内容不合法,并导致未定义的行为:
void f(float a);
void f(a)
float a; {
}
在这种情况下,函数的定义会将提交的参数从double
(提升的表单)转换为float
因为定义是旧式的。 但是该参数是以浮点形式提交的,因为该函数有一个原型。 你解决矛盾的方案有以下两种:
// option 1
void f(double a);
void f(a)
float a; {
}
// option 2
// this declaration can be put in a header, but is redundant in this case,
// since the definition exposes a prototype already if both appear in a
// translation unit prior to the call.
void f(float a);
void f(float a) {
}
如果您有选择,选项2应该是首选,因为它可以预先摆脱旧的样式定义。 如果函数的这种矛盾函数类型出现在同一个翻译单元中,编译器通常会告诉您(但不是必需的)。 如果这种矛盾出现在多个翻译单元上,错误可能会被忽视,并可能导致很难预测错误。 最好避免这些旧式的定义。
这是来电者的K&R风格或旧式声明。
请注意,该声明与现代声明明显不同。 K&R声明不会为函数引入原型,这意味着它不会将参数的类型暴露给外部代码。
链接地址: http://www.djcxy.com/p/40231.html上一篇: C function syntax, parameter types declared after parameter list