const最初的理解

const修饰的量不能再作为左值,初始化完成后值不能被修改!!

C中的const修饰的叫常变量

const int a = 10;
// int b[a];
// 首先这就不行,因为这在C语言中是常变量,本质上a还是个变量只是
// 不能被赋值改变值了
// const只是在语法上保证a不能左值被修改但是底层还是可以通过指针修改,比如
// 下边这段代码输出结果全部都是30
int* p = (int*)&a;
*p = 30;
printf("a = %d  *p = %d  *(&a) = %d\n", a, *p, *(&a));

C++中叫如果初始化给一个数字就叫常量,还可以拿来定义数组呢,但是如果不是一个立即数的话也会退化成一个常变量,类似C中的那种

  const int a = 10;
  int arr[a] = { 0 };//定义数组没问题,因为C++中这个叫常量
  int* p = (int*)&a;
  *p = 30;
  printf("a = %d  *p = %d  *(&a) = %d\n", a, *p, *(&a));
  cout << "a = " << a << "  *p = " << *p << "  *(&a) = " << *(&a) << endl;

运行结果是a = 10  *p = 30  *(&a) = 10

为什么是在这样的呢?因为C++中,所有出现const常量名字的地方,都被常量的初始化值给替换了

但是这段代码确实是已经把a内存中的值给改了

下边这段代码就是const修饰的是常变量了

 int b = 20;
 const int a = b;
 //int arr[a] = { 0 };//定义数组会报错,因为初始值已经不是一个立即数了,退化成常变量了
 int* p = (int*)&a;
 *p = 30;
 printf("a = %d  *p = %d  *(&a) = %d\n", a, *p, *(&a));
 cout << "a = " << a << "  *p = " << *p << "  *(&a) = " << *(&a) << endl;

const与指针的结合

C++中不允许把一个常量的值泄露给一个普通的指针或者引用(会被间接给修改了)

下面这种写法就是不允许的

    const int a = 10;
    int* p = &a;

const与一级指针的结合

C++中const修饰的是离它最近的类型(看这种东西就把int去掉就好看了)

const int* p;              *p不可以变,p可以变

int const* p;              这种和上边其实是一样的

int * const p;             p是常量不可以改,但是*p可以改,p不可以指向别人

const int * const p;   p和*p都不可以改了

常量的地址给一个这样的指针是可以的

    const int a = 10;
    const int* p = &a;

把一个普通变量的地址给一个const指针是可以的,可以理解为向更安全的级别转换是可以的

    int a = 10;
    int const* p = &a;

下边这行代码也没问题,详情看注释

    //下边表示p2是一个常量,p2不能泄露给一个二级指针,
    //const后边没有*的话,不参与类型的,所以下边这行代码的左右两边都是int*类型
    //所以可以赋值成功
    int* const p2 = &a;

const与二级指针的结合

第三个还必须初始化,因为这东西如果允许不初始化,那么后边在想使用赋值的时候也使用不了,因为const修饰的是p3本身,所以必须初始化,不初始化就会报错。

//const和二级指针结合有三种
const int** p;//**p不可以改,*p和p都是可以改的
int* const* p2;//*p2不可以改,**p2和p都可以改
int** const p3 ;//p3可以改,但是**和*可以改,这条代码必须初始化

如果试图将const int**转换成int**是错误的

如果试图将int** 转换成const int**也是错误的

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