C语言指针、数组与强制类型转换疑问:为何a[1]值变为4?
问题分析与解答
首先看你的代码:
#include <stdio.h> int main(){ char a[10]={0,1,0,1,0,1,0,1}; unsigned short *p; p=(unsigned short *)&a[0]; *p=1024; printf("%d",a[1]); return 0; }
核心原因在于数据类型的字节长度和内存字节序:
unsigned short类型在几乎所有现代系统中占2字节,而char类型占1字节。- 数组
a在内存中是连续存储的,a[0]和a[1]是相邻的两个内存单元,地址依次递增。 - 当你把
&a[0]强制转换为unsigned short*后,*p指向的是从a[0]开始的连续2字节内存空间。给*p赋值1024,本质是把1024的二进制值写入这两个字节。
1024的二进制表示(2字节)是:00000100 00000000。
当前主流系统都是小端字节序——即多字节数据的低字节存在内存低地址,高字节存在内存高地址:
- 低地址的
a[0]会被写入低字节00000000(十进制0) - 高地址的
a[1]会被写入高字节00000100(十进制4)
这就导致a[1]的值被覆盖成了4,而非原来的1。
如果是大端字节序的系统,结果会反过来:a[0]变成4,a[1]变成0,但这类系统现在非常少见。
另外需要注意:这种跨类型的指针强制转换属于C标准中的未定义行为,虽然实际中因为内存布局的规律会有可预见的结果,但不建议在生产代码中这么写,容易引发难以排查的内存问题。
内容的提问来源于stack exchange,提问作者somi
相关产品推荐
相关产品推荐

