上海海事大学自动化专业C语言课程代码参考(第十四周)

不知道大家最近有没有被ChatGPT刷屏啊,作为一个语言模型,可以调教成你的形状…啊不对,调教成你想让它成为的样子,非常好玩。我有尝试着让它帮忙写咱的C语言作业,效果还是很不错的,可以看来看看。

目录

上机实验

6-11          统计字符出现次数

6-12          字符串逆序

6-13          字符串字母大小写转换

6-14          矩阵各行元素之和

6-15          阵运算

6-16          找鞍点

6-17          期末分数排序

6-18          选择法排序

6-19           找出不是两个数组共有的元素

6-20          打印杨辉三角

结语


上机实验

6-11          统计字符出现次数

本题要求编写程序,统计并输出某给定字符在给定字符串中出现的次数。

输入格式:

输入第一行给出一个以回车结束的字符串(少于80个字符);第二行输入一个字符。

输出格式:

在一行中输出给定字符在给定字符串中出现的次数。

输入样例:

programming is More fun!

m

输出样例:

2

很简单的题目,遍历字符串即可。这种题目丢给ChatGPT做会怎么样呢?我们试试:

 结果非常的有趣,它完美地输出了这一个程序,并且使用了 string.h 内的函数 gets() !既然出现了gets()那我们就说说吧。这个函数输入一个char指针,即字符串头指针。函数会在输入缓冲区读一条字符串,存入这个指针的位置。详细的说明可以看这里

