C语言进阶⑩(数据的存储)数据类型_介绍+存储_大小端(知识点+笔试题)(下)

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
云解析DNS,个人版 1个月
简介: C语言进阶⑩(数据的存储)数据类型_介绍+存储_大小端(知识点+笔试题)

C语言进阶⑩(数据的存储)数据类型_介绍+存储_大小端(知识点+笔试题)(中):https://developer.aliyun.com/article/1513036

4.笔试题

4.1程序的执行结果为( )

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

A.300 300

B.44 44

C.300 44

D.44 300

解析:

 
#include<stdio.h>
int main()
{
    //二进制可以用计算机转化
    unsigned char a = 200;
    //200的二进制00000000000000000000000011001000
    //存的:11001000
    unsigned char b = 100;
    //100的二进制00000000000000000000000001100100
    //存的:01100100
    unsigned char c = 0;
    //相加不够int 要整形提升
    //00000000000000000000000011001000   +
    //00000000000000000000000001100100   =
    //00000000000000000000000100101100
    c = a + b;
    //存到c中c为(后8位)00101100为44
    //a+b不存到c中就是00000000000000000000000100101100为300
    printf("%d %d", a + b, c); //300 44
    return 0;
}

4.2在32位大端模式处理器上变量b等于( )

 
#include<stdio.h>
int main()
{
    unsigned int a = 0x1234; 
    unsigned char b = *(unsigned char*)&a;
    return 0;
}

A.0x00

B.0x12

C.0x34

D.0x1234

解析:

 
#include<stdio.h>
int main()
{
    unsigned int a = 0x1234; //int a是4个字节,存的是0x 00 00 12 34
                             //假设左边是低地址右边是高地址
                             //大端里存的就是          00 00 12 34
                             //小端里存的就是          34 12 00 00
    unsigned char b = *(unsigned char*)&a;
              //题目说大端,unsigned char*取出的是第一个字节的地址,为00 选A
    return 0;
}

4.3在屏幕上打印杨辉三角。

1

1 1

1 2 1

1 3 3 1

1 4 6 4 1

……

输入n,表示n行

解析:


由于此题要打印整个杨辉三角的数据而非取出某一项,所以不可避免的一定是要填出每一项,没有偷懒的余地,那就老老实实的根据规律填空即可。按照题设的场景,能发现数字规律为:d[i][j] = d[i - 1][j] + d[i - 1][j - 1]。所以只要按照这个方法填表即可。

法一:

 
#include<stdio.h>
void yang_hui_triangle(int n)
{
    int data[30][30] = { 1 }; //第一行直接填好,播下种子
    int i = 0, j = 0;
 
    for (i = 1; i < n; i++) //从第二行开始填
    {
        data[i][0] = 1; //每行的第一列都没有区别,直接给1,保证不会越界。
        for (j = 1; j <= i; j++) //从第二列开始填
        {
            data[i][j] = data[i - 1][j] + data[i - 1][j - 1]; //递推方程
        }
    }
 
    for (i = 0; i < n; i++) //填完打印
    {
        for (j = 0; j <= i; j++)
        {
            printf("%d ", data[i][j]);
        }
         printf("\n");
    }
}
int main()
{
    int n = 0;
    scanf("%d", &n);
    yang_hui_triangle(n);
    return 0;
}

法二:

由于在填第n行的杨辉三角时,只跟第n-1行的杨辉三角产生联系,不会跟之前的有联系,

所以没必要保存每一行的杨辉三角,填一行打一行就行了,这样能让空间复杂度从n^2降低到n。

(空间复杂度是数据结构的内容,现在可以先理解为数组开的空间)

但是在填数据的时候不能对之前的数据覆盖,所以需要从后向前填。

而填杨辉三角顺序对结果是没有影响的,所以可以实现。

 
#include<stdio.h>
void yang_hui_triangle(int n)
{
    int data[30] = { 1 };
    int i = 0, j = 0;
    printf("1\n"); //第一行就直接打印了
    for (i = 1; i < n; i++) //从第二行开始
    {
        for (j = i; j > 0; j--) //从后向前填,避免上一行的数据在使用前就被覆盖
        {
            data[j] += data[j - 1]; //公式同上,由于变成了一维,公式也变简单了。
        }
 
        for (j = 0; j <= i; j++) //这一行填完就直接打印了。
        {
            printf("%d ", data[j]);
        }
         printf("\n");
    }
}
int main()
{
    int n = 0;
    scanf("%d", &n);
    yang_hui_triangle(n);
    return 0;
}

※这种方法虽然降低了空间复杂度,但只能保存最后一行的数据,

不利于反复查询,两个填法各有各的适用场景。就本题而言,改进后的胜出。

4.4代码题猜凶手

日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯的一个。

以下为4个嫌疑犯的供词:

A说:不是我。

B说:是C。

C说:是D。

D说:C在胡说

已知3个人说了真话,1个人说的是假话。

现在请根据这些信息,写一个程序来确定到底谁是凶手。

