考虑指针时,它有助于绘制图表。指针是一个箭头,指向内存中的地址,带有指示值类型的标签。地址指示要看的地方,类型指示要取什么。投射指针会更改箭头上的标签,但不会更改箭头指向的位置。
dinmain是c类型为的指针char。Achar是内存的一个字节,因此当d取消引用时,您会在该内存的一个字节中获取值。在下图中,每个单元代表一个字节。
-+----+----+----+----+----+----+-
| | c | | | | |
-+----+----+----+----+----+----+-
^~~~
| char
d
当你施放d到int*,你是说d真的指向一个int值。在当今的大多数系统上,一个int占用4个字节。
-+----+----+----+----+----+----+-
| | c | ?₁ | ?₂ | ?₃ | |
-+----+----+----+----+----+----+-
^~~~~~~~~~~~~~~~~~~
| int
(int*)d
取消引用时(int*)d,您将获得由这四个字节的内存确定的值。您获得的值取决于这些标记的单元格中的?内容以及int在内存中的表示方式。
甲PC是小端,这意味着,一个值int被计算这种方式(假设它跨越4个字节):
* ((int*)d) == c + ?₁ * 2⁸ + ?₂ * 2¹⁶ + ?₃ * 2²⁴。因此,如果您使用十六进制(printf("%x\n", *n)),则最后两位始终是35(即字符的值'5')。
其他一些系统是big-endian,并在另一个方向上排列字节:* ((int*)d) == c * 2²⁴ + ?₁ * 2¹⁶ + ?₂ * 2⁸ + ?₃。在这些系统中,你会发现,价值总是开始与35时十六进制打印。某些系统的大小int不同于4个字节。很少有系统int以不同的方式排列,但是您极不可能遇到它们。
根据您的编译器和操作系统的不同,您可能会发现每次运行该程序时该值都不相同,或者始终相同,但是在对源代码进行很小的调整时它就会更改。
在某些系统上,int值必须存储在4(或2或8)倍数的地址中。这称为对齐要求。取决于地址是否c正确对齐,程序可能会崩溃。
与您的程序相反,这是当您有一个int值并指向它的指针时发生的情况。
int x = 42;
int *p = &x;
-+----+----+----+----+----+----+-
| | x | |
-+----+----+----+----+----+----+-
^~~~~~~~~~~~~~~~~~~
| int
p
指针p指向一个int值。箭头上的标签正确描述了存储单元中的内容,因此取消引用时不会感到惊讶。