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

A variable and its pointer, have different values

本文关键字:指针 变量      更新时间:2023-10-16

看看这个程序:

#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的非const指针指向它。在程序正文的中间,我使用(*p)++x的值增加了一(这怎么可能,而x定义为const?)

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

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

为什么?

常量删除后变量的更改会导致未定义的行为,在某些情况下,它会像不常量一样工作,在一些情况下,会导致内存冲突错误,在有些情况下,这会把你的计算机变成试图杀死你的兔子。。。

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

const int blah = 3;

然后你会遇到以下操作:

int foo = 4 + blah;

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

婴儿,你可能会马上分配7个,因为每次运行程序时添加都毫无意义。

现在让我们开始抛出const部分。

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

int * blah_pointer = (int *) & blah;

然后他通过做这个操作来增加blah值:

(*blah_pointer)++;

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

现在,当你读取存储在指针中的值时,你会得到增加的值!

好吧,但如果你只是在读我听到你问的废话,为什么会有一个旧的、不变的值:

std::cout << blah;

它就在那里,因为编译器试图变得智能,而不是真正从blah中读取值,它只会将其交换为blah的常数值,所以它不会读取它,而是实际将它交换为std::cout<lt;3.

未定义的部分是更改常量值-您永远不知道该值是存储在受保护区域还是未受保护区域,因此您无法判断会发生什么。

如果你想让编译器在每次遇到值时都检查它,只需将定义从更改即可

const int blah = 3;

const volatile int blah = 3;

它会告诉编译器以下内容,即使我正在编写的程序不允许更改blah值,它也可能在程序执行过程中发生更改,因此不要试图优化对内存的访问,并在每次使用该值时读取它。

我希望这能让事情变得更清楚。

我认为,在编译步骤中,编译器会用它的值替换所有常量变量(就像#define),这是GNU GCC编译器优化代码的方式
我不是100%确定,但我在学习C/C++语法时遇到了同样的问题,这是我在分解(将二进制可执行文件转换为汇编代码)程序后得出的结论
无论如何,只要试着分解你的输出,看看到底发生了什么。