在下面的代码片段中,为什么我们会得到600的输出?两个问题将帮助我理解这种行为。
1.我将变量 b 的类型指定为 uint8_t,为什么数学运算不限制为相同的类型?
1.我认为 * PRIu 8 * 是打印uint8_t的正确类型,为什么不工作?
我希望得到的答案是88,这是由于循环超出了uint8_t的范围。
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
void main()
{
uint8_t b = 200;
printf("%" PRIu8 "\n",b+b+b);
printf("%" PRIu8 "\n",3*b);
}
gcc版本9.4.0(Ubuntu 9.4.0- 1ubuntu 1 ~20.04.1)
3条答案
按热度按时间2j4z5cfb1#
我认为这是一个图书馆的bug。
在MS Visual Studio中,宏
PRIu8
被扩展为hhu
,您将获得预期的结果。值得注意的是,如果要使用clang,那么如果您将编写例如
你会再次得到预期的结果。
disbfnqx2#
在C语言中,无论何时用elipsis调用函数(
...
)参数,例如printf,所有这些参数都将经历 * 默认参数提升 *。这意味着任何较小的整数类型都将被转换为int
并以这种方式传递。因此在printf中,h
类型前缀是不相关的--它们将被printf忽略,并且没有任何效果(因为参数必须是int
)。此外,对于任何算术运算符(如
+
或*
),都将发生较小整数类型的相同转换,结果运算将以int
精度执行,得到int
结果。要获得预期的结果,请将其显式掩码为适当的大小:
f4t66c6m3#
如果我们看一下inttypes.h,我们会发现以下内容:
因此,这个格式说明符不包含任何长度修饰符。这在其对应参数的上下文中是有意义的,因为不可能将
uint8_t
传递给可变参数函数。由于此类型的秩小于int
,因此此类型的值将被提升为int
。这种提升也发生在表达式b+b+b
和3*b
中。如果对
char
显式地使用长度修饰符,将得到预期的结果。