目录
一、引用:
1、引用的概念:
2、引用的特性:
3、引用的使用场景:
编辑
4、引用和指针的区别:
二、内联函数:
三、auto关键字,基于范围的for,指针空值:
一、引用:
1、引用的概念:
引用是优化于C语言中的指针:
引用就是给一个已经存在的变量去一个别名,这个操作并没有开辟空间,这个别名和它本来的变量共用同一块空间。
这个类似于指针,但是二者不相同,比如指针开辟了额外的空间,但是引用并没有。
使用方法:
类型& 引用变量名(对象名) = 引用实体;
#include
using std::cout;
using std::endl;
int main()
{
int a = 0;
int& b = a;
b++;
a++;
cout << "a = " << a << endl << "b = " << b << endl;
return 0;
}
如上图所示:a和b是指向同一块空间的,所以对二者任意一个进行++,都会使a或者b加1
注意:
我引用的值必须二者的类型相同才能成为别名。
引用的指向不能被修改
理解:
这个别名就类似于“外号”,比如说西游记中:孙悟空,齐天大圣,孙行者,斗战胜佛等都是指同一个人的,然后如果孙悟空吃了一个蟠桃,那么齐天大圣也同样吃了一个蟠桃(类比为对a或b加1)
2、引用的特性:
1、引用在定义的时候必须初始化(而指针可以不用)
eg:int& a;//这个语句会报错
2、一个变量可以有多个引用(就像孙悟空可以有多个称号)
3、引用一旦引用了一个实体,就不能在引用其他的了。
3、引用的使用场景:
1、做参数:
这样就不需要向C语言那样进行传地址,进行解引用操作了。
void Swap(int& a, int& b)
{
int tmp = a;
a = b;
b = tmp;
}
int main()
{
int x = 1, y = 2;
Swap(x, y);
cout << "x = " << x << endl << "y = " << y << endl;
return 0;
}
2、做返回值:
int& Count()
{
static int n = 0;
n++;
return n;
}
int& Add(int a, int b)
{
int c = a + b;
return c;
}
int main()
{
int& ret1 = Add(1, 2);
Add(3, 4);
cout << "Add(1, 2) is :" << ret1 << endl;
int& ret2 = Count();
cout << "Count() is :" << ret2 << endl;
return 0;
}
如上所示:如果函数返回时,出了函数作用域,如果返回对象还在(还没还给系统),则可以使用引用返回,如果已经还给系统了,则必须使用传值返回。
上面就是Count函数就是在静态区开辟的,在出这个函数后不会还给操作系统,所以就能够引用返回;而在Add函数中局部变量c在出了这个函数就会销毁,所以返回就会是一个随机值。
4、引用和指针的区别:
1、引用没有开辟额外的空间,但是指针开辟了。
2、引用在定义时候必须初始化,但是指针可以不用。
3、没有NULL引用,但是有NULL指针
4、引用在初始化引用了一个实体后就不能再有另外一个了,但是指针可以随时指向另外的同类型的实体。
5、有多级指针,但是没有多级引用,引用只能起多个别名,如果对这个别名再起别名的意思是给同一个实体起多个名字。
6、对引用+1就会使引用的实体+1;对指针+1是将指针向后偏移一个类型的大小。
7、引用比指针更安全,因为指针可能会出现空指针,野指针。
8、访问实体的方式不同,指针需要解引用操作,引用是编译器自己处理
9、在sizeof中含义不同:引用结果为引用类型的大小;指针始终是地址空间所占的字节数。
二、内联函数:
内联函数类似于宏函数
宏函数:不需要建立栈帧,提高运行效率但是宏函数复杂,容易出错,可读性差,不能调试
所以在C++中引入了内联函数。
1、概念:
用关键字inline来对函数进行修饰,编译的时候,编译器会将在调用这个内联函数的地方展开
2、特性:这个是一种空间换时间的做法,这样可能会使目标文件变大,但是会少函数调用建立栈帧的开销进而提升运行效率。
3、内联函数对于编译器只是一个建议,如果编译器不认为这里用内敛函数好的话就不会变成内敛函数,内联函数建议针对于:函数规模小(比如只有几行代码)不是递归,频繁调用
4、内联函数不建议生命和定义分离,会导致链接错误,因为被展开后没有函数地址,链接就会找不到。
如上图所示,在汇编中,如果不用内敛函数是call,如果是内敛函数就直接展开。
三、auto关键字,基于范围的for,指针空值:
auto中:
随着程序越来越复杂,类型也有越来越复杂的,所以就可以用auto修饰变量,编译器会根据实际情况处理。
注意:auto不能在同一行进行多个变量的声明;
不能声明数组。
for:
对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。因 此C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围。
int main()
{
int array[] = { 1, 2, 3, 4, 5 };
for (auto& e : arr)
e *= 2;
for (auto e : arr)
cout << e << " ";
return 0;
}
如上auto& e是一个别名e的改变是可以引起array数组中值发生变化的,而下面不要&,这里是array数组中的值赋值给e,那e的改变就不能影响array数组了
指针空值:
C语言中:NULL可能被定义为字面常量0,或者被定义为无类型指针(void*)的常量。
所以在C++中引入了关键字:nullptr,在后面表示指针空值的时候最好使用nullptr。