You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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的内存低位字节,拆解步骤:

  1. &a获取unsigned long long类型变量a的内存地址,此时指针类型是unsigned long long *
  2. 通过(unsigned short *)强制转换,把这个地址当成unsigned short类型变量的地址看待
  3. 解引用这个转换后的指针,将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 07:42:56