目录
1、缺省参数(不能在函数声明和定义中同时出现,若声明和定义是分开的,则缺省参数放在声明里面)
2.3、为什么C++支持函数重载而C语言不支持(10_12_1:40)
3.4.2、C++中的引用初始化后,就不能第二次改变引用的指向:
1、缺省参数(不能在函数声明和定义中同时出现,若声明和定义是分开的,则缺省参数放在声明里面)
1.1、缺省参数的概念
缺省参数是 声明或定义函数时 为函数的 参数指定一个缺省值(缺省值只能为常量或者全全局变量) 。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。![]()
1.2、全缺省
即所有参数都给定默认值,如下:
1.3、半缺省
即只有部分参数指定默认值,但缺省值必须从右往左连续给定,即没有默认值的参数必须放在最左边:
2、函数重载
即运行函数名相同,根据参数列表(包括参数个数,参数类型,类型顺序)的不同,调用对应的函数。
注意:紧靠返回值不同不能构成重载,返回值不参与重载。
2.1、特殊情况
这种情况理论上说是可以的,因为整形和浮点型之间存在隐式类型转换,但由于我重载函数中既有整形参数又有浮点型参数,就不知道谁转换成谁,就产生了二义性。
2.2、特殊情况
当重载和缺省参数相遇时,如下:
这样可以构成重载函数,但因为缺省参数的存在,导致他不知道该调用哪个函数,产生二义性;
2.3、为什么C++支持函数重载而C语言不支持(10_12_1:40)
3、引用
3.1、概念:
引用 不是新定义一个变量,而 是给已存在变量取了一个别名 ,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。
3.2、引用就是取别名,别名变原名也变
3.3、引用的传参(核心)
我们以交换两个数的功能为例://C语言写法 void Swap(int* p1, int* p2) { int tmp = *p1; *p1 = *p2; *p2 = tmp; } //C++写法 void Swap(int& p1, int& p2) { int tmp = p1; p1 = p2; p2 = tmp; } int main() { int a = 0, b = 1; //C语言传参 Swap(&a, &b); //C++传参 Swap(a, b); return 0; }
3.4、C++引用的几种错误写法
3.4.1、引用必须初始化
3.4.2、C++中的引用初始化后,就不能第二次改变引用的指向:
int main() { int a = 0; int& c = a; int d = 1; //下面这一步是赋值,执行过后a和c的值都为1 //而不是c变成d的引用 c = d; return 0; }
所以C++中的引用并不能完全替代指针,例如不适合链表的插入结点操作,指针域如果是个引用就不能改变指向
3.5、引用作为返回值
3.5.1、错误的使用,这种直接返回的值是不确定的
因为出了作用域,对象就会被销毁,n空间处的数据可能会被摧毁也有可能保存,所以会是个不确定的值。
3.5.2、正确使用,将要返回的变量设置为静态变量;
由于变量c是静态变量,定义在静态区,这样函数test的栈帧的销毁就不影响c,而b就是c的引用,所以可以这样使用。又由于静态变量只能初始化一次,所以下面第二次调用test函数也不会影响c的值,即不会影响引用b的值。如果是下面这种情况就会影响其值:
3.5.3、引用做返回值的价值
(1)、可以提高效率;
(2)、可以修改返回对象;
3.6、常引用
3.6.1、如下:
a被const修饰成常变量,此时不能直接给a取别名b,因为别名是可以改变值的。
此时想给a取引用,也需要再引用前面加const:
3.6.2、如下:
3.6.3、根据3.6.1,我们发现一个神奇的现象
整形可以赋值给浮点型,此时是发生类型转换;
但是整形不能直接取一个double型的别名;
但是如果在double前加一个const就可以给整形取别名了,如下:
原因就在于:
不管是强制类型转换还是隐式类型转换,在转换过程中都会产生一个中间变量,整形i先赋值给该中间变量,然后中间变量才赋值给浮点型r,最关键的是该中间变量具有常属性,所以需要用常引用(前面加const)来个整形取别名。
3.7、引用和指针的区别
(1)、语法上:
语法上,引用没有开新空间,只是变量的别名,与变量共用一份空间;
语法上,指针开了新空间;
(2)、底层:
底层,引用开了空间并且用指针实现,引用的底层是汇编实现的。
(3)、 引用 在定义时 必须初始化 ,指针没有要求(4)、 引用 在初始化时引用一个实体后,就 不能再引用其他实体 ,而指针可以在任何时候指向任何一个同类型实体。(5)、 没有 NULL 引用 ,但有 NULL 指针(6)、在 sizeof 中含义不同 : 引用 结果为 引用类型的大小 ,但 指针 始终是 地址空间所占字节个数 (32位平台下占4 个字节 )。(7)、引用自加即引用的实体增加 1 ,指针自加即指针向后偏移一个类型的大小。(8)、有多级指针,但是没有多级引用。(9)、访问实体方式不同, 指针需要显式解引用,引用编译器自己处理。(10)、引用比指针使用起来相对更安全。
4.内联函数
4.1、建议
4.2、含义:
4.2.1、以inline修饰的函数叫做内联函数4.2.2、编译时C++编译器会在调用内联函数的地方展开(但默认情况下不会展开,具体方法PPt)4.2.3、没有函数调 用建立栈帧的开销,而且还可以调试(宏不能调试),内联函数还提升程序运行的效率。
4.3、特性:
4.3.1、inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运行效率。
4.3.2、inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归、且频繁调用的函数采用inline修饰。
4.3.3、inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。
5、auto关键字
该关键字通俗将讲就是可以自动确定类型,如下;
其中函数typeid()是用来显示一个变量的类型;
我们会发现auto就可以自动确认变量的类型;
5.1、auto的价值:
auto的价值就在于可以代替那种比较长的类型,如下:
5.2、auto的注意点
5.2.1、auto定义变量是必须初始化,才知道定义什么类型的变量;
5.2.2、auto不能作为函数参数;
5.2.3、auto不能作为返回值;
5.2.4、auto不能声明数组;
5.3、遍历数组小技巧(范围for)
5.3、改变数组小技巧(范围for)
6、nullptr关键字
与NULL相似,但NULL实质也是0,但nullptr等价于(void*),所以C++常用nullptr初始化指针;
//未完待续