const与指针

const与指针

const限定符与指针结合的时候,经常会让人迷惑。本文根据《C++ Primer》上给出的一些解释谈谈自己的理解:

指向常量的指针(pointer to const)

先来看一则书上的示例:

const double pi = 3.14; // pi是个常量,它的值不能改变
double *ptr = π // 错误:ptr是一个普通指针
const double *cptr = π // 正确:cptr可以指向一个双精度常量
*cptr = 42; // 错误:不能给 *cptr 赋值

double dval = 3.14; // dval是一个双精度浮点数,它的值可以改变
cptr = &dval; // 正确:但是不能通过cptr改变dval的值
  • 上述示例中,cptr就是一个指向常量的指针,不能用于改变指向的对象的值。
  • 而要存放一个常量的地址,只能使用指向常量的指针。
  • 但是可以将一个非常量dval的地址赋值给cptr,根据书上的解释,这里可以理解为,指针cptr会“自以为”指向了常量,所以不能通过该指针去改变其指向的值。

指针常量(const pointer)

同样先来看一则书上的示例:

int errNumb = 0;
int *const curErr = &errNumb; // curErr将一直指向errNumb
const double pi = 3.14159;
const double *const pip = π // pip是一个指向常量对象的指针常量
  • 这里我对const pointer采取的翻译是“指针常量”而不是书中的“常量指针”。因为我觉得,const pointer就是一个常量,其类型是一个指针,所以称“指针常量”可能比较符合我个人对其具体含义的理解。
  • 而“常量指针”应该理解为上文提到的“指向常量的指针”。
  • 上面的例子中curErr的例子说明,curErr指向的可以是变量,但是这个指针本身是个常量。
  • 而比较难以理解的是pip这个例子,书上给出的一种理解方式是,从右向左阅读:
    • 变量名pip左边是const,说明pip是个常量
    • 再向左看是*,说明pip是个指针,这就可以说pip是个指针常量。指针的值不能改变。
    • 接着是const double,说明指针常量pip指向的是一个双精度常量。pip所指向的对象不能改变。
  • 所以可以说,pip既是一个常量指针又是一个指针常量。

与类型别名的联系

在类型别名部分,也有一个与const和指针相关的例子:

typedef char *pstring;
const pstring cstr = 0; // cstr是指向char的常量指针

而在理解cstr的类型的时候,不能简单将其声明语句理解为:

const char *cstr = 0;

后者数据类型是char*成为了声明符的一部分,const char成了基本的数据类型。

前后两种声明的含义是不同的,前者声明了一个指向char的指针常量,后者声明了一个指向const char的常量指针。

参考书目

  1. C++ Primer(中文第5版)
原文地址:https://www.cnblogs.com/yanhewu/p/8378105.html