You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中%u与%d格式说明符的区别及地址打印差异问题

复现代码
#include<stdio.h>

int main(){
    int a = 3;
    printf("%u\n",&a);
    printf("%d\n",&a);
    return 0;
}
%u与%d的核心区别

两个格式符的解析规则完全不同,对应的数据类型也不一样:

  • %d:将传入参数按有符号int类型解析为十进制整数,遵循二进制补码规则,最高位为符号位,取值范围包含负数。
  • %u:将传入参数按无符号unsigned int类型解析为十进制整数,所有二进制位都用于表示数值,不存在符号位,取值范围从0开始,没有负数。
打印同一地址得到不同输出的原因

首先需要明确:用%d或%u打印内存地址本身就属于C标准定义的未定义行为,二者从设计上就不是用来处理指针类型参数的,输出异常是必然结果。具体数值差异的来源有两个:

  1. 解析规则差异
    内存地址是无符号的整数值,如果地址值被截断为int长度后,最高二进制位为1:用%d解析时会把最高位识别为符号位,最终输出一个负整数;用%u解析时最高位会被当作普通数值位,最终输出一个值很大的正整数。二者是同一段二进制数据按不同规则翻译得到的结果,和地址本身是否变化没有关系。
    举个实际例子:如果截断后的地址二进制对应32位十六进制值0xBFFFF123:
    • 按%d(有符号int)解析得到十进制值-1073745629
    • 按%u(无符号int)解析得到十进制值3221221667
  2. 长度不匹配导致截断
    目前主流64位环境下,指针类型长度为8字节,而int类型长度固定为4字节。用%d/%u打印指针时,printf只会从栈上读取4字节的内容,直接把高4位的地址数据截断,最终输出的值本身就不是完整的内存地址,结果自然不可靠。

打印内存地址的标准写法是使用%p格式符,同时将指针强转为void*类型,示例:

printf("%p\n", (void*)&a);

内容的提问来源于stack exchange,提问作者RACHIT MITTAL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 00:12:22