const变量的问题

发布于 2022-09-01 16:35:11 字数 308 浏览 20 评论 0

int main(){

	const int i =0;
	int *j = (int *)&i;
	*j = 2;
	printf("&i =%ld j =%ld \n", (long)&i,(long)j);
	printf("i =%d *j=%d\n", i,*j);
    return 0;
}

输出:
&i =-1081755992 j =-1081755992
i =0 *j=2
指针的地址就是变量i地址,为何*j的值改变了,const的变量i又没变,指针j改变的到底是什么?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

淡忘如思 2022-09-08 16:35:11

用到了C++的常量折叠(常量替换)特性
C++对于基本类型的常量,编译器并不为其分配存储空间;在编译的时候,将它放到符号表中;
在当取符号常量的地址等操作时,才为这些常量分配存储空间,在内存中创建一个它的拷贝,通过取地址访问到的就是这个拷贝而非原始的符号常量;

与#define宏比

define宏在预编译的展开为具体值,程序运行时不再有define的这个宏;
对内存的占用:每处使用宏的地方都会分配到内存;
const常量在编译时处理,程序运行时仍然可见;
对内存的占用:在只读段中分配一块地址存放常量数据,如果常量只是在多处只读使用,将不占用额外的空间;
如果有对常量取地址的操作,将额外分配一块内存拷贝;

与C语言中的const常量比

c语言中没有常量折叠这个特性,使用c编译器编译后执行上述代码,得到的结果都是2;

示例

为了更好理解,在你的例子中再加上一个变量,指向原有的地址,可以确定地址的内容是修改了的;


int main(){

	const int i =0;
	int *j = (int *)(&i);
	*j = 2;
	int *k = (int *)(&i); //这里再次引用&i的地址,其值是变化了的;确定这个地址的内存已经改变
	printf("&i =%ld j =%ld  k = %ld \n", (long)&i,(long)j,(long)k);

	
	printf("i =%d *j=%d *k=%d\n", i,*j,*k);
    return 0;
}

output:
&i =2293572 j =2293572  k = 2293572
i =0 *j=2 *k=2

更多示例参考:http://www.360doc.com/content/12/0824/20/8093902_232153101.shtml

一个人的旅程 2022-09-08 16:35:11

这个问题是因为发生了“常量替换”。正如你所说的,&i和j所代表的地址是一样的,×j = 2 时, i 和 ×j所指向的那块内存值都变成了2 ,也就是说实际上 i = 2 , j = 2 。 但是,为什么输出时 i = 0 , j = 2 呢?因为,i为const变量,在输出时 编译器(注意是编译器的对于const变量的方案)将i的值由2变为了0 ,所以实际上此时i输出的不是真正内存的值而是那个被保护的值 0。因此,×j输出的才是真正的内存值。
重要的事情说三遍 “i = 0 这是编译器的对于const变量的保护方案” “i = 0 这是编译器的对于const变量的保护方案” “i = 0 这是编译器的对于const变量的保护方案”

飘然心甜 2022-09-08 16:35:11

第二个 printf 以及被编译器优化了,即 printf("i =0 j=%d\n",j),就是楼上说的 常量替换。

聽兲甴掵 2022-09-08 16:35:11

慎用指针。C++ 的指针很强大,但是在一般的应用开发中应该弱化指针的作用,所谓的没有金刚钻就别揽瓷器活。

对于一般的应用开发,指针用于下面一些地方就足够了

  • 指向新对象(new),但要记得删除(delete),毕竟不通过new创建的对象离开函数范围就被销毁了。

  • 用于数组,但应该使用索引运算(pArray[index])来使用数据元素,不要通过指针运算(*(pArray + 3))来使用数组元素。

  • 函数指针,把函数作为参数传递

  • 传出参数(慎用,尽量使用引用代替)

可能有其它遗漏的,大家补充吧。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文