c++,我就想知道为什么会出现一个地址两个值的情况?求大神解答
发布网友
发布时间:2024-04-01 09:01
我来回答
共4个回答
热心网友
时间:2024-07-19 22:43
这个结果主要在于编译器的解释问题。
其关键问题在于const标识符,这里如果没有const那么一切将都是对的,引用就是别名。
但是如果出现了const那么问题就大了,因为编译器无法识别你引用的对象是const类型的。
先讲一下const的作用。
const在C++里是声明一个常对象,即不能变的对象。而实际上const只在编译时有用,汇编语言没有与它对应的指令。也就是说const实际上是编译指令。
那么编译器编译时怎么处理const对象呢?---直接替换!也就是说在这方面和预编译指令#define的区别在此时是一样的。(注意是在此时,有不一样的时候,不过区别也是在预编译里)也就是说编译完后,根本就不会存在const变量,因为它直接被数据替换掉了。
再讲一下引用的作用。
C++里解释引用就是取个别名,它和原来的变量有相同的地址和值。那具体怎么实现呢?其实就是定义了一个指针,指针指向原来的变量。编译时,引用的操作直接转化成对应的指针操作。其实引用的功能,指针是完全可实现的,只是有时候用引用会更方便一点儿。
现在解释你的代码。
编译时首先把代码中的数据存起来,即先把9存起来。
const int ax = 9;/*怎么编译呢?答案是不编译,作用就是把代码中用于运算的ax全替换成9。*/
int &a=(int &)ax; /*定义一个指向9(已经存起来的数据)的指针。*/
a=8;/*把存9的地址里的数据改成8。*/
cout<<a<<endl;/*输出指针指向的值。*/
cout<<ax<<endl;/*此时已经变成cout<<9<<endl;即输出数字9(注意这只是个数字,而不是指的存起来那个,汇编代码时也是有数字的,不是每个数据都要去存储器中找)*/
cout<<&a<<" "<<&ax<<endl;/*就是输出那个指针及存储的9的地址。*/
提示:由于const的存在,编译器编译时会出现两种数据,用于取地址的数据与用于输出和计算的数据。
老城百姓
热心网友
时间:2024-07-19 22:41
这个问题的本质你没有搞清楚这个常量它是存放在哪里的?
一般我们编译器看见你声明的是常量也就是常右值的时候, 你通过用它的地址改变他的值其实这个地址的值已经变了
只不过编译器看见你用的常右值就直间到寄存器里去拿值,
你可以在第一句加一个关键字 int const volatile ax = 9;
这里你打印出来的肯定就是修改后的值了有关这个关键字你可以百度搜索一下
热心网友
时间:2024-07-19 22:43
//结合代码反汇编来给你解释
#include<iostream>
using namespace std;
int main()
{
int i;
const int ax=9;
// 0x00401508 <+24>: mov DWORD PTR [esp+0x4],0x9 ;ax的地址是esp+4
int &a=(int&)ax;
/*
0x00401510 <+32>: lea eax,[esp+0x4]
0x00401514 <+36>: mov DWORD PTR [esp+0xc],eax
*/
a=8;
/*
0x00401518 <+40>: mov eax,DWORD PTR [esp+0xc]
0x0040151c <+44>: mov DWORD PTR [eax],0x8
*/
i=ax;
// 0x00401522 <+50>: mov DWORD PTR [esp+0x8],0x9 ;关键的地方来了,这里的ax是被编译器直接解释为9的
i=a;
/*
0x0040152a <+58>: mov eax,DWORD PTR [esp+0xc]
0x0040152e <+62>: mov eax,DWORD PTR [eax]
0x00401530 <+64>: mov DWORD PTR [esp+0x8],eax
*/
}
/*这下知道原因了吗,const变量被编译器直接用常量代替,
于是才有const int变量能直接用于定义静态数组,
于是你的cout<<ax就相当于cout<<9
于是就出现了你那样的情况*/
下面是代码的反汇编的图片
热心网友
时间:2024-07-19 22:41
第二行你是想让a引用ax吗?