为什么C中的00000000-00000001=11111111是无符号字符数据类型?

为什么C中的00000000-00000001=11111111是无符号字符数据类型?,c,binary,char,unsigned-char,C,Binary,Char,Unsigned Char,我观察到,当一个无符号char变量存储值0(00000000 2)并递减1(0000000 12)时,变量值变为255(11111111 2),这是一个无符号char变量可以保存的最高值 我的问题是:为什么00000002-000000012会变成11111112?(我想看看它背后的算法) 我观察到的C代码是这样的: #include <stdio.h> main(){ unsigned char c = 0; unsigned char d = c - 1; p

我观察到,当一个无符号char变量存储值0(00000000 2)并递减1(0000000 12)时,变量值变为255(11111111 2),这是一个无符号char变量可以保存的最高值

我的问题是:为什么00000002-000000012会变成11111112?(我想看看它背后的算法)

我观察到的C代码是这样的:

#include <stdio.h>

main(){

  unsigned char c = 0;

  unsigned char d = c - 1;

  printf("%d\n%d", c, d);

}
见:

无符号整数算术始终以2n模执行,其中n为 该特定整数中的位数。例如,对于无符号整数, 将一个添加到
UINT\u MAX
将给出
​0
​, 从
​0
​ 给予
UINT\u MAX


因此,在您的示例中,由于
无符号字符
通常为8位,因此得到28-1=255。

这称为模运算,这是处理无符号数字的一种非常合理的方法。同样的原因,为什么“从00:00减去1小时”的答案会给你“23:00”,而不是“-01:00”。你知道当一个六位数的汽车里程表从999999继续时,它会变成000000吗?如果它从000000向后移动,它将变为999999。在二进制中从00000000到11111111是一样的。详细地说,从右到左处理数字:首先我们有0减1:1更大,所以我们从左边的数字“借用”1。然后我们有10减1,结果是1。在下一个位置,我们有0减0减1,所以它是0减1。同样,我们借钱,结果得到1。这一直延续到最后一个位置,在那里我们再次借用1并得到1。现在我们有八个1作为结果位,从左边的位置借用一个1,它在八个位之外,被丢弃或忽略。你期望什么?@samuel:嗯,0没有足够的借位,所以你从它的左边借用1。这等于10,你可以从中减去1。正如我所写的,这一直到最后一个数字,在这一点上,我们借用了100000000(256位小数)。即,而不是0000 0000− 0000 0001,我们有10000-0000 0001,这显然是1111111。只有当你被允许借用你没有的10000美元时,它才有效。这与工作模256相同。
0
255