1G=1024M;
1M=102KB;
1KB=1024B(字节);
1B=8bits(位);
#include<stdio.h> #include<stdlib.h> //C语言中的逻辑运算符 //逻辑与(&&);逻辑或(||);逻辑非(!)。 //强调逻辑运算符与位逻辑运算符不同 //C语言中的位运算符有以下两类: //位逻辑运算符:&(位“与”)、^(位“异或”)、 | (位“或”)、~(位“取反”)。 //移位运算符: << (左移)、 >> (右移) void main(){ //一:取反运算(~) unsigned char ch1 = 165; //一个字符有8位,ch1换算成二进制是 1010 0101 //位取反的操作符为“~”, //即每位都取反,0变成1,1变成0,需要注意的是,位取反运算并不改变操作数的值。 //那么~ch1=0101 1010,换算成十进制是90 unsigned char ch2 = ~ch1; //printf(" %d", ~ch1);// 打印 -166 错误 解释: ~ch1是取反运算,值会存储在cpu的寄存器中,所以printf函数不确定~ch1的类型 printf(" 取反运算%d", (unsigned char)~ch1);// 打印 90 正确 printf(" 取反运算%d",ch2);// 打印 90 正确 //二:与运算(&)----清零 //位与运算的操作符为&,将对两个操作数的每一位 //进行与运算,位“与”运算的准则如下:(两者都为1的时候才是1,有一个为0就是0) //1 & 1 = 1 1 & 0 = 0 0 & 1 = 0 0 & 0 = 0 unsigned char ch3 = 15; //ch1 1010 0101 //ch3 0000 1111 //ch1&ch3 0000 0101 十进制是5 unsigned char ch4 = ch1&ch3; printf(" 与运算%d", ch4);// 打印 5 正确 //对于ch1&ch3的分析,发现与运算可以用来"保持一部分位不变(不变用1),部分为全部为0(变0用0)" //三:或运算(|)---置1 //位或运算的操作符为|,将对两个操作数的每一位进行或运算,位“或”运算的准则如下:(两者有一个是1就是1,两者都为0才是0) //1 | 1 = 1 1 | 0 = 1 0 | 1 = 1 0 | 0 = 0 //例子 //ch1 1010 0101 //ch3 0000 1111 //ch1|ch3 1010 1111 十进制是175 unsigned char ch5 = ch1|ch3; printf(" 或运算%d", ch5);// 打印 175 正确 //对于ch1|ch3的分析,发现与运算可以用来"保持一部分位不变(不变用0),部分为全部为1(变1用1)" //四:异或运算(^)---取反 //位或运算的操作符为^,将对两个操作数的每一位进行异或运算。 //通俗地讲,如果位“异或”运算的两个位相同(同为0或同为1),结果为0, //若两个位不同(一个为0,另一个为1),结果为1,对应的准则为:(两者相同结果是0,两者不同结果是1) //1 ^ 1 = 0 1 ^ 0 = 1 0 ^ 1 = 1 0 ^ 0 = 0 //例子 //ch1 1010 0101 //ch3 0000 1111 //ch1^ch3 1010 1010 十进制170 unsigned char ch6 = ch1^ch3; printf(" 异或运算%d", ch6);// 打印 170 正确 //对于ch1^ch3的分析,发现与运算可以用来"保持一部分位不变(不变用0),部分取反(取反用1)" //五:左移运算(<<) //A称为操作数,其必须为数字型变量或数字型常量, //此处的数字型包括整型、浮点型和char型,A中存储的0、1序列向左或右移动n位, //移动后的值作为整个表达式的输出,执行移位运算并不改变操作数A的值。 unsigned char ch7 = 1; //例子 //ch7 0000 0001 十进制是1 //ch7<<1 0000 0010 十进制是2 (1*2) //ch7<<2 0000 0100 十进制是4 (2*2) unsigned char ch8 = ch7<<1; unsigned char ch9 = ch7<<2; printf(" 左移运算ch7<<1=%d", ch8);// 打印 2 正确 printf(" 左移运算ch7<<2=%d", ch9);// 打印 4 正确 unsigned char cha = 128; //例子 //cha 1000 0000 十进制是128 //cha<<1 0000 0000 十进制是0 unsigned char chb = cha << 1; printf(" 左移运算cha<<1=%d", chb);// 打印 0 正确 //六:右移运算(>>) unsigned char chc = 255; //例子 //chc 1111 1111 十进制是255 //chc>>1 0111 1111 十进制是127 (255/2) //chc>>2 0011 1111 十进制是63 (127/2) unsigned char chd = chc >> 1; unsigned char che = chc >> 2; printf(" 右移运算chc >> 1=%d", chd);// 打印 127 正确 printf(" 右移运算chc >> 2=%d", che);// 打印 63 正确 //练习 // 1010 0101十进制是165 //练习1:前四位不变,后四位清零 //分析:清零操作使用与运算符;前四位不变1111,后四位清零0000,二进制是1111 0000---十进制是240 unsigned char chf = 240; unsigned char chg = ch1&chf; //ch1 1010 0101 十进制是165 //chf 1111 0000 十进制是240 //ch1&chf 1010 0000 十进制是160 printf(" 前四位不变,后四位清零%d", chg);// 打印 160 正确 //练习2:前四位不变,后四位置1 //分析:置1使用或运算符,前四位不变--0000,后四位置1--1111,二进制是 0000 1111---十进制是15 unsigned char chh = 15; unsigned char chi = ch1 | chh; //ch1 1010 0101 十进制是165 //chh 0000 1111 十进制是15 //ch1|chf 1010 1111 十进制是175 printf(" 前四位不变,后四位置1--%d", chi);// 打印 175 正确 //练习3:前四位不变,后四位取反 //分析:取反有2中方法,取反运算符和异或运算符,取反运算符只能全部取反,异或运算符可以部分取反 //前四位不变,说明只能使用异或运算符;前四位不变0000;后四位取反1111,二进制是 0000 1111---十进制是15 //注:异或相同为0,不同为1,两个0的值仍然是0,两个1的值是0,一个0和一个1结果是1 unsigned char chj = ch1^chh; //ch1 1010 0101 十进制是165 //chh 0000 1111 十进制是15 //ch1|chf 1010 1010 十进制是170 printf(" 前四位不变,后四位取反--%d", chj);// 打印 170 正确 system("pause"); }
在C语言的位运算中,左移也就是所说的逻辑移位,右端补0,而右移是算数移位,左端补齐的是最高位的符号位。因此负数左移,有可能变成正数
,但负数右移,肯定还是负数。
特别注意,这是运算的变量是有符号类型的情况,如果是无符号类型,就算最高位是1,那么左移填充的符号位依然是0。
位运算注意点 在进行位运算时,要求所有参与运算变量必须是 unsigned char类型,这是因为正数和负数在内存中都是以补码方式存储 如果使用char,这是有符号的类型,那么如果这个char小于0,那么在内存中的存储就会变化,当出现拷贝操作时,就会改变原数据 如果使用unsigned char,所有的数据都是正数(正数的原码,补码一致),拷贝时,系统就不会修改原数据了