"%ul" 表示"%u"(无符号整数)后跟字母"l"。也许您打算使用"%lu"(无符号长),但是对于uint64_t,这两者都不正确。
正确的说明符在inttypes.h,它是"%" PRIu64。
这也不会像您建议的那样打印0x,它会打印十进制表示。使用"%" PRIx64 表示十六进制(也不会打印前导0x)。
继续,您的代码会导致 undefined behaviour。根据严格的别名规则,不允许使用uint64_t类型的表达式来访问任何一开始没有写成uint64_t或int64_t的变量。
您可以通过使用正确类型的变量来避免严格的别名规则,无论是在联合中还是在其他地方,例如:
uint64_t x;
memcpy(&x, a, sizeof x);
printf("%" PRIu64 "\n", x);
您的编译器会对此进行优化,因此不必担心它效率低下或其他问题。
请注意,此输出是实现定义的,因为编译器可以选择各种方式来对 uint64_t 的位进行排序。两种常见的顺序是 big-endian 和 little-endian。
您问题的另一部分是关于其他整数类型。不幸的是,您坚持使用编译器提供的内容。很可能它没有提供uint94_t。你必须滚动你自己的代码来实现你想要的。例如,您可以模拟 96 位大端:
uint8_t a[12] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C};
uint64_t x = 0, y = 0;
mempcy((unsigned char *)&x + 4, a, 4);
memcpy(&y, a+4, 8);
printf("%" PRIx64 "%" PRIx64 "\n", x, y);
当然你可以一个字一个字地打印出来。