c语言符号深度理解和再认识( 三 )


短路问题依据就是表达式从左依次执行 。
六、位运算符号 (一)、基本了解
按位与(&),按位或(|)、按位异或(^)、按位取反(~) 。都是二进制进行运算的 。
int main(){printf("%d\n", 2 | 3);printf("%d\n", 2 & 3);printf("%d\n", 2 ^ 3);printf("%d\n", ~0);return 0;}//输出结果是3 2 1 -1.
说明:
2|3就是2和3的按位或,2(10)|3(11) = 3(11),二进制中两个对应的值都为0,则为0,否则为1 。
2&3就是2和3的按位与,2(10)|3(11) = 2(10),二进制中两个对应的值都为1,则为1,否则为0 。
2^3就是2和3的按位异或,2(10) ^3(11) = 2(01),二进制中两个对应的值不相同时,则为1,否则为0 。
~0就是按位取反,0(0 0 0000 0000),~0(1 1 1111 1111(补码)=1 0 0000 0001(原码) =-1 )
(二)、逻辑运算符和按位运算符区别
逻辑运算符对应的逻辑表达式,需要的是真假 。而按位运算符是逐个比特位进行计算
(三)、按位异或(^)
任何数和0的按位异或都是这个数本身 。
两个相同的数的异或是0 。
按位异或支持交换律和结合律 。
(四)、实例:交换两个数 第一种方法;创建临时变量
#include int main(){int temp = 0;int a = 10;int b = 20;temp = a;a = b;b = temp;printf("%d,%d\n", a, b);return 0;}
第二种方法:加法运算
#include int main(){int a = 10;int b = 20;a = a + b;b = a - b;a = a - b;printf("%d,%d", a, b);return 0;}
注意:加饭运算中二进制有进位现象,如果两个足够大的数相加,那么返回时就会出现溢出问题 。
3.第三种方法:按位异或方法
#include int main(){int a = 10;int b = 20;a = a ^ b;b = a ^ b;a = a ^ b;printf("%d,%d\n", a, b);return 0;}
注意:异或运算只是对比特位进行比较判断,并不会出现二进制进位溢出问题 。
(五)、建议
位操作需要用宏定义好后再使用 。
实例 1.实现一个宏,对任意一个比特位设置为1
#include #define SetBit(x,n)(x |= (1<<(n-1)))//1<=0){if (x & 1<
也可以对多个比特位设置,这里有宏定义,可以直接多次设置宏 。
2.实现一个宏,对任意一个比特位设置为0
#include #define ClrBit(x,n) (x &= ~(1<<(n-1)))extern void ShowBit(int x);//ShowBit函数输出比特位void ShowBit(int x){int num = sizeof(x) * 8-1;//控制循环次数while (num>=0){if (x & 1<
(六)、整型提升问题
先run代码:
#include int main(){char c = 0;printf("%d\n", sizeof(c));printf("%d\n", sizeof(~c));printf("%d\n", sizeof(c<<1));printf("%d\n", sizeof(c>>1));return 0;}//输出结果是1 4 4 4
这里发生了整型提升,这里整形提升就不细讲了,后期我们再深入讲解整型提升 。
这里我们只需要知道计算机计算是在CPU中的寄存器进行的,一般情况下,在32位下,寄存器的位数也是32位,char类型只有八个比特位,只能填补低8位,那么高24位呢?就需要进行整型提升 。
(七)、左移和右移 1.基本了解
左移:最高位丢弃,最低为补零
右移:1. 无符号数:最低位丢弃,最高位补零(逻辑右移) 2.有符号数:最低为丢弃,最高位补符号位(算术右移)
//左移#include void ShowBit(int x){int num = sizeof(x) * 8 - 1;//控制循环次数while (num >= 0){if (x & 1