> 文章列表 > C++初阶 -1- C++入门part2

C++初阶 -1- C++入门part2

C++初阶 -1- C++入门part2

文章目录

  • 6.引用
    • 什么是引用?
    • 引用的使用
    • 引用的应用
      • 传值、传引用效率比较
      • 权限
      • 引用和指针的区别⭐
  • 7.内联函数
  • 8.auto关键字
  • 9.基于范围的for循环
  • 10.指针空值——nullptr

6.引用

什么是引用?

  • “别名”
int a = 0;
int& b = 0;

C++初阶 -1- C++入门part2
👆即 地址为0x000000BC0C6FFB94的空间即可以称为“a”,也可以成为“b”

引用:类型& 引用变量名(对象名) = 引用实体;
引用变量名 必须有且只有一个引用实体

  1. 可以取多个“别名”
  2. 可以给 “别名” “取别名”
  3. 可以给 任何类型 “取别名”
int a = 0;
int& b = a;
int& c = b;int* p = &a;
int*& pb = p;

C++初阶 -1- C++入门part2

引用的使用

  • 引用必须初始化C++初阶 -1- C++入门part2
  • 常引用
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;

📍类型转换会产生临时变量
在这里插入图片描述

引用和指针的区别⭐

语法上有区别,但底层实现本质上是相同的。

  1. 引用概念上定义一个变量的别名,指针存储一个变量地址。
  2. 引用在定义时必须初始化,指针没有要求
  3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何
    一个同类型实体
  4. 没有NULL引用,但有NULL指针
  5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32
    位平台下占4个字节)
  6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
  7. 有多级指针,但是没有多级引用
  8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
  9. 引用比指针使用起来相对更安全

7.内联函数

inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。

  • C++ 推荐:
    1. constenum 代替宏常量
    2. inline 代替宏函数 → 适合“小”函数

inline 内联函数的特性:

  1. inline是一种以空间换时间的做法
  2. inline对于编译器而言只是一个建议,可能展开也可能不展开
  3. inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址
    了,链接就会找不到。(内联函数不进符号表

在这里插入图片描述


8.auto关键字

auto 自动识别类型

int a = 0;
auto b = a;
auto c = &a;

在这里插入图片描述

  • auto 不能

    1. 一行命名多个
      C++初阶 -1- C++入门part2

    2. 不能声明数组
      C++初阶 -1- C++入门part2

  • 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;
}
  • 使用条件:
    1. for循环迭代的范围必须是确定
    2. 迭代的对象要 实现++和== 的操作。

10.指针空值——nullptr

简而言之,NULL在C++中出现了bug,所以引入 nullptr

nullptr 使用注意:

  1. 在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入 的。
  2. 在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。
  3. 为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr。

END