chap2
chap2
1️⃣地址的表示
一个int变量的“地址”为0x100,则它的4个字节被存储在内存的0x100, 0x101, 0x102, 0x103
疑问:0x101比0x100只多了1bit,为什么能存下8bit的字节?
解答:地址本身只是一个标识符,用来定位内存中的位置,而不是表示其中存储的数据量; 所以当内存地址从 0x100 增加到 0x101 时,我们是在线性地址空间中前进了一个字节的距离,而不是仅仅增加了一个二进制位。
2️⃣补码数的符号扩展
假设我们有一个8位有符号数:-5
- 二进制表示(补码):1111 1011(最高位1表示负数)
- 扩展到16位:1111 1111 1111 1011(高位填充1)
- 扩展后的值仍然是-5
可以看到,符号扩展后,有符号数仍能==保持原值==
3️⃣字节大小不同的数据类型的转换
比如short sx要转换为unsigned型,则有两种转换方式(第二种是错的)
(unsigned)sx
或(unsigned)(int)sx
:- 在这种情况下,short 类型的 sx (-12345) 会先被隐式转换为 int 类型
- 由于 int 通常是 4 字节,完整的负数位模式会被保留
- 当转为 unsigned int时,这个位模式被解释为正数,得到 4294954951
(unsigned)(unsigned short)sx
:- short sx = -12345 的二进制表示(16位)是:1100 1111 1100 0111
- 当转换为 unsigned short 时,这个完全相同的位模式被重新解释为无符号数:53191
- 所以当
(unsigned short)sx
这一步执行时,位模式保持不变,但 解释方式变了 ,导致值变成了 53191。然后当再转换为 unsigned int 时,这个 53191 会被 保留 (因为 unsigned int 可以容纳这个值)。 - 与此相对,第一种方法
(unsigned)(int)sx
中:- sx 先转换为 int(通常是32位),会进行符号扩展,保持值为 -12345
- 然后将这个32位的有符号数转换为无符号数,得到 4294954951
C 语言标准规定,==当有符号整数类型转换为无符号类型时,应该先将其转换为对应的 有符号 整数类型的更大类型==,==然后再转成无符号类型==。
所以在示例中,代码 unsigned uy = sx;
相当于 (unsigned)(int)sx
,而不是 (unsigned)(unsigned short)sx
。这种转换顺序确保了负数的位模式能够被正确地解释为无符号数。
This post is licensed under CC BY 4.0 by the author.