我的书说,我应该这样编写过程的原型(没有任何参数):void test(void);
我通常会编写一个过程原型,它没有像这样的任何参数:void test();
并且它可以工作。
这两个声明之间有什么区别?
这可能是C和C ++之间的区别。
void test(void);
更多是C习语。
void test();
更多是C ++习惯用法。
在C中,函数declaration中的参数列表为空,表示该函数接受unspecified个参数-在definition中,它表示接受no个参数:
void foo(); // declaration, number of arguments is unspecified
void foo() // definition, number of arguments is zero
{
...
}
声明和定义中void
的参数列表均表示该函数不使用任何参数:
void foo( void ); // declaration, number of arguments is 0
void foo( void ) // definition, number of arguments is 0
{
...
}
所以为什么会这样?
原型声明语法和void
关键字都不是C的最初组成部分-无法指定“此函数不返回值”和“此函数接受这种类型的许多参数”。在白垩纪早期,函数定义写为
foo( a, b, c ) // return type of int assumed
T a; // for arbitrary types T, Q, R
Q b;
R c;
{
// do something interesting with a, b, and c
}
并且相应的声明只是写为
foo(); // strictly not necessary, since the compiler would assume a return type of int
C最初没有机制针对函数声明来验证函数call中参数的数量和类型。如果您将foo
称为
foo( x, y, z, oops );
编译器无法告诉您您传递了太多参数,或者x
,y
或z
中的任何一个都是错误的类型。直到运行时,您才知道有问题。
1989年标准引入了void
关键字以及函数原型语法,因此您现在可以在函数declaration中指定参数的数量和类型,从而使编译器可以捕获与上述不匹配的内容:
void foo( T, Q, R ); // only need to specify types in a declaration
void foo( T a, Q b, R c )
{
// do something interesting with a, b, c
}
和void
关键字作为参数列表意味着该函数使用了[[no参数:
void foo( void );
因为遗留代码永远存在,所以仍然支持旧式函数定义和声明,尽管不再支持隐式函数为int
键入。这就是为什么您仍然可以declare
void foo();
的原因,尽管最佳实践是在不带参数的情况下将其声明为void foo( void );
。否则,如果您尝试使用类似[]的参数调用foo
foo( x );
编译器将无法捕获不匹配的内容。