透彻理解C++中const的含义

关于const修饰变量、参数、返回值、成员函数不同的意义,网上有很多讲解的,这里不再赘述。在Dan Saks的一篇讲解const的文章中非常清楚的从编译器角度讲了const的含义,本文只做一定的总结,原文参考http://blog.csdn.net/bianbian17556231/archive/2010/03/20/5398276.aspx
先看一个例子:

typedef char* VP;
const char *data[3] = {"I","Love","u"};      (1)
const VP data1[3] = {"I","Love","u"};       (2)

data[1] = "hate";       //能正常修改
data1[1] = "hate";      //编译器报错,提示data1[1]是无法修改的左值

根据编译器报错的提示信息,你可能猜到了在(2)式中的指针变为了常量指针,而(1)没有改变。那为什么会造成这种情况呢,这得从编译器的角度来说明变量的申明顺序问题。
1)对c和c++中的声明做透彻分析,之前我们觉得不就一个声明嘛,就是定义一个变量而没有初始化嘛,有啥好讲的。我之前也是这样不求甚解,自从看了Dan Saks的文章后,我才明白专家之所以能成为专家是有道理的。。。
c和c++中声明包含零个或者多个声明说明符,和一个声明符
例如:static unsigned long int *x[N];
static unsigned long int :声明说明符
*x[N] :声明符
a) 一个声明符就是被声明的名称,可能还伴有操作符,如,(),[],&等,以本例为例,*表示x是一个指针,[]表示序列, *x[N]表明x是含有N个指针的序列。
可能基础比较弱的人一直分不清楚指针数组和数组指针,以及返回指针的函数和函数指针怎么写。其实与运算符一样,操作符也是有优先级的,在本例中[]的优先级要比*的优先级高,所以首先其是一个序列,然后才声明序列中的元素是指针。而(*x)[N]中()的优先级比[]的优先级高,所以首先确定了其是一个指针。

b)声明说明符包含类型说明符和与类型无关的说明符,分清楚这个对于理解例子中的两个例子为什么会出现不同的情况至关重要。注意在1)式中char是类型说明符,而const是与类型无关的说明符,所以1)式中const并不会修饰变量data,应该理解为指向const char的指针序列,而不是指向char的const指针序列。。

c)声明说明符在一个声明中出现的顺序并不重要,如:

const void *data[N];
void const *data[N];

这两者实际上是等价的,但是要注意对于指针的声明是从右到左来看的,所以对于在对指针的声明说明符中,正确的写法应该将const放在类型说明符的右边。如:

T const *p
T* const p

上面的式子中表示指向const T的指针,而下面的式子修饰了操作符*则表示指向T类型的const指针,说以对于最开始的问题中的2)按照正确的写法应该是:

VP const data1[3] = {"I","Love","u"};
展开:
char* const data1[3] = {"I","Love","u"};

这样对照刚刚的讲解,现在是不是就能理解为什么data1序列中的指针为const类型了。
d)补充说明,良好的编程习惯有时来源于对原理的透彻理解。如很多人会这样写对一个指针的声明

const int* p;
而不是
const int *p;

理解了上面对变量声明说明符和操作符的讲解,相信应该清楚了为什么要推荐下面的这种写法了吧。
本篇博客只是对Dan Saks的文章按照个人的理解做的总结,如有错误,欢迎给出指正。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值