🌈个人主页 :@ꪔ小林Y
✨个人专栏 :《C++小白闯关日记》,《C语言小白闯关日记》,《数据结构入门------从原理到实战》
🍀代码信条 :每一行代码都是成长的脚印👣,每一次调试成功都是对坚持的回应
目录
一.缺省参数
- 缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参,缺省部分分为全缺省和半缺省。(有些地方把缺省参数也叫默认参数)
- 全缺省 就是全部形参给缺省值,半缺省 就是部分形参给缺省值。C++规定半缺省参数必须从右往左依次连续缺省,不能间隔跳跃给缺省值。
- 带缺省参数的函数调用,C++规定必须从左到右依次给实参,不能跳跃给实参
- 函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省值。
- 示例:
cpp
#include<iostream>
using namespace std;
//简单的缺省
void Func(int a = 0)
{
cout << a << endl;
}
//全缺省
void Func1(int a = 10,int b = 20,int c= 30)
{
cout << "a= " << a << endl;
cout << "b= " << b << endl;
cout << "c= " << c << endl<<endl;
}
//半缺省
void Func2(int a, int b = 10,int c=20)
{
cout << "a=" << "a" << endl;
cout << "b=" << "b" << endl;
cout << "c=" << "c" << endl;
}
int main()
{
Func(1);
Func();
Func1(1, 2, 3);
Func1(1, 2);
Func1(1);
Func1();
Func2(1);//至少传1个值
Func2(1,2,3);
}

二.函数重载
我们知道C是不支持同名函数的存在的。
但是C++支持在同一个作用域中出现同名函数,但是要求这些同名函数的形参不同,可以是参数个数不同或者类型不同。这样C++函数调用就表现出了多态性为,使用更灵活。例:
c
#include<iostream>
using namespace std;
//函数重载(以参数类型不同为例)
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 Add(double left,double right)" << endl;
return left + right;
}
int main()
{
cout << Add(1, 2) << endl;
cout << Add(1.1, 2.2) << endl;
return 0;
}

三.引用
1.引用的介绍
引用就是给已存在变量取了一个别名
类型& 引用别名=引用对象
cppint& j=i;//这就可以理解为给i取了一个别名j
2.引用的特性
- 引用在定义时必须初始化(定义的时候就必须指出谁是谁的别名)
- 一个变量可以有多个引用
- 引用一旦引用一个实体,再不能引用其他实体
3.引用的使用
- 引用在实践中主要适于引用传参 和传引用返回 中减少拷贝提高效率 和改变引用对象时同时改变被引用对象。
- 引用传参跟指针传参功能类似,引用传参相对更方便一些。
- 传值返回会产生临时对象作为函数调用表达式的返回值,传引用返回本质是返回返回对象的引用,从而提高了效率,同时可以改变返回对象。
- 引用和指针在实践中相辅相成,功能有重叠性,但是各有特点,互相不可替代。C++的引用跟其他语言的引用是有很大区别的,除了用法,最大的点是C++引用定义后不能改变指向,Java的引用可以改变指向。(例如链表,树,节点定义位置这些只能使用指针,引用是无法替代的)
- 传引用返回
cpp
//下面的这个传引用返回其实是不正确的
int& func()
{
int ret = 0;
return ret;
}
int main()
{
int x = func();
cout << x << endl;//本质相当于返回了ret的别名,即野指针的访问
//越界读一般不会报错,只有写才会报错
return 0;
}

cpp
//正确使用传引用
int& func()
{
static int ret = 0;
return ret;
}//本质相当于返回ret的别名
int main()
{
int x=func();
cout<<x<<endl;
return 0;
}
cpp
Type& Func()
{
//...
return ret;//出了Func函数作用域,ret还在,就还可以用引用返回
}
4.const引用
- 可以引用一个const对象,但是必须用const引用,const引用也可以引用普通对象,因为对象的访问权限在引用过程中可以缩小,但不能放大;
- 不需要注意的是类似
int& rb=a*3;double d=12.34;int& rd=d;这样一些场景下a*3的和结果保存在一个临时对象中,int& rd=d;也是类似,在类型转换中会产生临时对象存储中间值,也就是rb和rd引用的都是临时对象,而c++规定临时对象具有常性,所以这里就触发了权限放大,必须要用常引用才可以; - 所谓临时对象就是编译器需要一个空间暂存表达式的求值结果时临时创建的一个未命名对象,C++中把这个未命名对象叫做临时对象。
cpp
#include<iostream>
using namespace std;
int main()
{
const int a = 0;
//不能权限放大
//int& b=a;
//不是权限放大,拷贝赋值
int e = a;
const int* b = a;
int c = 0;
//可以权限缩小
const int& d = c;
//指针:
const int* p1 = &a;
//不能权限放大
//int* p2=p1;
const int* p2 = p1;
//可以权限缩小
int* p3 = &e;
const int* p4 = p3;
return 0;
}
5.指针和引用的关系
- 语法概念上引用是一个变量的取别名不开空间 ,指针是存储一个变量地址,要开空间。
- 引用在定义时必须初始化 ,指针建议初始化,但是语法上不是必须的。
- 引用在初始化时引用一个对象后,就不能再引用其他对象;而指针可以在不断地改变指向对象。
- 引用可以直接访问 指向对象,指针需要解引用才是访问指向对象。
- sizeof中含义不同,引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节,64位下是8byte)
- 指针很容易出现空指针和野指针的问题,引用很少出现,引用使用起来相对更安全一些。
四.inline函数
- 用inline修饰的函数叫做内联函数 ,编译时C++编译器会在调用的地方展开内联函数,这样调用内联函数就不需要建立栈帧了,就可以提高效率。
- inline对于编译器而言只是一个建议,也就是说,你加了inline编译器也可以选择在调用的地方不展开,不同编译器关于inline什么情况展开各不相同,因为C++标准没有规定这个。inline适用于频繁调用的短小函数,对于递归函数,代码相对多一些的函数,加上inline也会被编译器忽略。
- C语言实现宏函数也会在预处理时替换展开,但是宏函数实现很复杂很容易出错的,且不方便调试,C++设计了inline目的就是替代C的宏函数。
- vs编译器 debug版本下面默认是不展开inline的,这样方便调试,debug版本想展开需要设置一下。
- inline不建议声明和定义分离到两个文件,分离会导致链接错误。因为inline被展开,就没有函数地址,链接时会出现报错。inline函数直接定义到.h文件。
五.nullptr
- C++中NULL可能被定义为字面常量0,或者c中被定义为无类型指针(void*)的常量。不论采取何种定义 ,在使用空值的指针时,都不可避免的会遇到一些麻烦。
- C++因此引入nullptr,其是一个特殊的关键字,是一种特殊类型的字面量,它可以转换成任意其它类型的指针类型 。使用nullptr定义空指针可以避免类型转换的问题,因此nullptr只能被隐式的转换为指针类型,而不能转换为整数类型。
🎊本期C++入门的内容就结束了。如果文中有表述不准的地方,或是你有更清晰的理解思路,强烈欢迎在评论区留言交流------ 技术路上多碰撞,才能更快进步
觉得内容对你有帮助的话,别忘了点赞❤️➕收藏🌟,方便后续回顾复习;想跟着一起系统学习数据结构的朋友,也可以点击关注,下一期我们会聚焦更进一步的学习。不见不散✌️
