【C/C++】指针常量、常量指针、指向常量的常指针

目录

  • 1.概念
  • 2. const pointer
  • 3. pointer to a constant
    • 3.1 (pointer to a constant)-constant
    • 3.2 poiner-constant
    • 3.3 (pointer to a constant)-variable
    • 3.4 poiner-variable
    • 3.5 多层级关系时的兼容
    • 3.6 用处
  • 4. a constant pointer to a constant

1.概念

首先明确这几个术语的具体含义:

  1. 指针常量(常指针):英语为:const pointer,即指针自己是常量
  2. 常量指针:英语为:pointer to a constant,即不能通过该指针去修改目标的指针
  3. 指向常量的常指针:英语为:a constant pointer to a constant,指针自己既是常量,也不能通过该指针去修改目标的指针

从英语可以很快速的理解这几个术语的含义,但是由于翻译的问题,就导致大家在初学 C++ 时会很晕头转向,被这几个概念搞的摸不清头脑
同样由于翻译的问题,还存在下面这组术语:

  1. 常量指针:指针自己是常量,这一版翻译主要强调的是指针自己是常量
  2. 指向常量的指针:即不能通过该指针去修改目标的指针,这一组的中文名可以见名思意,一目了然
  3. 指向常量的常量指针:指针自己既是常量,也不能通过该指针去修改目标的指针

而第二组的翻译和第一组的翻译在常量指针的位置刚好出现了两种截然不同的结果,或许这就是很多人在网上搜文章时感觉都不是很统一的原因吧,一部分文章按照第一组翻译去解释意思,另一部分文章按照第二组去解释就会导致看下来更加的晕头转向了

防止读者产生误会,我会在后续使用英语名来代替中文名,另外读者不用过分纠结中文名字,只需要能够分辨清楚 const pointerpointer to a constant 的定义方法与用法即可

2. const pointer

const pointer 意为指针自己是常量,所以无法更改指针的指向,并且一定要对指针进行初始化
定义方法如下:

 int a=1;
 int *const p1=&a;

const 放在 * 后面,强调修饰的是 p1 ,所以 p1 是常量,这样有助于读者更好的理解

3. pointer to a constant

pointer to a constant 意为指向常量的指针,指针本身是可以变化的,而且指针可以指向变量也可以指向常量,唯一不行的是通过指针去修改变/常量的值
定义方法如下:

const int *p1;

或者

int const *p1;

const 放在 * 前面,强调修饰的是 *p1 ,所以 *p1 是常量,这样有助于读者更好的理解
pointer to a constant 不要求进行初始化,因为指针本身还是一个变量,只有常量才会要求必须进行初始化
下面的表格给出了 pointer to a constantt 和被指对象的类型的兼容性,表格中所有指针均可以重新指向别的对象

pointer to a constant(指向常量的指针) poiner(普通指针)
constant(常量) ×
variable(变量)

下面来逐一分析表格中的情况:

3.1 (pointer to a constant)-constant

对应下列的代码:

const int a=1;
const int *p1=&a;

该代码定义了一个常量 a ,并且将指针 p1 指向了常量 a,常量 a 不可以被任何方式进行修改

3.2 poiner-constant

假设下列的语句是合法的(下列语句是错误的):

 const int a=1;
 int *p1=&a;

那么就可以通过 *p1 来修改常量 a 的值,这与常量的概念不符,故不可以让普通指针指向常量

3.3 (pointer to a constant)-variable

对应下列的代码:

int a=1;
const int *p1=&a;

该代码定义了一个常量 a ,并且将指针 p1 指向了变量 a,变量 a 可以被直接修改,但是不可以通过 *p1 的方式对 a 进行修改

3.4 poiner-variable

对应下列的代码:

int a=1;
int *p1=&a;

该代码定义了一个常量 a ,并且将指针 p1 指向了变量 a,变量 a 可以被直接或者使用 *p1 修改

3.5 多层级关系时的兼容

这里先明确一个概念:在上述的代码中,只是涉及到了一层间接关系,即指针指向的是基本数据类型(不是指针),而在多层间接关系中,上述的部分规则将会不再适用
例如下面的代码在一层间接关系中是正确的:

int a=1;
const int *p1=&a;

pointer to a constant 可以与变量进行兼容,只是不能通过指针修改变量
而在二层间接关系时,这样的代码就会失效:

int a=1;
int *p2 = &a;
const int **p3 = &p2;

pointer to a constant 不能和普通指针兼容,若要使 p3 获得 p2 的地址,可以做如下的改动:

int a=1;
int *p2 = &a;
int **p3 = &p2;

或者

int a=1;
const int *p2 = &a;
const int **p3 = &p2;

在涉及到多层间接关系时,不允许 constnon-const 进行混用

3.6 用处

在进行函数调用时,若传参是数组,由于传递的时数组首地址,则可能调用函数时修改了原数组的内容,所以可以在定义函数时,声明 pointer to a constant 的形参,来防止函数内部修改数组,例如:

#include 
using namespace std;
int add(const int *begin,const int *end){
    int sum=0;
    for(;begin!=end;begin++)
        sum+=(*begin);
    return sum;
}
int main(){
    int arr[5]{1,2,30};
    cout<<add(arr,arr+5);
    return 0;
}

定义 add 函数时,形参声明为 pointer to const 防止对数组元素进行修改,同时还带来一个好处:不管入参是否为常量数组,它都可以进行接收,例如在主函数中,把 arr 改为 const 修饰,程序也可以运行,而如果是普通指针用作形参,则不能接收常量数组

4. a constant pointer to a constant

a constant pointer to a constant 含义为:指针的指向不可以改变,指针可以指向变量也可以指向常量,但是不能通过指针去修改变/常量的值,它的性质就像是 const pointerpointer to const 的结合体
定义方法如下:

int a=1;
const int *const p1=&a;

或者

int a=1;
int const*const p1=&a;

你可能感兴趣的:(c++,c++)