假如说你正在开发一个底层的程序,那与内存的直接交互是不可避免的,程序当中会存在不少指针。用指针来操作内存十分灵活,但也是不少问题的根源,减少这些问题就是这篇文章的目的。
在我正式开始讲解之前,需要让大家熟悉一种并不常用的写法。
定义一个const指针,比如:
const int* ptr;
当然我们还可以这样写:
int const * ptr;
以上两种写法是等价的。我必须强调一下,第二种写法是比较正式的,只不过第一种用的多而已。如果你刚刚学完C++语言,可能会把第二中写法与int * const ptr;混淆,请注意const关键词与 * 的位置。
实际情况当中,我们可能会需要一个指向指针的指针,比如:
int ** ptr;
现在,我们需要给他一个值,比如
ptr = &count_ptr;
count_ptr也是一个指针,如果count_ptr的类型为int*,这是没有任何问题的。但如果count_ptr的类型是const int*呢?这样的话,我们必须写为这样:
int const ** ptr; //与const int ** ptr;等价
那如果count_ptr的类型是int* const呢?ptr定义语句当中的const的位置必须改变。它正确的写法是:
int * const * ptr;
const关键字在两个 * 的中间,定义语句开始变得难读了。当然我们掌握了正确的阅读方法,就不会有任何问题。指针的定义是从右到左阅读的,首先观察离ptr这个名字最近的 * ,它的左面有const,右面没有关键字,这代表ptr指向了一个常量,而它本身则是一个普通变量。然后向左看,观察第二个,也是离ptr比较远的 * ,它的左面没有关键字,右面有const,这代表ptr指向的指针(就是count_ptr)所指的内容为普通变量,但它本身是个常量。
以此类推,我们要让ptr本身也是一个常量,可以这样写:
int * const * const ptr;
注意,让ptr本身成为常量的关键字是第一个 * (从右到左数)右面的const。
如果count_ptr所指的内容同样为常量,可以这样写:
int const * const * const ptr;
到这里,你就会明白我为什么在一开始提到那种写法。让const关键字贴近 * ,会使这种复杂的定义语句更容易阅读。