printf如何识别传入整数的大小?以uint32_t与uint8_t为例
为什么printf用
0x%x时,能区分uint32_t和uint8_t的打印内容长度? 先看你给出的代码和输出:
示例代码
uint32_t X = 0xAABBCCDD; printf("uint32_t 0x%x\n", (uint32_t) X); printf("uint8_t 0x%x\n", (uint8_t) X);
输出结果
uint32_t 0xaabbccdd uint8_t 0xdd
这里的核心原因是C语言的可变参数默认提升规则,再加上%x格式符的作用逻辑,一步步拆解给你看:
先说
uint8_t的情况:uint8_t本质就是unsigned char,属于宽度小于int的整数类型。当你把它传给printf这种可变参数函数时,C语言会自动把它提升为int类型(毕竟int完全能装下uint8_t的所有取值,最大值才255)。而你把X强制转成uint8_t时,已经截断了高位的0xAABBCC,只剩下0xDD,提升为int后值还是0xDD。%x格式符会把传入的参数当作unsigned int来打印,所以最终输出的就是dd。再看
uint32_t的情况:在绝大多数32位或64位的现代系统中,uint32_t的宽度和unsigned int是一致的(都是4字节),所以它不需要做类型提升,直接以unsigned int的类型传入printf。%x会完整打印这个4字节无符号整数的所有十六进制位,也就是aabbccdd。
补充一句:如果是在某些特殊系统(比如古老的16位系统)中,uint32_t的宽度大于unsigned int,那它会被提升为unsigned long,这时候用%x就会出问题,得换成%lx才能正确打印,但这种情况现在几乎碰不到了。
内容的提问来源于stack exchange,提问作者Mohammad Nabil
相关产品推荐
相关产品推荐

