我试图做的是制作一个1位的掩码,一直到位组的左侧,其余为零,不管可变大小。我尝试了以下方法:
unsigned char x = ~(~0 >> 1);
对我而言,无论是在char还是int上完成,都应该有效,但它不会!
对我而言,操控如下:
||||||||
0|||||||
|0000000
它看起来应该是这样的,并且在16位整数上:
|||||||| ||||||||
0||||||| ||||||||
|0000000 00000000
为什么这个结构不起作用?无论我是尝试将其分配给unsigned char还是int。
,它都给我零我在K& R的50页上,所以我很新。我不知道字面意思是什么,我不知道什么是"算术"转变是,我不知道如何使用后缀',我当然不能使用结构。
答案 0 :(得分:1)
~0
是int
零,其中所有位都被反转,即int
由所有位组成。在2s补码机器上,这是-1
。右移-1
会导致符号扩展,因此~0 >> 1
仍然是全部。
您想要的是右移unsigned
数量,不调用符号扩展名。
~0u >> 1
是一个无符号整数,高位为零,其他所有都设置为1,所以
~(0u >> 1)
是无符号整数,高位为1,其他所有为零。
现在让它适用于所有数据大小是非常重要的,因为C事先将整数运算的操作数转换为int
或unsigned int
。例如,
~(unsigned char)0 >> 1
生成int
-1
的结果,因为未签名的字符被提升为&#34; <{1}}应用到int
之前。
为了得到你想要的所有数据类型,我能看到的唯一方法是使用~
来查看数据中有多少字节(或八位字节)。
sizeof
答案 1 :(得分:0)
C的一般规则是表达式以公共类型计算,在本例中为(带符号)整数。 (~0)和(~0> 1)的评估是有符号整数,并且移位是算术移位。在您使用符号扩展实现的情况下,所以:
(0xffffffff >> 1) => (0xffffffff)
逻辑移位会在左侧注入您期望的零,因此您的问题是如何使编译器进行逻辑移位。尝试:
unsigned char a = ~0;
unsigned char b = a >> 1; // this should do a logical shift
unsigned char c = ~b;
有更好的方法来做你正在尝试的事情,但这应该可以帮助你解决当前的问题。
答案 2 :(得分:0)
有两件事会给你意想不到的结果。
0
,其被视为signed int
。int
。如果您在战略要点使用unsigned char
,那么您应该没问题。
unsigned char c = ((unsigned char)~0 >> 1);
c = ~c;