C中的Shift运算符取代了零而不是零

时间:2017-04-05 19:22:32

标签: c types binary bit-shift

以下是代码:

#define u8 char
#define u32 unsigned int

typedef struct {
    //decoded instruction fields
    u8 cond; // Condition (f.ex. 1110 for always true)
    u8 instruction_code; // Is a constant since we only use branch
    u32 offset; // Offset from current PC
} dcdinst;

u8 mem[1024];

mem[0x0] = 0b11101010;

u8* instruction_addr = &mem[pc];

if (instruction_addr == NULL) {
    return false;
}

unsigned int first_part = instruction_addr[0];

// Here is the code that presents a problem:
// I try to get the upper part of the first byte
inst.cond = first_part >> 4;

first_part是以下字节:11101010。 inst.cond变为11111110,但我需要它为00001110。

所以,我的实际问题是我希望得到从地址instruction_addr开始的指令的前4位。我试图通过使用右移位运算符>>来做到这一点,但问题是,不是在字节的左边增加0,而是前置1。

我在stackoverflow上发现我首先必须将值转换为无符号值,这是我使用变量first_part所做的,但我仍然遇到同样的问题。我不明白为什么转变似乎"看"我的变量是负数,而它的类型是#34; unsigned"。

有人有想法吗?

1 个答案:

答案 0 :(得分:3)

您的u8类型正在使用char而未指定签名,这意味着它具有未定义的签名。默认情况下,您的编译器可能正在使用signed char。因此,您在操作期间和促销期间都会签名延期。

变化:

#define u8 char
#define u32 unsigned int

为:

typedef unsigned char u8;
typedef unsigned int u32;

(或正确使用stdint.h类型),您的存储空间应该是无符号的。

使用typedef也意味着编译器参与了这种别名,它不仅仅是一个预处理器文本替换,消除了一类微妙的错误。