Post

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型,则有两种转换方式(第二种是错的)

  1. (unsigned)sx(unsigned)(int)sx
    • 在这种情况下,short 类型的 sx (-12345) 会先被隐式转换为 int 类型
    • 由于 int 通常是 4 字节,完整的负数位模式会被保留
    • 当转为 unsigned int时,这个位模式被解释为正数,得到 4294954951
  2. (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.