为什么以下代码打印255
?
#include <stdint.h>
#include <stdio.h>
int main(void) {
uint8_t i = 0;
i = (i - 1) % 16;
printf("i: %d\n", i);
return 0;
}
我假设15
,尽管i - 1
评估为整数。
答案 0 :(得分:15)
由于C标准中的integer promotions。简而言之:任何类型&#34;较小的&#34;使用前将int
转换为int
。你无法避免这种情况。
所以发生了什么: i
被提升为int
。表达式计算为int
(您使用的常量也是int
)。模数为-1
。然后通过作业将其转换为uint8_t
:255
。
对于printf
,i
整数提升为int
(再次):(int)255
。但是,这没有任何害处。
请注意,在C89中,对于a < 0
,a % b
不一定是否定的。它是实现定义的,可能是15
。但是,自C99起,-1 % 16
保证为-1
,因为除法必须产生代数商。
如果你想确保模数给出正结果,你必须通过施放unsigned
来评估整个表达式i
:
i = ((unsigned)i - 1) % 16;
建议:启用编译器警告。至少分配的转换应该给出截断警告。
答案 1 :(得分:12)
这是因为-1 % n
会返回-1
而非n - 1
1 。由于i
在这种情况下是无符号的8位int,因此它变为255。
1 See this question for more details关于负整数的模数如何在C / C ++中起作用。