缺省参数
*1.缺省参数的概念**2.缺省参数的分类* 函数重载
*1.函数重载概念**2.C++支持重载的原理---名字修饰**3.extern "C"* 引用
*1.引用的概念**2.引用的特性**3.引用的应用*
缺省参数 1.缺省参数的概念缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。
void Func(int a = 0) //缺省值就是0 { cout << a << endl; } int main() { Func(); //没有传参时,使用参数的默认值 Func(1); //传参时,使用指定的实参 renturn 0; }2.缺省参数的分类
一、全缺省参数:所有参数都给了缺省值
void Func(int a = 1,int b = 2,int c = 3) //三个参数都有默认值,也就是缺省值 { cout << "a = " << a << endl; cout << "b = " << b << endl; cout << "c = " << c << endl << endl; } int main() { Func(); //不传参,输出结果就是 1,2,3 Func(10); //只传了一个实参,从左往右传,输出结果就是 10,2,3 Func(10,20); //传了两个实参,输出结果就是 10,20,3 Func(10,20,30); //传了三个实参,输出结果是 10,20,30 renturn 0; }
这里注意,只传一个参数时,会默认是从左往右传,所以不会出现只传给b或者c,也不会出现只传b和c。
二、半缺省参数:缺省部分参数,且必须从右往左缺省
void Func(int a,int b = 2,int c = 3) //只有b和c有缺省值 { cout << "a = " << a << endl; cout << "b = " << b << endl; cout << "c = " << c << endl << endl; } int main() { Func(10); //只传了一个实参,从左往右传,输出结果就是 10,2,3 Func(10,20); //传了两个实参,输出结果就是 10,20,3 Func(10,20,30); //传了三个实参,输出结果是 10,20,30 renturn 0; }
这里注意,缺省参数只能从右往左缺省,且必须连续缺省,不能间隔给。传参时还是默认从左往右传,而且至少要传一个参数,不能没有实参。
注意:
1.缺省参数不能在函数声明和定义中同时出现(要么在声明,要么在定义,推荐写在声明里)
2.缺省值必须是常量或者全局变量
3.C语言不支持
函数重载是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 顺序)不同,常用来处理实现功能类似数据不同的问题。
#includeusing namespace std; //1.参数类型不同 int Add(int left,int right) { cout << "int Add(int left,int right)" << endl; return left + right; } double Add(double left,double right) { cout << "double(double left,double right)" << endl; return left + right; } //2.参数个数不同 void f() { cout << "f()" << endl; } void f(int a) { cout << "f(int a)" << endl; } //3.参数顺序不同 void f(int a,char b) { cout << "f(int a,char b)" << endl; } void f(char b,int a) { cout << "f(char b,int a)" << endl; } int main() { Add(1,2); Add(1.1,2.2); f(); f(1); f(1,'a'); f('a',1); return 0; }
注意:
1.返回值不同,不能构成重载,因为调用的时候不能区分。
2.缺省值不同,不能够成重载。
3.有一种情况:一个无参,一个带参,如图
他构成重载,但是使用时会有问题,传参的话还好,如果不传参,调用就会出现歧义(二义性),不知道调用的是第一个还是第二个,所以会报错。
为什么C语言不支持重载,C++支持重载?C++是如何支持重载的?
在C/C++中,一个程序运行起来要经历几个阶段:预处理、编译、汇编、链接。
C语言不支持函数重载,因为编译的时候,两个重载函数的函数名相同,在func.o符号表中存在歧义和冲突,其次链接的时候也存在歧义和冲突,因为他们都是直接使用函数名去标识和查找,而重载函数,函数名相同。
而C++的目标文件符号表中不是直接用函数名来标识和查找函数,而是通过函数修饰规则来区分。
1、函数名修饰规则,但是这个修饰规则不同的编译器下不同:Linux下(g++)是_Z+函数名长度+函数名+参数首字母。
2、有了函数名修饰规则,只要参数不同,func.o的符号表里面重载的函数就不存在二义性和冲突了。
3、链接的时候,test.o的main的函数里面去调用两个重载的函数,查找地址时,也是明确。
有些时候在C++工程中可能需要将某些函数按照C的风格来编译,在函数前加extern"C",意思是告诉编译器,将该函数按照C语言的规则来编译。
引用 1.引用的概念引用不是新定义一个变量,而是给已经存在的变量取了一个别名,编译器不会为引用变量开辟内存空间,他和他的引用变量共用同一块内存空间。
类型&引用变量名(对象名)=引用实体:
void TestRef() { int a = 10; int& ra = a; //定义引用类型 printf("%pn",a); printf("%pn",&ra); }
注意,引用类型必须和引用实体是同种类型的。
2.引用的特性1、引用在定义时必须初始化
2、一个变量可以有多个引用
3、引用一旦引用一个实体,则不能再引用其他实体
void TestRef() { int a = 10; //int& b; //该语句编译时会出错,必须要初始化 int& b = a; int& c = a; int& d = b; //类似一个人有多个名字,多个代号 printf("%pn",a); printf("%pn",&b); printf("%pn",&c); printf("%pn",&d); //运行结果都一样 }
还有这种情况:
int a = 10; int& b = a; int c = 20; b = c; //这里是把c赋值给b,而不是让b变成c的别名3.引用的应用
1、做参数
void Swap(int& a, int& b) { int tmp = a; a = b; b = tmp; } int main() { int x = 0, y = 1; Swap(x,y); return 0; }
2、引用做返回值
一、传值返回值
int Add(int a, int b) { int c = a + b; return c; } int main() { int ret = Add(1,2); cout << ret << endl; return 0; }
临时变量存在于:
1、如果c比较小,则一般是寄存器充当变量
2、如果c比较大,临时变量放在调用Add函数的栈帧中
所有的传值返回都会生成一个拷贝
二、传引用返回值
int& Add(int a, int b) { int c = a + b; return c; } int main() { int ret = Add(1,2); cout << ret << endl; return 0; }
当前代码的问题是:
1、存在非法访问,因为Add(1,2)的返回值是c的引用,所以Add栈帧销毁了以后,会去访问c位置空间。
2、如果Add函数栈帧销毁,清理空间,那么取c值的时候取到的就是随机值,给ret的就是随机值,当前这个取决于编译器的实现了
ps:vs下销毁栈帧没有清空间数据
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)