如何在 C 中打印 u16 数组?

问题描述

我想打印 u16 变量的 MSB 和 LSB,这是我的代码

__u16 reg = 0x10A0; /* Device register to access */
__s32 res;
char buf[10];

buf[0] = reg;

printf("0x%X\n",buf[0]);

代码只是以十六进制格式打印 LSB 部分,但您能告诉我如何打印 MSB 部分吗?

解决方法

此代码仅打印 LSB 部分

当然,buf[0] = reg; 只复制 8 位。

你得到的结果不是明确定义的,因为 char 不能可靠地存储原始二进制文件。它可能会在您的系统上签名,然后您可能会因此而获得各种细微的错误。

第 1 步是修复您的类型。摆脱 char 以及自制的车库标准整数类型,支持标准 C 类型:

#include <stdint.h>

uint16_t reg = 0x10A0u; 
uint8_t  buf [10];

然后决定数组的字节顺序。假设您希望索引 0 是最高有效字节,那么快速和脏版本如下所示:

buf[0] = reg >> 8;
buf[1] = reg;

这将适用于这种特定情况。然而,好的编译器会抱怨隐式提升和类似的东西。严格来说,您应该养成在进行任何类型的移位之前始终强制转换为 uint32_t 的习惯(假设 >=32 位系统)。我们可以使代码更加坚固,并像这样使警告静音:

buf[0] = ((uint32_t)reg >> 8) & 0xFFu;
buf[1] = ((uint32_t)reg >> 0) & 0xFFu;

这种方法也可以安全地扩展到更大的类型。

此外,SO 和其他地方的各种庸医解决方案会告诉您为此使用 union 或字符指针。这样的解决方案使代码不必要地依赖字节序而无所获。即使在不同字节序 CPU 之间,shift 版本也 100% 可移植。

最后,用 printf 打印。您可以从标头 inttypes.h 自动获取任何 uintn_t 的正确格式说明符。它为小写十六进制提供 PRIx8,为大写十六进制提供 PRIX8

完整的程序:

#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>

int main (void)
{
  uint16_t reg = 0x10A0u; 
  uint8_t  buf[10];

  buf[0] = ((uint32_t)reg >> 8) & 0xFFu;
  buf[1] = ((uint32_t)reg >> 0) & 0xFFu;

  printf("0x%"PRIX8 "%"PRIX8 "\n",buf[0],buf[1]);
}