我一直认为函数原型必须包含函数的参数及其名称。但是,我只是尝试了这个:
int add(int,int);
int main()
{
std::cout << add(3,1) << std::endl;
}
int add(int x, int y)
{
return x + y;
}
它有效!我甚至尝试过极小心地编译:
g++ -W -Wall -Werror -pedantic test.cpp
它仍然奏效。所以我的问题是,如果你不需要函数原型中的参数名,为什么它这么常见呢?这有什么用途吗?它与函数的签名有关吗?
答案 0 :(得分:17)
不,这些不是必需的,实际上被编译器忽略了。你甚至可以在不同的声明中给它们不同的名字;以下是完全合法的:
int foo(int bar);
int foo(int biz);
int foo(int qux) {
...
}
将它们放入的原因是文档:
答案 1 :(得分:8)
参数名称是完全可选的,对编译没有影响。它们可能放在那里以便更好地阅读代码。
答案 2 :(得分:4)
声明中不需要参数名称。它们纯粹是文档。
您甚至不需要定义中的名称:
int f(int)
{
return 0;
}
在C ++中编译得很好(尽管不在C语言中)。这有时对例如有用。继承,重载,函数指针。
答案 3 :(得分:3)
您不需要在函数原型中包含参数名称。您只需要完整的签名,其中包括参数类型和(在函数模板特化的情况下)返回值。
但是,为了编写自我记录代码,包含参数名称仍然很常见。也就是说,这个声明的函数是:
void foo(int number_of_foos_desired, string foo_replacement);
通过仅查看原型,更容易理解,而不是这个:
void foo(int, string);
当您编写调用此函数的代码时,许多现代IDE也会在您键入时弹出参数名称。如果您没有在原型中包含参数名称,他们可能无法弹出此信息。
答案 4 :(得分:1)
它与函数的签名有很多关系。
使用.h文件的一个好处是,当有人出现并希望了解您的程序/ api所做的事情时,他们可以查看您的头文件并了解正在执行的操作,他们的输入和输出,一切如何在一起等等。
如果您遇到类似
的方法int doStuff(int,int)
这比具有签名的方法的说法要少得多:
int doStuff(int firstNumberToAdd, int secondNumberToAdd);
第二个,你至少可以了解正在进行的操作以及正在发生的事情。这是编写自我记录代码背后的想法。
如果您有兴趣,可以查看Steve McConnell编写的Code Complete。
答案 5 :(得分:1)
有不同的场景。我发现在处理inheritance
和virtual functions
方面非常有帮助。如果您使用的virtual function
在子类中生成未使用的警告,则可以省略变量名称。