前言:
距离学习C语言已经过去了2年了,这期间接触了C++、java,做过一些课设。有些是用C++做的,有些则是用java做的,但是自我感觉,编程语言只是一门工具,在其中运用到的还是我们的计算机基础。每次遇到瓶颈的时候,我总是会想,我的基础是否牢靠,这里特指我的C语言基础。是的,期间翻过那么一两次书,自以为已经复习了一遍,但是未曾深入了解,或者未曾归纳总结的,即使之后再次遇到,也只是一笑,然后回头查看资料。
哈哈哈,废话不多说,我就是想把C语言当中的位运算(当然啦,c++、java都是一样的)和文件操作熟悉一下。每个例子讲解的格式都是:(六个运算&|^~<<>>)
含义 |
实例 |
用途 |
一、&按位运算符
含义:参与运算的两个数据,按二进制位进行与运算。如果两个相应的二进制都为1,结果为1;否则为0。(如果是负数就需要以补码形式表示为二进制数再参与运算)
实例:
1 &1 | 1 |
1&0 | 0 |
0&1 | 0 |
0&0 | 0 |
用途:
1.清零:
如果要对一个存储单元清零,就是让它的二进制位为0,所以我们可以找到一个二进制数(满足:原来数中为1的数,新数为0)然后二者进行按位运算即可。
2.取一个数中某些指定位:
eg我们要对一个字符数据取出其低8位的值是,我们就可以让这个数与一个上8位都为0,下8位为1的二进制数&运算。
11010101 | 01011011 | |
& | 00000000 | 11111111 |
00000000 | 01011011 |
3.一个编程运用:如果我们需要完成大小写英文字母的转化(当然你可以直接用+‘32’),那么我们可以看看大小写英文字母ASCALL中,A~Z(65~90),a~z(97~122)。那么看看其二进制的区别,这里以A和a作为例子:
A | 100 0001 |
a | 110 0001 |
你就会发现它们之间只是第三位(左到右)的不同,大写为0,小写为1,所以只需要知道找到符合的二进制数进行&运算和I运算。
二、|按位或运算
含义:参与运算的两个数据,按二进制位进行或运算。只要存在1,结果就为1。
实例:
1 | 1 | 1 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
用途:同时,可以参与数字转换的计算。
三、^按位异或
含义(XOR):参与运算的两个数据,按二进制位进行按位异或运算。同号结果为0,异号结果为1。
实例:
1 ^ 1 | 0 |
1 ^ 0 | 1 |
0 ^ 1 | 1 |
0 ^ 0 | 0 |
用途:
1.使特定位翻转,这个理解和上面一样,我们可以将二进制位0,1转换。
2.交换两个值,不用临时变量(这个在java基础专栏里面也有提到,因为这样形式比较复杂,常用于加密算法)
a = a^b;//异或值赋给a
b = b^a;//b^a之后的值为a,赋值给b
a = a^b;//a^b之后的值为b,赋值给a
为什么可以进行这样的操作,那是因为异或运算符有可逆性(运算之后再次运算就可以回到原值)。
四、~取反运算
含义:~是一个单目运算符,用来对一个二进制进行取反,即0变1,1变0。
实例:
~ | 0010101 |
1101010 |
用途:在二进制计算的时候可以考虑运用到。
五、<<左移运算
含义:用来将一个数的各二进制位全部左移若干位(若高位左移溢出,舍去)。
实例:a=<<2 将a的二进制左移两位,右边补0。
用途:左移一位相当于该数乘以2,所以我们可以用在程序计算中,直接循环<<,不需要*=2。
六、>>右移运算
含义:用来将一个数的各二进制位全部右移若干位。
实例:a>>2表示将a的各个二进制位右移2位,移到右端的低位被舍弃,对无符号数,高位补0。
a==1111 1110(为-2) | |
无符号数:a>>1 | 0111 1111(逻辑右移时) |
有符号数:a>>1 | 1111 1111(算术右移时) |
用途:右移一位相当于除以2,右移n位相当于除以2^n
注意:
- 对无符号数,右移时左边高位移入0;
- 对于有符号的值,如果原来的符号位为0,则左边也是移入0。
- 如果符号位原来为1,则左边移入0还是1,要取决于所用的计算机系统。有的1,有的0。
- 移入0的称为“逻辑右移”,移入1的称为“算术右移”。
总结:
将这些运算符结合起来,灵活的使用,就会有神奇的效果(如有误,请指出,谢谢)。