直接回复没有缩进,看着难受,但是没关系,现在很多功能强大的IDE都能帮我们完成代码格式化。我们测试无误之后就能将这一段代码当作我们的作业了(

#include <stdio.h>
#include <string.h>

int main()
{
    char a[100], b;
    int i, sum = 0;

    gets(a);
    scanf("%c", &b);
    for (i = 0; i < strlen(a); i++)
    {
        if (a[i] == b)
            sum++;
    }
    printf("%d\n", sum);

    return 0;
}

好!很有精神!

6-12          字符串逆序

本题要求编写程序,输入一个字符串,对该字符串进行逆序,输出逆序后的字符串。

输入格式:

输入在一行中给出一个不超过80个字符长度的、以回车结束的非空字符串。

输出格式:

在一行中输出逆序后的字符串。

输入样例:

Hello World!

输出样例:

!dlroW olleH

也是很简单,只需要找到字符串的结尾就行了。同样的,我们再拿ChatGPT来试试:

#include <stdio.h>
#include <string.h>

int main()
{
    char a[100];
    int i;

    gets(a);
    for (i = strlen(a) - 1; i >= 0; i--)
        printf("%c", a[i]);

    return 0;
}

可以看到,在这一段程序中,出现了另一个函数 strlen() 。这个函数是读取字符串长度。为防止混淆,在这里说一下strlen和sizeof的区别。

sizeof返回的是整个堆的长度,也就是已分配内存的长度。在这个例子内,sizeof(a)返回的值为100;而strlen计算的是从开始到字符串结束,也就是到‘\0’的长度。所以它们两个的返回值并不一样。

了解了strlen之后,我们很容易就明白,程序是倒序的单个字符打印。

6-13          字符串字母大小写转换

本题要求编写程序,对一个以“#”结束的字符串,将其小写字母全部转换成大写字母,把大写字母全部转换成小写字母,其他字符不变输出。

输入格式:

输入为一个以“#”结束的字符串(不超过50个字符)。

输出格式:

在一行中输出大小写转换后的结果字符串。

输入样例:

Hello World! 123#

输出样例:

hELLO wORLD! 123

这一题也是非常简单。在看到题目之后直接就能注意到,大写字母和小写字母的ASCII码的范围并不一样,并且遵循某种转化关系。只需要判断字符的大小,并计算即可。这部分的代码如下:

#include <stdio.h>
#include <string.h>

int main()
{
    char a[100];
    int i;

    gets(a);
    for (i = 0; i < strlen(a) && a[i] != '#'; i++)
    {
        if (a[i] >= 'a' && a[i] <= 'z')
            printf("%c", a[i] - 32);
        else if (a[i] >= 'A' && a[i] <= 'Z')
            printf("%c", a[i] + 32);
        else
            printf("%c", a[i]);
    }

    return 0;
}

但是,有没有更简单的方法呢?当然有!ChatGPT给出了这样的方法:

#include <stdio.h>
#include <string.h>
#include <ctype.h>

int main()
{
    char a[100];
    int i;

    gets(a);
    for (i = 0; i < strlen(a) && a[i] != '#'; i++)
    {
        if (isupper(a[i]))
            printf("%c", tolower(a[i]));
        else if (islower(a[i]))
            printf("%c", toupper(a[i]));
        else
            printf("%c", a[i]);
    }

    return 0;
}

可以注意到,这里多用了一个头文件<ctype.h>。尖括号表示这是C语言标准头文件,也就是正常的编译器都会自带的头文件。

这里有两对、四个新的函数"isupper" "tolower" "islower" "toupper"。

这四个函数的意思就和字面上一样,判断是否为大写字母、将大写字母转换成小写字母、判断是否为小写字母、将小写字母转换为大写字母。可以看到,用了这个函数能稍微简化一点点开始我们所写的代码。

6-14          矩阵各行元素之和

本题要求编写程序,求一个给定的m×n矩阵各行元素之和。

输入格式:

输入第一行给出两个正整数m和n(1≤m,n≤6)。随后m行,每行给出n个整数,其间以空格分隔。

输出格式:

每行输出对应矩阵行元素之和。

输入样例:

3 2

6 3

1 -8

3 12

输出样例:

9

-7

15

这题也是并不复杂。首先将头两位数字保存,作为后续循环的循环次数;然后开始循环,每次循环只读一位,读完缓冲区为止。

代码如下:

#include <stdio.h>

int main()
{
    int m, n, i, j, a[10][10], sum;

    scanf("%d%d", &m, &n);
    for (i = 0; i < m; i++)
    {
        sum = 0;
        for (j = 0; j < n; j++)
        {
            scanf("%d", &a[i][j]);
            sum = sum + a[i][j];
        }
        printf("%d\n", sum);
    }

    return 0;
}

6-15          阵运算

本题要求编写程序,给定一个n×n的方阵,计算该矩阵除副对角线、最后一列和最后一行以外的所有元素之和。副对角线为从矩阵的右上角至左下角的连线。

输入格式:

输入第一行给出正整数n(1<n≤10);随后n行,每行给出n个整数,其间以空格分隔。

输出格式:

在一行中给出该矩阵除副对角线、最后一列和最后一行以外的所有元素之和。

输入样例:

4

2 3 4 1

5 6 1 1

7 1 8 1

1 1 1 1

输出样例:

35

这一题也并不复杂,只需要遍历二维数组,再判断当前的数是否符合条件即可。代码如下:

#include <stdio.h>

int main()
{
    int a[11][11], n, i, j, sum = 0;

    scanf("%d", &n);
    for (i = 1; i <= n; i++)//录入部分
        for (j = 1; j <= n; j++)
            scanf("%d", &a[i][j]);
    for (i = 1; i <= n; i++)//计算部分
        for (j = 1; j <= n; j++)
        {
            if (i != n && j != n && j != n - i + 1)
                sum += a[i][j];
        }
    printf("%d", sum);

    return 0;
}

6-16          找鞍点

本题要求编写程序,求一个给定的n阶方阵的鞍点。一个矩阵元素的“鞍点”是指该位置上的元素值在该行上最大、在该列上最小。

输入格式:

输入第一行给出一个正整数n(1≤n≤6)。随后n行,每行给出n个整数,其间以空格分隔。

输出格式:

输出在一行中按照“行下标列下标”(下标从0开始)的格式输出鞍点的位置。如果鞍点不存在,则输出“NONE”。题目保证给出的矩阵至多存在一个鞍点。

输入样例1:

4

1 7 4 1

4 8 3 6

1 6 1 2

0 7 8 9

输出样例1:

2 1

输入样例2:

2

1 7

4 1

输出样例2:

NONE

这题的重点在于,如何固定二维数组的某一位而遍历另一位。一种实现方法如下:

#include <stdio.h>

int main()
{
    int a[10][10], n, i, j, max, k, flag = 0;

    scanf("%d", &n);
    for (i = 0; i < n; i++)//数据录入
        for (j = 0; j < n; j++)
            scanf("%d", &a[i][j]);

    for (i = 0; i < n; i++)
    {
        max = a[i][0];
        k = 0;
        for (j = 1; j < n; j++)
            if (a[i][j] > max)
            {
                max = a[i][j];
                k = j;
            }
        for (j = 0; j < n; j++)
            if (a[j][k] < max)
                break;
        if (j == n)
        {
            printf("%d %d", i, k);
            flag = 1;
            break;
        }
    }
    if (flag == 0)
        printf("NONE");

    return 0;
}

6-17          期末分数排序

本题要求编写程序,考试结束了,全班同学的分数都出来了。老师需要对分数做一次排序,看看从高到低,分数的排列是怎样的。

输入格式:

第一行是一个n,表示班级同学的人数,1<=n<=5000。第二行开始有n个分数,0<=分数<=100,分数都是整数,没有零点五分。

输出格式:

输出排序后的分数,按照从大到小排列,相同的分数排在一起,每两个分数之间间隔一个空格。

输入样例:

10

0 60 73 60 82 90 100 18 55 84

输出样例:

100 90 84 82 73 60 60 55 18 0

这题我们可以用冒泡排序。冒泡排序老师上课有讲过,咱便不再赘述了。直接看代码吧:

#include <stdio.h>

#define SWAP(a, b)    \
    {                 \
        int temp = a; \
        a = b;        \
        b = temp;     \
    }

int main()
{
    int a[5000], n, i, j;

    scanf("%d", &n);
    for (i = 1; i <= n; i++)
        scanf("%d", &a[i]);
//****************************************************冒泡排序本体
    for (i = 1; i <= n; i++)
        for (j = 1; j <= n - i; j++)
            if (a[j] < a[j + 1])
                SWAP(a[j], a[j + 1]);
//****************************************************
    for (i = 1; i <= n; i++)
        printf("%d%c", a[i], i == n ? '\n' : ' ');

    return 0;
}

可以看到这里有几行我们不曾见过的写法,我们来看看。

首先是第三行的define定义函数。这种写法的好处是,它可以直接完成一种类似函数的效果,但是却能调用外面一级函数内的局部变量。或者说,在C语言中,使用#define定义的宏是不占用内存空间的。在使用#define定义宏时,编译器会把宏展开为该宏定义的内容,但不会为宏开辟内存空间。例如:

#define SWAP(a,b) {int temp=a;a=b;b=temp;}

这个宏定义的作用是实现两个变量的交换,但在程序运行时,并不会为宏开辟内存空间。

那么如何完成多行的宏定义呢?很简单,在行尾加 '\' 即可。于是,就有了我们代码的3~8行。

这种实现过程不用宏定义则需要借助指针。例如:

void swap(int *a, int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}

上面的swap函数也实现了两个变量的交换,在函数被调用时,编译器会为该函数开辟内存空间,在该函数运行时,系统会把函数所需的参数和变量放到这段内存中,运行完后再释放掉。

6-18          选择法排序

本题要求编写程序,将给定的n个整数从大到小排序后输出。

输入格式:

输入第一行给出一个不超过100的正整数n。第二行给出n个整数,其间以空格分隔。

输出格式:

在一行中输出从大到小有序的数列,相邻数字间有一个空格,行末不得有多余空格。

输入样例:

4

5 1 7 6

输出样例:

7 6 5 1

选择排序也是讲过的,我们用同样的办法swap就可以了:

#include <stdio.h>

#define SWAP(a, b)    \
    {                 \
        int temp = a; \
        a = b;        \
        b = temp;     \
    }

int main()
{
    int a[100], n, i, j, k;

    scanf("%d", &n);
    for (i = 0; i < n; i++)
        scanf("%d", &a[i]);
    for (i = 0; i < n; i++)
    {
        k = i;
        for (j = i; j < n; j++)
            if (a[j] > a[k])
                k = j;//找出最大的
        SWAP(a[i], a[k]);
    }
    for (i = 0; i < n; i++)
        printf("%d%c", a[i], i == n ? '\n' : ' ');

    return 0;
}

6-19           找出不是两个数组共有的元素

本题要求编写程序,给定两个整型数组,找出不是两者共有的元素。

输入格式:

输入分别在两行中给出两个整型数组,每行先给出正整数N(≤20),随后是N个整数,其间以空格分隔。

输出格式:

在一行中按照数字给出的顺序输出不是两数组共有的元素,数字间以空格分隔,但行末不得有多余的空格。题目保证至少存在一个这样的数字。同一数字不重复输出。

输入样例:

10 3 -5 2 8 0 3 5 -15 9 100

11 6 4 8 2 6 -5 9 0 100 8 1

输出样例:

3 5 -15 6 4 1

这一题很简单,嵌套一次循环即可。示例的代码如下:

#include <stdio.h>

int main()
{
    int a[25], b[25], n, m, i, j, flag;

    scanf("%d", &n);
    for (i = 0; i < n; i++)
        scanf("%d", &a[i]);
    scanf("%d", &m);
    for (i = 0; i < m; i++)
        scanf("%d", &b[i]);
    for (i = 0; i < n; i++)
    {
        flag = 1;
        for (j = 0; j < m; j++)
            if (a[i] == b[j])
            {
                flag = 0;
                break;
            }
        if (flag)
            printf("%d ", a[i]);
    }

    return 0;
}

6-20          打印杨辉三角

本题要求编写程序,按照规定格式打印前n行杨辉三角。

输入格式:

输入在一行中给出n(1≤n≤10)。

输出格式:

以正三角形的格式输出前n行杨辉三角。每个数字占固定4位。

输入样例:

6

输出样例:

          1

        1   1

      1   2   1

    1   3   3   1

  1   4   6   4   1

1   5  10  10   5   1

我们是不是写过这道题……?好像是写过的,不过不太想找了。我们现在用二维数组来写。代码如下:

#include <stdio.h>

int main()
{
    int n, a[10][10];

    scanf("%d", &n);
    a[0][0] = 1;
    for (int i = 1; i < n; i++)
    {
        a[i][0] = 1;
        for (int j = 1; j < i; j++)
        {
            a[i][j] = a[i - 1][j] + a[i - 1][j - 1];
        }
        a[i][i] = 1;
    }
    for (int i = 0; i < n; i++)
    {
        for (int k = 0; k < n - i - 1; k++)
        {
            printf("  ");
        }
        for (int j = 0; j <= i; j++)
        {
            printf("%4d", a[i][j]);
        }
        printf("\n");
    }

    return 0;
}

结语

不知道你有没有发现,这次的代码风格和以往的有很大不同。这是为什么呢?

因为基本全部代码均由ChatGPT生成,我只做了一点点修改,欸嘿。

不知道你怎么看待这种情况,那么,下周见

(不知道这种算不算原创,如有侵权请联系删除

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值