C语言—位操作符(一)
前言
上一篇我们学习了位操作符,下来我们来做几道题,进行巩固
一、练习一
不能创建临时变量(第三个变量),实现两个整数的交换。
首先这道题是比较恶心的,第一次做的话,可能无从下手,但是如果大家学习完上一篇,就知道要使用位操作符。
1.方法1:
#include<stdio.h>
int main()
{
int a = 10;
int b = 20;
printf("交换前:a=%d.b=%d\n", a, b);
a = a -b;
b = a+b;
a = b - a;
printf("交换后:a=%d.b=%d\n", a, b);
}
缺陷:如果a和b足够大的话,可能,在交换的过程中,会存在溢出的情况
2.方法2:
#include<stdio.h>
int main()
{
int a = 10;
int b = 20;
printf("交换前:a=%d,b=%d\n", a, b);
a = a ^ b;
b = a ^ b;//b=a^b^b;b=a
a = a ^ b;//a=a^a^b;a=b
printf("交换后:a=%d,b=%d\n", a, b);
return 0;
}
缺陷:代码的可读性不高
二、练习二
编写代码实现:求⼀个整数存储在内存中的二进制中1的个数。
1.方法1:
#include<stdio.h>
int main()
{
int num = 0;
int cnt = 0;
scanf("%d", &num);
while (num > 0)
{
if (num % 2 == 1)
cnt++;
num /= 2;
}
printf("%d\n", cnt);
return 0;
}
缺点:没有考虑负数的情况
2.方法2:
#include<stdio.h>
int main()
{
int num = -1;
int cnt = 0;
scanf("%d", &num);
for (int i = 0; i < 32; i++)
{
if (((num >> i) & 1) == 1)
cnt++;
}
printf("%d", cnt);
return 0;
}
缺陷:循环了32次,看看每一位上是否是1
3.方法3:
//方法3:
//num=7 num=6
//00000111 -- 7
//00000110 -- 6
//00000110 -- 6 num=7&6=6
//00000101 -- 5
//00000100 ---4 num=6&5=4
//00000011 ---3
//00000000 -- 0 num=4&3=0
//结束
#include<stdio.h>
int main()
{
int num = 1;
int cnt = 0;
scanf("%d", &num);
while (num)
{
cnt++;
num = (num - 1) & num;
}
printf("%d", cnt);
return 0;
}
缺点:不容易想出来
三、练习三
编写代码将13⼆进制序列的第5位修改为1,然后再改回0
13的2进制序列: 00000000000000000000000000001101
将第5位置为1后:00000000000000000000000000011101
将第5位再置为0:00000000000000000000000000001101
#include<stdio.h>
//13的2进制序列: 00000000000000000000000000001101
//将第5位置为1后:00000000000000000000000000011101
//将第5位再置为0:00000000000000000000000000001101
int main()
{
int a = 13;
a = a | (1 << 4);
printf("a = %d\n", a);
a = a & ~(1 << 4);
printf("a = %d\n", a);
return 0;
}
四.单身狗问题
1.有一个数组只有一个数字出现一次,其余数字都是成对出现的,编写一个函数找出只出现一次的数字。
例如:
有数组的元素是:1 2 3 4 5 1 2 3 4
5只出现了1次,要找出数字5。
2.题目:一个数组中只有两个数字出现了一次,其他所有数字都出现了两次。编写一个函数找出这两个只出现一次的数字。
例如:
有数组的元素是:1,2,3,4,5,1,2,3,4,6
这俩道题会在写一篇csdn博客中讲解,大家先把前3道题,理解清楚后,在看下一篇。
完