【C++ 语言】引用 ( 引用简介 | 指针常量 | 常量指针 | 常引用 | 引用参数 | 引用 指针 对比 )

简介: 【C++ 语言】引用 ( 引用简介 | 指针常量 | 常量指针 | 常引用 | 引用参数 | 引用 指针 对比 )

文章目录

I . 引用概念

II . 引用声明

III . 引用 地址 内存 分析

IV . 常引用

V . 引用作为参数

VI . 引用 与 指针 对比



I . 引用概念


C++ 对 C 扩充 : 引用 ( Reference ) 概念 , 是 C++ 在 C 的基础上进行的扩充 , 在 C 语言中是没有引用的 ;


引用本质 : 引用的本质就是为一个变量指定一个别名 , 这个别名与变量的使用方式是相同的 ;




II . 引用声明


引用声明 :


① 引用声明格式 : 类型标识符 &引用别名 = 目标变量 ;


② 示例代码 :


int a = 0;
int &b = a;



③ 引用标识 : 此处的 & 操作不是取地址运算 , 只是起一个引用标识的作用 ;


④ 类型标识符 : int 是类型标识符 , 注意引用的类型标识符要与被引用的变量相同 ;


⑤ 初始化 : 声明引用的同时 , 必须进行初始化 , 因为引用定义的是一个变量的别名 , 这个变量必须在声明的时候指定 ;


//引用相当于常量指针 , 必须在声明的时候就初始化 , 声明完毕后初始化是无效的 , 编译执行会报错
//错误示例 , 引用声明后必须马上初始化
int a = 0;
//声明的时候必须初始化 , 此时的声明时错误的
int &b;
//此时对引用进行赋值就是错误的
b = a;



⑥ 引用使用 : 引用声明后 , 该引用 b 与 a 是等价的 , 凡是可以使用 a 的地方都可以使用 b ;


注意 : 引用声明完成之后 , 不能讲该引用名称再次声明为其它变量的名称 ;




III . 引用 地址 内存 分析


int a = 0;
int &b = a;


变量 与其 引用地址相同 : 对 变量 a 和 引用 b 取地址操作 , &a 与 &b 的值是相等的 ;

( 引用名称 是 变量名称 的一个别名 )



编译器实现 : 编译器将引用实现为 int * const b 指针 , 其指针本身是常量 , 即存储的地址是不可变的 , 指针指向的内容是可变的 ;

( 既然引用是一个 指针常量 , 说明其还是需要占用内存的 )



const 修饰指针规则 : 左数 右指 (const 在 * 左边数据是常量, const 在 * 右边指针是常量);

左数 ( 常量指针 ) : const 出现在 * 左边时, 指针指向的数据为常量, 指向的数据不可改变;

右指 ( 指针常量 ) : const 出现在 * 右边时, 指针地址本身是常量, 指针地址不可改变;



指针常量 : 表示该指针本身是一个常量 ;

常量指针 : 表示指向一个常量的指针 ;




IV . 常引用


常引用 :


① 常引用简介 : 引用本身是一个常量指针 , 指针本身的地址不可改变 , 常引用 在常量指针的基础上 , 将指向的数据也设置成常量 , 即不能通过该引用修改变量的值 ;

( 引用代表的地址不能修改 <引用自带属性> , 常引用 在引用的基础上 , 指向的数据也不能修改 )



② 常引用声明格式 : const 类型标识符 &引用别名 = 目标变量 ;



③ 示例代码 :


int a = 0;
const int &b = a;



④ 等价说明 : 上述常引用 b 等价于 const * int * b , 即该常引用的引用本身 , 以及其代表的变量 , 都不能通过该引用进行修改 ;


这里注意 , 不同通过引用进行修改 , 但是可以通过变量名称 a 进行修改 ;



⑤ 作用及意义 : 使用 引用数据类型 作为 函数参数 , 如果不需要在 函数中 修改该引用变量的值 ( 指针指向的数据的值 ) , 就将该参数声明为常引用 , 这样能最大限度增加安全性 , 避免因为误操作导致不必要的问题出现 ;




V . 引用作为参数


C 语言中的参数 分类 :


① 普通变量参数 : C 语言中 普通变量 ( 非指针变量 ) 作为参数 , 只能进行值传递 , 不能通过参数返回结果 ;


② 指针变量参数 : C 语言中 , 如果要让函数的参数可以将结果返回 , 则必须使用指针作为参数 ;



