C++指针、引用与const说明符

本文深入解析C++中的引用、指针及其与const限定符的交互作用,包括引用的特点、指针的操作、指向指针的引用以及const限定符的使用规则。同时探讨了顶层const和底层const的区别,以及如何利用类型别名简化复杂类型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++指针、引用与const说明符
一、引用

int ival = 1024 ;
int &refVal = ival;  //用&+变量名的形式来定义引用类型
int &refVal2;        //错误,引用必须初始化
int &refVal3 = ival, &refVal4 = refVal;  //允许在一条鱼居中定义多个引用,每个引用标示符都必须以&开头

特点:
1、一旦初始化完成,引用将和它的初始值绑定在一起,无法令引用重新绑定到另外一个对象,因此引用必须初始化。
2、定义一个引用之后,对其进行的所有操作都是在与之绑定的对象上进行的。
3、引用不是对象,只是所绑定对象的别名,所以不能定义引用的引用。
4、引用只能绑定在对象上,而不能与字面值或某个表达式的计算结果绑定在一起。
5、一般情况下,引用的类型要和与之绑定的对象严格匹配。
二、指针

int ival = 42;
int *p = &ival;    //p是指向变量ival的指针
*p = 0;            //通过p向变量ival赋值
int *pNull = nullptr;    //生成空指针

特点:
1、指针本身就是对象,允许对指针进行赋值和拷贝,而且在指针的生命周期内可以先后指向不同的对象。
2、指针无需在定义时赋初值,但建议指针一定要初始化。
3、一般情况下,指针类型要与其所指向的对象严格匹配。
4、对指针解引用会得出所指的对象,给解引用的结果赋值,实际上为给指针所指的对象赋值。
5、给指针赋值是指令它存放一个新的地址,从而指向一个新的对象。

注:引用不是对象,没有实际地址,不能定义指向引用的指针。

void* 指针:可用于存放任意对象的地址,但并不能确定该地址中存放的是什么类型的对象。可以将void*指针和别的指针进行比较、作为函数的输入或输出,或者赋值给另外一个void *指针,但不能直接操作指针所指的对象。
三、指向指针的引用

int i = 42;
int *p;         //p是int型指针
//从右向左阅读r的定义,离变量名最近的符号对变量类型有最直接的影响,因此r是一个引用,
//*符号说明r引用的是一个指针,基本数据类型部分指出r引用的是一个int指针
int *&r = p;    //r是对指针p的引用
r = &i;         //给r赋值&i,即令p指向i
*r = 0;         //解引用r得到i,亦即p指向的对象,将i的值改为0

四、const限定符

int i = 42;
const int ci = i;
int j = ci;

特点:
1、const对象一旦创建后其值就不能再改变,所以const对象必须初始化。
2、只能在const类型的对象上执行不改变其内容的操作。初始化操作不改变const对象,如果用一个对象去初始化另一个对象,则它们是不是const无关紧要(顶层const?)
3、默认状态下,const对象仅在文件内有效。
4.1 const的引用
把引用绑定到常量对象(const对象)上,即为对常量的引用。常量引用是对const的引用。

const int ci = 1024;
const int &r1 = ci;    //对常量的引用,引用及其对应的对象都是常量
r1 = 42;               //错误,不能通过对常量的引用修改所绑定对象的值
int &r2 = ci;          //错误,不能将非常量引用绑定到常量对象

特点:
1、对常量的引用不能用于修改它所绑定的对象。
2、不能将非常量的引用绑定到常量对象上,对常量对象的引用,只能使用常量引用。
3、特殊的,针对“引用类型必须与其所引用对象的类型一致”的例外情况:初始化常量引用时允许用任意表达式作为初始值,只要该表达式的结果能够转换成引用类型即可。允许为一个常量引用绑定非常量的对象、字面值,甚至一般表达式。

int i = 42;
const int &r1 = i;             //允许将常量引用绑定到普通非常量对象上
const int &r2 = 42;            //允许将常量引用绑定到字面值
const int &r3 = r1*2;          //允许将常量引用绑定到表达式
int &r4 = r1*2;                //错误,普通非常量引用,只能绑定在对象上,而不能与字面值或某个表达式的计算结果绑定在一起。

4.2 指针和const(指向常量的指针和常量指针)
4.2.1 指向常量的指针
指向常量的指针不能用于改变其所指对象的值,要向存放常量对象的地址,只能使用指向常量的指针。

const double pi = 3.14;             //pi是常量,其值不能改变
double *ptr = π                  //错误,普通指针不能指向常量对象
const double *cptr = π           //指向常量的指针
*cptr = 42;                         //错误,不能通过指向常量的指针修改其所指对象的值
double dval = 3.14;
cptr = &dval;                       //允许令指向常量的指针指向非常量对象,但不能通过cptr修改dval的值

特殊的,针对“指针类型必须与其所指对象的类型一致”的例外情况:允许令一个指向常量的指针指向一个非常量对象。
4.2.2 const指针
把指针本身定义为常量,即为常量指针,常量指针必须初始化,一旦初始化完成,则它的值(存放在指针中的地址)不能再改变。把*放在const关键字之前说明指针是一个常量,不变的是指针本身的值而非指针指向的值。

int errNumb = 0;             
int *const curErr = &errNumb;     //指向非常量对象的常量指针,curErr将一直指向errNumb 
const double pi = 3.14;           
const double *const pip = π    //指向常量对象的常量指针,pip 将一直指向pi,且不能通过pip修改pi的值
*pip = 3.14;                      //错误,pip是指向常量的指针,不能通过pip修改其所指对象的值
*curErr = 0;                       //允许通过curErr修改errNumb 的值

五、顶层const
顶层const表示指针本身是个常量,底层const表示指针所指的对象是一个常量。顶层const可以表示任意的对象是常量,如算术类型、类、指针等;用于声明引用的const都是底层const,指针类型既可以是顶层const,也可以是底层const。
当执行对象的拷贝操作时,顶层const不受影响,底层const的限制不能忽略。执行拷贝操作并不会改变被拷贝对象的值,因此拷入和拷出的对象是否是常量没有影响;但必须具有相同的底层const资格,或者两个对象的数据类型必须能够转换。一般来说非常量可以转换成常量,反之不行。
六、类型别名

typedef double wages;       //wages是double的同义词
typedef wages base, *p;     //base是double的同义词,p是double*的同义词

using SI=Sales_item;        //SI是Sales_item的同义词
typedef char *pstring;
//const是对给定类型的修饰,pstring是指向char的指针,const pstring则是指向char的常量指针,
//而非指向常量字符的指针
const pstring cstr=0;        //cstr是指向char的常量指针
const pstring *ps;           //ps是一个指针,它的对象是指向char的常量指针
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值