const要点

const要点

  • C的const是虚假的,就是个只读量,只是说不能通过变量名进行修改,但是拿到指针就可修改;
  • C++的const会保险一些,会有类似符号表的东西;但是类内的const普通成员变量则依旧会被通过指针改变
  • 静态const和全局const虽然可以通过指针修改,编译时期可能不会报错,但是运行到那个地方就会报错
  • const只在编译期间保证常量被使用时的不变性,无法保证运行期间的行为。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class A {
public:
const int val2 = 22;
static int val3;
static const int val4 = 44; // !
};
int A::val3 = 33;
const int val5 = 55;
int val6 = 66;
int main() {
const int val1 = 11;
int* p1 = (int*)&val1; // 栈区,拿到地址随便改,但是符号表会覆盖
*p1 = 1111;
cout << &val1 << " " << val1 << endl;
cout << p1 << " " << *p1 << endl;
cout << "===" << endl;

A ins;
int* p2 = (int*)&ins.val2;
*p2 = 2222; // 栈区,拿到地址随便改
cout << &ins.val2 << " " << ins.val2 << endl;
cout << p2 << " " << *p2 << endl;
cout << "===" << endl;

int* p3 = (int*)&A::val3;
*p3 = 3333; // 全局数据区,但是不在常量区,可以修改
cout << p3 << " " << *p3 << endl;
cout << &A::val3 << " " << A::val3 << endl;
cout << "===" << endl;

int* p4 = (int*)&A::val4;
//*p4 = 4444; // 编译不出错,运行会异常(常量区不能修改)
cout << p4 << " " << *p4 << endl;
cout << &A::val4 << " " << A::val4 << endl;
cout << "===" << endl;

int* p5 = (int*)&val5;
//*p5 = 5555; // 编译不出错,运行会异常(常量区不能修改)
cout << p5 << " " << *p5 << endl;
cout << &val5 << " " << val5 << endl;
cout << "===" << endl;

int* p6 = (int*)&val6;
*p6 = 6666; // 全局数据区,但是不在常量区,可以修改
cout << p6 << " " << *p6 << endl;
cout << &val6 << " " << val6 << endl;
return 0;
}

输出结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
00EFFD98 11
00EFFD98 1111
===
00EFFD80 2222
00EFFD80 2222
===
0027C038 3333
0027C038 3333
===
00279B38 44
00279B38 44
===
00279B30 55
00279B30 55
===
0027C03C 6666
0027C03C 6666
*/

C++内存分区

C++内存分区

参考

  1. C++:const常量的存储位置
  2. C/C++的四大内存分区和常量的存储位置
  3. 阿秀的笔记