C语言对8位数字的算术运算过程

Process of arithmetic operation on 8 bit numbers in C

当我们对8位数字进行算术运算时,它们被提升为整数。 我有以下代码片段。

unsigned char startTime=7;
unsigned char endTime=5;  
unsigned char diff = endTime-startTime;

我了解到,在 RHS 中,两者都被提升为整数,因此结果为 -2,最终结果为 254。 我想知道编译器究竟是如何做到这一点的。 这是我的感受,但不确定。 编译器将它们都提升为整数。 为结果创建临时整型变量。 执行算术运算。 5-7 的结果 = 0xFFFF FFFF FFFF FFFE。 现在只分配 8 位 0xFE 给 LHS,所有高 3 字节都被剥离。因此,如果我们打印它,我们会看到 254。

如您所见,startTimeendTime 被提升为 int,而 endTime-startTime 的结果为 −2。 C 标准根据结果的 描述此行为,即 −2。它没有根据对结果进行编码的 来描述行为;它不要求结果由位 11111111111111111111111111111110.

表示

在许多C实现中,基本上所有常见的现代实现,二进制补码系统用于有符号整数,其中-2的32位表示为11111111111111111111111111111110。但是C标准也允许使用补码(在其中 −2 是 11111111111111111111111111111101) 或符号和大小(其中 −2 是 100000000000000000000000000000010)。

无论使用哪个系统,将-2转换为八位unsigned char的结果都是254。(C允许unsigned char比八位宽,但这个答案确实not address that.) 这是因为C标准规定整数值转换为unsigned char的结果是unsigned char类型域中通过加减[=18得到的值=] 反复。也就是说,它是被转换的值模 256。对于 −2,我们有 −2 + 256 = 254,因此 C 标准要求的结果是 254.

由于 C 标准要求此结果需要使用补码、补码或符号和大小,因此 C 编译器(或整个 C 实现)负责做任何必要的事情以获得这个结果。当使用二进制补码时,编译器所要做的就是将 int 表示的低八位用作 unsigned char 表示的位。这是当今补码受到青睐的原因之一。如果 C 实现使用一个补码或符号和大小,它将负责执行将 −2 int 值转换为 254 unsigned char 值所需的任何工作。