问个const的问题

trueytht 2009-03-19 09:16:39
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
const int a = 10;
int *p = (int *) &a;
cout << *p << " " << a << endl;
cout << p << " " << &p << endl;
*p = 20;

cout << *p << " " << a << endl;

cout << p << " " << &p << endl;

return 0;
}

输出结果:
10 10
0xbfe46c64 0xbfe46c60
20 10
0xbfe46c64 0xbfe46c60

const是readonly,原来我以为是新开辟了一块物理内存,但是 p的地址没变,p所指向的内容也没变。
请告知什么原理?多谢!
...全文
219 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
dutor 2009-03-19
  • 打赏
  • 举报
回复
我想你是这个意思吧,p值并不等于a
cout<<p<<&a<<endl;
sjhui19840325 2009-03-19
  • 打赏
  • 举报
回复

#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
const int a = 10;
int *p = (int *) &a;
cout<< *p <<" " <<a << endl;
cout <<p << " " << &a << endl; //你应该输出a的地址看看是否与p所指的地址依旧相同
*p = 20;

cout <<*p <<" " <<a << endl;

cout <<p << " " <<&a << endl; // 正如楼上所说,p所指的地址没有变化,但p的内容变化了
//在编译时 const类型的全被用具体的值给代替了
return 0;
}

downmooner 2009-03-19
  • 打赏
  • 举报
回复
楼主搜索:volatile的作用
trueytht 2009-03-19
  • 打赏
  • 举报
回复
多谢,知道了const folding,是编译器优化,事先替换const。

但a的值真的改变了吗?const 不是readonly吗?
liqinghua1653 2009-03-19
  • 打赏
  • 举报
回复
const在编译阶段就之接用常量替换了, 尽管有个地址, 但是没有用这个地址的内容(所以你改变了不会影响已经替换的东西)
fairchild811 2009-03-19
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 feng4206yu 的回复:]
p指向a,这没变....虽然a被声明为const,但是通过指针同样可以改变....事实上程序中的a已经改变了(为20),但是编译器认为a本身是不会变的,所以很早把程序中a出现的地方都替换为了10,这就是为什么a仍然输出10的原因...常量折叠...
[/Quote]

up, 通过指针可以改变const int a;p的地址是不会变的
帅得不敢出门 2009-03-19
  • 打赏
  • 举报
回复

