C语言-移位,位域,和运算符优先级

1. 位移操作 << >>

C提供了一系列的移位运算,以向左或者向右移动位模式。

1.1 左移,右边补0

简单的例子:

1 << 7 
//1左移7位  即:1->  1000 0000
左移:右边补0

项目的例子:

#define FUN_NUM ((1 << 7) - 1)  //FUN_NUM 为127
	1 左移7位 0000 0001 左移 =  1000 0000
	减1 = 0111 1111 127
	故 FUN_NUM = 127
	注意运算符优先级: - 高于 << >> 

1.2 右移,分为逻辑右移和算术右移

逻辑右移,左边补0
	(逻辑右移 不管是什么类型,空缺自动补0)
算术右移,左边补最高有效位的拷贝(应用于有符号位的运算)
	(算数右移 若是无符号数,则空缺补0,若是负数,空缺补1)

规定:

对于无符号数据,右移必须是逻辑的
对于有符号数据,几乎所有编译器对其进行算术右移,程序员也是这样使用;

例子1:

8 >>2   // 8右移2位 即: 1000 -> 0010
语法: 需要移位的数字 << />> 移位的次数

例子2:

int iTest = 8;
unsigned int uiTest = -8;
printf("iTest=%x\n",iTest>>1);
printf("uiTest=%x\n",uiTest>>1);

结果:
	iTest=4
	uiTest=7ffffffc
	
说明:8  1000 			右移1位 0100 4
	  -8 源码:0x10 00 00 08 
		 反码:0xff ff ff f7
		 补码:0xff ff ff f8(1111 1000)
		 右移1位 0xff ff ff fc(1111 1100)

有符号数和无符号数详解
https://blog.youkuaiyun.com/lqy971966/article/details/106033332

1.3 项目中常用:

背景: 如求很多 NAME_LEN_X 是不是在 NAME_LEN 集合中

typedef enum tagNAME_LEN
{
	NAME_LEN_1 = 1 ,
	NAME_LEN_2 ,
	NAME_LEN_3 ,
	NAME_LEN_4 ,
	NAME_LEN_5 ,
	NAME_LEN_6 ,
	NAME_LEN_7 ,
	NAME_LEN_MAX
}NAME_LEN;

for(int i=NAME_LEN_1; i<NAME_LEN_MAX; i++)
{
	……
	newName = (int)1<<i; 
	/*
	1左移i位 即变成
	NAME_LEN_1 0000 0010 2
	NAME_LEN_2 0000 0100 4 
	……
	NAME_LEN_7 1000 0000 128
	*/
	
	……
}

define NAME_BIT(name) (((int)0x1)<<name)

tag = NAME_BIT(NAME_LEN_1) |
	  NAME_BIT(NAME_LEN_2) |
	  ……
	  NAME_BIT(NAME_LEN_7) ;
//tag = 1111 1111

比较:
define TEST(newName,tag) (((((int)0x1)<<newName) & tag))
即: 求 newName 是不是在 tag 中

2. 位域操作 :

  1. 定义: 有些信息存储时,并不需要占用一个完整的字节,而只需要占几个或一个二进制

  2. 例子:存放开关变量,只有0或1 两种状态

  3. 操作:

     struct bs
     {
     	int iSwitch:2; //开关变量 iSwitch 只要两个字节存储
     	int b:2;
     	int c:6;
     }
    

3. 运算符优先级

  1. 指针优先,单目运算符高于双目运算符
  2. 算数> 移位 >位运算 如:
    1 << 3+2 && 7 等价于 (1 << (3+2)) && 7
  3. 逻辑运算符最后计算
  4. 位异或:同为0 异为1, 0^0 = 0
  5. & :位与操作 1&2 = 0
  6. && :逻辑与操作 1&&2=1

参考:

  1. https://blog.youkuaiyun.com/qq_41916395/article/details/81562881
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值