C++中的指针与引用详细解读.docx
- 文档编号:23462761
- 上传时间:2023-05-17
- 格式:DOCX
- 页数:15
- 大小:403.19KB
C++中的指针与引用详细解读.docx
《C++中的指针与引用详细解读.docx》由会员分享,可在线阅读,更多相关《C++中的指针与引用详细解读.docx(15页珍藏版)》请在冰豆网上搜索。
C++中的指针与引用详细解读
C++中的指针与引用详细解读
1、指针和引用的定义
在深入介绍之前我们首先来看一下指针和引用的定义、指针和引用的区别,然后分别针对指针和引用展开讨论,深入细节为何有这些差异。
指针的权威定义:
InadeclarationTDwhereDhastheform*cv-qualifier-seqoptD1AndthetypeoftheidentifierinthedeclarationTD1is“derived-declarator-type-listT”,thenthetypeoftheidentifierofDis“derived-declarator-type-listcv-qualifier-seqpointertoT”.Thecv-qualifiersapplytothepointerandnottotheobjectpointerto.
——摘自《ANSIC++Standard》
注:
可能有些读者并不明白cv-qualifier-seq
CV-qualifiers(CV限定符)
CV-qualifiers有三种:
const-qualifier(const限定符)、Volatile-qualifier(volatile限定符)、以及const-volatile-qualifier(const-volatile限定符)。
const类对象的非静态、非mutable、以及非引用数据成员是const-qualified;
volatile类对象的非静态、非引用数据成员是volatile-qualified;
const-volatile类对象的非静态、非引用数据成员是const-volatile-qualified。
当CV-qualifiers用于限定数组类型时,实际上是数组成员被该CV-qualifiers限定,而非该数组类型。
复合类型并不因其成员被CV-qualifier限定而被该CV-qualifier限定,也就是说,即使复合类型的成员有CV-qualifier限定,该复合类型也不是CV-qualified对象。
引用的权威定义:
InadeclarationTDwhereDhastheform&D1AndthetypeoftheidentifierinthedeclarationTD1is“derived-declarator-type-listT”,thenthetypeoftheidentifierofDis“derived-declarator-type-listcv-qualifier-seqreferencetoT”.Cv-qualifiedreferencesareill-formedexceptwhenthecv-qualifiersareintroducedthroughtheuseofatypedeforatemplatetypeargument,inwhichcasethecv-qualifiersareignored.
——摘自《ANSIC++Standard》
上面这些定义初看有些难懂,如果是这样的话,那说明你对C++还不够熟悉,你还有很长的路要走。
下面用通俗易懂的话来概述一下:
指针-对于一个类型T,T*就是指向T的指针类型,也即一个T*类型的变量能够保存一个T对象的地址,而类型T是可以加一些限定词的,如const、volatile等等。
见下图,所示指针的含义:
引用-引用是一个对象的别名,主要用于函数参数和返回值类型,符号X&表示X类型的引用。
见下图,所示引用的含义:
2、指针和引用的区别
首先,引用不可以为空,但指针可以为空。
前面也说过了引用是对象的别名,引用为空——对象都不存在,怎么可能有别名!
故定义一个引用的时候,必须初始化。
因此如果你有一个变量是用于指向另一个对象,但是它可能为空,这时你应该使用指针;如果变量总是指向一个对象,i.e.,你的设计不允许变量为空,这时你应该使用引用。
如下图中,如果定义一个引用变量,不初始化的话连编译都通不过(编译时错误):
而声明指针是可以不指向任何对象,也正是因为这个原因,使用指针之前必须做判空操作,而引用就不必。
其次,引用不可以改变指向,对一个对象”至死不渝”;但是指针可以改变指向,而指向其它对象。
说明:
虽然引用不可以改变指向,但是可以改变初始化对象的内容。
例如就++操作而言,对引用的操作直接反应到所指向的对象,而不是改变指向;而对指针的操作,会使指针指向下一个对象,而不是改变所指对象的内容。
见下面的代码:
#include
using namespace std;
int main(int argc,char** argv)
{
int i=10;
int& ref=i;
ref++;
cout<<"i="<
cout<<"ref="< int j=20; ref=j; ref++; cout<<"i="< cout<<"ref="< cout<<"j="< return 0; } 对ref的++操作是直接反应到所指变量之上,对引用变量ref重新赋值”ref=j”,并不会改变ref的指向,它仍然指向的是i,而不是j。 理所当然,这时对ref进行++操作不会影响到j。 而这些换做是指针的话,情况大不相同,请自行实验。 输出结果如下: 再次,引用的大小是所指向的变量的大小,因为引用只是一个别名而已;指针是指针本身的大小,4个字节。 见下图所示: 从上面也可以看出: 引用比指针使用起来形式上更漂亮,使用引用指向的内容时可以之间用引用变量名,而不像指针一样要使用*;定义引用的时候也不用像指针一样使用&取址。 最后,引用比指针更安全。 由于不存在空引用,并且引用一旦被初始化为指向一个对象,它就不能被改变为另一个对象的引用,因此引用很安全。 对于指针来说,它可以随时指向别的对象,并且可以不被初始化,或为NULL,所以不安全。 const指针虽然不能改变指向,但仍然存在空指针,并且有可能产生野指针(即多个指针指向一块内存,free掉一个指针之后,别的指针就成了野指针)。 总而言之,言而总之——它们的这些差别都可以归结为”指针指向一块内存,它的内容是所指内存的地址;而引用则是某块内存的别名,引用不改变指向。 ” 3、特别之处const 在这里我为什么要提到const关键字呢? 因为const对指针和引用的限定是有差别的,下面听我一一到来。 常量指针VS常量引用 常量指针: 指向常量的指针,在指针定义语句的类型前加const,表示指向的对象是常量。 定义指向常量的指针只限制指针的间接访问操作,而不能规定指针指向的值本身的操作规定性。 常量指针定义”constint*pointer=&a”告诉编译器,*pointer是常量,不能将*pointer作为左值进行操作。 常量引用: 指向常量的引用,在引用定义语句的类型前加const,表示指向的对象是常量。 也跟指针一样不能利用引用对指向的变量进行重新赋值操作。 指针常量VS引用常量 在指针定义语句的指针名前加const,表示指针本身是常量。 在定义指针常量时必须初始化! 而这是引用天生具来的属性,不用再引用指针定义语句的引用名前加const。 指针常量定义”int*constpointer=&b”告诉编译器,pointer是常量,不能作为左值进行操作,但是允许修改间接访问值,即*pointer可以修改。 常量指针常量VS常量引用常量 常量指针常量: 指向常量的指针常量,可以定义一个指向常量的指针常量,它必须在定义时初始化。 常量指针常量定义”constint*constpointer=&c”告诉编译器,pointer和*pointer都是常量,他们都不能作为左值进行操作。 而就不存在所谓的”常量引用常量”,因为跟上面讲的一样引用变量就是引用常量。 C++不区分变量的const引用和const变量的引用。 程序决不能给引用本身重新赋值,使他指向另一个变量,因此引用总是const的。 如果对引用应用关键字const,起作用就是使其目标称为const变量。 即没有: Constdoubleconst&a=1;只有constdouble&a=1; 总结: 有一个规则可以很好的区分const是修饰指针,还是修饰指针指向的数据——画一条垂直穿过指针声明的星号(*),如果const出现在线的左边,指针指向的数据为常量;如果const出现在右边,指针本身为常量。 而引用本身与天俱来就是常量,即不可以改变指向。 4、指针和引用的实现 我们利用下面一段简单的代码来深入分析指针和引用: #include using namespace std; int main(int argc, char** argv) { int i=1; int& ref=i; int x=ref;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+ 中的 指针 引用 详细 解读
![提示](https://static.bdocx.com/images/bang_tan.gif)