按位运算与其它操作符(整形提升)

  1. 不能使用if for > <等语句,比较两个数的大小。大于返回1 小于返回-1 等于返回0
条件操作符
exp1 ? exp2 : exp3
exp1是否为真?为真,exp2;否则exp3
#include<stdio.h>
int Max(int a, int b)
{
	//格式:return a > b ? a : b;
	return (a - b) >> 31 ? -1 : (a - b ? 1 : 0);
	//相减为负数,右移补首符号位'-',则右移32位全是1
	//相减为非负数,右移补0
}
int main()
{
	printf("%d\n", Max(10, 11));  //-1
	printf("%d\n", Max(10, 10));  //0
	printf("%d\n", Max(21, 20));  //1
	return 0;
}
  1. 逻辑操作符(短路操作符):
    1)逻辑与’&&’
#include<stdio.h>
int main()
{	
	int i = 0, a = 0, b = 2, c = 3, d = 4;
	i = a++ && ++b && d++;  //第一个为假,后续不执行
	printf("a =%d,b =%d,c =%d,d =%d\n", a, b, c, d);  //1,2,3,4
	return 0;
}

2)逻辑或’||’

#include<stdio.h>
void show1()
{   
	int i = 0, a = 0, b = 2, c = 3, d = 4;
	i = a++ || ++b || c-- || d++;  //a++先运算为0则假,'或'++b先运算为2则真,直接将1赋值给i,后续不执行
	printf("show1:i=%d\n", i);  //1
	printf("验证:a=%d,b=%d,c=%d,d=%d\n", a, b, c, d);  //验证结果为:1,3,3,4 
	printf("\n");
}
void show2()
{
	int a = 1;
	int b = 0;
	int c = 2;
	if (a++ || b++ || c++)  //'或',a++为真,不执行b++,c++
	printf("show2:a=%d,b=%d,c=%d\n", a, b, c);  //2,0,2
	printf("验证:a=%d,b=%d,c=%d\n", a, b, c);  //2,0,2,验证不执行
}
int main()
{
	show1();
	show2();
	return 0;
}
  1. ‘%’,浮点型判断是否为0,位移运算符
#include<stdio.h>
void show1()  //%计算,浮点型转换
{
	int a = 2.716;
	printf("%d\n", a);  //2.7
	printf("%d\n", 10 % 3);  //1     
	printf("%d\n", -10 % 3);  //-1     
	printf("%d\n", 10 % -3);  //1    
	printf("%d\n", -10 % -3);  //-1      
	printf("%f\n", 5 / 2);  //0.000000
	printf("%f\n", (float)5 / 2);  //2.500000
	printf("%f\n", 5 / (float)2);  //2.500000
	printf("%f\n", (float)(5 / 2));  //先整型后转换,2.000000
}
void show2()  //浮点型判断是否为0
{
	float num = 0.0f;
	int i = 0;
	for (i = 0; i < 10; i++)
		num = num + 0.1f;
	for (i = 0; i < 10; i++)
		num = num - 0.1f;
	if (num == 0)
		printf("num == 0\n");  //不执行
	if (num == 0.000000) 
		printf("num == 0\n");  //不执行
	if (num >= -0.000001 && num <= 0.000001)  //判断浮点型(num == 0.0f),不可与0直接比较
		printf("num == 0\n");
	else
		printf("num != 0\n");
}
void show3()  //位移运算符
{
	char ch1 = 1;
	char ch2 = -1;
	printf("%d\n", ch1 << -29);  //相当于右移29位,即左移3位,8
	printf("%d\n", ch2 << -29);  //相当于右移29位,即左移3位,-8
}
int main()
{
	show1();  //%计算,浮点型转换
	show2();  //浮点型判断是否为0
	show3();  //位移运算符
	return 0;
}
  1. 按位运算:
    (1)按位与:两个数据以二进制形式进行“与”运算;按位与运算符(&)
    运算规则:0&0=0; 0&1=0; 1&0=0; 1&1=1; 即:两个相应位同时为“1”,则为1,否则为0;
    (2)按位或:两个数据以二进制形式进行“或”运算;按位或运算符(|)
    运算规则:0|0=0; 0|1=1; 1|0=1; 1|1=1; 即:两个相应位只要一个为“1”,则为1,否则为0;
    (3)按位异或:两个数据以二进制形式进行“异或”运算。按位异或运算符(^)
    运算规则:0^ 0=0; 0^ 1=1; 1^ 0=1; 1^1=0;即:两个相应位只要值不同,则为1,否则为0。
    (4)按位取反:一个数据以二进制形式进行“取反”运算。取反运算符(~)
    运算规则:~1 = 0; ~0 = 1; 即:对一个二进制数按位取反,将0变1,1变0。
    (“~”优先级比算术运算符、关系运算符、逻辑运算符和其他运算符都高)
