为什么我的位操作构造在C中不起作用

时间:2014-08-16 23:22:37

标签: c

我试图做的是制作一个1位的掩码,一直到位组的左侧,其余为零,不管可变大小。我尝试了以下方法:

unsigned char x = ~(~0 >> 1);

对我而言,无论是在char还是int上完成,都应该有效,但它不会!

对我而言,操控如下:

||||||||
0|||||||
|0000000

它看起来应该是这样的,并且在16位整数上:

|||||||| ||||||||
0||||||| ||||||||
|0000000 00000000

为什么这个结构不起作用?无论我是尝试将其分配给unsigned char还是int。

,它都给我零

我在K& R的50页上,所以我很新。我不知道字面意思是什么,我不知道什么是"算术"转变是,我不知道如何使用后缀',我当然不能使用结构。

3 个答案:

答案 0 :(得分:1)

~0int零,其中所有位都被反转,即int由所有位组成。在2s补码机器上,这是-1。右移-1会导致符号扩展,因此~0 >> 1仍然是全部。

您想要的是右移unsigned数量,调用符号扩展名。

~0u >> 1

是一个无符号整数,高位为零,其他所有都设置为1,所以

~(0u >> 1)

是无符号整数,高位为1,其他所有为零。

现在让它适用于所有数据大小是非常重要的,因为C事先将整数运算的操作数转换为intunsigned 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)

有两件事会给你意想不到的结果。

  1. 您刚开始使用0,其被视为signed int
  2. 中间结果转换为int
  3. 如果您在战略要点使用unsigned char,那么您应该没问题。

    unsigned char c = ((unsigned char)~0 >> 1);
    c = ~c;