运算符
按位与&
- 如果(x)i == 1 , (y)i ==1 , 那么(x&y)i = 1
- 否则的话(x&y)i = 0
- 按位与常用于两种应用:
1让某一位或某些位为0 :x & 0xFE
2取一个数中的一段: x & oxFF
按位或|
- 如果(x)i == 1 或 (y)i ==1 , 那么(x&y)i = 1
- 否则的话(x&y)i == 0
- 按位与常用于两种应用:
1让某一位或某些位为1 :x | ox01
2把两个数拼起来: ox00FF | 0xFF00
按位取反~
- (~x)i = 1 - (x)i
- 把1位变为0,0位变1
- 想得到全部位为1的数:~0
- 7的二进制是0111,x | 7使得低三位为1,而
- x & ~7,就使得低三位为0
逻辑运算vs按位运算
- 对于逻辑运算,它只看到两个值:0,1
- 可以认为逻辑运算符相当于把所有非0值都变为1,然后按位运算
5&4 -> 4 而 5&&4 -> 1&1 -> 1
5|4 -> 5 而 5| |4 -> 1 | 1 -> 1
~4 -> 3 而 !~4 -> !1 -> 0
按位异或^
- 如果(x)i == (y)i ,那么(x^y)i = 0
- 否则的话,(x^y)i == 1
- 如果两个位相等,那么结果为0;不相等,结果为1
- 如果x和y相等,那么x^y的结果为0
- 对一个变量用同一个值异或两次,等于什么也没做
eg: x^y^y -> x
左移<<
- i<<j
- i中所有的位向左移动j个位置,而右边填入0
- 所有小于int类型,位移以int的方式来做,结果是int
- x<<=1 等价于 x*=2
- x<<=n 等价于 x*=2^n
右移>>
- i>>j
- i中所有的位向右移动j个位置
- 所有小于int类型,位移以int的方式来做,结果是int
- 对于unsigned类型,左边填入0
- 对于signed的类型,左边填入原来的最高位(保持符号不变)
- x>>=1 等价于 x/=2
- x>>=n 等价于 x/=2^n
输出一个数的二进制
#include <stdio.h>
int main(int argc, char const *argv[])
{
int number;
scanf("%d", &number);
unsigned mask = 1u<<31; //将1移到最高位
for ( ; mask ; mask >>=1 ) { //将1不断向右移
printf( "%d" , number & mask?1:0); //将1与0输出
}
printf( "\n");
return 0;
}
扩展(MUC的SFR)
SBS = 1u<<2 -> 100
PE = 1u<<3 -> 1000
U |= SUS|PE ->1100 让某些比特位1
U &~SBS ->1011 ,&后0可以清除位
U &~PE->10111 ,&后0可以清除位 让某些比特位为0
段位
- 把一个int的若干位组合成一个结构
struct {
unsigned int leading : 3 ;
unsigned int FLAG1 : 1 ;
unsigned int FLAG2 : 1 ;
int trailing :11;
};
- 可以直接用段位的成员名称来访问
- 比位移,与,或还方便
- 编译器会安排其中的位排列,不具有可移植性
- 当需要的位超过一个int时会采用多个int
#include <stdio.h>
void prtBin(unsigned int number) ;
struct U0 {
unsigned int leading : 3;
unsigned int FLAG1:1;
unsigned int FLAG2: 1;
int trailing: 27;
};
int main(int argc, char const *argv[])
{
struct u0 uu;
uu.leading = 2;
uu. FLAG1 = 0;
uu. FLAG2 = 1;
uu.trailing = 0;
printf( "sizeof( uu)=%luln", sizeof(uu) ) ;
prtBin(*(int*)&uu) ;
return 0;
}
void prtBin(unsigned int number)
{
unsigned mask = 1u<<31;
for ( ; mask ; mask >>=1 ) {
printf( "%d", number & mask?1:0);
}
printf( "\n");
}
#include <stdio.h>
void prtBin(unsigned int number) ;
struct U0 {
unsigned int leading : 3;
unsigned int FLAG1:1;
unsigned int FLAG2: 1;
int trailing: 32; // 此时已经超过了一个int
};
int main(int argc, char const *argv[])
{
struct u0 uu;
uu.leading = 2;
uu. FLAG1 = 0;
uu. FLAG2 = 1;
uu.trailing = 0;
printf( "sizeof( uu)=%luln", sizeof(uu) ) ;
prtBin(*(int*)&uu) ;
return 0;
}
void prtBin(unsigned int number)
{
unsigned mask = 1u<<31;
for ( ; mask ; mask >>=1 ) {
printf( "%d", number & mask?1:0);
}
printf( "\n");
}
可以从输出结果看,用两个int 来表达变量