C++基础:指针和const限定符

指针和const限定符之间存在着两种交互类型:指向const对象的指针和const指针。两种类型的含义相信都不难理解(下文马上介绍),但是在具体的应用环境下,相信还是会有很多初学者犯迷糊。尤其是面临找工作的初学者,如果不能弄清const和指针之间的一些细致的区别和联系,可能会给你的笔试或面试带来麻烦。

本文的所有基础知识均来源于《C++ Primer》中文版第四版,P110页,去读读吧:)

当const用于限定一个基础对象时,意义再清楚不过了,例如:

const double c_pi = 3.14;  //double const c_pi = 3.14;

上面两句代码代表的意思是一样的,事实上,const在限定类型的时候,放在类型前和放在类型后都是没有问题的(后面的一个试验将进一步证明这一点)。

但是,当把指针加进来时,情况变得稍微复杂了一些。

1. 指向const对象的指针

const double *cptr;

以上cptr就是一个指向double类型const对象的指针。但是cptr本身并不是const的,则你可以使用改变cptr指针本身的值(做指针运算或将其指向另一个对象),但是不能用cptr去改变它所指向对象的值。再来看以下代码:

const double c_pi = 3.14; double pi = 3.14; double* ptr; const double* cptr;//节省篇幅,写为一行

则以下的做法:

a. ptr = &c_pi;     //error!

b. ptr = π

c. cptr = &c_pi;

d. cptr = π

以上的代码,a是不对的(编译出错),其他都是可行的。注意d,也就是说,允许将非const对象赋给指向const对象的指针。这样的话,就不能通过cptr来修改pi的值,但是,pi的值可以通过其他的渠道修改,也就是说,cptr所指向的对象只是说不可以通过cptr解引用以后修改,但是仍有可能通过其他的方式来修改(如果基础对象本身是非const的话)。

在实际的应用中,指向const对象的指针,常用于做函数的形参,确保传递给函数的实际对象不会因为形参而被修改。指向const对象指针的另一个用途是用来指向const对象(必须用 "指向const对象的指针" 来指向const对象)。

2. const指针

int num = 9;

int* const c_ptr = #

以上的代码定义了一个const指针,可以从右向左练作 "c_ptr是const指针,它指向int型对象"。const指针的意思与其他const对象一样,即指针本身的值不可修改,不能进行指针运算,不能让其再指向另外一个对象,甚至不能赋回同样的值(如:c_ptr = c_ptr; //error!)。但是指针本身指向的基础对象可以使用指针解引用后修改其值。

你或许已经全部理解了,好,我们再来看看以下的代码(不要犯迷糊哦,因为下面代码的目标就是要让你犯迷糊,但是,我的终极目标是让你不再迷糊,ohyeah! ):

        const int c_num = 5;

        int num = 6;

a.     int const *ptr_0; 

b.     int const *ptr = &c_num;

c.     int const *ptr_1 = #

d.     int * const ptr_2;//-----------------------error!

e.     int * const ptr_3 = &c_num;//----------error!

f.     int * const ptr_4 = #

g.     ptr = ptr;

h.     *ptr = 7;//----------------------------------error!

i.     *ptr_1 = 7;//--------------------------------error!

j.     ptr_4 = ptr_4;//----------------------------error!

k.     *ptr_4 = 7;

上面的代码,其实主要在考察(int const*)和(int* const)到底是两个什么东西,int* const不用说,是const指针;int const*其实和const int *一样。一个很简单的记忆方法是从右往左来阅读定义。上面代码错误的原因依次为:

d错误的原因是const指针必须初始化;

e错误的原因是试图用const指针指向const对象,const对象必须用"指向const对象的指针"来指向,而不是const指针,这是要特别注意的!

h和i用于演示使用"指向const对象的指针"是无法改变基础对象值的,无论其所指向的对象是否是const;

j的错误在于试图改变const指针本身的值。

通过上面的说明,我想我们都应该能够区分以下的声明了:

int * const ptr;//-------error!

int const *ptr;

const int *ptr;

3. 指向const对象的const指针

如果把两者结合起来,就是指向const对象的const指针,意义也是将两者结合起来:既不能修改指针值,也不能通过该指针修改其所指向的对象。

const int c_num = 4;

int num = 5;

const int* const ptr = &c_num;

cosnt int* const ptr_1 = #

上面的代码都是对的,原因相信不用多解释了吧,呵呵。

4. 再加上typedef

如果把typedef加进来,问题又变得迷糊了。

typedef string *pstring;

cosnt pstring cstr;

cstr到底是(const string*)呢,还是(string *const)?答案是后者,如果此时你把typedef当作文本扩展,就极有可能弄错cstr的真正含义。再看如下代码:

string str;

typedef string* pstring;

a. const pstring cstr_1 = &str;

b. pstring const cstr_2 = &str;

c. string* const cstr_3 = &str;

上面a、b、c所声明的都是const指针,注意a和b也再次说明了const与类型的前后关系是不确定的,C++ Primer建议将const放在类型前面。

5. 总结

没什么说的,希望我们都不再迷糊,o(∩_∩)o...哈哈!ps:C++ Primer很好很强大!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值