求教啊,关于const

ktaurus 2013-11-02 11:53:41
#include <iostream>
using namespace std;

int main()
{
const int a = 1;
int b = 2;
int *p = &b;
*(p + 3) = 3;

cout<<(unsigned)&a - (unsigned)&b<<endl;
cout<<a<<" "<<&a<<" "<<p + 3<< " " << *(p + 3)<<endl;


return 0;
}

以上代码用VS2012编译结果为:
12
1 0103FCC8 0103FCC8 3
请按任意键继续. . .

为什么是12,为什么a没变3...

#include <iostream>
using namespace std;

int main()
{
const int a = 1;
int b = 2;
int *p = &b;
*(p - 1) = 3;

cout<<(unsigned)&b - (unsigned)&a <<endl;
cout<<a<<" "<<&a<<" "<<p - 1<< " " << *(p - 1)<<endl;
return 0;
}



用c-free 编译结果是这样的

4
1 0x23ff38 0x23ff38 3
请按任意键继续. . .

a还是没变3啊。。

求解
...全文
287 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
max_min_ 2013-11-03
  • 打赏
  • 举报
回复
a被常量表达式初始化就成了一个编译期常量. 如果你对a没有取地址操作,编译器会做优化,不会为a划分内存,划分内存也仅仅是为了满足&a. 里面的值会被初始化为i的值.但是在程序上,名字i表示的是原先的值,而不是内存里的值. (盗用了一位前辈的话) 也就是所谓的常量重叠了!
ktaurus 2013-11-03
  • 打赏
  • 举报
回复
你可以用c语言试一下,也有可能是编译器的问题
DavidL 2013-11-03
  • 打赏
  • 举报
回复
引用 2 楼 ktaurus 的回复:
[quote=引用 1 楼 zhanglingxiang1 的回复:] const定义的变量是常量,值不能改变的
问题是确实可以改的, 用C写的话就可以..[/quote] 这个值真不能改,const定义就是为了防止值的修改啊。
ktaurus 2013-11-03
  • 打赏
  • 举报
回复
话说VS2012编译C也不行。。codeblocks就可以。。
DavidL 2013-11-03
  • 打赏
  • 举报
回复
你能保证a,b的地址是连续的吗?不能保证连续那p-1就不会是a的地址
ktaurus 2013-11-03
  • 打赏
  • 举报
回复
引用 1 楼 zhanglingxiang1 的回复:
const定义的变量是常量,值不能改变的
问题是确实可以改的, 用C写的话就可以..
ktaurus 2013-11-03
  • 打赏
  • 举报
回复
引用 17 楼 lunat 的回复:
你改为release试一试。 另外,可以通过调试,看下栈数据。
嗯 release下输出确实是4
lunat 2013-11-03
  • 打赏
  • 举报
回复
你改为release试一试。 另外,可以通过调试,看下栈数据。
引用 16 楼 ktaurus 的回复:
[quote=引用 12 楼 lunat 的回复:] 是当做立即数了,编译器直接把取a值的部分用常量替换了。 [quote=引用 10 楼 ktaurus 的回复:] [quote=引用 7 楼 max_min_ 的回复:] a被常量表达式初始化就成了一个编译期常量. 如果你对a没有取地址操作,编译器会做优化,不会为a划分内存,划分内存也仅仅是为了满足&a. 里面的值会被初始化为i的值.但是在程序上,名字i表示的是原先的值,而不是内存里的值. (盗用了一位前辈的话) 也就是所谓的常量重叠了!
是编译器把他当作立即数了吗[/quote][/quote] 还有就是这个 cout<<(unsigned)&a - (unsigned)&b<<endl;在VS2012编译下 输出是12..[/quote]
ktaurus 2013-11-03
  • 打赏
  • 举报
回复
引用 12 楼 lunat 的回复:
是当做立即数了,编译器直接把取a值的部分用常量替换了。 [quote=引用 10 楼 ktaurus 的回复:] [quote=引用 7 楼 max_min_ 的回复:] a被常量表达式初始化就成了一个编译期常量. 如果你对a没有取地址操作,编译器会做优化,不会为a划分内存,划分内存也仅仅是为了满足&a. 里面的值会被初始化为i的值.但是在程序上,名字i表示的是原先的值,而不是内存里的值. (盗用了一位前辈的话) 也就是所谓的常量重叠了!
是编译器把他当作立即数了吗[/quote][/quote] 还有就是这个 cout<<(unsigned)&a - (unsigned)&b<<endl;在VS2012编译下 输出是12..
ktaurus 2013-11-03
  • 打赏
  • 举报
回复
引用 13 楼 zhanglingxiang1 的回复:
看下这篇文章吧 http://blog.csdn.net/burningcpu/article/details/2010841
这文章没讲清楚,而且错了
lunat 2013-11-03
  • 打赏
  • 举报
回复
如果你要修改就不要声明为const,否则就涉嫌欺骗编译器(优化器),结果它就有可能做出它认为对你好(基于你的const声明)但实际上对你不好的事情(你的修改不一定会生效)。 这种代码简直不堪入目。const定义不赋值?去const不用const_cast? const Integer int_l; Integer *pInt=(Integer*)&int_l;
引用 13 楼 zhanglingxiang1 的回复:
看下这篇文章吧 http://blog.csdn.net/burningcpu/article/details/2010841
DavidL 2013-11-03
  • 打赏
  • 举报
回复
看下这篇文章吧 http://blog.csdn.net/burningcpu/article/details/2010841
lunat 2013-11-03
  • 打赏
  • 举报
回复
是当做立即数了,编译器直接把取a值的部分用常量替换了。
引用 10 楼 ktaurus 的回复:
[quote=引用 7 楼 max_min_ 的回复:] a被常量表达式初始化就成了一个编译期常量. 如果你对a没有取地址操作,编译器会做优化,不会为a划分内存,划分内存也仅仅是为了满足&a. 里面的值会被初始化为i的值.但是在程序上,名字i表示的是原先的值,而不是内存里的值. (盗用了一位前辈的话) 也就是所谓的常量重叠了!
是编译器把他当作立即数了吗[/quote]
ktaurus 2013-11-03
  • 打赏
  • 举报
回复
引用 7 楼 max_min_ 的回复:
a被常量表达式初始化就成了一个编译期常量. 如果你对a没有取地址操作,编译器会做优化,不会为a划分内存,划分内存也仅仅是为了满足&a. 里面的值会被初始化为i的值.但是在程序上,名字i表示的是原先的值,而不是内存里的值. (盗用了一位前辈的话) 也就是所谓的常量重叠了!
是编译器把他当作立即数了吗
ktaurus 2013-11-03
  • 打赏
  • 举报
回复
引用 5 楼 zhanglingxiang1 的回复:
[quote=引用 2 楼 ktaurus 的回复:] [quote=引用 1 楼 zhanglingxiang1 的回复:] const定义的变量是常量,值不能改变的
问题是确实可以改的, 用C写的话就可以..[/quote] 这个值真不能改,const定义就是为了防止值的修改啊。[/quote] 用C语言通过指针是可以修改的,你可以自己编译试试。 但是c++中貌似是把const修饰的编译为立即数了。
ktaurus 2013-11-03
  • 打赏
  • 举报
回复
引用 4 楼 ktaurus 的回复:
话说VS2012编译C也不行。。codeblocks就可以。。
用C语言通过指针是可以修改的,你可以自己编译试试。 但是c++中貌似是把const修饰的编译为立即数了。
DavidL 2013-11-02
  • 打赏
  • 举报
回复
const定义的变量是常量,值不能改变的

64,649

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