C语言_操作符实战_几个用操作符解决问题的整理(讲解)

1,不创建临时变量交换两个数

这里输入a的值,b的值,不能创建临时变量tmp实现交换

第一种:


#include<stdio.h>
int main()
{
	int a, b = 0;
	scanf("%d%d", &a, &b);
	a = a + b;
	b = a - b;//此时b=a+b-b=a
	a = a - b;//此时a=a+b-a=b实现了交换a ,b的目的
	printf("a=%d b=%d",a,b);
	return 0;
}

在这里插入图片描述
(注意这种算法存在问题,因为当a,b数字很大时a+b的值可能会超过int类整形的范围,a+b的值会发生丢失)

第二种:

#include<stdio.h>
int main()
{
	int a, b = 0;
	scanf("%d%d", &a, &b);
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("a=%d b=%d",a,b);
	return 0;
}

在这里插入图片描述
这里以a=-1,b=4来举例

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
实现交换

2,求二进制中数字1的个数

题出处

方法1:

数字%2获得二进制位,再通过数字除2找下一位,

直到最后数字/2后为0,假停下循环

#include<stdio.h>
int main()
{
	int count = 0;
	int n = 0;
	scanf("%d",&n);
	while (n)
	{
		if (n % 2 == 1)
			count++;
		n = n / 2;
	}
	printf("二进制位中1的个数为%d",count);
	return 0;
}

在这里插入图片描述

但这里有缺陷,负数的二进制位没有办法计算

在这里插入图片描述
负数%2余数是-1不会执行count++

方法2:

我们知道&操作符

在二进制中1&0=0,只有1&1=1

1在计算机中储存的是000000000…1

所以我们将输入的二进制数字&1

如果得到1说明二进制位最后一位是1,此后变量>>1

来检测下一位二进制数字是不是0,一共进行32次。

#include<stdio.h>
int main()
{
	int a = 0;
	scanf("%d",&a);
	int count = 0;
	for (int i = 0; i < 32; i++)
	{
		int j = 1;
		if ((a & j) == 1)
		{
			count++;
		}
		a = a >> 1;
	}
	printf("二进制中1的个数%d",count);
	return 0;
}

在这里插入图片描述

这时负数的二进制位1的个数也可以计算

方法三:

采用相邻的两个数据进行按位与运算

#include<stdio.h>
int main()
{
	int a = 0;
	scanf("%d",&a);
	int count = 0;
	while (a)
	{
		a = a & (a - 1);
		count++;
	}
	printf("二进制位为1的个数为%d",count);
	return 0;
}

在这里插入图片描述
在这里插入图片描述

当a=3时

a的二进制位为 0 1 1
a-1二进制的为 0 1 0
--------a&a-1为 0 1 0 (count=1)

此后a的二进制位为0 1 0
------a-1的二进制为0 0 1
--------------a&a-1为0 0 0 (count=2)
此时a=0为假跳出循环

在二进制位存在一个以上的1时a&(a-1)一定不可能是0,因为一定存在相同的二进制位。

当最后一位为1时a&a-1最后一位变成0,赋值给了a相当于移动了一位
当最后一位为0时a&a-1最后一位为0,赋值给了a相当于舍弃了一位

在二进制位只存在一个1时a&a-1一定是0,count加1后离开循环,最后统计的就是a中二进制位1的个数

3,求两个二进制位不同数字的个数

题出处

首先我们知到二进制位数字有两种情况0 和 1

我们首先通过异或操作将不同的数字变为1存到变量c中

在计算变量c中二进制1的个数,这里求二进制1的个数不在赘述

#include<stdio.h>
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d%d",&a,&b);
	int c = a ^ b;
	int count = 0;
	for (int i = 0; i < 32; i++)
	{
		int j = 1;
		if ((c & j) == 1)
		{
			count++;
		}
		c = c >> 1;

	}
	printf("%d",count);
	return 0;
}

在这里插入图片描述

4,表达式求值

表达式求值一部分是按照操作符的优先级和结合性的顺序进行的

优先级高的先运算,当表达式优先级相同时运算方向根据结合性来看,这里不多赘述。

同时有些时候表达式的操作数可能会转化成其他类型

整形转换(隐形类型转换)

eg:

#include<stdio.h>
int main()
{
	char a = 3;
	char b = 137;
	char c = a + b;
	printf("%d",c);
	return 0;
}

在这里插入图片描述
发现这里并不是我们想的140,

这是因为char类型大小是一个字节,而一个整形是4个字节

char—8个比特位,

int—32个比特位,

整型提升是按照符号位进行提升的符号位就是二进制位的首位

+号操作符操作的是int型,所以char类型先补到32位

a=0 0 0 0 0 0 1 1(补位,符号位为0)

a=0000…0 1 1(32位)

b= 1 1 1 1 1 1 1 1(补位)

b=0 0 0 0 0 0 1 1 1 1 1 1 1(32位)

a+b=0 0…1 0 0 0 0 0 1 0(32位)

c=a+b(c是字符类型,只能存8位,所以会发生截断)

c=1 0 0 0 0 0 1 0

printf("%d")所以c还要进行整形提升

c的符号位是1,所以补1到32位

c整型提升后

1 1 1 1 1 1…1 0 0 0 0 0 1 0(32位)(补码)
1 1 1 1 1 1…1 0 0 0 0 0 0 1(32位)(补码)
1 0 0 0 0 0…0 1 1 1 1 1 1 0(32位)(原码)

符号位为1说明是负数
翻译原码得-116

有些数字如果是无符号位数,整形提升补零
整型提升只发生在有二进制位且大小小于int的时候

在这里插入图片描述
发生了整型提升。

当从int转换成比int大的类型时不会出现这种情况,不会截断

计算机在计算表达式时方法不一定唯一

eg:

           a*b+c*d+e*f

可以计算ab,cd,e*b,再把三者加起来,

或者把ab+cd看成一个整体先计算,然后再算e*f,再加起来,

所以表达式的运算不一定时唯一的,要注意规避这种情况。

eg:int c=(++a)+(++a)+(++a);

#include<stdio.h>
int main()
{
	int a = 4;
	int c = (++a) + (++a) + (++a);
	printf("%d",c);

}

在这里插入图片描述
这里计算是先计算三次++a, a=7在求和得21

但不同编译器计算顺序不同,也可以先算两次++a(把前两个表达式看成整体),在计算后面的+(++a).

太复杂的计算式点到为止,不必深究

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NUC_Dodamce

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值