关于C语言位运算的讨论

关于C语言位运算的讨论

基础:数据的二进制的表示方法

  • 原码
  • 反码
  • 补码
  • 计算机里采用的是补码,对于正数,没有差别,主要是理解负数

C下的位运算

  • 核心运算符号
  • 异或
  • 取反
  • 左移得到值
  • 右移得到值
/*
	>> <<

*/
#include<stdio.h>

int main(void)
{
	int a=1;
	int b=-1;
	unsigned int c = 1;

	int e = 7;		// 0111   
	int f = 9;		// 1001

	printf("0x%x,%d\n",e&f,e&f);
	printf("0x%x,%d\n",e|f,e|f);
	printf("0x%x,%d\n",~e,~e);

/*

	printf("initial:===============================\n");
	printf("0x%08X \t %d\n",a,a);
	printf("0x%X \t %d\n",b,b);
	printf("0x%08X \t %d\n",c,c);

	// 左移两位
	a = a<<2;
	b = b<<2;
	c = c<<2;
	printf("move left 2 bit:===============================\n");
	printf("0x%08X \t %d\n",a,a);
	printf("0x%X \t %d\n",b,b);
	printf("0x%08X \t %d\n",c,c);


	a=1;
	b=-1;
	c=1;
	// 右移两位
	a = a>>2;
	b = b>>2;
	c = c>>2;
	printf("move right 2 bit:===============================\n");
	printf("0x%08X \t %d\n",a,a);
	printf("0x%X \t %d\n",b,b);
	printf("0x%08X \t %d\n",c,c);

	return 0;
*/
}

代码做一下调整

/*
	位运算   二进制的位 bit
	内存  int 4Byte  32bit
	%o八进制
	%x十六进制
	>> <<

*/
#include<stdio.h>

int main(void)
{
	// 先用1,再用9
	int a = 1;
	int b = -1;
	unsigned int c = 1;

	int e = 7;		// 00000000 00000000 00000000 00000111     00000000000000000000000000001111 <<
	int f = 9;		// 00000000 00000000 00000000 00001001	   00000000000000000000000000000011	>>
					// 11111111 11111111 11111111 11110110
					// 10000000 00000000 00000000 00001010

	printf("0x%x,%u,%d\n",e&f,e&f,e&f);		// 位与
	printf("0x%x,%u,%d\n",e|f,e|f,e|f);		// 位或
	printf("0x%x,%u,%d\n",e^f,e^f,e^f);		// 位异或
	printf("0x%x,%u,%d\n",~f,~f,~f);		// 按位取反

	printf("\n最大的正整数:%u\n",-1);		// -1是有符号的,全f,当成无符号数,即为最大的正整数

	// 未移位
	printf("initial:===============================\n");
	printf("0x%08X \t %d\n",a,a);
	printf("0x%X \t %d\n",b,b);
	printf("0x%08X \t %d\n",c,c);

	// 左移两位
	a = a<<2;
	b = b<<2;
	c = c<<2;
	printf("move left 2 bit:===============================\n");
	printf("0x%08X \t %d\n",a,a);
	printf("0x%X \t %d\n",b,b);
	printf("0x%08X \t %d\n",c,c);


	a=1;
	b=-1;
	c=1;
	// 右移两位
	a = a>>2;
	b = b>>2;
	c = c>>2;
	printf("move right 2 bit:===============================\n");
	printf("0x%08X \t %d\n",a,a);
	printf("0x%X \t %d\n",b,b);
	printf("0x%08X \t %d\n",c,c);

	return 0;

}

交换两个数的值

//法1. 方法不太好,a+b时可能会导致正溢出
int main()
{
	int a = 3;
	int b = 5;
	printf("交换前:a=%d b=%d", a, b);
	a = a + b;//可能会导致溢出
	b = a - b;//a+b-b=a
	a = a - b;//a+b-a=b 
	printf("交换后:a=%d b=%d", a, b);
	
	return 0;
 
}

//法2.异或法
/* 
下述a\b为任意整数
异或:相同则为0,相异则为1
      最简单的理解:把不一样的保留,做了为1的标记;
      一样的,则标记为0,相当于丢掉
原理:两次异或,即还原了

a^a=0
0^b=b
1 只有两个内存空间可以使用,没有新的内存空间
2 第一套值:a,b
3 第二套值:ab异或,存于a空间,b保留
4 第三套值:ab异或,再异或b,即还原出了原来的a,存于b空间,第二套值中的ab异或值保存
5 第四套值:ab异或,再异或a,这个a即当前存于b空间里的a的值,得到原来的b的值,存于a空间,到此,完成交换


*/ 
int main()
{
	int a = 3;
	int b = 5;
	printf("交换前:a=%d b=%d\n", a, b);
	a = a ^ b;
	b = a ^ b;//a^b^b=a
	a = a ^ b;//a^b^a=b 新的b即原来看a
	printf("交换后:a=%d b=%d\n", a, b);
	
	return 0;
 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值