C语言为何不能用%d打印变量地址?类型不匹配为何不终止执行?
关于%p的输出格式
%p是C标准规定专门用来输出指针(内存地址)的格式说明符,它的默认输出就是带0x前缀的十六进制数值,这是符合标准的正常行为,不是你的配置有问题。内存地址本质确实是无符号整数,但标准选择用十六进制格式展示是为了更方便开发者做内存相关的调试,和十进制的正整数只是展示形式不同,指向的内存位置是完全正确的。
为什么有的教程里用%d输出地址没问题
这和运行环境的位数直接相关:
- 32位系统下,指针的长度是4字节,和
int类型的长度一致,此时把指针传给%d做解析,不会发生字节截断,所以看起来输出结果是对的 - 你当前使用的是64位系统,指针长度是8字节,而
int在绝大多数64位编译环境下还是4字节,用%d解析指针的时候只会取指针的低4字节,并且按照有符号整数的规则解析,自然就会出现负数或者不符合预期的数值。你看到的教程大概率是在32位环境下运行的,这种写法本身就是不符合C标准的错误写法,只是刚好在32位环境下没触发问题而已。
为什么程序没有崩溃只是输出错误值
C语言本身不对可变参数函数的参数类型做运行时校验,printf的格式符和传入参数的匹配完全由开发者自己保证。你这种格式符和参数类型不匹配的行为属于未定义行为(Undefined Behavior),未定义行为的后果是完全不确定的:可能输出错误值、可能程序崩溃、甚至可能在某些环境下看起来完全正常运行都有可能,你当前遇到的只是未定义行为的一种表现形式而已,绝对不能因为程序没有崩溃就认为这种写法是合法的。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

