文章目录
一、【例题1】
1、题目描述
统计二进制中1的个数
题目内容:
写一个函数返回参数二进制中 1 的个数。
比如: 15 :0000 1111
4 个 1
题目链接:二进制中1的个数
2、解题思路
这道题其实我在你真的懂C语言中的位操作符吗?这篇文章中讲到过解题方法;
这里直接上手
3、代码详解
int NumberOf1(int x) { int c = 0; while (x) { x = x & (x - 1); c++; } return c; } int main() { int n = 0; scanf("%d", &n); int ret = NumberOf1(n); printf("%d\n", ret); return 0; }
二、【例题2】
1、题目描述
求两个数二进制中不同位的个数
题目链接:两个整数二进制位不同个数
2、解题思路
- 这里我们只需要把两个数进行
异或^
(异或规则:相同为0,相异为1)
- 然后我们把异或的结果赋值给一个整型变量;
- 再求出这个整型变量中有多少个1,就得到不同位的个数啦
如图:
3、代码详解
int diff(int x, int y) { int z = 0; int c = 0;//计数器 z = x ^ y;//存储异或的结果 while (z) { z = z & (z - 1);//计算z中有多少个1 c++; } return c; } int main() { int m, n; scanf("%d %d", &m, &n); int ret = diff(m, n); printf("%d\n", ret); return 0; }
运行结果:
三、【例题3】
1、题目描述
打印整数二进制的奇数位和偶数位
题目内容:
获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列
2、解题思路
假设求100
二进制的奇数位和偶数位
如图:
移动规则:
然后再把得到的结果和1
相与&
(想与:两个都是1才是1,否则0)
3、代码详解
void print(int m) { int i = 0;//写一个循环 //打印奇数位 printf("奇数位: "); for (i = 30; i >= 0; i -= 2)//30表示第31位数,要向右移动30位 { printf("%d", (m >> i) & 1); } printf("\n"); //打印偶数位 printf("偶数位: "); for (i = 31; i >= 1; i -= 2) { printf("%d", (m >> i) & i); } } int main() { int n = 0; scanf("%d", &n); print(n); return 0; }
运行结果:
四、【例题4】
1、题目描述
判断整数奇偶性
判断一个整数的奇偶性,从键盘任意输入一个整数,编程判断它的奇偶性。
题目链接:判断整数奇偶性
2、解题思路
- 这个问题对于我们的困扰在于:我们如何才能知道已经没有任何输入了,这就需要用到输入函数的返回值。
- 我们知道输入函数为
scanf
,当这个函数返回EOF
时,就代表没有任何输入了。所以我们可以循环判断函数的返回值是否等于EOF
。
- 其中
EOF
是一个宏,可以认为它的值就是整数-1
。
它的定义如下:
#define EOF -1
3、代码详解
#include <stdio.h> #define EOF -1 int main() { int n = 0; //while (~scanf("%d", &n)),也可以使用 ~ 符号 while (scanf("%d", &n) != EOF) { if (n % 2 == 0) { printf("Even\n"); } else { printf("Odd\n"); } } return 0; }
- 这里,我们先考虑
scanf("%d", &n)
这个函数的返回值,当你从控制台输入两个数时,它会根据输入的格式正确与否,返回输入成功的数的个数,所以正常情况下是返回2。 - 当没有任何输入时,它会返回
EOF
,所以导致循环语句内的条件变为假,从而退出循环,退出循环以后就顺理成章的结束进程了;
总结:
EOF
读取结束或者遇到错误,返回EOF
;
输入多个数字时,就需要用到EOF
;
五、【例题5】
1、题目描述
判断是元音还是辅音
题目链接:判断是元音还是辅音
2、解题思路
- 这里也是需要我们多行输入,唯一不同的是要判断10个元音3字母(大写和小写)。
- 所以我们可以定义一个数组,把输入的字母和数组进行比较。
3、代码详解
int main() { char v[] = { 'a','A', 'e','E', 'i','I', 'o','O', 'u','U' }; char ch = 0; while (~scanf("%c", &ch)) { int i = 0;//判断10次 for (i = 0; i < 10; i++) { if (ch == v[i]) { printf("Vowel\n"); break;//判断成功就跳出循环 } } if (i == 10) //如果i=10,表示把ch判断了10次,都不是元音字母,那么只能是辅音字母了 { printf("Consonant\n"); } } return 0; }
运行结果:
貌似情况不太对呀?
-
scanf("%c", &ch)
当我们输入:a
时,scanf
其实读取到了a和\n
;所以才会出现执行结果错误的情况
解决办法2中:
-
scanf(" %c", &ch)
,在%c
前加一个空格 - 用
getchar()
去清理缓冲区。
修改后的代码:
int main() { char v[] = { 'a','A', 'e','E', 'i','I', 'o','O', 'u','U' }; char ch = 0; while (~scanf(" %c", &ch)) { int i = 0;//判断10次 for (i = 0; i < 10; i++) { if (ch == v[i]) { printf("Vowel\n"); break;//判断成功就跳出循环 } } if (i == 10) //如果i=10,表示把ch判断了10次,都不是元音字母,那么只能是辅音字母了 { printf("Consonant\n"); } //getchar();//清理缓冲区 } return 0; }
运行结果:
总结:
- 读取字符时,才会考虑
\n
,所以要用到清理缓冲区