变量及其指针具有不同的值

时间:2015-04-24 13:20:11

标签: c++

看看这个节目:

#include <iostream>
using namespace std;
int main()
{
 const int x = 0;
 int *p;

 p=(int*)&x;
 (*p)++;

 cout<<x<<endl;
 cout<<*p;
}

如上所述,我将x声明为const int,并使用强制转换,一个名为p的非常量指针指向它。在我的程序正文中间,我使用x(*p)++的值增加了一个(如何可能,x被定义为const?)

现在,当我打印*px时,它们会返回不同的值,而*p应该指向x的地址:

ap1019@sharifvm:~$ ./a.out
0
1

为什么?

2 个答案:

答案 0 :(得分:6)

恒定删除后变量的变化会导致未定义的行为,在某些情况下,它只会起作用,就好像它不会是const一样,在某些情况下它会导致内存冲突错误,在某些情况下,它会把你的电脑变成兔子,试图杀死你......

关于行为的一些背景知识。想象一下你是一个编译器。您遇到变量:

const int blah = 3;

然后您会遇到以下操作:

int foo = 4 + blah;

因为你是聪明的编译器而且你知道blah是常量 - 因此它不会改变,而不是从blah中读取值,你可以交换值来获取内存中的blah存储位置读取它只需添加3到4并将其分配给foo。

婴儿你可能会立即分配7,因为每次运行程序时添加都是没有意义的。

让我们现在进入抛弃const部分。

一些非常偷偷摸摸的程序员正在做以下事情:

int * blah_pointer = (int *) & blah;

然后他通过执行此操作来增加blah值:

(*blah_pointer)++;

会发生什么 - 如果变量不在受保护的存储器中(不是只读),程序将只增加存储在存储器中的变量的值。

现在,当您读取存储在指针中的值时,您将获得增加的值!

好的,但是如果你正在阅读我听到的问题,为什么会有一个旧的,不变的值:

std::cout << blah;

它就在那里,因为编译器试图变得聪明,而不是实际从blah读取值,它只是将它交换为常量值为blah,所以不是读它而是实际将它交换到std :: cout &LT;&LT; 3。

未定义的部分正在改变常数值 - 您无法知道该值是否会存储在受保护或未受保护的区域中,因此您无法说明会发生什么。

如果您希望编译器在每次遇到它时实际检查该值,只需更改定义:

const int blah = 3;

const volatile int blah = 3;

它将告诉编译器以下内容,即使我正在编写的程序不允许更改blah值,也可能在程序执行期间更改,因此不要尝试优化对内存的访问权限每次使用该值时都读取它。

我希望这更清楚。

答案 1 :(得分:3)

我认为,在编译步骤中,编译器会将所有常量变量替换为其值(类似#define),这是GNU GCC编译器优化代码的方式。登记/> 我对此并不是百分之百确定,但在学习C / C ++语法时我遇到了同样的问题,而且这是我在解体后做出的结论(转换二进制文件)可执行程序到汇编代码)我的程序。
无论如何,只是尝试反汇编你的输出,看看到底发生了什么。