变量及其指针具有不同的值
A variable and its pointer, have different values
看看这个程序:
#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?)
现在,当我打印*p
和x
时,它们返回不同的值,而*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++语法时遇到了同样的问题,这是我在分解(将二进制可执行文件转换为汇编代码)程序后得出的结论
无论如何,只要试着分解你的输出,看看到底发生了什么。
- 指针变量在 cout 函数中不起作用
- 如何将指针变量作为引用参数传递?
- 有没有办法在同名类 (c++) 中为对象分配一个指针变量
- 我试图了解在异或操作后指针变量正在更改
- 调用带有指针对象错误的指针变量
- 如何在 cuda 中将结构的指针变量从主机复制到设备
- 非指针变量和类成员上的新放置
- 线路抑制状态错误 C4703 可能未初始化的局部指针变量"back"已使用
- 全局外部指针变量在 DLL 中不可见
- 如何访问在 c++ 中在类内声明的结构类型指针变量?
- C++ 中指针变量的内存释放
- 使用指针变量打印特定的数组变量
- 如何使用构造函数初始化内存地址(指针变量)?
- 如何释放为指针变量本身提供的内存?
- 如果地址已知,如何获取指针变量的名称
- 如何处理参数中的基类和指针变量
- 指针变量 在数组中定位零
- 隐式指针变量,在自动定义中具有另一个指针变量
- 为什么可以将Char指针变量初始化为字符串,而INT指针变量不能初始化到整数数组
- 错误 C4703 可能未初始化的局部指针变量'y'使用