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;
}
运行结果:
10, 3.5, #
20, 9.8, @
30, 1.2, @
默认参数除了使用数值常量指定,也可以使用表达式指定,例如:
float d = 10.8;
void func(int n, float b=d+2.9, char c='@')
{
cout<<n<<", "<<b<<", "<<c<<endl;
}
C++规定,默认参数只能放在形参列表的最后,而且一旦为某个形参指定了默认值,那么它后面的所有形参都必须有默认值。实参和形参的传值是从左到右依次匹配的,默认参数的连续性是保证正确传参的前提。
下面的写法是正确的:
void func(int a, int b=10, int c=20){ }
void func(int a, int b, int c=20){ }
但这样写不可以:
void func(int a, int b=10, int c=20, int d){ }
void func(int a, int b=10, int c, int d=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;
}
这段代码在编译时会报错,错误信息表明不能在函数定义和函数声明中同时指定默认参数。对代码稍作修改,将 func() 函数的定义放到其他源文件中,如下所示(示例2)。
// main.cpp
#include <iostream>
using namespace std;
void func(int a, int b = 10, int c = 36);
int main()
{
func(99);
return 0;
}
//module.cpp 代码:
#include <iostream>
using namespace std;
void func(int a, int b = 10, int c = 36)
{
cout<<a<<", "<<b<<", "<<c<<endl;
}
运行结果:
99, 10, 36
修改后的代码是可以编译通过的,为什么将func()的定义放到其他源文件中就不一样了呢?
这是因为C++ 规定,在给定的作用域中只能指定一次默认参数。
对于示例1,func() 的定义和声明位于同一个源文件,它们的作用域也都是整个源文件,这样就导致在同一个文件作用域中指定了两次默认参数,违反了 C++ 的规定。
对于示例2,func() 的声明位于main.cpp,作用域也是main.cpp,而 func() 的定义位于module.cpp,作用域也是module.cpp,func() 的声明和定义位于不同的作用域,相互之间不影响。
C/C++有四种作用域:
函数原型作用域
局部作用域(函数作用域)
块作用域
文件作用域(全局作用域)
继续对代码进行修改,将 func() 定义处 b、c 的默认值分别设置为 5、57,而声明处 b、c 的默认值不变,依然为 10、36。编译并运行程序,发现输出结果与上面一样,这说明编译器使用的是当前作用域中的默认参数。站在编译器的角度看,它不管当前作用域中是函数声明还是函数定义,只要有默认参数就可以使用。
3、多次声明同一函数
在多文件编程时,我们通常的做法是将函数声明放在头文件中,并且一个函数只声明一次,但是多次声明同一函数也是合法的。
不过有一点需要注意,在给定的作用域中一个形参只能被赋予一次默认参数。换句话说,函数的后续声明只能为之前那些没有默认值的形参添加默认值,而且该形参右侧的所有形参必须都有默认值。
#include <iostream>
using namespace std;
//多次声明同一个函数
void func(int a, int b, int c = 36);
void func(int a, int b = 5, int c);
int main()
{
func(99);
return 0;
}
这种声明方式是正确的。第一次声明时为 c 指定了默认值,第二次声明时为 b 指定了默认值;第二次声明是添加默认参数。需要提醒的是,第二次声明时不能再次给 c 指定默认参数,否则就是重复声明同一个默认参数。
C++函数的默认参数补充的更多相关文章
- C#函数的默认参数——填坑记
昨天踩了一个坑.默认参数 + 增量发布的坑. 过程是这样的. 1. 有一个底层的方法,格式形如 void Test<T>(int p1, string p2, Func<T> ...
- C++中函数的默认参数
使用方法: (1)在函数声明或定义时,直接对参数赋值,该参数就是默认参数. (2)在函数调用时,省略部分或全部参数,这时就会使用默认参数进行代替. 注意事项: (1)一般在声明函数是设置默认参数. 如 ...
- python定义函数时默认参数注意事项
如果在调用一个函数时,没有传递默认参数,则函数内的默认参数是对函数的默认参数属性__defaults__的引用, 如 def func(arg1=[]): arg1.append(2) 调用func时 ...
- 对C++虚函数使用默认参数的注意事项
本文为大便一箩筐的原创内容,转载请注明出处,谢谢:http://www.cnblogs.com/dbylk/ 备忘一个关于虚函数的小知识点 使用多态调用一个类型中定义的虚函数时,编译器会根据指针的当前 ...
- JavaScript函数的默认参数(default parameter)
JavaScript函数的默认参数(default parameter) js函数参数的默认值都是undefined, ES5里,不支持直接在形参里写默认值.所以,要设置默认值,就要检测参数是否为un ...
- Python函数的默认参数的设计【原创】
在Python教程里,针对默认参数,给了一个“重要警告”的例子: def f(a, L=[]): L.append(a) return L print(f(1)) print(f(2)) print( ...
- 【C/C++】函数的默认参数/函数的占位参数/函数重载/注意事项
函数的默认参数 返回值类型 函数名(参数=默认值){} #include <iostream> using namespace std; int func(int a = 10, int ...
- C++中函数的默认参数和C语言中volatile的学习
1.函数默认参数 1 int func(int a,int b=10) 2 { 3 return a*b; 4 } 5 6 int main() 7 { 8 int c=func(2); 9 cout ...
- Delphi函数参数传递 默认参数(传值)、var(穿址)、out(输出)、const(常数)四类
Delphi的参数可以分为:默认参数(传值).var(传址).out(输出).const(常数)四类 可以对比C/C++的相关知识,类比学习. 1.默认参数是传值,不会被改变,例子 function ...
随机推荐
- mysql--浅谈多表查询1
这是对自己学习燕十八老师mysql教程的总结,非常感谢燕十八老师. 依赖软件:mysql5.6 系统环境:win 连接查询 在谈连接查询之前我们需要对数学上的笛卡尔积有一定的了解 现在有两个集合m和n ...
- [题解](双向bfs)hdu_3085_Nightmare Ⅱ
发现直接搜索比较麻烦,但是要同时两个人一起走容易想到双向bfs,比较普通, 在判断是否碰到ghost时只要比较两点的曼哈顿距离大小和step*2(即ghost扩散的距离)即可,仔细思考也是可以想到的 ...
- Eclipse Photon 小技巧(tips)
本文内容: Eclipse 4.8版本 代号 photon 光量子 ,感觉更像ide了,虽然这些技巧广为认知,但是作为eclipse来说,也是很重要的. Code completion allows ...
- .NET 基础 一步步 一幕幕[XML基础操作]
XML可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言. 什么是XML,学他有什么用? 优点:容易读懂,格式标准任何语言都内置了XML分析引擎,不用单独进行文件分 ...
- hdu1392凸包裸题
//极角排序 #include <bits/stdc++.h> #define sqr(x) ((x)*(x)) using namespace std; ],top; struct PO ...
- Codeforces Round #431 (Div. 2) A
Where do odds begin, and where do they end? Where does hope emerge, and will they ever break? Given ...
- Uvalive-4494-(数位dp)
题意:求a->b中的二进制出现过多少个1,很显然的数位dp,对于某一位来说,如果这位是0,那么dp[i]=dp[i-1] 如果这一位是1 那么dp[i]=dp[i-1]+1<<(p ...
- 学习flask的网址
学习flask的网址: http://www.bjhee.com
- pytorch 安装错误,报 GLIBCXX_3.4.20 错误
pytorch 从源码安装 链接:http://blog.csdn.net/u012442157/article/details/78134888 发现错误: 解决方案: http://blog.cs ...
- 多线程----Thread类,Runnable接口,线程池,Callable接口,线程安全
1概念 1.1进程 进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 任务管理器中: 1.2线程 线程是进程中的一个执行单元 ...