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

按位或操作返回错误结果,求代码问题原因排查

问题根源:有符号char的符号扩展

这个问题的核心在于MSVC(你用的MVS Community 2017)中char类型默认是有符号的,当它参与位运算时会触发符号扩展,导致结果不符合预期。

具体过程拆解

你的代码执行步骤里,问题出在n = n | arr[1];这一行:

  1. arr[1]的值是0xc0,作为有符号char,它对应的十进制是-64(因为0xc0的最高位是1,是负数的补码表示)。
  2. 当有符号char参与运算时,会被自动提升为int类型。为了保持数值不变,编译器会进行符号扩展——把最高位(符号位)填充到int的高24位,所以0xc0就变成了0xffffffc0。
  3. 此时n的值是0x0a00(uint16_t类型),也会被提升为int类型的0x00000a00。
  4. 两者按位或的结果是0xffffffc0 | 0x00000a00 = 0xffffffc0,最后赋值给uint16_t的n时,会截断高16位,得到0xffc0,这就是你看到的错误结果。

解决方案

有几种简单的修复方式,任选其一即可:

1. 声明无符号char数组

直接把数组类型改成unsigned char,从根源避免符号扩展:

unsigned char arr[] = { 0x0a, 0xc0 };
uint16_t n{};
n = arr[0];
n = n << 8;
n = n | arr[1]; // 此时n的值为0x0ac0,符合预期

2. 强制转换为无符号类型再运算

在使用arr[1]时,先强制转为unsigned char,截断符号扩展的部分:

char arr[] = { 0x0a, 0xc0 };
uint16_t n{};
n = arr[0];
n = n << 8;
n = n | (unsigned char)arr[1]; // 强制转换后避免符号扩展

3. 使用明确的无符号8位整数类型

引入<stdint.h>头文件,用uint8_t定义数组,类型更清晰:

#include <stdint.h>
uint8_t arr[] = { 0x0a, 0xc0 };
uint16_t n{};
n = arr[0];
n = n << 8;
n = n | arr[1]; // 无符号类型不会触发符号扩展

内容的提问来源于stack exchange,提问作者Konstantin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:46:48