复习:

逻辑运算符的短路算法

1.位运算

位与::&

位或:|

位异或:^

位反:~ 注意前面的好多0也要取反

1
2
3
4
~0x5a (一个int下)
:0xffffffa5
如果我不想看到那么多f怎么办呢
unsigned char a=~0x5a;//将4字节的0xffffffa5保存到变量a中,其他的f全部丢失 这里由于明显除去f的是非负数,所以用unsigned char 就可以

2.移位运算符

a<<b //a左移b个位置,右边的空位用0补齐

a>>b //a右移b个位置

对于无符号类型数字:

左边空出来的空位用0填充

对于有符号类型的数字:

左边空出来的空位用符号位(原来数的符号)填充

左移n位相当于乘以2的n次方,右移类推

不要用乘除,效率低

1
2
3
int a=8;
a<<1;
printf("%d",a);//a的值是不改变的,只是拿着a的值的副本去左移右移

注意:原本的数可能会出现不能被整除的情况,所以右移后的数不严格等于除以2的n次方的数

3.移位运算与位运算的结合

a)位清0操作

原理:通过某些特定0位的二进制数如:11111110 (这种只有个别位为0的数)与原来数据进行按位与&操作

(明确,按位&运算中,真值不影响,假值影响才大)

连续位清0,其他位保持不

公式:A &=~(B << C )

说明:A:操作的数据

B:连续的位数 :1/3/7/0xf/0x1f/0x2f/0x3f/0xff

​ 1位、2位、3位……

C:起始位

1.将某个数据A的第0位清0,其他位保持不变

1
A &=~(1<<0)

2.将某个数据A的第1位清0,其他位保持不变

1
A&=~(1<<1);

3.将某个数据的第2位清0,其他位保持不变

1
A&=~(1<<2);

4.将某个数据的第0、1位清0,其他位保持不变

1
A&=~(3<<0);

5.将某个数据的的1、2位清0,其他位保持不变

1
A&=~(3<<1);

6.将某个数据的0、1、2、3位清0,其他位保持不变

1
A&=~(0XF<<0); 

b)位置1操作:

原理:通过一个特定位为1的二进制数来与原数据进行按位|运算,实现置1;

(明确:在按位或运输中,假值不影响,真值才影响)

连续位置1,其他位保持不变

公式:A |= (B<<C)

A:要特定位置1的数

B:连续的位数

C:连续位数的起始位

1.将某个数据A的第0位置1,其他位保持不变

1
A|=(1<<0);

2.将某个数据A的第1位置1,其他位保持不变

1
A|=(1<<1);

3.将某个数据的第2位置1,其他位保持不变

1
A|=(1<<2);

4.将某个数据的第0、1位置1,其他位保持不变

1
A|=(3<<0);

5.将某个数据的的1、2位置1,其他位保持不变

1
A|=(3<<1)

6.将某个数据的0、1、2、3位置1,其他位保持不变

1
A|=(0XF<<0)

建议:如果将来操作的位数大于等于两位,建议清0后置1

变换:以上是用于置0,置1 的,实际上,我们还可以进行一些进阶操作

如果我们要给一个二进制数的特定连续位设为某些特定值(这种方法要先把这些位清0)

例如:将数据0xe578a431的第4,5,6,7位置0xa,其他位保持不变

代码:

1
2
3
4
5
int a =0xe578a431;

a&=~(0xf<<4);

a|=(0xa<<4);

4.取地址运算符和解引用运算符:

1.计算机内存地址都是由32/64位二进制数组成,也就是任何地址都是32/64位,4/8字节

2.取地址运算符&:获取一个变量对应的内存首地址,%p打印

3.注意:

1
2
3
4
5
printf("%d",a);
printf("%d",*&a);

a=100;
*&a=100;

两者等价:gcc都翻译为:先获取地址后取内容