为什么此代码打印 0
Why does this code print 0
为什么下面的代码打印0?即为什么变量a
位于变量d
之后,即使指针变量c
是在它们之间声明的?
#include<iostream>
using namespace std;
int main () {
unsigned int a = 100;
unsigned int &b = a;
unsigned int *c = &b;
unsigned int d = (unsigned int)(c);
int e = &d - c;
int &f = e;
e ++;
cout << e << " " << endl;
return 0;
}
向后工作:
e ++;
cout << e << " " << endl;
如果打印 0,则执行此代码之前的值 e
必须-1
。
int e = &d - c;
所以上面地址减法的结果一定是-1
的。
unsigned int a /* = whatever, the value of a doesn't matter */;
unsigned int &b = a;
unsigned int *c = &b;
unsigned int d /* = whatever, the value of d doesn't matter */;
b
是对a
的引用,所以&b
等价于&a
。
所以&d - c
等价于&d - &a
,减法得到-1
。
结论:d
的地址是a
地址之后的sizeof (unsigned int)
字节。(指针减法按指向类型的大小缩放。
可能。
事实上,减去指向两个独立定义的对象的指针的行为是未定义的。该标准实际上没有说明它应该做什么。
在实践中,编译器可能会为指针减法生成最简单的代码,并且该简单代码可能会将不相关的指针视为可比的指针,即使语言没有说它们是可比的。
考虑到程序的输出,b
和d
很可能恰好彼此相邻分配。没有说声明的变量必须按照声明它们的顺序进行分配。如果希望按定义的顺序在内存中分配对象,请将它们放入struct
或使其成为数组的元素。
该程序,或者在具有不同编译器选项的同一系统上运行同一程序,则也可能会产生不同的结果。原则上,它甚至可以在月球的不同阶段表现不同,一切都相同。
并且允许编译器假定代码的行为已明确定义,并执行仅在给定该假设的情况下有效的转换。实际上,通过减去两个不相关的指针,您已经向编译器承诺它们都指向同一数组对象的元素或刚过它的末尾(其中单个对象被视为 1 元素数组)(或者两者都是空指针;这是 C 和 C++ 之间的一个区别)。你对编译器撒谎,这意味着它对你没有进一步的义务。
别这样。
除非使用自己的内存管理系统显式放置对象,否则它们在内存中的相对位置将取决于编译器和系统。
您的行int e = &d - c;
正在减去 2 unsigned int *
。
在内存中,&d
比c
大 8 个字节(这取决于您的系统,但我们假设int
是 4 个字节)。实际上,您以这种方式构建堆栈:
unsigned int a = 100; // &a is 0x0
unsigned int &b = a; // &b is 0x0 (it's just an alias)
unsigned int *c = &b; // &c is 0x4
unsigned int d = (unsigned int)(c); // &d is 0x8
一个unsigned int
在内存中使用 4 个字节。所以,当你做&d - c
时,它必须返回2
,因为你正在使用指针算法和unsigned int*
(4*2=8);
您可以尝试int e = (short*)&d - (short*)c
结果应该4
因为大小为 2 (2*4=8 short
。
您可以尝试int e = (char*)&d - (char*)c
结果应该8
因为大小为 1 (1*8=8 char
)。
尝试打印变量和地址以了解:
#include<iostream>
using namespace std;
int main () {
unsigned int a = 100;
unsigned int &b = a;
unsigned int *c = &b;
unsigned int d = (unsigned int)(c);
int e = (short*)&d - (short*)c;
//int &f = e;
//e ++;
cout << "&a: " << (unsigned int)&a << endl;
cout << "&b: " << (unsigned int)&b << endl;
cout << "&c: " << (unsigned int)&c << endl;
cout << "&d: " << (unsigned int)&d << endl;
cout << endl;
cout << " a: " << a << endl;
cout << " b: " << b << endl;
cout << " c: " << (unsigned int)c << endl;
cout << " d: " << d << endl;
cout << endl;
cout << " e: " << e << endl;
return 0;
}
在这里,对于int e = (short*)&d - (short*)c;
,结果是:
&a: 3220197356
&b: 3220197356
&c: 3220197360
&d: 3220197364
a: 100
b: 100
c: 3220197356
d: 3220197356
e: 4
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 为什么这个 c++ 代码打印出长度 5,当我打印出字符串时,程序会自动终止?
- 我应该如何修改此代码以使用给定字符串中的字母打印菱形图案
- C ++如何使用UTF8十六进制代码打印UTF8符号?
- 如何使代码打印文本文件中的第一行?
- 如何修改代码以打印出数组 v2
- Printf 命令不打印时添加了查找常见除数的新代码
- 使用用户输入打印 6X10 矩阵的代码 - C++
- 任何人都可以弄清楚这段代码如何显示运行错误?它打印无限时间 -1 以及正确答案
- 我编写了以下代码来读取C++矩阵,然后打印其行和列.我收到此错误
- 无法在野牛代码中打印正确的值
- C++:正则表达式匹配代码,打印多个匹配项?
- 如何在c++中仅使用for循环打印此代码的垂直直方图
- 为什么我的代码在要求打印长度和宽度的值后不接受多个输入?
- 这个随机字符串打印代码有什么问题?
- 打印C 代码执行逐步执行
- 打印代码 128 C 条形码通过与 OPOS 公共控件 1.8 交互C++代码
- 这个打印代码是如何工作的
- 我的堆栈的打印代码出现分段错误,不知道我哪里出错了。
- 如何打印代码的执行时间