user-0 提问: 内存管理中局部常量为什么有的改变,有的不改变?

回复:
user: user-1
content: 引用 14 楼 zaixiankaifa 的回复:int main() { 	int *pi=(int*)&ci; //	*pi=200;  	const  int ci2=300; 	//ci2=200; 	pi=(int*)&ci2; 	*pi=200; 	printf("ci2=%d\n",ci2); 	printf("*pi=%d\n",*pi);  	printf("&ci2=%x\n",&ci2); 	printf("pi=%x\n",pi);  return 0; }  localhost:linux root# a.out ci2=300 *pi=200 &ci2=50794dec pi=50794dec  我加了两条打印信息,把ci2地址和pi都打印出来,结果发现,ci2地址和pi相同,这就很奇怪了,相同的地址,居然指向不同的变量?   这是为什么  这是你的理解错误；  ci2地址和pi相同这是正确的，因为pi的值就是ci2的地址值。 ----看这条语句 pi = (int*)&ci2; ------ 把ci2的地址值（&ci2） 强制转换成 int*，并赋值给pi  地址只是变量(数据)，或者函数（代码）在内存中的位置。 C,C++ 通常用 某种整型量，表示地址的值。

user: user-2
content: 当然了，你通过指针，然后就要改这个内存，编译器就没有办法了

user: user-2
content: 这个有啥说的，发现变量是const类型的就报编译错误呗

user: user-0
content: 引用 8 楼 ggglivw 的回复:直接赋值改变const，vs2005还是08开始就会报编译错误，你直接编译不过   直接赋值改变const ? 能讲讲机制原理是怎么样的么?

user: user-2
content: 直接赋值改变const，vs2005还是08开始就会报编译错误，你直接编译不过

user: user-3
content: pi=(int*)&ci2; 这一行在编译的时候是会有一个warning的, 被你忽视掉了. 把一个const int的变量的地址赋给一个没有const修饰的int *变量, 在逻辑上是有错误的. 在正式的软件开发中, 除了error外, 所有编译warning也都要消除掉的.  具体这个问题, const int的变量保存在什么地方是由编译器决定的. 一种情况是保存在普通变量data段, const只是给编译器看的. 你使用类型强制转换绕过编译器的检查, 就可以强制修改了. 另一种情况保存在常量区域如text段, 这个段加载后会把对应的内存页表修改为read only, 所有对它的修改都无效.  也就是说一个逻辑上错误的代码, 编译器可以自主选择处理方式, 从而带来结果的不确定性.

user: user-0
content: 引用 5 楼 ggglivw 的回复:const也只是内存中一个东西而已，这个不改变是编译器在编译阶段的保证，防止你手误，如果你硬要通过指针修改内存的值，他也没用办法  那为什么直接赋值过去改变不可以滴?  既然是在栈里面,使用指针可以改变,赋值改变为什么不可以? 不是很懂,请教一下

user: user-2
content: const也只是内存中一个东西而已，这个不改变是编译器在编译阶段的保证，防止你手误，如果你硬要通过指针修改内存的值，他也没用办法

user: user-4
content: 引用 14 楼 zaixiankaifa 的回复:int main() { 	int *pi=(int*)&ci; //	*pi=200;  	const  int ci2=300; 	//ci2=200; 	pi=(int*)&ci2; 	*pi=200; 	printf("ci2=%d\n",ci2); 	printf("*pi=%d\n",*pi);  	printf("&ci2=%x\n",&ci2); 	printf("pi=%x\n",pi);  return 0; }  localhost:linux root# a.out ci2=300 *pi=200 &ci2=50794dec pi=50794dec  我加了两条打印信息,把ci2地址和pi都打印出来,结果发现,ci2地址和pi相同,这就很奇怪了,相同的地址,居然指向不同的变量?   这是为什么 看错了，回答唐突了 你代码的问题，要不就是不同编译器的处理不同 仔细检查一下你的代码...

user: user-4
content: 引用 14 楼 zaixiankaifa 的回复:int main() { 	int *pi=(int*)&ci; //	*pi=200;  	const  int ci2=300; 	//ci2=200; 	pi=(int*)&ci2; 	*pi=200; 	printf("ci2=%d\n",ci2); 	printf("*pi=%d\n",*pi);  	printf("&ci2=%x\n",&ci2); 	printf("pi=%x\n",pi);  return 0; }  localhost:linux root# a.out ci2=300 *pi=200 &ci2=50794dec pi=50794dec  我加了两条打印信息,把ci2地址和pi都打印出来,结果发现,ci2地址和pi相同,这就很奇怪了,相同的地址,居然指向不同的变量?   这是为什么 强制类型转换的过程中都对应一个临时变量的问题，所以输出结果不一样

user: user-0
content: int main() { 	int *pi=(int*)&ci; //	*pi=200;  	const  int ci2=300; 	//ci2=200; 	pi=(int*)&ci2; 	*pi=200; 	printf("ci2=%d\n",ci2); 	printf("*pi=%d\n",*pi);  	printf("&ci2=%x\n",&ci2); 	printf("pi=%x\n",pi);  return 0; }  localhost:linux root# a.out ci2=300 *pi=200 &ci2=50794dec pi=50794dec  我加了两条打印信息,把ci2地址和pi都打印出来,结果发现,ci2地址和pi相同,这就很奇怪了,相同的地址,居然指向不同的变量?   这是为什么

user: user-5
content: const  int ci2=300; //const承诺不变 //ci2=200; pi=(int*)&ci2; //(int*)这就变了心，哎 *pi=200; printf("ci2=%d\n",ci2);//相信你的承诺，直接读入300

user: user-6
content: 不要纠结各种常量了，这个世界上唯一不变的就是变化。用API WriteProcessMemory还能修改正运行的其它进程的内存里面的所谓常量呢！

user: user-7
content: 常量折叠？ 不同编译器实现不同。 const在我看来只是逻辑上的东西，故意揪编译器的实现没多大意义。

user: user-8
content: const其实只是编译层面的保证

user: user-9
content: 既然开始声明了一个变量为const，为什么后来又想改变他的值？  如果知道这个值在以后是会被修改的，何必把他声明成const的？  这样做只会使代码前后矛盾，越来越难以理解。  与其把时间花在各种trick上，不如好好想想怎样设计比较合理。

user: user-10
content: 何不问老师！！