C语言中的Shift运算符以1而不是0开头 [英] Shift operator in C prepends ones instead of zeros

查看:159
本文介绍了C语言中的Shift运算符以1而不是0开头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是代码:

#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.

first_part is the following byte: 11101010. inst.cond becomes 11111110, but I need it to be 00001110.

所以,我的实际问题是我想获取指令的前4位,该位的起始地址为instruction_addr.我试图通过使用右移位运算符>>来做到这一点,但问题是它不是在字节的左边加0,而是在前面加1.

So, my actual problem is that I want to get the first 4 bits of my instruction which starts at the address instruction_addr. I tried to do so by using the right shift operator >> but the problem is that instead of prepending 0s to the left of the byte, it prepends 1s.

我在stackoverflow上发现,我首先必须将值转换为无符号值,这就是我使用变量first_part所做的事情,但是我仍然遇到相同的问题.我不明白为什么这种转变似乎将我的变量视为"负变量,而其类型却是无符号的".

I found on stackoverflow that I first had to cast the value to a unsigned one, and that's what I did by using the variable first_part, but I still have the same problem. I don't understand why the shift seems to "see" my variable as a negative one while its type is specifically "unsigned".

有人有主意吗?

推荐答案

您的u8类型使用的是char,没有指定签名,这意味着它具有未定义的签名.默认情况下,您的编译器可能正在使用signed char.因此,在操作过程中和升级过程中,您都需要进行符号扩展.

Your u8 type is using char without specifying signedness, which means it has undefined signedness. It's likely your compiler is using a signed char by default. Thus, you're subject to sign-extension during operations and during promotion.

更改:

#define u8 char
#define u32 unsigned int

收件人:

typedef unsigned char u8;
typedef unsigned int u32;

(或正确使用stdint.h类型),并且您的存储空间实际上应未签名.

(or use stdint.h types properly), and your storage should be actually unsigned.

使用typedef也意味着编译器会涉及此别名,这不仅是预处理器文本替换,而且消除了一类细微的错误.

Using typedefs also means the compiler is involved with this aliasing, it's not just a preprocessor text replacement, eliminating a class of subtle errors.

这篇关于C语言中的Shift运算符以1而不是0开头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