5: const int a = 10;
0040307D mov dword ptr [a],0Ah
6: int *p = (int *) &a;
00403084 lea eax,[a]
00403087 mov dword ptr [p],eax
7: cout << *p << " " << a << endl;
0040308A push edi
0040308B mov eax,offset stlp_std::cout (004b6c60)
00403090 mov edx,dword ptr [p]
00403093 mov edx,dword ptr [edx]
00403095 mov dword ptr [esp],edx
00403098 mov ecx,eax
0040309A call @ILT+10(stlp_std::basic_ostream<char,stlp_std::char_traits<char> >::operator<<) (0040100
0040309F mov dword ptr [ebp-30h],eax
004030A2 add esp,0FFFFFFF8h
004030A5 mov eax,dword ptr [ebp-30h]
004030A8 mov dword ptr [esp],eax
004030AB mov dword ptr [esp+4],offset stlp_std::locale::collate+0FFFFFFECh (004ba53c)
004030B3 call @ILT+220(stlp_std::operator<<) (004010e1)
004030B8 add esp,8
004030BB mov dword ptr [ebp-2Ch],eax
004030BE push edi
004030BF mov dword ptr [esp],0Ah
004030C6 mov eax,dword ptr [ebp-2Ch]
004030C9 mov ecx,eax
004030CB call @ILT+10(stlp_std::basic_ostream<char,stlp_std::char_traits<char> >::operator<<) (0040100
004030D0 mov dword ptr [ebp-28h],eax
004030D3 push edi
004030D4 mov dword ptr [esp],offset @ILT+5(stlp_std::endl) (0040100a)
004030DB mov eax,dword ptr [ebp-28h]
004030DE mov ecx,eax
004030E0 call @ILT+165(stlp_std::basic_ostream<char,stlp_std::char_traits<char> >::operator<<) (004010
8: cout << p << " " << &p << endl;
004030E5 push edi
004030E6 mov eax,offset stlp_std::cout (004b6c60)
004030EB mov edx,dword ptr [p]
004030EE mov dword ptr [esp],edx
004030F1 mov ecx,eax
004030F3 call @ILT+50(stlp_std::basic_ostream<char,stlp_std::char_traits<char> >::operator<<) (0040103
004030F8 mov dword ptr [ebp-24h],eax
004030FB add esp,0FFFFFFF8h
004030FE mov eax,dword ptr [ebp-24h]
00403101 mov dword ptr [esp],eax
00403104 mov dword ptr [esp+4],offset stlp_std::locale::collate+0FFFFFFF0h (004ba540)
0040310C call @ILT+220(stlp_std::operator<<) (004010e1)
00403111 add esp,8
00403114 mov dword ptr [ebp-20h],eax
00403117 push edi
00403118 lea eax,[p]
0040311B mov dword ptr [esp],eax
0040311E mov eax,dword ptr [ebp-20h]
00403121 mov ecx,eax
00403123 call @ILT+50(stlp_std::basic_ostream<char,stlp_std::char_traits<char> >::operator<<) (0040103
00403128 mov dword ptr [ebp-1Ch],eax
0040312B push edi
0040312C mov dword ptr [esp],offset @ILT+5(stlp_std::endl) (0040100a)
00403133 mov eax,dword ptr [ebp-1Ch]
00403136 mov ecx,eax
00403138 call @ILT+165(stlp_std::basic_ostream<char,stlp_std::char_traits<char> >::operator<<) (004010
9: *p = 20;
0040313D mov eax,dword ptr [p] ;//------
00403140 mov dword ptr [eax],14h ;//-------
10: cout << *p << " " << a << endl;
00403146 push edi
00403147 mov eax,offset stlp_std::cout (004b6c60)
0040314C mov edx,dword ptr [p]
0040314F mov edx,dword ptr [edx]
00403151 mov dword ptr [esp],edx
00403154 mov ecx,eax
00403156 call @ILT+10(stlp_std::basic_ostream<char,stlp_std::char_traits<char> >::operator<<) (0040100
0040315B mov dword ptr [ebp-18h],eax
0040315E add esp,0FFFFFFF8h
00403161 mov eax,dword ptr [ebp-18h]
00403164 mov dword ptr [esp],eax
00403167 mov dword ptr [esp+4],offset stlp_std::locale::collate+0FFFFFFF4h (004ba544)
0040316F call @ILT+220(stlp_std::operator<<) (004010e1)
00403174 add esp,8
00403177 mov dword ptr [ebp-14h],eax
0040317A push edi
0040317B mov dword ptr [esp],0Ah;//---------------
00403182 mov eax,dword ptr [ebp-14h]
00403185 mov ecx,eax
00403187 call @ILT+10(stlp_std::basic_ostream<char,stlp_std::char_traits<char> >::operator<<) (0040100
0040318C mov dword ptr [ebp-10h],eax
0040318F push edi
00403190 mov dword ptr [esp],offset @ILT+5(stlp_std::endl) (0040100a)
00403197 mov eax,dword ptr [ebp-10h]
0040319A mov ecx,eax
0040319C call @ILT+165(stlp_std::basic_ostream<char,stlp_std::char_traits<char> >::operator<<) (004010
11: cout << p << " " << &p << endl;
004031A1 push edi
004031A2 mov eax,offset stlp_std::cout (004b6c60)
004031A7 mov edx,dword ptr [p]
004031AA mov dword ptr [esp],edx
004031AD mov ecx,eax
004031AF call @ILT+50(stlp_std::basic_ostream<char,stlp_std::char_traits<char> >::operator<<) (0040103
004031B4 mov dword ptr [ebp-0Ch],eax
004031B7 add esp,0FFFFFFF8h
004031BA mov eax,dword ptr [ebp-0Ch]
004031BD mov dword ptr [esp],eax
004031C0 mov dword ptr [esp+4],offset stlp_std::locale::collate+0FFFFFFF8h (004ba548)
004031C8 call @ILT+220(stlp_std::operator<<) (004010e1)
004031CD add esp,8
004031D0 mov dword ptr [ebp-8],eax
004031D3 push edi
004031D4 lea eax,[p]
004031D7 mov dword ptr [esp],eax
004031DA mov eax,dword ptr [ebp-8]
004031DD mov ecx,eax
004031DF call @ILT+50(stlp_std::basic_ostream<char,stlp_std::char_traits<char> >::operator<<) (0040103
004031E4 mov dword ptr [ebp-4],eax
004031E7 push edi
004031E8 mov dword ptr [esp],offset @ILT+5(stlp_std::endl) (0040100a)
004031EF mov eax,dword ptr [ebp-4]
004031F2 mov ecx,eax
004031F4 call @ILT+165(stlp_std::basic_ostream<char,stlp_std::char_traits<char> >::operator<<) (004010
12: return 0;


常量折叠
常量 在遇到取地址时会为其分配地址
修改的只是这个副本
而本身并未改变
  • 打赏
  • 举报
回复
今早linux有人问过了。自己看吧。
http://topic.csdn.net/u/20090317/14/5ebc67cc-75e6-469b-8f58-9c38fc232d78.html
不需要再贴了吧
feng4206yu 2009-03-19
  • 打赏
  • 举报
回复
p指向a,这没变....虽然a被声明为const,但是通过指针同样可以改变....事实上程序中的a已经改变了(为20),但是编译器认为a本身是不会变的,所以很早把程序中a出现的地方都替换为了10,这就是为什么a仍然输出10的原因...常量折叠...

64,636

社区成员

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

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