标签:
大家看到const关键字, 大多数人会不会认为它是一个const常量, 我告诉大家这是错误的认知, 那么它实际的意义是什么呢? 其实const不能把变量变成常量, 而是把一个变量, 变成了一个只读变量, 所以我们不能直接修改它的值, 但是我们可以通过它的地址, 来修改它的值.
1. const的普通用法
// const int n = 5;
int const n = 5; // 这两句话的作用是一样的, 都是声明了一个名为a的只读变量, 我们不可以直接修改a的值.
int a[n] = {1, 2, 3, 4, 5}; // 要求数组的大小是一个常量, 也就是说是一个确定的值, 而n是一个只读变量, 也就是说在n初始化时就有了一个确定的值, 所以可以用来当作数组的大小
2. const用于指针
int a = 5;
int b = 10;
//const int * p = &a;
int const * p = &a; // 这两句话的作用也是一样的, 都是声明了一个名为p的常量指针, 也就是说p所对应的存储空间是只读的, 我们不能通过p来改变其中的内容
p = &b; // 正确的写法
*p = 20; // 错误的写法, 因为const修饰是*p, 所以*p是只读的, 我们不能向只读的存储空间中写入数据(p所指向的b是一个变量, 而不是一个常量, 但是这也不行)
b = 20; // 正确的写法, 因为b是一个变量, 没有const修饰b
---------------------------------------------------------------------------------------
int * const q = &a; // 作用: const位于*的右侧, 声明q是一个指针常量
q = &b; // 错误的写法, q是一个只读的指针变量, 我们不可以对其重新赋值
*q = 20; // 正确的写法, 因为*q前并没有const修饰, 所以q指向的存储空间还是可读写的, 所以*q是一个变量, 而不是一个常量, 我们可以通过q来修改对应存储空间中的内容
b = 20; // 正确的写法
大家要看一下const所在的位置是不同的, 所以起到的作用也是不同的, 大家要多我思考. 总结: 1. const在*左侧, 则不能改的是*p, 也就是说不能这样赋值: *p = 20; 2. const在*右侧, 则不能改的是p, 也就是说不能这样赋值: p = &b;
3. const的几种情况:
1)
int main() {
const int a = 5;
int * p = (int *)&a;
*p = 10;
printf("%d\n", a);
printf("%d\n", *p);
}
// 我们发现打印出来a是值是5, *p的值是10. 为什么会出现这样的情况呢? 难道是存储空间会存储不同的两个值? 当然不会, 因为编译器在预处理时, 只对const修饰的变量值读取一次, 所以打印出来a是5, 实际上我们通过指针变量p改变了a的值, 所以实际上a的值是10. 总结: 1. const修饰的局部变量存储在堆栈中, 我们可以通过指针修改它的值. 2. 编译器只对const修饰的变量的值读取一次, 就是在预处理的时候. 3. 如果a是一个const修饰的全局变量, 则这样写就不可以了, 因为它的值是存储在全局存储空间中, 其值只有可读属性, 不能修改.
也就是说下面这样写是不可以的:
const int a = 5;
int main() {
int * p = (int *)&a;
*p = 10; // 这样写就是错误的了.
printf("%d\n", a);
printf("%d\n", *p);
}
2)
int a = 5;
int b =10;
const int * const p = &a; // 指针本身和指针所指向的存储空间都是只读的.
p = &b; // 错误的写法, 因为p前面有const修饰, 所以p是一个指针常量, 也就是说p的值是不能被重新赋值的.
*p = 20; // 错误的写法, 因为*p前面有const修饰, 所以*p是一个常量, 也就是说p是一个常量指针, 它所指向的存储空间是只读的.
// ok, const的基本使用就说到这里, 大家可以回过头去对比一下, 认真思考, 相信会有不小的收获...
标签:
原文地址:http://www.cnblogs.com/ZeroHour/p/4341865.html