1.
int Add (int a, int b = 3); int Add (int a, int b) { }
2.
int Add (int a, int b); int Add (int a, int b = 3) { }
两者都有效;这是标准方式和 why ?
如果将声明放在头文件中,并将定义放在单独的 .cpp 文件中,并将 #include 放在另一个 .cpp 文件的 Headers 中,您将能够看到差异 .
.cpp
#include
具体来说,假设:
int Add(int a, int b);
int Add(int a, int b = 3) { ... }
#include "lib.h" int main() { Add(4); }
test.cpp 的编译将看不到默认参数声明,并且将失败并显示错误 .
test.cpp
因此,默认参数定义通常在函数声明中指定:
int Add(int a, int b = 3);
在C中,关于它们在参数列表中的位置对默认参数施加的要求如下:
必须指定给定参数的默认参数不超过一次 . 多次指定它(即使具有相同的默认值)是非法的 .
具有默认参数的参数必须在参数列表的末尾形成一个连续的组 .
现在,记住这一点,只要满足上述要求,就可以在C中“增长”具有默认参数的参数集,从一个函数声明到下一个声明 .
例如,您可以声明一个没有默认参数的函数
void foo(int a, int b);
为了在声明之后调用该函数,您必须明确指定两个参数 .
稍后(进一步向下)在同一翻译单元中,您可以再次重新声明它,但这次使用一个默认参数
void foo(int a, int b = 5);
从这一点开始,你可以用一个明确的参数来调用它 .
再向下,您可以重新声明它再次添加一个默认参数
void foo(int a = 1, int b);
从这一点开始,您可以在没有明确参数的情况下调用它 .
完整示例可能如下所示
void foo(int a, int b); int main() { foo(2, 3); void foo(int a, int b = 5); // redeclare foo(8); // OK, calls `foo(8, 5)` void foo(int a = 1, int b); // redeclare again foo(); // OK, calls `foo(1, 5)` } void foo(int a, int b) { // ... }
至于你问题中的代码,两种变体都是完全有效的,但它们意味着不同的东西 . 第一个变量立即声明第二个参数的默认参数 . 第二个变体最初声明您的函数没有默认参数,然后为第二个参数添加一个 .
两个声明的净效果(即第二个声明后面的代码看到的方式)完全相同:函数的第二个参数有默认参数 . 但是,如果您设法在第一个和第二个声明之间挤压一些代码,则这两个变体的行为会有所不同 . 在第二个变体中,函数在声明之间没有默认参数,因此您必须明确指定两个参数 .
第一种方式优于第二种方式 .
这是因为头文件将显示该参数是可选的以及它的默认值 . 此外,这将确保默认值将是相同的,无论相应的.cpp文件的实现 .
在第二种方式中,不保证第二个参数的默认值 . 默认值可能会更改,具体取决于相应的.cpp文件的实现方式 .
必须在函数原型的第一次出现时指定默认参数 - 通常在函数原型中 . 如果函数原型被省略,因为函数定义也作为原型,那么应该在函数头中指定默认参数 .
4 回答
如果将声明放在头文件中,并将定义放在单独的
.cpp
文件中,并将#include
放在另一个.cpp
文件的 Headers 中,您将能够看到差异 .具体来说,假设:
lib.h
lib.cpp
test.cpp
test.cpp
的编译将看不到默认参数声明,并且将失败并显示错误 .因此,默认参数定义通常在函数声明中指定:
lib.h
在C中,关于它们在参数列表中的位置对默认参数施加的要求如下:
必须指定给定参数的默认参数不超过一次 . 多次指定它(即使具有相同的默认值)是非法的 .
具有默认参数的参数必须在参数列表的末尾形成一个连续的组 .
现在,记住这一点,只要满足上述要求,就可以在C中“增长”具有默认参数的参数集,从一个函数声明到下一个声明 .
例如,您可以声明一个没有默认参数的函数
为了在声明之后调用该函数,您必须明确指定两个参数 .
稍后(进一步向下)在同一翻译单元中,您可以再次重新声明它,但这次使用一个默认参数
从这一点开始,你可以用一个明确的参数来调用它 .
再向下,您可以重新声明它再次添加一个默认参数
从这一点开始,您可以在没有明确参数的情况下调用它 .
完整示例可能如下所示
至于你问题中的代码,两种变体都是完全有效的,但它们意味着不同的东西 . 第一个变量立即声明第二个参数的默认参数 . 第二个变体最初声明您的函数没有默认参数,然后为第二个参数添加一个 .
两个声明的净效果(即第二个声明后面的代码看到的方式)完全相同:函数的第二个参数有默认参数 . 但是,如果您设法在第一个和第二个声明之间挤压一些代码,则这两个变体的行为会有所不同 . 在第二个变体中,函数在声明之间没有默认参数,因此您必须明确指定两个参数 .
第一种方式优于第二种方式 .
这是因为头文件将显示该参数是可选的以及它的默认值 . 此外,这将确保默认值将是相同的,无论相应的.cpp文件的实现 .
在第二种方式中,不保证第二个参数的默认值 . 默认值可能会更改,具体取决于相应的.cpp文件的实现方式 .
必须在函数原型的第一次出现时指定默认参数 - 通常在函数原型中 . 如果函数原型被省略,因为函数定义也作为原型,那么应该在函数头中指定默认参数 .