C语言int* ip=(int*)p含义及对应示例代码输出结果解释
#include <stdio.h> int main(){ char p[5] = "ABCD"; int* ip = (int *)p; printf("%d\n", *(ip + 0)); // 1145258561 printf("%d\n", ip); // 6422016 }
int* ip = (int *)p 语句含义 - 语句中的
p是长度为5的char数组,数组名在表达式中使用时会自动退化为指向首元素的char*类型指针,指向数组第一个字符'A'所在的内存地址。 (int *)p是C语言的强制类型转换操作:它不会修改内存中存储的实际数据,只是告诉编译器,将这个地址对应的内存块按照int类型的规则解析、访问。- 整体语句的作用是:定义一个
int*类型的指针变量ip,将转换后的指针值赋值给ip。后续通过ip访问内存时,访问步长为sizeof(int)(主流桌面/服务器环境为4字节),内存内容会被解析为int类型整数,而非原来的char类型字符。
示例代码输出原理
以下解释基于主流x86/x86_64小端序、int占4字节的运行环境,这类指针跨类型转换的结果属于C标准规定的实现定义行为,不同字节序、不同int长度的平台结果会有差异。
第一个输出1145258561的由来
ip是int*类型指针,*(ip + 0)等价于*ip,表示从ip指向的起始地址开始,读取连续4字节的内容,按照int类型整数解析。- char数组
p的前4个字节依次存储的是字符'A'、'B'、'C'、'D',对应的ASCII十六进制值分别是0x41、0x42、0x43、0x44。 - 小端序环境下,多字节整数的存储规则是:低地址存放整数的低有效字节,高地址存放整数的高有效字节。p数组的内存地址从低到高对应4字节int的从低到高有效位,拼合后的4字节整数十六进制值为
0x44434241。 - 将
0x44434241转换为十进制,计算结果恰好是1145258561,和输出值一致。
第二个输出6422016的由来
- 这里的
ip存储的是它指向的内存地址值,需要注意:用%d格式符打印指针属于未定义行为,正确打印指针应该使用%p格式符,示例中能正常输出是因为当前运行环境下指针宽度和int宽度恰好匹配。 - 输出值
6422016是程序运行时操作系统给char数组p分配的虚拟内存起始地址,这个值不是固定的:如果开启了地址空间随机化(ASLR),每次程序运行分配的地址都可能变化,不存在固定的解析逻辑。
注意:这类将char强制转换为int的写法存在兼容性风险:很多架构要求int类型的存储地址必须是4字节对齐的,char数组默认没有这个对齐保证,未对齐的指针访问可能触发硬件异常导致程序崩溃,生产环境不建议随意使用这类类型双关写法。
内容的提问来源于stack exchange,提问作者MinhChi
相关产品推荐
相关产品推荐

