按位操作_C语言快速入门与计算机二级备考
按位运算
- 按位运输的对象只能说整型或者字符型数据
按位运算符
-
&按位的与比较两个二进制数据的每一位,若对应的两位都是1则得1,其它情况则为0
应用:
- 让某一位变为0:如&0xFE->111111110,其它数与之进行与运算,最后一位一定变成0,而前7位保留原值
- 取一个数中的一段:&0xFF->11111111,其它数与之进行与运算保留原值,而一个int中其它字节的内容变为0
-
|按位的或比较两个二进制数据的每一位,若对应的两位有一个是1则得1,否则得0
应用:
- 使得一位或几位为1:如|0x01->00000001,或运算后最后一位变为1,其它位保留原值
- 把两个数拼起来:如0x00FF|0xFF00,或运算后得0xFFFF
-
~按位取反每一个比特取反(与求((20241111220037-9ary9v3 "补码"))不同)
-
^按位的异或C中没有表示幂次的符号,^不代表数学中的上标
比较两个二进制数据的每一位,两个位相等,那么结果为0,不相等,结果为1
应用:
- 两个相等的数,异或运算后得0
- 加密:对一个变量异或两次(即每个位翻转两次),等于什么都没做
-
<<左移i<<j将i中所有的位向左移动j位,右侧空处填0所有小于int的类型,移位以int的方式做,结果是int
x<<1等价于x乘2;x<<n等价于x乘2n;最多能移的位数取决于int的大小 -
>>右移i>>ji中所有的位向右移j位,同样以int的方式来做,结果为int对于
unsigned类型,左边空位填0,但对于有符号的signed类型,左侧填入原来的最高位以保证符号不变,例如1000在右移后为0100,由负数变成正数,故实际右移后为1100x>>1等价于x÷2;x>>n等价于x÷2n -
移位的位数不要用复数,这是没有定义的行为
逻辑运算与按位运算区别
-
对于逻辑运算,它只看到0和1两个值
-
可以认为逻辑运算相当于把所有非0值都变成1,然后做按位运算;例如:
按位运算:
5&4得到4(0101&0100->0100)逻辑运算:
5&&4相当于1&1,得到1
位运算的应用
-
输出一个数的二进制:八进制/十六进制都可直接输出,但二进制不行
int num; scanf("%d",&num); unsigned mask =1u<<31;//让mask等于无符号1左移31位,得到一个最高位为1,其余为0的数,即1000…… for (;mask;mask>>=1)//当mask存在时进行循环,循环每一轮mask要右移一位 //即从1000……,进行一次循环后变成0100…… //当所有位都走完后,数字变成00……00,循环结束 { printf("%d",num&mask?1:0);//每次循环将mask与数字进行与运算 //num上与maskd的1对应的那一位是1时,得非0的数,否则得到0 }
位段
- 当需要一次操作不止一位时,可以利用位段,把一个int的若干位组合成一个结构
-
struct U0 { unsigned int leading : 3 ; unsigned int FLAG1 : 1 ; unsigned int FLAG2 : 2 ; int trailing : 27 ; }uu; //这时,sizeof(uu)=4,即一个int,而若结构中所有东西加起来超过32位,则需要多个int uu.leading=2; uu.FLAG1=0; uu.FLAG2=1; uu.trailing=0; void prtbin(unsigned int num)//设此为刚刚输出二进制的函数的函数原型 prtbin(*(int*)&uu);//对这个结构体以整数的方式访问 //最终输出的二进制数为00……010010(共32位) //从左往右 010为leading(3个位),0为FLAG1,01为FLAG2,其余的0为trailing //在定义了位段后,可以直接用位段成员的名称来访问,比上述的按位运算方便
本文来自博客园,作者:无术师,转载请注明原文链接:https://www.cnblogs.com/artlessist/p/18547860
本文使用知识共享4.0协议许可 CC BY-NC-SA 4.0
特别说明版权归属的文章以及不归属于本人的转载内容(如引用的文章与图片)除外
浙公网安备 33010602011771号