Loading

C++ 基础系列——函数默认参数

1. 定义

在 C++中,定义函数时可以给形参指定一个默认的值,这样调用函数时如果没有给这个形参赋值,就使用这个默认的值。

也就是说,调用函数时可以省略有默认值的参数。如果用户指定了参数的值,那么就使用用户指定的值,否则使用参数的默认值。

#include<iostream>

using namespace std;

//带默认参数的函数
void func(int n, float b=1.2, char c='@'){
    cout<<n<<", "<<b<<", "<<c<<endl;
}

int main(){
    //为所有参数传值
    func(10, 3.5, '#');

    //为 n、b 传值,相当于调用 func(20, 9.8, '@')
    func(20, 9.8);

    //只为 n 传值,相当于调用 func(30, 1.2, '@')
    func(30);

    return 0;
}

默认参数只能放在形参列表的最后,而且一旦为某个形参指定了默认值,那么它后面的所有形参都必须有默认值。

void func(int a, int b=10, int c=20){ }
void func(int a, int b, int c=20){ }

2. 默认实参函数声明与定义

除了函数定义处,也可以在函数声明处指定默认参数。不过在给定的作用域中一个形参只能被赋予一次默认实参。

#include <iostream>

using namespace std;

void func(int a, int b = 10, int c = 36);

int main(){
    func(99);
    return 0;
}

void func(int a, int b = 10, int c = 36){
    cout<<a<<", "<<b<<", "<<c<<endl;
}

编译报错,不能在函数定义和函数声明中同时指定默认参数。

// main.cc
#include <iostream>
using namespace std;

void func(int a, int b = 10, int c = 36);

int main(){
    func(99);
    return 0;
}
// module.cc
#include <iostream>

using namespace std;

void func(int a, int b = 10, int c = 36){
    cout<<a<<", "<<b<<", "<<c<<endl;
}

此时可以编译通过,func() 的声明位于 main.cc,作用域也是 main.cc,而 func() 的定义位于 module.cc,作用域也是 module.cc,func() 的声明和定义位于不同的作用域,相互之间不影响。

// 将 func() 定义处 b、c 的默认值分别设置为 5、57,而声明处 b、c 的默认值不变,依然为 10、36。
// module.cc
#include <iostream>

using namespace std;

void func(int a, int b = 5, int c = 57){
    cout << a << ", " << b << ", " << c << endl;  // 
}

定义处的默认值不会生效,会输出声明处的结果。因为编译器不管当前作用域中是函数声明还是函数定义,只要有默认参数就可以使用。它使用的是当前作用域的默认参数。

3. 多次声明同一函数

在多文件编程时,我们通常的做法是将函数声明放在头文件中,并且一个函数只声明一次,但是多次声明同一函数也是合法的。

不过有一点需要注意,在给定的作用域中一个形参只能被赋予一次默认参数。也就是说,,函数的后续声明只能为之前那些没有默认值的形参添加默认值,而且该形参右侧的所有形参必须都有默认值。

// 多次声明同一个函数
string screen(int a, int b, int c=36);
string screen(int a, int b, int c=35);  // 错误
string screen(int a, int b=35, int c);  // 准确 

通常应该在函数声明中指定默认参数,并将该声明放在合适的头文件中。

4. 默认实参初始值

局部变量不能作为默认实参。除此之外,只要表达式的类型能转换成形参所需要的类型,该表达式就能作为默认实参。

int a = 80;
char def = ' ';
int b = 100;

string screen(int x=a, int y =b, char c=def);

string windows = screen();  // 调用 screen(80,100,' ');
void f2()
{
    def = '*';          // 改变默认实参的值
    int a = 100;        // 隐藏了外层定义的 width,但没有改变默认实参值
    window = screen();  // 调用 screen(80,100,'*')
}
posted @ 2021-08-21 21:26  锦瑟,无端  阅读(721)  评论(0编辑  收藏  举报