c - uint8_t 在达到 255 后不翻转到 0 无法正常工作

标签 c uint8t stdint gcc5

我是 C-Headers - stdint.hinttypes.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/

相关文章:

将 double 转换为 uint8_t*

C - Arduino - 无法将 'uint8_t*' 转换为 'uint16_t*'

c - MISRA C 2004 和 c99

c++ - 程序执行步骤

c - 为什么在printf中指定为整数的char被正确打印

c - learn c hard way章节堆和栈代码

python - 将 python int 解析为 Mysql unsigned TINYINT

c - 应该如何为 x86_64 定义 [u]int_fastN_t 类型,有或没有 x32 ABI?

c - 如何从 int32_t 中提取字节 block 并使用 c 将其存储在 int16_t 或 int8_t 中?

c - 我不明白为什么这个字符串连接有效