我是 C-Headers - stdint.h
和 inttypes.h
的新手。我正在尝试一些代码以了解 uint8_t
的工作原理。但是,它似乎遇到了问题。
我声明了 4 个 uint8_t
整数,边界值分别为 0、255、256、-1,并对其执行了一些简单的算术运算。我这样做是因为我想知道 c 编译器(我在 linux 上使用 gcc 5.4.0
)会生成什么错误/警告。如果没有,我很想知道输出是什么样子的。下面给出的代码。
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
int main() {
int a = 10;
printf("%d\n", a++);
printf("%d\n\n", a);
// 8 bit unsigned integer -> range[0, 255]
uint8_t ua81=0, ua82=255, ua83=256, ua84=-1;
printf("--------STDINT.H----uint8_t--DEMO--------\nua81 = %" PRIu8 "\n", ua81);
printf("ua82 = %" PRIu8 "\nua83 = %" PRIu8 "\nua84 = %" PRIu8 "\n\n", ua82, ua83, ua84);
printf("ua81+1 = %" PRIu8 "\nua82-3 = %" PRIu8 "\nua83-4+7 = %" PRIu8 "\nua84-1+20 = %" PRIu8 "\n----------\n\n", ua81+1, ua82-3, ua83-4+7, ua84-1+20);
return 0;
}
这段代码的输出如下:
vagrant@ubuntu-xenial:~/Documents/Coding Practice/p_c$ vi stdint_h.c
vagrant@ubuntu-xenial:~/Documents/Coding Practice/p_c$ gcc -Wall stdint_h.c -o a
stdint_h.c: In function ‘main’:
stdint_h.c:11:33: warning: large integer implicitly truncated to unsigned type [-Woverflow]
uint8_t ua81=0, ua82=255, ua83=256, ua84=-1;
^
vagrant@ubuntu-xenial:~/Documents/Coding Practice/p_c$ ./a
10
11
--------STDINT.H----uint8_t--DEMO--------
ua81 = 0
ua82 = 255
ua83 = 0
ua84 = 255
ua81+1 = 1
ua82-3 = 252
ua83-4+7 = 3
ua84-1+20 = 274
----------
如前所述,我为此使用了带有 gcc 5.4.0
编译器的 Linux 机器。
vagrant@ubuntu-xenial:~/Documents/Coding Practice/p_c$ gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
我无法理解为什么对于变量 ua84
,在达到 255
后,该值没有滚动到 0
,而ua83
也是如此。考虑到 255 之后的翻转,我认为 ua84
的值应该是 18
。
我觉得这与 warning
中提到的 Implicit Truncation 有关,编译时生成的变量 ua83
.我不知道那到底有什么问题。我还想知道如何去做我仍然想继续使用 uint8_t
。
最佳答案
由于隐式提升,ua84-1+20
将是一个 int
并且其值为 274。您应该明确地将结果转换为 uint8_t
让它变成 18。
printf
没有足够的魔力来根据格式(*) 转换其参数。它只期望它收到它需要的东西并提取传递的参数。所以在这里你应该写:
printf("ua81+1 = %" PRIu8 "\nua82-3 = %" PRIu8 "\nua83-4+7 = %" PRIu8 "\nua84-1+20 = %"
PRIu8 "\n----------\n\n", (uint8_t)(ua81+1), (uint8_t)(ua82-3), (uint8_t)(ua83-4+7),
(uint8_t)(ua84-1+20));
(*) 更准确地说,这是格式说明符的问题。在段落 7.21.6.1 The fprintf function §7 draft n1570 for C11 中说:
hh Specifies that a following d, i, o, u, x, or X conversion specifier applies to a signed char or unsigned char argument (the argument will have been promoted according to the integer promotions, but its value shall be converted to signed char or unsigned char before printing); ...
因此,如果您明确使用了 %hhu
,您将得到 18(即使传递了 274)。但不幸的是,来自 inttype.h 的宏只需要正确显示预期范围的值,因此许多实现将 PRIu8
翻译为 u
(感谢 Eric Postpischil 注意到).
关于c - uint8_t 在达到 255 后不翻转到 0 无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56055188/