当前位置: 首页 > news >正文

【落羽的落羽 C++】C++入门基础:引用,内联,nullptr

在这里插入图片描述

文章目录

  • 一、引用
    • 1. 引用的概念
    • 2. 引用的特点
    • 3. 引用的使用
    • 4. const引用
    • 5. 引用和指针
  • 二、inline内联
  • 三、nullptr

一、引用

1. 引用的概念

引用是C++中的一个较为重要的概念。它是给已存在变量取的“别名”,编译器不会为引用变量开辟内存空间,它和它引用的变量共用一块内存空间。比如,“萨姆”是流萤的别名,“萨姆”就是对流萤的引用,当我们称呼萨姆时,指的仍然是流萤这个人。
具体用法是:类型& 引用别名 = 引用对象;

int a = 1;
//b和c是对a的引用,b和c都是a的别名
int& b = a;
int& c = a;
//也可以再对b取别名d,d还是对a的引用,也是他的别名
int& d = b;

可以看到:
b,c,d的值与地址和a是完全相同的:

在这里插入图片描述

2. 引用的特点

使用引用时,我们需要注意:

  • 引用在定义时必须初始化
  • 一个变量可以有多个引用
  • 引用变量只能引用定义时指定的对象,无法修改引用对象
  • 因为它们共用一块地址,所以对引用变量的修改也会改变引用对象。
int a = 1;//没有初始化,会报错:
int& b;//一个变量可以有多个引用:
int& b = a;
int& c = a;
//后续无法再修改b和c的引用对象了//对引用变量的修改会改变引用对象:
b = 2; //a,b,c的值变成了2
int d = 3;
c = d; //这里并非是引用,而是赋值。a,b,c的值变成了3

3. 引用的使用

引用在实践中主要用于引用传参和引用做返回值。

引用传参,例如void Swap(int& x, int& y);,函数的形参是引用类型。在调用函数时,x和y分别是对实参的引用,在函数内部交换了x和y的值,也就改变了实参的值。显然,引用传参和传址调用一样,规避了传值调用中无法改名实参的缺点。引用传参和指针传参在功能上是类似的,引用传参相对更方便一点。

引用做返回值的使用涉及到类和对象的概念。简单概括,用普通类型做返回类型,返回值就只是一个常量数值,后续不能再对这个数值进行修改;用引用类型做返回类型,返回值就是函数内return的变量的引用,后续还可以对这个变量进行修改。以后我们再深入理解。

4. const引用

一个const变量也可以引用,但必须用const引用(常引用)const引用也可以引用普通变量,但普通引用不能引用const变量。
在这里插入图片描述在这里插入图片描述

当然,被const修饰了,const引用类型自然也不能被修改:

在这里插入图片描述

需要注意的是,类似a*2,20这种具有常性的对象,也必须要用常引用:
在这里插入图片描述

5. 引用和指针

C++中指针和引用很相似,在实践中它们相辅相成,功能有重叠,但是各有特点,不能互相替代。

  • 引用是给一个变量起别名,不额外开辟空间。指针是存储一个变量的地址,要开空间。
  • 引用在定义时必须要初始化。指针建议初始化,但在语法上不是必须的。
  • 引用在初始化时引用一个对象后,就不能再改变引用对象。而指针可以不断改变指向对象。
  • 引用可以直接访问引用对象。指针需要解引用才能访问指向对象。
  • 引用变量的大小取决于引用类型。指针变量大小始终是4或8个字节。
  • 指针很容易出现空指针和野指针的问题。引用使用起来更安全一点。

在这里插入图片描述

二、inline内联

inline是C++中的一个关键字,用来修饰函数。用inline修饰的函数叫做内联函数,编译时C++编译器会在调用函数的地方展开内联函数,这样调用函数时就需要建立栈帧了,可以提高效率。
但inline对于编译器而言只是一个建议,加了inline编译器也可以选择不展开函数,C++没有明确规定展不展开。inline适用于频繁调用的短小函数,对于递归函数或代码相对多一些的函数,加上inline也会被忽略。
当然,C语言中的宏函数也会在预处理时替换展开,但是宏函数在实现中很复杂容易出错,且不容易调试。C++设计出inline的目的就是替代C语言的宏函数。
VS编译器debug版本下是默认不展开inline的,这样方便调试,debug版本想要inline展开需要额外设置。
最后,inline不建议声明和定义分离到两个文件,这样会导致链接错误。因为inline被展开,函数地址没有了,链接时会出现报错。

#define Add(x, y) ((x)+(y)) //宏函数inline int Add(int x, int y) //内联函数
{return x + y;
}

换言之,内联函数像宏函数一样直接在函数调用处展开。它继承了宏函数的优点,但没有宏函数的缺点。

三、nullptr

我们对空指针NULL已经不陌生了。NULL实际上是一个宏,在传统的C头文件stddef.h中,可以找到:

在这里插入图片描述
C语言中,NULL被定义成无类型指针(void*)的常量。在C++中,NULL被定义成字面常量0,不论采用哪种定义,在使用NULL时,都可能会遇到问题,比如:

void Fun(int* ptr);
void Fun(int x);

这两个函数构成了函数重载,编译时没有问题。
假如后续调用中有Fun(NULL);,我们本想调用参数是int*的Fun函数,但由于NULL被定义成0,会调用成参数是int的Fun函数;写成Fun((void*)NULL),调用会报错;写成Fun((int*)NULL);才能调用第一个Fun函数:

在这里插入图片描述

所以,为了解决这个问题,C++11中引入了nullptr。nullptr是一个关键字,它是一种特殊类型的字面量,可以转换成任意其他类型的指针类型。使用nullptr定义空指针可以避免类型转换的问题,因为nullptr只能隐式地转换为指针类型,不能转换为整数类型。

在这里插入图片描述

在这里插入图片描述

本篇完,感谢阅读


http://www.mrgr.cn/news/93672.html

相关文章:

  • c语言笔记 一维数组与二维数组
  • 【Tools】Windows下Git 2.48安装教程详解
  • [数据抓取] Python 网络爬虫 - 学习手册
  • 硬件基础(4):(1)AD采集电路设计
  • 使用express创建服务器保存数据到mysql
  • 【Linux】权限相关知识点
  • GPU编程实战指南01:CUDA编程极简手册
  • P6412题解
  • 前端快速搭建Node服务(解决跨域问题)
  • HCIA复习拓扑实验
  • 【项目日记(十)】瓶颈分析与使用基数树优化
  • 快乐数 力扣202
  • FreeSWITCH 之 chat
  • π0及π0_fast的源码剖析——核心模块src的全面分析与解读:如何实现PaLI-Gemma、如何去噪生成动作
  • ROS分布式部署通信
  • C#类型转换基本概念
  • 【江协科技STM32】ADC数模转换器-学习笔记
  • 考研数一非数竞赛复习之Stolz定理求解数列极限
  • 【CVPR2025】 EVSSM:用状态空间模型高效去模糊
  • LINUX网络基础 [五] - HTTP协议