#include<stdio.h>
int main()
{
	int a = 99; 
	 //99的二进制形式‭0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0110 0011‬
	int b = 5; 
	 //5的二进制形式0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0101
	int c = -65;  
	//负数以补码形式存储在计算机,以补码形式参与按位与运算。-65就是65的二进制形式取反(反码)加一(补码)
	//-65的二进制补码形式‭‭1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1011 1111‬
	int d = 0;
	int e = 1;
	printf("%d\n", a & b);  //即0110 0011 & 0000 0101 = 0000 0001, 结果为1
	printf("%d\n", a & c);  //即0110 0011‬ & 1011 1111‬‬ = 0010 0011, 结果为35
	printf("%d\n", a & d);  //清零数据
	printf("%d\n", a | b);  //即0110 0011 | 0000 0101 = 0110 0111, 结果为103
	printf("%d\n", a | c);  //即0110 0011‬ | 1011 1111‬‬ = 1111 1111, 结果为-1
	printf("%d\n", a | d);  //无变化
	printf("%d\n", a ^ b);  //即0110 0011 ^ 0000 0101 = 0110 0110, 结果为102
	printf("%d\n", a ^ c);  //即0110 0011‬ ^ 1011 1111‬‬ = 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1101 1100, 结果为-36
	printf("%d\n", a ^ d);  //无变化
	printf("~a=%d\n", ~a);  //即~0110 0011 = 1001 1100,结果为-100
	printf("~b=%d\n", ~b);  //即~0000 0101 = 1111 1010,结果为-6
	printf("~c=%d\n", ~c);  //即~1011 1111 = 0100 0000,结果为64
	printf("~d=%d\n", ~d);  //即~0000 0000 = 1111 1111,结果为-1
	printf("~e=%d\n", ~e);  //即~0000 0001 = 1111 1110,结果为-2
	printf("a&~1=%d\n", a&~1);  //使二进制最后一位变为0,即0110 0011 &~ 0000 0001 = 0110 0010,结果为98
	return 0;
}

按位与 特殊用途:取一个数中指定位:
方法:找对应X要取的位,该数的对应位为1,其余位为零,此数与X相与即可得到X中的指定位。
例:取X=1010 1110的低4位,用 X & 0000 1111 = 0000 1110 即可得到;还可用来取X的2、4、6位。

按位或 特殊用途:对一个数据的某些位置1:
方法:找对应X要置1的位,该数的对应位为1,其余位为零。此数与X相或即可使X中的某些位置1。
例:将X=1010 0000的低4位置1 ,用 X | 0000 1111 = 1010 1111即可得到。

“异或运算”的特殊作用:使特定位翻转:
方法:找对应X要翻转的各个位,该数的对应位为1,其余位为零,此数与X对应位异或即可使特定位翻转。
例:X=1010 1110,使X低4位翻转,用X ^ 0000 1111 = 1010 0001即可得到。

附:如果两个不同长度的数据进行位运算时,系统会将二者按右端对齐,然后进行位运算。
例: 在C语言中long型占4个字节,int型占2个字节,如果一个long型数据与一个int型数据进行“与”运算,右端对齐后,左边不足的位依下面三种情况补足,
(1)如果整型数据为正数,左边补16个0。
(2)如果整型数据为负数,左边补16个1。
(3)如果整形数据为无符号数,左边也补16个0。

  1. 整形提升
    C的整型算术运算总是至少以缺省整型类型的精度来进行的,因此在每次运算时要保证足够整形精度。
    为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。
int main()
{
	char a = 0xb6;    short b = 0xb600;    int c = 0xb6000000;
	if (a == 0xb6)
		printf("a");  //不输出
	if (b == 0xb600)
		printf("b");  //不输出
	if (c == 0xb6000000)
		printf("c");  //输出c,因为a与b发生了整形提升
	return 0;
}
  1. 算数类型转换
int main()
{	
	int a = 1;
	char b = 'a', c = 'b';
	double d;
	printf("%d\n", sizeof(!a));  //编译器版本不同答案不同
	printf("%d\n", sizeof(c - b));  //不是1,是4
	d = c - b;
	printf("%d\n", sizeof(d));  //8
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值