int main() {
const int i =10;
int *j = const_cast<int*>(&i);
cout<<endl<<"address of i "<<&i;
cout<<endl<<"value of j "<<j;
(*j)++;
cout<<endl<<"value of *j "<<*j;
cout<<endl<<"value of i "<<i;
// If Not use Const //
int k = 10;
int *p = &k;
cout<<endl<<"address of k "<<&i;
cout<<endl<<"address of p "<<&p;
(*p)++;
cout<<endl<<"value of *p "<<*p;
cout<<endl<<"value of k "<<k<<endl;
}
输出为 :
i
0xbf8267d0
地址j
0xbf8267d0
的价值*j
11
的值 值i
10
k
0xbf8267d0
地址p
0xbf8267c8
地址*p
11
的值k
11 的值
有人可以解释为什么在输出的第 3 行和第 4 行吗
*j is 11
和i is 10
.
为什么i
也不是 11?
编译器可以假定在这种情况下不会修改 const 变量。 它可以采取措施来生成更高效的代码。 在您的示例中,由于i
被声明为 const
编译器将std::cout << i
替换为(有效(std::cout << 10
抛弃恒常性会导致未定义的行为,因此实际上没有什么可以保证发生。
考虑类似的事情
const int i = 5;
// ...
if (i > 10) { // impossible!
std::cout << "hello world!";
}
在上面,优化编译器可以在编译时确定常量5
不可能大于 10
,因此它将删除 if 检查和主体,如果您查看程序集,您甚至不会看到"hello world!"
字符串,因为它会被优化并丢弃! 即使您将...
替换为const_cast
并修改了i
的值,也不会更改允许编译器执行的优化(假设i
不会更改(。
解释很简单:未定义的行为是未定义的。当你使用const_cast
抛弃一个实际声明const
对象的恒常性,然后修改它时,你的程序表现出未定义的行为,它几乎可以做任何事情。它可以做你所期望的事情,做你意想不到的事情,它可以在线订购披萨。
在你的特定情况下,编译器可能通过用文字10
替换它来优化i
的所有使用(因为i
是const
,所以它的值永远不会以任何方式改变(。
同时,i
可能没有放在内存的只读部分(否则,你会在(*j)++
上崩溃(,并且由于j
是指向int
(而不是const int
(的指针,因此无法优化*j
读取,因此实际存储在*j
中的值(这是i
的存储(被打印出来。
但以上只是猜测,真的。实际原因可能是任何事情。具有未定义行为的程序是完全错误的,无法预测其行为。