C++经典面试题之深入解析const修饰指针的作用

一、前言

  • 我们知道,当一个变量用 const 修饰后就不允许再改变它的值,那么如果在定义指针变量的时候用 const 修饰会怎样呢?
  • 同样,要在定义的时候进行初始化,如下所示:
int  a;
int  *p = &a;
  • 当用 const 进行修饰时,根据 const 位置的不同有三种作用,原则是:谁被修饰谁的内容就不可变,其它的都可变。

二、const int *p = &a

  • 其实,在 const int*p = &a 中 const 和 int 可以互换位置,二者是等价的。当把 const 放最前面的时候,它修饰的就是 *p,那么 *p 就不可变,*p 表示的是指针变量 p 所指向的内存单元里面的内容,此时这个内容不可变,其它的都可变,如 p 中存放的是指向的内存单元的地址,这个地址可变,即 p 的指向可变,但指向谁,谁的内容就不可变。
  • 这种用法常见于定义函数的形参,例如 printf 和 scanf,它们的原型中很多参数都是用 const 修饰的,这样做的好处是安全。我们通过参数传递数据时,就把数据暴露了,而大多数情况下只是想使用传过来的数据,并不想改变它的值,但往往由于编程人员个人水平的原因会不小心改变它的值,这时在形参中用 const 把传过来的数据定义成只读的,这样就更安全,这也是 const 的最有用之处。
  • 因此,如果不想改变某个参数传过来的值,那么定义函数时就最好用 const 修饰这个参数,否则就不要用 const 修饰。

三、int *const p = &a

  • 此时 const 修饰的是 p,因此 p 中存放的内存单元的地址不可变,而内存单元中的内容可变,即 p 的指向不可变,p 所指向的内存单元的内容可变。

四、const int *const p = &a

  • 此时 *p 和 p 都被修饰,那么 p 中存放的内存单元的地址和内存单元中的内容都不可变。

五、总结

  • 综上所述,使用 const 可以保护用指针访问内存时由指针导致的被访问内存空间中数据的误更改。因为指针是直接访问内存的,没有拷贝,而有些时候使用指针访问内存时并不是要改变里面的值,而只是要使用里面的值,因此要小心不要把里面的数据修改。
  • 需要注意的是,在上面的“const int *p = &a”情况中,虽然在 *p 前加上 const 可以禁止指针变量 p 修改变量 a 中的值,但是它只能“禁止指针变量 p 修改”,也就是说,它只能保证在使用指针变量 p 时,p 不能修改 a 中的值。
  • 我们并没有说 const 可以保护 a 禁止一切的修改,其它指向 a 的没有用 const 修饰的指针变量照样可以修改 a 的值,而且变量 a 自己也可以修改自己的值。
  • 现有如下代码:
# include <stdio.h>
int main(void) {
    
       
    int a = 10;
    const int *p = &a;
    int * q = &a;
    *q = 20;
    printf("a = %d\n", a);
    a = 30;
    printf("a = %d\n", a);
    // *p = 30;  // 错误写法
    return 0;
}
  • 运行结果是:
a = 20
a = 30
  • 可见,只有用 const 修饰过的指针变量 p 不能修改 a 中的内容,而没有用 const 修饰过的指针变量 q 照样可以修改 a 中的内容,而且 a 自己也可以重新给自己赋值。

おすすめ

転載: blog.csdn.net/Forever_wj/article/details/128864117