让我们想象一个相当典型的平台,其中一个字节为 8 位,内存使用 little-endian 字节顺序排列,anint
表示内存中的 4 个字节。在这个平台上,值的1
布局如下:
00000001 00000000 00000000 00000000
^
the first element of 'a'
p
被声明为指向char
(not int
) 的指针,并被初始化为指向数组的第一个元素a
。这个平台上的 Achar
代表一个字节。int
上面解释为 a的值char
如下所示:
00000001 -------- -------- --------
| |
------
char is only 8 bits wide
因此,无论我们读取一个字节还是四个字节,即,无论我们读取*p
还是a[0]
,值都是1
。但是,当您增加p
指向 的指针时char
,它现在指向内存中的下一个字符,即下一个字节:
00000001 00000000 00000000 00000000
00000001 00000000 -------- --------
^ ^ ^ ^
p p+1 p+2 p+3 ...
a[1]
指向下一个int
( 2
),p[1]
指向下一个char
,即0
.
在旁注中,您实际上偶然发现了一种方法来确定给定处理器是使用小端还是大端字节顺序。如果系统是大端(最高有效字节在前),那么您的第一个printf
将打印 0。这是因为内存布局会发生变化:
0000000 00000000 00000000 00000001
^
the first element of 'a'
0000000 -------- -------- --------
^
p
如果您有多个以 big-endian 顺序排列的代表值 1 的字节,并且您只读取第一个字节,则可以使用它的值(1
或0
)来测试机器的字节序:
int n = 1;
if(*(char*)&n == 1)
// little endian
else
// big endian