示例程序:
#include <stdio.h>
int main() {
int x = 0;
printf("%p", &x);
return 0;
}
我读到大多数机器都是字节可访问的,这意味着只有一台机器
字节可以存储在单个内存地址(例如0xf4829cba stores the value 01101011
)上。假设x
是32位整数,对变量的引用不应该返回四个内存地址,而不是一个吗?
请ELI5,因为我现在很困惑。
非常感谢您的宝贵时间。
-马特
答案 0 :(得分:3)
您获得的地址(不是“引用”)是存储变量的内存的开始。然后,变量将根据其类型占用所需的字节数。因此,如果int
是目标体系结构中的32位,则得到的地址是用于存储int
的四个字节中的第一个。
+−−−−−−−−+ address−−−>| byte 0 | | byte 1 | | byte 2 | | byte 3 | +−−−−−−−−+
答案 1 :(得分:2)
用 objects 1 而不是 bytes 来思考可能会有所帮助。 C语言中最有用的数据类型占用多个字节。
对于像&x
这样的表达式,它求值多个地址,可以将其视为您房屋的地址-您没有为房屋中的每个房间都指定一个唯一的地址,对吗?不,为了告诉其他人您的房子在哪里,您只需要指定一个地址即可。为了知道int
或double
或struct humongous
对象的位置,我们只需要知道第一个字节的地址即可。
您可以以几种不同的方式访问和操作较大对象中的各个字节。您可以使用位屏蔽操作,例如
int x = some_value;
unsigned char aByte = (x & 0xFF000000) >> 24; // isolate the MSB
或者您可以使用unsigned char
将对象映射到union
的数组上:
union {
int x;
unsigned char b[sizeof (int)];
} u;
u.x = some_value;
aByte = u.b[0]; // access the initial byte - depending on byte ordering, this
// may be the MSB or the LSB.
或通过创建指向第一个字节的指针:
int x = some_value;
unsigned char *b = (unsigned char *) &x;
unsigned char aByte = b[0];
字节排序是一回事-有些架构存储从最高有效字节开始的多字节值,而其他架构则从最低有效字节开始:
For any address A
A+0 A+1 A+2 A+3
Big endian +---+---+---+---+
|MSB| | |LSB|
+---+---+---+---+ Little endian
A+3 A+2 A+1 A+0
为原始Macintosh提供支持的M68K芯片为大端格式,而x86为小端格式。
&
和|
之类的按位运算符会考虑字节顺序-x & 0xFF000000
将始终隔离MSB 2 。当您将对象映射到unsigned char
的数组时,第一个元素可能会映射到MSB,或者可能会映射到LSB,或者可能会映射到其他对象(旧的VAX体系结构使用“中间端” ”订购了2301或1032的32位浮点数,不记得是哪个临时值)。
int
和8位字节。