我使用模运算符发现了一个非常奇怪的行为。
给出以下代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main()
{
uint8_t x = 2;
uint8_t i;
for(i=0; i<5; i++)
{
x = (x - 1) % 10;
printf("%d ", x);
}
printf("\n");
}
我希望结果是1 0 3 4 2
,而是获得1 0 255 4 3
。
我认为它与整体推广有关,但我不明白如何转换完成。
答案 0 :(得分:8)
首先,在C中,%
不是模数运算符。它是余数运算符。
否则,你是正确的,整数推广发生了。 uint8_t
当它作为算术运算符的参数出现时,会隐式转换为int
。
因此当x
达到0时,x - 1
将变为-1。然后,-1 % 10
为-1(并且不 9),并且分配给uint8_t
的-1产生255(因为无符号整数溢出是以模运算的方式定义的)。 / p>
答案 1 :(得分:7)
我不清楚你为什么期望0之后的3;数学上,0-1产生-1,-1除以10的余数为-1或9,具体取决于你对余数的定义。
话虽如此,在x从0过渡到255的步骤中发生的事情是0-1产生-1,而C的%
运算符定义余数,使得得到-1的结果。关键是接下来会发生什么:将-1分配给类型为uint8_t
的变量。由于-1超出了可表示值(0到255)的范围并且类型是无符号的,因此通过将模256的值(一加上最大值)减少到范围内来进行转换,从而产生255。