int变量地址强转为char*后用printf打印为何会输出字符串?
代码运行逻辑说明
首先给出核心逻辑拆解,你贴出的可运行代码如下:
#include <stdio.h> #define NUM 6513249 int main() { int a = NUM; char * pt = (char *) &a; printf("a is: %d\n", a); printf("string is: %s\n", pt); return 0; }
核心原理拆解
- 第一步:先把宏定义的数值
6513249转成十六进制格式,得到结果是0x00636261,每个字节对应的ASCII值如下:0x61对应字符a0x62对应字符b0x63对应字符c0x00对应C语言字符串的结束标记\0
- 第二步:结合X86、X86_64架构默认的小端存储规则:多字节数据的低字节会存在内存的低地址位置,所以占4字节的int类型变量
a,在内存中从低地址到高地址的存储顺序为0x61 0x62 0x63 0x00 - 第三步:你对强制类型转换的认知是正确的,
(char *)&a确实只是取到int变量a的内存首地址,也就是存储0x61的最低地址,赋值给pt - 第四步:
printf的%s格式符的工作逻辑是:从传入的char指针地址开始,逐个读取地址指向的字节,转成对应的ASCII字符输出,直到遇到\0(也就是0值字节)就终止输出。所以从pt指向的0x61开始读,自然就依次输出a、b、c,遇到下一个字节0x00就停止,最终输出字符串abc
额外注意
这个代码的写法是未定义行为,仅在当前取值、当前小端架构下刚好能正常输出:如果NUM的取值中没有0值字节,printf读取%s的时候就会越过int变量的内存范围,访问非法内存,触发崩溃或者输出乱码。
内容的提问来源于stack exchange,提问作者Ben B
相关产品推荐
相关产品推荐

