#include <stdio.h> #include <inttypes.h> uint8_t n = UINT8_MAX; int main() { printf("%hhu ",n++); printf("%hhu",n); return 0; }
使用gcc -std = c99 -Wall * .c进行编译,打印:255 0
另外,使用C99的PRI *宏是否可以接受?他们是如何命名的?
N = 256;将有符号整数值256转换为uint8_t,然后将其赋值给n.此转换由标准定义,取值为modulo-256,因此结果是n设置为0.不确定在哪里可以找到表,但整数转换的规则是6.3.1.3:
1 When a value with integer type is
converted to another integer type
other than _Bool, if the value can be
represented by the new type, it is
unchanged.2 Otherwise, if the new type is
unsigned, the value is converted by
repeatedly adding or subtracting one
more than the maximum value that can
be represented in the new type until
the value is in the range of the new
type.49)3 Otherwise, the new type is signed
and the value cannot be represented in
it; either the result is
implementation-defined or an
implementation-defined signal is
raised
正如AndreyT指出的那样,这并未涵盖在计算过程中出现超出范围值时发生的情况,而不是转换期间发生的情况.对于6.2.5 / 9涵盖的无符号类型:
A computation involving unsigned
operands can never overflow, because a
result that cannot be represented by
the resulting unsigned integer type is
reduced modulo the number that is one
greater than the largest value that
can be represented by the resulting
type.
对于签名类型,3.4.3 / 3说:
EXAMPLE An example of undefined behavior is the behavior on integer overflow.
(间接,我知道,但是当这是未定义行为的规范示例时,我懒得继续搜索显式描述).
另请注意,在C中,整数提升规则非常棘手.算术运算总是在相同类型的操作数上执行,因此如果表达式涉及不同的类型,则有一个规则列表来决定如何选择要执行操作的类型.两个操作数都被提升为此公共类型.但是,它始终至少是一个int,因此对于像uint8_t这样的小类,算术将在int中完成,并在赋值给结果时转换回uint8_t.例如:
uint8_t x = 100; uint8_t y = 100; unsigned int z = x * y;
结果是10000,而不是16,如果z也是uint8_t,那将是结果.
另外,使用C99的PRI *宏是否可以接受?他们是如何命名的?
可以接受谁?我不介意,但您可能想检查您的编译器是否支持它们.海湾合作委员会在我最早的版本中做了,3.4.4.它们在7.8.1中定义.
如果您没有C标准的副本,请使用:http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf.这是标准的“草稿”,在标准发布后的某个时间发布,包括一些更正.