【C语言】详解C语言操作符中的重点难题(代码+图解)

文章目录

一、【例题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,就得到不同位的个数啦

如图:

【C语言】详解C语言操作符中的重点难题(代码+图解)

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;
}

运行结果:

【C语言】详解C语言操作符中的重点难题(代码+图解)

三、【例题3】

1、题目描述

打印整数二进制的奇数位和偶数位

题目内容:

获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列

2、解题思路

假设求100二进制的奇数位和偶数位

如图:

【C语言】详解C语言操作符中的重点难题(代码+图解)

移动规则:

【C语言】详解C语言操作符中的重点难题(代码+图解)

然后再把得到的结果和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;
}

运行结果:

【C语言】详解C语言操作符中的重点难题(代码+图解)

四、【例题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;
}

运行结果:

【C语言】详解C语言操作符中的重点难题(代码+图解)

貌似情况不太对呀?

  • 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;
}

运行结果:

【C语言】详解C语言操作符中的重点难题(代码+图解)

总结:

  • 读取字符时,才会考虑\n,所以要用到清理缓冲区
上一篇:如何将word中的图片复制到windows live writer 保持大小不变--清晰度不变


下一篇:你真的理解C语言的灵魂 “ 指针 ” 吗?(初阶篇)