文章目录
- 6.引用
- 什么是引用?
- 引用的使用
- 引用的应用
- 传值、传引用效率比较
- 权限
- 引用和指针的区别⭐
- 7.内联函数
- 8.auto关键字
- 9.基于范围的for循环
- 10.指针空值——nullptr
6.引用
什么是引用?
- “别名”
int a = 0;
int& b = 0;
👆即 地址为0x000000BC0C6FFB94的空间即可以称为“a”,也可以成为“b”
引用:类型& 引用变量名(对象名) = 引用实体;
引用变量名 必须有且只有一个引用实体
- 可以取多个“别名”
- 可以给 “别名” “取别名”
- 可以给 任何类型 “取别名”
int a = 0;
int& b = a;
int& c = b;
int* p = &a;
int*& pb = p;
引用的使用
- 引用必须初始化
- 常引用
void TestConstRef()
{
const int a = 10;
//int& ra = a; // 该语句编译时会出错,a为常量
//正确的:
const int& ra = a;
// int& b = 10; // 该语句编译时会出错,b为常量(非常量引用的初始值必须为左值),10为常量,int为整型变量
//正确的:
const int& b = 10;
double d = 12.34;
//int& rd = d; // 该语句编译时会出错,类型不同
//正确的:
const int& rd = d;
}
引用的应用
1.做函数参数:输出型函数,形参的改变需要影响实参
void Swap(int& x, int& y)
{
int tmp = x;
x = y;
y = tmp;
}
int main()
{
int x = 13, y = 7;
Swap(x, y);
cout << x << " " << y << endl;
return 0;
}
2.做返回值:引用返回
如上图,引用返回的作用:①减少拷贝;②调用者可以修改返回对象
变量 add 的空间在函数结束后被归还给操作系统,则 add 空间储存的内容将不得而知。
- sum.出了函数生命还在的变量可以用引用返回
//C语言:传值返回
int func(const int x, const int y)
{
int n = x + y;
return n;
}
//C++:引用返回
int& func()
{
static int n = 0;
n++;
// ...
return n;
}
int& Add(int x, int y)
{
int add = x + y;
return add;
}
int main()
{
cout << "Add=" << Add(x, y) << endl;
Count();
Count();
Count();
Count();
Count();
cout << "Count=" << Count() << endl;
return 0;
}
输出:
Add=-858993460 随机值
Count=6
传值、传引用效率比较
以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低。
权限
⭐指针、引用和赋值,权限可以缩小,但是不能放大
- 权限放大:
const int c = 2;//对c空间只有“只读”的权限
int& d = c;
- 权限缩小:
int x = 1;//可读可写
const int& y = x;//可读
- 权限保持:
const int* p1 = nullptr;
const int* p2 = p1;
📍类型转换会产生临时变量
引用和指针的区别⭐
语法上有区别,但底层实现本质上是相同的。
- 引用概念上定义一个变量的别名,指针存储一个变量地址。
- 引用在定义时必须初始化,指针没有要求
- 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何
一个同类型实体 - 没有NULL引用,但有NULL指针
- 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32
位平台下占4个字节) - 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
- 有多级指针,但是没有多级引用
- 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
- 引用比指针使用起来相对更安全
7.内联函数
以
inline
修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。
- C++ 推荐:
const
和enum
代替宏常量inline
代替宏函数 → 适合“小”函数
inline
内联函数的特性:
- inline是一种以空间换时间的做法
- inline对于编译器而言只是一个建议,可能展开也可能不展开
- inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址
了,链接就会找不到。(内联函数不进符号表)
8.auto关键字
auto
自动识别类型:
int a = 0;
auto b = a;
auto c = &a;
-
auto
不能:-
一行命名多个
-
不能声明数组
-
-
aoto
的应用:
简化代码 -
与
typedef
的缺陷
typedef char* ptr;
const ptr p1;(编译错误 typedef后实际上是: char* const p1;常量指针必须初始化;没有为什么,语法归档
const ptr* p2;//编译正常
9.基于范围的for循环
范围for
——语法糖:对于一个有范围的集合,自动依次取其中的数据赋值给对象var
(var只是这个取得一个变量名),自动判断结束
int main()
{
int array[] = { 1, 2, 3, 4, 5 };
for (auto& var : array)
var *= 2;
for (auto num : array)
cout << num << " ";
输出结果:2 4 6 8 10
//这里的var和num都是变量名,两者一不一样或取什么名字都是不影响的
return 0;
}
- 使用条件:
- for循环迭代的范围必须是确定的
- 迭代的对象要 实现++和== 的操作。
10.指针空值——nullptr
简而言之,NULL在C++中出现了bug,所以引入 nullptr
nullptr
使用注意:
- 在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入 的。
- 在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。
- 为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr。
END