直接在代码注释里写解析:

 
//分析:
//k表示凶手(killer),0表示假话,1表示真话
//if k==A,a==0,b==0,c==0,d==1;
//if k==B,a==1,b==0,c==0,d==1;
//if k==C,a==1,b==1,c==0,d==1;
//if k==D,a==1,b==0,c==1,d==0;
//所以c是凶手,怎么用代码求出呢?
#include<stdio.h>
int main()
{
    char k = 0;
    for (k = 'A';k <= 'D';k++)
    {
        //把四句话用表达式表示出来,真为1,假为0
        if ((k != 'A') + (k == 'C') + (k == 'D') + (k != 'D') == 3)
        {
            printf("%c是凶手\n", k);
        }
    }
    return 0;
}

4.5代码题猜名次

5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果:

A选手说:B第二,我第三;

B选手说:我第二,E第四;

C选手说:我第一,D第二;

D选手说:C最后,我第三;

E选手说:我第四,A第一;

比赛结束后,每位选手都说对了一半,请编程确定比赛的名次。

直接在代码注释里写解析:

 
//考虑到一共五个人,直接模拟推理有些太难,计算机最擅长的遍历此时就会派上用场,
//将每个人从第1到第5来一遍,则一共会产生5 ^ 5种可能性,这个只需要一个5层循环即可搞定。
//但是这样会导致一些不期望出现的结果出现,因为我并没有查重,所以会出现两个人抢名次的情况,
//也就是两个人或者更多的人名次相同的情况,例如两个第二,三个第三这样的,
//所以即使满足了条件,也要查看一下五个人的名次是否重复,
//这个交给一个函数来执行,只要五个人名次并列,那就返回0,否则返回1即可。
//有了这个思路,就能完成以下代码。
//往后面学习还会有更好的方法
#include <stdio.h>
int checkData(int* p)
{
    int tmp[7] = { 0 }; //标记表,实际是哈希表的思路。一开始每个元素都是0。
 
    for (int i = 0; i < 5; i++)
    {
        if (tmp[p[i]]) //如果这个位置的标记已经是1,则代表重复,直接返回0。
        {
            return 0;
        }
        tmp[p[i]] = 1; //如果不是,则给这个位置标记为1。
    }
    return 1; //全部标记完毕也没有出现重复的情况,代表OK。
}
 
int main()
{
    int p[5] = { 0 }; //0 1 2 3 4分别代表A B C D E
    for (p[0] = 1; p[0] <= 5; p[0]++)
    {
        for (p[1] = 1; p[1] <= 5; p[1]++)
        {
            for (p[2] = 1; p[2] <= 5; p[2]++)
            {
                for (p[3] = 1; p[3] <= 5; p[3]++)
                {
                    for (p[4] = 1; p[4] <= 5; p[4]++) //五层循环遍历
                    {
                        //这里是五个人的描述,由于比较表达式只有0和1两个结果,
                        //如果要两个条件有且只有一个为真,
                        //则可以用比较表达式的值总和为1的方式直接判定。
                        //别忘了还要判定不能并列。
                        if (
                            (p[1] == 2) + (p[0] == 3) == 1 && //B第二,我第三
                            (p[1] == 2) + (p[4] == 4) == 1 && //我第二,E第四
                            (p[2] == 1) + (p[3] == 2) == 1 && //我第一,D第二
                            (p[2] == 5) + (p[3] == 3) == 1 && //C最后,我第三
                            (p[4] == 4) + (p[0] == 1) == 1 && //我第四,A第一
                            checkData(p) //不能并列
                            )
                        {
                            for (int i = 0; i < 5; i++)
                            {
                                printf("%d ", p[i]);
                            }
                            printf("\n");
                        }
                    }
                }
            }
        }
    }
    return 0;
}

本章完(留一张关于智力题的图)

本篇完。

目录
相关文章
|
3天前
|
存储 安全 C语言
C语言中的数据类型
C语言中的数据类型
|
6天前
|
存储 C语言
C语言数据类型、变量和运算符以及printf相关问题
C语言数据类型、变量和运算符以及printf相关问题
|
5天前
|
C语言
C语言------数据类型与输入输出
这篇文章是C语言的数据类型与输入输出实训教程,通过示例代码演示了整型、实型、字符型数据的定义、使用和输出,以及如何使用printf()和scanf()函数进行格式化输出和输入。
C语言------数据类型与输入输出
|
11天前
|
C语言
C语言数据类型和变量
C语言数据类型和变量
19 5
|
11天前
|
存储 小程序 C语言
C语言数据的存储(内含百度笔试题)
C语言数据的存储(内含百度笔试题)
21 4
|
1月前
|
C语言
C语言1 数据类型
C语言1 数据类型
7 0
|
C语言
我们要掌握好多少C语言知识点才能做好C语言项目?
我们要掌握好多少C语言知识点才能做好C语言项目?
1234 0
|
5天前
|
存储 C语言
【C语言函数】static和extern关键字修饰
【C语言函数】static和extern关键字修饰
|
6天前
|
C语言 C++
|
14天前
|
机器学习/深度学习 C语言
九/十:《初学C语言》— 扫雷游戏实现和函数递归基础
【8月更文挑战第5天】本篇文章用C语言采用多文件编写实现了一个基础的扫雷游戏(附源码),并讲解了关于函数递归的基础概念及其相对应的习题练习(附源码)
29 1
九/十:《初学C语言》— 扫雷游戏实现和函数递归基础