0

我有一个指向字节缓冲区的指针,我从中将每个偶数索引字节复制到一个 int(由于数据存储到缓冲区中的协议,我知道奇数周期用于读取)。现在当我这样做时

signed int a;
...
//inside a loop
a = buffer[2*i]; //buffer is unsigned

它给了我一个无符号数。但是,当我这样做时

a = (int8_t)buffer[2*i]

该号码以签名形式显示。这迫使我重新思考 c 中的符号扩展是如何工作的,尤其是在上述情况下。我的理解是,因为我声明了一个已签名的,编译器会自动进行符号扩展。任何人都可以花一些时间来解释为什么不是这样。我只是在这个陷阱里呆了一个小时,不想以后再落入同样的陷阱。

4

2 回答 2

2

buffer是一个无符号八位整数数组(或充当一个)。所以 的值buffer[2*i]在 0 到 255(含)的范围内,并且该范围内的所有值都可以表示为ints,因此分配

a = buffer[2*i];

保留值,提升到更广泛的类型int是通过用零填充来完成的。

int8_t如果你在分配之前投到,

a = (int8_t)buffer[2*i]

缓冲区中大于 127 的值以实现定义的方式转换为 type int8_t,很可能只是将位模式重新解释为带符号的 8 位整数,这会导致从 -128 到 -1 的负值。这些值可以表示为ints,因此它们保留在赋值中,int然后通过符号扩展完成对更广泛类型的保留值提升。

于 2012-10-21T16:09:35.297 回答
1

int_8 只有 8 位,如果最高位为 1,则它具有负值: 1xxxxxxx ,如果将这样的值分配给带符号的 int(32 或 64 位),当然会得到负值。更长的 int 在赋值后看起来像11111111 11111111 11111111 1xxxxxxx,只需一个简单的 xor 就可以达到 00000000 ^ 1001 => 11111001 的效果。

于 2012-10-21T16:15:27.017 回答