网站首页 > 基础教程 正文
把指针和引用放在一起说,不表示指针和引用很相似,难以区分,实际上他们的共同点非常少。指针和引用都跟内存中的某块地址绑定在一起。正是因为这个共同点,初学者常常把引用等同于指针。这是灾难性的。
(一)从概念上区分指针和引用
指针可以理解为一种特殊的数据对象。一般的变量值,是由一系列比特位表示的数字或字符。而指针的变量值,当然也是一个长整型数值,但这个长整型值有特殊的涵义,它表示内存块的地址。
如果是非const的指针,它的值是可以变化的。
引用是C++引入的概念,C里面没有。它是一个变量别名。怎么理解?引用初始化的时候,赋给该引用的地址,必须是用过的,即跟一个已知变量绑定的。也就是说,不能给赋给引用没使用过的内存,引用的值也不能为NULL。也就是说,至始至终,引用只是一个已知变量的别名。它不独立存在。在编译器的符号表中,变量本名和别名指向同一地址。
(二)指针和变量的行为差别很大
理解了指针和引用的概念,也就不难理解以下它们的差别。
指针定义的时候不必初始化,可以是NULL值。引用则都不可以。
指针的值是可变的。引用一经初始化,它的值是不可更改的。注意,一旦定义了一个引用,访问它和访问变量名本身的方式和效果是一致的。这是理解引用的关键。如:
int x = 0; int& a = x;
执行a++,x和a的值都是1。执行x++效果是一样的。
如果定义 int y = 0; 并让 a = y; 效果是a和x的值变成0,并不是引用a跟变量y的地址绑定。同样的规则对类,结构和数组都适用。
相应的,如果定义了一个指针p,执行p++,其涵义完全不同。C++对指针的自增运算符做了重载。
常量指针和指向常量的指针都是C++支持的。由于引用生来就是常量,所以不存在常量引用的说法。但是绑定到常量的引用是有意义的。
引用的大小由对应的对象大小决定。指针的大小由操作系统的位数来决定。32位操作系统一般4个字节。64位操作系统一般是8个字节。
引用是类型安全的,而指针不是。后面有会一章专门来介绍指针。
(三)为什么要引入引用的概念?
没有引入引用之前,C中的函数调用,如果要保存更改到输入参数,只能通过指针来实现。这样做,有两个劣势。其一,不够直观。其二,涉及到对象传递,效率低下。下面结合一个引用的例子,来说明引用作为地址参数传递,是如何克服这两缺点的。试看:
#include <iostream>
using namespace std;
void exchange(int& x,int& y){
int temp = x;
x = y;
y = temp;
}
int main(){
int x=1,y=2;
exchange(x,y);
cout << "x=" << x <<endl;
cout << "y=" << y <<endl;
}
函数exchange交换引用参数x和y的值。调用函数时,直接赋予对应类型的变量为参数即可,没有多余的*或者&,地址的概念被隐藏了。x和y的值最后被交换过来了,很直观吧。
关于效率,如果是传指针给函数,按传值模式来处理函数调用。也就是说,函数要给对应的实参(指针),生成一个副本并入栈,如果指针指向的对象较大,则开销会比较大。如果是传引用给函数,函数被调用的时候,简单地把该地址入栈,读取时,直接按该地址寻址即可,对象的大小就无关痛痒了。
(四)引用的其它用途
由于引用在函数调用时的优势,C++对于运算符的重载,拷贝构造函数的实现,都依赖于引用。这两个概念,后面章节也会介绍到。
- 上一篇: Java中关于引用的介绍 java中引用的概念
- 下一篇: 指针和引用的区别 指针和引用的区别知识讲解
猜你喜欢
- 2024-10-09 探讨C++中引用变量的原理以及特点
- 2024-10-09 C++编程:函数参数类型-引用、指针、值
- 2024-10-09 C++ 引用,如何定义对象的常引用?linux C++第50讲
- 2024-10-09 深入浅出C++引用:理解与应用 c++引用的含义
- 2024-10-09 c++引用详解 c++引用怎么写
- 2024-10-09 c语言-指针和引用的理解 c中指针和引用的区别
- 2024-10-09 2 C++重点概念理解系列2-理解引用的本质
- 2024-10-09 C++|指针,理解指针从为什么需要指针这种数据类型开始
- 2024-10-09 C|函数指针和指针函数的联系与区别
- 2024-10-09 const、指针、引用的关系 const与指针的关系
- 最近发表
- 标签列表
-
- gitpush (61)
- pythonif (68)
- location.href (57)
- tail-f (57)
- pythonifelse (59)
- deletesql (62)
- c++模板 (62)
- css3动画 (57)
- c#event (59)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- exec命令 (59)
- canvasfilltext (58)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- node教程 (59)
- console.table (62)
- c++time_t (58)
- phpcookie (58)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)