每周几个C语言小题目(第二周)

(位运算) 【1】现有一个嵌入式设备终端传输过来的数据包是一个32位无符号的整型数,这个数据包里面各位含义如下:

  • 00-07位:表示温度数据

  • 08-15位:表示湿度数据

  • 16-19位:表示4扇门状态(门的编号0-3)

  • 20-23位:表示四盏灯的状态(灯编号0-3)

  • 24-31位:预留备用

下面是最近一段时间接受的数据包:

0x12344520, 0xff004B1C,0x00553C1E

请编写一个程序接收这3个数据包,并解析出对应的数据【温度,湿度,门0-3,灯0-3】(门和灯的状态0-关,1-开)。

解析:对于此题,要想获得某一位的数据,首先想到的应该是移位操作,比如,对于二进制数据0000 0001 0000 0000,要想获得它第8位的1数据,并将其输出,我只需要将其右移8位即可,即0x10 >> 8,再以整型数据输出,即可得到1;因此,本题的代码如下,仅供参考,如有更好的办法欢迎留言讨论。

#include <stdio.h>

int main()
{
    unsigned int data, a[10];        //定义一个数组用于存放数据移位后的0和1

    printf("请输入一组数据: ");        
    scanf("%x",&data);
    for(int i = 0; i <= 7; i++)        //定义差值变量,处理数据第16-23位的移位次数
    {
        a[i] = data << (15 - i) >> 31;
    }
    printf("温度: %d, 湿度: %d\n", data << 24 >> 24, data << 16 >> 24);
    printf("door0: %s, door1: %s, door2: %s, door3: %s\n",
    a[0] ? "开" : "关", a[1] ? "开" : "关", a[2] ? "开" : "关", a[3] ? "开" : "关");
    printf("led0 : %s, led1 : %s, led2 : %s, led3 : %s\n", 
    a[4] ? "开" : "关", a[5] ? "开" : "关", a[6] ? "开" : "关", a[7] ? "开" : "关");

    return 0;
}

 (循环控制) 【2】编写一个程序,输出26个小写字母。

解析,此题考虑从循环的角度除法,作者将采用几种不同的循环方式,供大家参考;

第一种:while循环

#include <stdio.h>

int main()
{
    char a = 'a';
    while(a <= 'z')
    {
        printf("%c",a);
        a++;
    }

    return 0;
}

 第二种:do while 循环

#include <stdio.h>

int main()
{
    char a = 'a';
    do
    {
        printf("%c", a);
        a++;
    } while (a <= 'z');

    return 0;
    
}

第三种:for 循环

#include <stdio.h>

int main()
{
    for(char a = 'a'; a <= 'z'; a++)
    {
        printf("%c", a);
    }
    return 0;
}

最后输出结果如下:

(循环控制) 【3】编写一个程序,在用户输入某个大写字母后,产生一个金字塔图案。 例如输入字母E,则产生如下图案:  

          A
        ABA
      ABCBA
    ABCDCBA

  ABCDEDCBA

解题思路:观察每一行的元素不难发现,我们一共需要输出三部分

第一部分是空格‘ ’,第二部分是正向字母输出,第三部分是逆向字母部分输出

且每一行都是以A开头,以A结束,且这些元素与行数都有很大关系;

如例式所示:一共有五行数据,

第一行前面有4个空格,输出1个正向字母 ,0个逆向字母

第二行前面有3个空格,输出2个正向字母,1个逆向字母

第三行前面有2个空格,输出3个正向字母,2个逆向字母

第四行前面有1个空格,输出4个正向字母,3个逆向字母

第五行前面有0个空格,输出5个正向字母,4个逆向字母

因此我们可以发现规律,即每一行输出的正向字母数量与行数相同,

前面的空格数量=总行数-正向字母数量,逆向字母数量=正向字母数量-1

而总行数=输入的字母的ascii码-A+1,如此,我们就有了很清晰的代码思路

我们可以先打印总需要的行数

如下所示

for(int n = 'A'; n = word; n++)

 此代码表示从A到输入的字母word共要打印word-A+1行

接下来对每行的数据单独处理

对第word-n+1行,需要打印word-n个空格,n-A+1个正向字母,n-A个逆向字母,因此,代码如下:

#include <stdio.h>

int main()
{
    char word;
    printf("请输入一个大写字母:");
    scanf("%c", &word);
    for(int n = 'A'; n <= word ; n++)
    {
        for(int i = word - n; i >= 1 ; i--)
        {
            printf(" ");
        }
        for(int i = 'A'; i <= n; i++)
        {
            printf("%c", i); 
        }
        for(int i = n - 1; i >= 'A'; i--)
        {
            printf("%c", i);
        }
        printf("\n");
    }

    return 0;
}

最后输入大写字母Z,打印金字塔如下:

(分支控制、循环控制) 【4】编写一个程序,接受一个整数输入,然后显示所有小于或等于该数的素数。

提示: 素数指只能被1和自身整除的大于等于2的整数,例如2、3、5、7、11……

解题思路:对于一个自然数N,要想知道所有比它小或等于它的素数,就需要对所有比它小的数进行判断,若是素数则输出,不是则判断下一个数,因此此题需要用到for循环

判断一个数是否为素数,只需要它满足条件:只能被它自己和1整除;

在C语言中,判断一个数a能否被某个数b整除,只需要判断a%b == 0 即可,由于素数有且只有两个能整除它的数。我们定义一个变量num,当a能整除b的时候,num++,因此,对于一个自然数来说,如果从1到它自己,执行完所有数之后,num 只等于2,即表示这个数是素数,在每次循环之后,我们需要给num清零,以方便下一个数继续判断;

因此,代码如下:

#include <stdio.h>

int main()
{
    unsigned long long int a, i, j, num = 0;

    printf("请输入一个正整数: ");
    scanf("%llu", &a);

    for(i = 1; i <= a; i++)
    {
        for(j = 1; j <= i; j++)
        {
            if(i%j == 0)
            {
                num++;
            }
        }
        if(num == 2)
        {
            printf("%llu,", i);
        }
        num = 0;
    }

    return 0;
}

 (循环控制、多路分支) 【5】编写一个程序,接收用户的输入信息,当用户输入完成后(#代表输入完成),自动统计用户输入的空格数、大小写字母数和其他字符数。

解析:我们知道,用户在输入字符量时,会先进入到缓冲区中,而getchar()函数的用法是在缓冲区 取出一个字符,如果需要判断用户输入的字符是什么类型,我们使用getchar()函数即可,而getchar()函数与scanf一样拥有输入的功能,因此不需要再写一个scanf输入字符。

用户输入#后,则表示输入完成,此时getchar无需再从缓冲区拿走字符,循环结束,因此此题我们需要使用while循环,在while循环中对getchar()函数获取的字符进行判断,然后使相应的变量自增计数,因此代码如下:

#include <stdio.h>

int main()
{
    int num1 = 0, num2 = 0, num3 = 0;
    int c;

    printf("请输入一段字符: ");

    while((c = getchar()) != '#')
    {
        if(c == ' ')
        {
            num1++;
        }
        else if((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
        {
            num2++;
        }
        else
        {
            num3++;
        }
    }
    
    printf("空格数为: %d\n大小写字符数为: %d\n其他字符数: %d\n", num1, num2, num3);

    return 0;
}

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值