C语言 位运算符

二进制补码
用一个字节中的后7位表示0~127,高阶位设置为0,。如果高阶位是1,表示的值为负

二进制反码
反转每一个二进制位,然后加1,得到一个二进制补码数的相反数

八进制
每个八进制位对应3个二进制位。例如,八进制数0377的二进制形式是11111111。即,用111代替0377中的最后一个7,再用111代替倒数第2个7,最后用011代替3,并舍去第1位的0.表明比0377大的八进制要用多个字节表示。

十六进制
用015表示数字。但是,由于没有单独的数表示1015,所以用字母A~F来表示。例如,十六进制数A3F(在C中写作0xA3F)表示为:
10x16^2 + 3x16^1 + 15x16^0 = 2623(十进制)
A表示10,F表示15。在C语言中,A~F既可用小写也可用大写。因此,2623也可写作0xa3f。
每个十六进制位都对应一个4位的二进制数(即4个二进制位)。

C按位运算符
二进制反码或按位取反:~
一元运算符~把1变为0,把0变为1。不会修改原值
~(10011010) //表达式
(01100101) //结果值
newval = ~val; //将val的反码赋给newval,val值不变

按位与:&
二元运算符&通过逐位比较两个运算对象,生成一个新值。对于每个位,只有两个运算对象中相应的位都为1时,结果才为1(从真/假方面看,只有当两个为都为真时,结果才为真)。
(10010011) & (00111101) //表达式
(00010001) //结果值
val &= 0377; //按位与和赋值结合的运算符 等价于 val = val & 0377;

按位或:|
二元运算符 | 通过逐位比较两个运算对象,生成一个新值。对于每个位,如果两个运算对象中相应的位为1,结果就为1(从真/假方面看,如果两个运算对象中相应的一个位为真或两个位都为真,那么结果为真)。
(10010011) | (00111101) //表达式
(10111111) //结果值
val |= 0377; //按位或和赋值结合的运算符

按位异或:^
二元运算符 ^ 通过逐位比较两个运算对象。对于每个位,如果两个运算对象中相应的位一个为1(但不是两个为1),结果为1(从真/假方面看,如果两个运算对象中相应的一个位为真且不是两个位同为真,那么结果为真)。
(10010011) ^ (00111101) //表达式
(10101110) //结果值
val ^= 0377; //按位异或和赋值结合的运算符

移位运算符
左移:<<
左移运算符(<<)将其左侧运算对象每一位的值向左移动其右侧运算对象指定的位数。左侧运算对象移出左末端位的值丢失,用0填充空出的位置。
(10001010) << 2 //表达式
(00101000) //结果值

该操作产生一个新的位值,但是不改变其运算对象。例如,假设stonk为1,那么stonk << 2为4,但是stonk本省不变,仍为1。可以使用左移赋值运算符(<<=)来改变变量的值。该运算符将变量中的位向左移动其右侧运算对象给定值得位数。
int stonk = 1, onkoo;
onkoo = stonk << 2; //把结果4赋给onkoo,stonk值不变
stonk <<= 2; //把stonk的值改为4 等价于stonk = stonk << 2;

右移:>>
右移运算符(>>)将其左侧运算对象每一位的值向右移动其右侧运算对象指定的位数。左侧运算对象移出右末端位的值丢失。对于无符号类型,用0填充空出的位置;对于有符号类型,其结果取决于机器。空出的位置可用0填充,或者用符号位(即,最左端的位)的副本填充
(10001010) >> 2 //表达式,有符号值
(00100010) //在某些系统中的结果值
(11100010) //在另一些系统上的结果值

(10001010) >> 2 //表达式,无符号值
(00100010) //所有系统都得到该结果值

int sweet = 16, ooosw; // 二进制表示:10000
ooosw = sweet >> 3; // 00010 即 ooosw = 2,sweet值仍然为16
sweet >>= 3; // sweet的值为2

你可能感兴趣的:(C语言 位运算符)