为什么要打印以下代码?
#include <stdint.h>
#include <stdio.h>
int main(void) {
uint8_t i = 0;
i = (i - 1) % 16;
printf("i: %d\n", i);
return 0;
}
我假设
255
,尽管15
的计算结果是一个整数。 最佳答案
因为c标准中的integer promotions。简而言之:任何小于int
的类型在使用前都转换为int
。总的来说,这是不可避免的。
接下来:i
被提升为int
。表达式的计算结果为int
(您使用的常量也是int
)。模量-1
。然后通过赋值将其转换为uint8_t
:255
。
对于printf
则i
被整数提升为int
(再次):(int)255
。不过,这没有坏处。
注意,在c89中,fora < 0
,a % b
不一定是负的。它是由实现定义的,可以是15
。然而,自c99以来,-1 % 16
被保证为-1
,因为除法必须产生代数商。
如果你想确保模给出一个正的结果,你必须通过转换来计算整个表达式。
i = ((unsigned)i - 1) % 16;
建议:启用编译器警告。至少赋值的转换应该给出截断警告。
关于c - 为什么取模运算返回意外值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32019039/