0

所以我使用以下代码将整数放入 char[] 或 unsigned char[]

(unsigned???) char test[12];

test[0] = (i >> 24) & 0xFF;
test[1] = (i >> 16) & 0xFF;
test[2] = (i >> 8) & 0xFF;
test[3] = (i >> 0) & 0xFF;

int j = test[3] + (test[2] << 8) + (test[1] << 16) + (test[0] << 24);

printf("Its value is...... %d", j);

当我使用类型 unsigned char 和值 1000000000 时,它会正确打印。

当我使用 char 类型(相同值)时,我得到 98315724 打印?

所以,问题真的是谁能解释到底发生了什么?


在检查两个不同数字的二进制文件后,我仍然无法弄清楚发生了什么。我认为签名是当 MSB 设置为 1 表示负值(但负字符?wth?)

我明确告诉缓冲区要插入什么,以及如何解释内容,所以不明白为什么会发生这种情况。

为了清楚我检查的内容,我在下面包含了二进制/十六进制。

11 1010 1001 1001 1100 1010 0000 0000 // 二进制表示 983157248

11 1011 1001 1010 1100 1010 0000 0000 // 二进制表示 1000000000

3 A 9 9 CA 0 0 // 十六进制表示 983157248

3 B 9 ACA 0 0 // 十六进制表示 1000000000

4

3 回答 3

0

当您说i & 0xFFetc 时,您正在创建 range 中的值[0, 256)。但是(你的)char有一个范围[-128, +128),所以你实际上不能明智地存储这些值(即行为是实现定义的,而且推理起来很乏味)。

用于unsigned char无符号值。线索就在名字里。

于 2013-06-06T18:05:00.377 回答
0

除了 Kerrek SB 的回答之外,请考虑以下问题:

计算机(几乎总是)对负数使用称为二进制补码的符号,高位用作“负”指示符。考虑到计算机将专门处理有符号位,问问自己当你对有符号类型执行移位时会发生什么。

您可能想阅读当左侧操作数为负值时,为什么左移操作会调用未定义行为?在 StackOverflow 上获取提示。

于 2013-06-06T18:11:07.460 回答
0

这一切都与internal representation每个人type使用它data来解释它的方式有关。在internal representationasigned character中,字节的第一位保存符号,其他位保存值。当第一位为 1 时,数字为负数,后面的位表示complement正值。例如:

unsigned char c;  // whose internal representation we will set at 1100 1011
c = (1 * 2^8) + (1 * 2^7) + (1 * 2^4) + (1 * 2^2) + (1 * 2^1);
cout << c;        // will give 203

                  // inversely:

char d = c;       // not unsigned
cout << d;        // will print -53
                  // as if the first is 1, d is negative, 
                  // and other bits complement of value its positive value
                  // 1100 1011  -> -(complement of 100 1011)
                  // the complement is an XOR +1   011 0101

                  // furthermore:

char e;           // whose internal representation we will set at 011 0101
e = (1 * 2^6) + (1 * 2^5) + (1 * 3^2) + (1 * 2^1);
cout << e;        // will print 53
于 2019-04-27T15:13:27.727 回答