C语言中左值类型转换的疑问:解析*(unsigned short *)&a = b语句
关于C语言中左侧指针类型转换的疑问解答
先看你给出的示例代码:
#include <stdio.h> int main() { unsigned long long a; unsigned short b; b = 10; *(unsigned short *)&a = b; printf("a = %lld\n", a); return 0; }
先拆解*(unsigned short *)&a = b;的作用
这条语句本质是直接操作变量a的内存低位字节,拆解步骤:
&a获取unsigned long long类型变量a的内存地址,此时指针类型是unsigned long long *- 通过
(unsigned short *)强制转换,把这个地址当成unsigned short类型变量的地址看待 - 解引用这个转换后的指针,将
b的值写入对应内存区域——也就是只修改a的低2字节(假设unsigned short占2字节),a的其余字节保持原有值(注意:这里a未初始化,原有值是随机的,属于未定义行为,实际测试可能输出低2字节为10、高位随机的数)
为什么不能用右侧类型转换替代?
如果写成a = (unsigned long long)b;,这是把b的值零扩展为unsigned long long类型后,覆盖整个a的所有字节,最终a的高位全为0、低位是10。这和你想要的“只修改LSB位,其余位保留”的需求完全不符——这就是为什么不能用右侧转换的原因。
这类场景下是否需要左侧的类型转换?
是的,必须这么做,原因很简单:
- 如果你要只修改变量的部分内存字节,而非覆盖整个变量,就需要通过指针类型转换,把原变量的地址“伪装”成目标宽度的指针,再解引用赋值。
- 这种操作常见于:手动处理字节序(比如把多字节数据拆成单个字节写入)、操作硬件寄存器的特定字节、或者在无结构体的情况下手动拼接多字节数据等场景。
注意事项
这种属于C语言里的类型双关操作,C标准中只有通过char *类型访问其他类型的内存是明确允许的,用unsigned short *访问unsigned long long的内存属于未定义行为,但主流编译器(GCC、Clang、MSVC)都会按照预期处理。另外要注意目标类型的对齐要求:如果原变量的地址不符合目标类型的对齐规则,可能会触发总线错误(不过unsigned long long的地址通常是自然对齐的,所以unsigned short的对齐要求肯定满足)。
内容的提问来源于stack exchange,提问作者sg777
相关产品推荐
相关产品推荐

