指针类型转换代码疑问:*a='B'的作用及数组元素重定义影响
指针类型转换与数组内存操作解析
一、*a='B';的实际作用
首先明确数组b的内存布局:char b[] = "Hye";在内存中是连续的4字节(字符串末尾自动追加'\0'终止符),顺序为:b[0]='H'、b[1]='y'、b[2]='e'、b[3]='\0'。
a = (int*)&b;:将数组b的起始地址强制转换为int*类型,让指针a以4字节(int的典型长度)为单位访问b的内存区域。*a='B';:'B'是char类型(1字节),会先被提升为int类型的值0x00000042(对应ASCII的'B')。随后这个4字节的int值会被写入a指向的内存——也就是b的前4个字节。
在小端字节序(绝大多数x86/x86_64系统采用)下,int的低字节存放在内存低地址,写入后b的内存内容变为:b[0]='B'(0x42)、b[1]='\0'(0x00)、b[2]='\0'(0x00)、b[3]='\0'(0x00)。
此时字符串b的第二个字符就是终止符'\0',printf("%s", b)遇到终止符就停止输出,所以第一段代码结果为B。
二、第二段代码输出变化的原因
第二段代码执行*a='B';后,b的前4字节已被修改为B、\0、\0、\0。后续的b[1]='y';和b[2]='e';直接修改了数组元素:
b[1]='y':把原来的'\0'替换为字符'y'b[2]='e':把原来的'\0'替换为字符'e'
此时b的内存内容变为:b[0]='B'、b[1]='y'、b[2]='e'、b[3]='\0',形成完整的字符串"Bye",所以printf输出整个字符串Bye。
关键提醒
这种跨类型指针访问属于C标准定义的未定义行为:不同类型的指针有不同的对齐要求和内存访问宽度,在不同编译器、架构下可能产生完全不同的结果,实际开发中必须避免此类写法。
内容的提问来源于stack exchange,提问作者Rajesh Paul
相关产品推荐
相关产品推荐

