const int* pi 和 int* const pi的区别
一、从 const int i 说起
有了 const 修饰的 i 我们不称它为变量,而称符号常量。
这就是 const 的作用。i 是不能在它处重新赋新值了。
无论 const 和 int 哪个在前在后,它们都是一样的,完全等价的。
const int i 等价于 int const i
const int i 与 int a 比较
int a = 10;
a = 20; //这里 a 可以重新赋值
const int i = 10;
i = 20; //错误写法,这里 i 不可以重新赋值
二、 再看看 const int* pi
我们看到变量 pi 前面是 " * " 号, 说明 变量 pi 是一个指针变量。
在 " * " 前面的是 const int ,说明 pi 指针是指向 const int 类型的指针变量。
指向 const int 类型的指针变量 它可以重新指向其他变量,但不可以通过解引用改变指向的数值。
嘿嘿,还有一点, pi 指向的 无论是 const int 类型还是 int 类型都统一的被 pi 看作const int类型。
当然 int const *pi 也是一 样的,前面我们说过,它们实际是一样的。
与 int* pa 比较
int a = 10;
int i = 20;
int* pa = &a;
const int* pi = &i;
eg1:
pa = &i; //正确,可以重新指向
pi = &a; //正确
eg2:
*pa = 30; //正确
*pi = 30; //错误,指向的是一个 const int 类型,不可以给它赋值!
三、int* const pi的语义
变量 pi 前面是 const ,说明 变量 pi是一个常变量。
其次, 前面是 int* ,常变量 pi 是一个指向 int 类型的指针。
pi 不可以改变它的指向,但可以解引用改变指向的值。
与 const int* pa 比较
int a = 10;
int i = 20;
const int* pa = &a;
int* const pi = &i;
eg1:
pa = &i; //正确
pi = &a; //错误
eg2:
*pa = 30; //错误
*pi = 30; //正确
总结
我们区分 const int* pi 和 int* const pi 的最简单的、最直接的办法是看变量 pi 前面是什么,就是说看 pi 和什么先结合,就得到了 pi 本身的属性 和 被指向变量的属性。这样解决问题就 Just so so 了!
四、补充三种情况
情况一:int *pi 指针指向 const int i 常量的情况
const int i = 10;
int* pi;
pi = &i; // 这样可以吗?不行,VC 下是编译错。
const int 类型的 i1 的地址是不能赋值给指向 int 类型地址的指针 pi 的。否则 pi 岂不是能修改 i1 的值了吗!
pi = (int *) &i1; //这样可以吗?强制类型转换可是 C 所支持的。
实践证明,是可以的,可以用 pi 解引用改变指向的值。
情况二:const int *pi 指针指向 const int i 的情况
const int i = 10;
const int * pi;
pi=&i;
两个类型相同,可以这样赋值。很显然,i 的值无论是通过pi 还是 i 都不能修改的。
情况三:用 const int *const pi 声明的指针
int i;
const int * const pi = &i;
pi值不能改,也不能通过 pi 修改 i 的值。因为不管是 *pi 还是 pi 都是 const的。
以上内容来自《彻底搞懂C指针》,如有错误,请大佬指正。
非常感谢您能耐心地看完我的博客!