C位运算

1.shift+被红色区域选择的字符可以键入字符上面的符号,例如shift+6 就是“^”符号

2.二进制数系统中,位简记为b,也称为比特,每个二进制数字0或1就是一个位(bit)。位是数据存储的最小单位,其中8 bit 就称为一个字节(Byte)

C语言位运算符号有以下几个:

& 按位
| 按位 或
^ 按位 异或
~ 按位 取反
<< 按位 左移

>> 按位 右移

位运算就是以bit位计算

比如十进制8,转换二进制:0000 1000

比如十进制4,转换二进制:0000 0100

& 按位 与运算 两者位相同是1结果为1,否者为0

8:0000 1000

4:0000  0100

8&4=?


结果:8&4=0

|  按位  或运算 两者位相同为0结果为0,否者为1


结果:8|4=12

^ 按位  异或运算 不知道这样描述这个异或....,感觉看运算过程比较好理解

十    二进制

8 :0000 1000

4 :0000 0100

12:0000 1100

这个结果和 |或运算相同,咱们在多举例

8  :0000 1000

12 :0000 1100

4   :0000 0100

规律就是位相同为0,否则就是1

~ 按位取反,这个简单就是位是1就是0,0就是1

unsigned int a=0;

printf("%u",~a);        //打印C无符号最大的整数

十进制           二进制

0                 :00000000 00000000 00000000 00000000

4294967295 :1111111 1111111 1111111 1111111


<< 左移

8:0000 1000

8<<1 = 16    // 000 1000 0

8<<2 =32    // 00 1000 00

规律就是在低位加N个0就是结果,高位直接抛弃

>> 右

8:0000 1000

8>>1 = 4    // 0 0000 100

8>>2 = 2    // 00 0000 10

移有点特殊,在处理有符号数字的时候,符号位1,最高位是补0或是补1 取决于编译系统的规定。

测试环境:4字节int,VS2010

-1610612736:10100000 00000000 00000000 00000000

 -50331648   : 11111      10100000  00000000 00000000 000

-1610612736>>5= -50331648   


测试

#include "stdio.h"
#include "stdlib.h"
/*
&按位	与
|按位	或
^按位	异或
~按位	取反
<<按位	左移
>>按位	右移

源1	0000 1000	8
源2	0000 0100	4
&	0000 0000	0
|	0000 1100	4+8=12
^	0000 1100	12

    0000 1000
~	1111 0111	1+2+4+16+32+64+128=247

	 0000 1000	8
8<<2
结果:001000 00	32

	 0000 1000	8
8>>2
结果:000000 10	2


//测试结果代码
char n=8,n1=4;
unsigned char n2=8;
printf("%d %d %d %d %d\n",n&n1,n|n1,n^n1,n<<2,n>>2);
n2=~n2;
printf("%u",n2);
*/
void show_level(const char * user,int m,const int *level_list,int leng){
	int i,j,k=0;
	//int base=2;																	//2进制
	printf("%s(权限列表)",user);

	//十转任意进制算法
	j = m;
	while(j){
		j=j>>1;																		// j>>1 等价于 j/2
		k++;
	}
	for (i=k-1;i>=0;i--){
		j = 1<<i;																	// 1<<i		0000 0001<< X位  等价于 2的N次方
		//printf("%d %d %d\n",j,m/j,(m/j)%base );
		printf("%d",m/j & 1);														// m/j&1 得到最高位	
	}
	printf(":");

	for(i=0;i<leng;i++){															//遍历所有权限位
		if (m	&	level_list[i]){													//判断权限位
			printf("\tVIP%d",i+1);
		}
	}
	printf("\n");
}

int add_level(int m,const int *level_list,int leng){
	int i,j,k;
	printf("输入添加的权限(1-%d):",leng);
	/*
	 <<	位运算符	
	2<<2
	00000010
	00001000*/
	//j = 2<<(leng-2);
	do{
		do{																		//获取一组数字
			/*
				fflush是一个计算机函数,功能是冲洗流中的信息,该函数通常用于处理磁盘文件。fflush()会强迫将缓冲区内的数据写回参数stream 指定的文件中。
				外文名		 fflush 
				头文件		 stdio.h 
				原    型	 int fflush(FILE *stream) 
				功 能		 清除读写缓冲区
				fflush		 的返回值类型是int类型,那么这个int类型具体的返回是什么呢?如果成功刷新,fflush返回0。指定的流没有缓冲区或者只读打开时也返回0值。返回EOF指出一个错误。

				scanf函数返回成功读入的数据项数,读入数据时遇到了“文件结束”则返回EOF。
			*/
			fflush(stdin);														//清除读写缓冲区
		}while(scanf("%d",&i)!=1);
	}while(!(i>=1 && i<=8));													//判断输入的数字是否超过 level_list 最大的值
	m =m | level_list[i-1];														//加入权限
	return m;
}

int del_level(int m,int *level_list,int leng){
	int i,j,k;
	printf("输入删除的权限(1-%d):",leng);
	do{
		do{																		//获取一组数字
			fflush(stdin);														//清除读写缓冲区
		}while(scanf("%d",&i)!=1);
	}while(!(i>=1 && i<=8));													//判断输入的数字是否超过 level_list 最大的值
	m =m  & (~level_list[i-1]);													//删除权限
	return m;
}

int main(){
	int level_list[]={1,2,4,8,16,32,64,128};
	char user[20]="admin";														//默认用户名
	unsigned int m=0;															//权限位
	int select =-1;																//选择项

	do{
		system("cls");
		printf("1.查看权限\t2.加入权限\t3.删除权限\t4.-1退出\n");
		fflush(stdin);
		scanf("%d",&select);
		switch(select){
			case 1:
				show_level(user,m,level_list,sizeof(level_list)/sizeof(level_list[0]));			//显示权限
				system("pause>nul");
				break;
			case 2:
				show_level(user,m,level_list,sizeof(level_list)/sizeof(level_list[0]));			//显示权限
				m = add_level(m,level_list,sizeof(level_list)/sizeof(level_list[0]));			//添加权限
				show_level(user,m,level_list,sizeof(level_list)/sizeof(level_list[0]));			//显示权限
				system("pause>nul");
				break;
			case 3:
				show_level(user,m,level_list,sizeof(level_list)/sizeof(level_list[0]));			//显示权限
				m = del_level(m,level_list,sizeof(level_list)/sizeof(level_list[0]));			//删除权限
				show_level(user,m,level_list,sizeof(level_list)/sizeof(level_list[0]));			//显示权限
				system("pause>nul");
				break;
		}

	}while(select!=-1);

	return 0;
}


  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值