C语言中的Shift运算符以1而不是0开头 [英] Shift operator in C prepends ones instead of zeros
问题描述
这是代码:
#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 typedef
s 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屋!