你声明了一个名为
x
的 6 个元素的
short
数组。
你给每个元素赋了值。初始值如下:
+
| x[0] | 0x0102 |
+
| x[1] | 0x1112 |
+
| x[2] | 0x2122 |
+
| x[3] | 0x3132 |
+
| x[4] | 0x4142 |
+
| x[5] | 0x5152 |
+
我在这里做了一些假设,但如果不是你的情况,请进行修改。
sizeof(char) = 1 bytes
sizeof(short) = 2 bytes
sizeof(int) = 4 bytes
Endianness = little endian
因此在内存中,它看起来像这样:
+
| 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+
| 51 | 52 | 41 | 42 | 31 | 32 | 21 | 22 | 11 | 12 | 01 | 02 |
+
| x[5] | x[4] | x[3] | x[2] | x[1] | x[0] |
+
- 第一行:字节编号(仅用于标识目的)
- 第二行:内存中内容的十六进制表示(每两个十六进制字符代表一个字节)
- 第三行:数组
x
的索引
您将x
的基地址转换为char
指针cp
并将其赋值。 printf()
看到了在*x
中大小为1
字节的字符。
x
指向字节0,cp
也是如此,但对于后者,只有1
字节被考虑,因为sizeof(char)
为1
。
字节0处的内容恰好为0x02
。
所以,
cp = (char*) x;
printf("1) *cp = %x\n", *cp);
打印输出2
。
sp
是一个short
指针,与x
相同类型。所以*sp
会打印与*x
相同的内容。它将从给定地址开始考虑前2
个字节。sp
指向字节0
。因此,将考虑字节0
和1
。因此,值为0x0102
,由之前提到的代码打印出来。
sp = x;
printf("2) *sp = %x\n", *sp);
cp
仍然指向字节0
。 cp[3]
等效于*(cp+3)
。由于cp
是一个char
指针,cp+3
将指向0 + 3*sizeof(char)
,即0 + 3*1
,这又是字节3
。
在字节3
处,我们有0x11
,因为sizeof(char)
是1
,所以只考虑单个字节。
因此,
printf("3) cp[3] = %x\n", cp[3]);
将打印11
在
ip = (int*) x;
ip = ip + 1;
printf("A) *ip = %x\n", *ip);
整数指针
ip
被分配到
x
的基地址。然后,
ip
增加了
1
。最初,
ip
指向字节0。由于
ip+1
将指向字节
0 + 1*sizeof(int)
,即
0 + 1*4
,这又是字节4。
因此,
ip
现在指向字节4。由于它是一个整数指针,因此会考虑4个字节-即字节4、5、6和7,其内容为
31322122
。
cp[6]
表示
*(cp+6)
。
cp+6
指向字节6,其内容为
32
。
因此,
printf("B) cp[6] = %x\n", cp[6]);
打印输出32
。
sp = sp + 5;
printf("C) *sp = %x\n", *sp);
sp
在加上5
之后,现在指向字节0 + 5*sizeof(short)
,也就是0 + 5*2
,即字节10,而在考虑2个字节(字节10和11)的内容后,它的内容为5152
。
*x = *cp + 2;
*cp的值为0x02。
*cp + 2的值是0x02 + 0x02 = 0x04 = 0x0004。
这个值被赋给了由*x指向的整数(字节0和1)。
因此,字节0现在是0x04,字节1现在是0x00。
cp[1]就是*(cp+1)。cp+1指向字节1,内容现在为0x00,这将在输出时打印出来。
printf("D) cp[1] = %x\n", cp[1]);
完成了。
x
是第0
个元素的地址,基本上它是short*
。 - zerkms"%x"
对于大多数值来说都是错误的格式。 - Bo Perssonprintf
文档中有关格式说明符期望的具体信息。你会发现%x
期望一个“无符号整数”,而你实际上是在向printf
传递char
值,这样做实际上是在欺骗它。唯一能拯救你的运行时错误的是默认参数提升,它将这些值提升为“int”,虽然仍然是错误的,但至少大小兼容。 - WhozCraig