C++ 中的引用参数 : C++ 在 C 语言基础上扩展了 引用 数据类型 , 使用引用可以替代上面的指针作为参数的情况 , 使参数具有返回结果的能力 ;



作用及意义 :


① 具有返回值能力 : 使用引用作参数 , 可以将参数当做返回值使用 ;


② 提高参数传递效率 : 大型对象作参数时 , 使用引用类型 , 可以提高参数传递效率 ;




VI . 引用 与 指针 对比

引用与指针的相同点 : 都具有地址的概念 ;


① 指针 : 指针指向内存中的一块空间 , 指针变量的内容是一个内存地址 ;


② 引用 : 引用是变量的别名 , 即某块内存空间的别名 , 相当于一个 指针常量 , 也指向一块内存空间 ;



引用与指针的不同点 :


① 引用比指针更严格 :

引用在定义时必须被初始化 , 而且只能初始化这一次 , 相当于 指针常量 ;

指针 是可变的 , 指针指向的地址 , 以及 地址中的数据 都是可变的 ;

引用的变量值内容可变 , 变量的地址不可变 ;


② 是否可以为空 : 指针可以为空 , 但是引用必须不能为空 , 因其在声明时必须进行初始化操作 ;


③ sizeof 操作区别 : sizeof ( 引用 ) 获取的是被引用的变量的大小 ( 随变量类型变化 ) , sizeof ( 指针 ) 获取的是指针变量本身的大小 ( 固定的 ) ;


④ 类型安全性 : 引用是类型安全的 , 指针类型不安全 , 引用比指针多了类型检查机制 ;


目录
相关文章
|
29天前
|
安全 算法 编译器
【C++ 泛型编程 进阶篇】深入探究C++模板参数推导:从基础到高级
【C++ 泛型编程 进阶篇】深入探究C++模板参数推导:从基础到高级
246 3
|
28天前
|
自然语言处理 编译器 C语言
【C++ 20 新特性】参数包初始化捕获的魅力 (“pack init-capture“ in C++20: A Deep Dive)
【C++ 20 新特性】参数包初始化捕获的魅力 (“pack init-capture“ in C++20: A Deep Dive)
38 0
|
29天前
|
机器学习/深度学习 算法 编译器
【C++ 泛型编程 中级篇】深度解析C++:类型模板参数与非类型模板参数
【C++ 泛型编程 中级篇】深度解析C++:类型模板参数与非类型模板参数
47 0
|
29天前
|
存储 JSON 安全
【C++ JSON库 json值的创建手段】深入探究C++中JSON对象定位与操作:从引用到回调函数
【C++ JSON库 json值的创建手段】深入探究C++中JSON对象定位与操作:从引用到回调函数
62 0
|
29天前
|
设计模式 算法 数据安全/隐私保护
【C++ 引用 】C++深度解析:引用成员变量的初始化及其在模板编程中的应用(二)
【C++ 引用 】C++深度解析:引用成员变量的初始化及其在模板编程中的应用
25 0
【C++ 引用 】C++深度解析:引用成员变量的初始化及其在模板编程中的应用(二)
|
29天前
|
存储 算法 编译器
【C++ 引用 】C++深度解析:引用成员变量的初始化及其在模板编程中的应用(一)
【C++ 引用 】C++深度解析:引用成员变量的初始化及其在模板编程中的应用
39 0
|
27天前
|
监控 安全 算法
悬垂引用与临时对象在C++中的深入探讨: 风险、原因与预防策略
悬垂引用与临时对象在C++中的深入探讨: 风险、原因与预防策略
54 3
|
28天前
|
算法 编译器 C++
【C++ 模板编程 基础知识】C++ 模板类部分特例化的参数顺序
【C++ 模板编程 基础知识】C++ 模板类部分特例化的参数顺序
21 0
|
存储 算法 程序员
【C/C++ 线性表 简介】C/C++中的线性表探索:从标准库到自定义实现
【C/C++ 线性表 简介】C/C++中的线性表探索:从标准库到自定义实现
44 0
|
29天前
|
存储 安全 编译器
【C++ 函数设计的艺术】深挖 C++ 函数参数的选择 智能指针与 std::optional:最佳实践与陷阱
【C++ 函数设计的艺术】深挖 C++ 函数参数的选择 智能指针与 std::optional:最佳实践与陷阱
108 0