sse 哈工大 C 语言编程练习 39

2026年3月11日

收获:

1.字符串指针数组在赋值之前要申请对应大小的空间,使用完之后记得进行释放 (free)。


1. 矩阵转置(Q6403)

题目描述:

用二维数组作为函数参数,实现矩阵转置。按如下函数原型编程计算并输出 m×n 阶矩阵的转置矩阵。其中,m 和 n 的值由用户从键盘输入。已知 m 和 n 的值都不超过 10。

c 复制代码
void Transpose(int a[][N], int at[][M], int m, int n);
void InputMatrix(int a[][N], int m, int n);
void PrintMatrix(int at[][M], int n, int m);

输入提示信息: "Input m, n:" "Input %d*%d matrix:\n"
输入格式: "%d,%d"
输出提示信息和格式: "The transposed matrix is:\n"
输出格式(输完矩阵的一行要换行): "%d\t"

程序运行示例:

复制代码
Input m, n:3,5↙
Input 3*5 matrix:
2 6 7 4 3↙
5 5 7 9 4↙
3 3 6 3 3↙
The transposed matrix is:
2       5       3
6       5       3
7       7       6
4       9       3
3       4       3
c 复制代码
#include <stdio.h>
#define N 10
#define M 10

// 函数声明
void Transpose(int a[][N], int at[][M], int m, int n);
void InputMatrix(int a[][N], int m, int n);
void PrintMatrix(int at[][M], int n, int m);

int main()
{
    int a[M][N], at[N][M], m, n;
    
    printf("Input m, n:");
    scanf("%d,%d", &m, &n);
    printf("Input %d*%d matrix:\n", m, n);
    
    // 输入矩阵
    InputMatrix(a, m, n);
    
    // 转置矩阵
    Transpose(a, at, m, n);
    
    // 输出转置后的矩阵
    printf("The transposed matrix is:\n");
    PrintMatrix(at, n, m);
    
    return 0;
}

// 输入矩阵函数
void InputMatrix(int a[][N], int m, int n){
    for(int i = 0; i < m; i++){
        for(int j = 0; j < n; j++){
            scanf("%d", &a[i][j]);
        }
    }
    return;
}

// 矩阵转置函数:将 a[i][j]转置到 at[j][i]
void Transpose(int a[][N], int at[][M], int m, int n){
    for(int i = 0; i < m; i++){
        for(int j = 0; j < n; j++){
            at[j][i] = a[i][j];
        }
    }
    return;
}

// 打印矩阵函数
void PrintMatrix(int at[][M], int n, int m){
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            printf("%d\t", at[i][j]);
        }
        printf("\n");
    }   
    return;
}

2. 学生成绩统计(Q492)

题目描述:

输入 10 个学生的 C 语言成绩(假设成绩为整数值),求最高成绩、最低成绩和平均值。

输入格式要求: "%d" 提示信息:"请输入 10 个学生的 C 成绩:\n"
输出格式要求:

  • "10 个学生的 C 成绩分别为:\n"
  • "%d\t"
  • 10 个成绩的最后输出一个"\n"
  • "最高成绩是%d,是第%d个学生\n"
  • "最低成绩是%d,是第%d个学生\n"
  • "10 名学生的 C 成绩的平均分为:%.2f\n"

程序运行示例:

复制代码
请输入 10 个学生的 C 成绩:
80 90 93 78 83 67 79 60 64 45
10 个学生的 C 成绩分别为:
80  90  93  78  83  67  79  60  64  45  
最高成绩是 93,是第 3 个学生
最低成绩是 45,是第 10 个学生
10 名学生的 C 成绩的平均分为:73.90
c 复制代码
#include <stdio.h>

int main()
{
    int arr[10], min[2], max[2], sum = 0;
    
    printf("请输入 10 个学生的 C 成绩:\n");
    printf("10 个学生的 C 成绩分别为:\n");
    
    // 输入成绩并累加
    for(int i = 0; i < 10; i++){
        scanf("%d", &arr[i]);
        printf("%d\t", arr[i]);
        sum += arr[i];
    }
    
    // 初始化最小值和最大值
    min[0] = 1, min[1] = arr[0];  // min[0]:位置,min[1]:值
    max[0] = 1, max[1] = arr[0];  // max[0]:位置,max[1]:值
    
    // 查找最高分和最低分
    for(int i = 1; i < 10; i++){
        if(arr[i] < min[1]){
            min[0] = i + 1;  // 记录位置(从 1 开始)
            min[1] = arr[i]; // 记录最小值
        }
        if(arr[i] > max[1]){
            max[0] = i + 1;  // 记录位置
            max[1] = arr[i]; // 记录最大值
        }
    }
    
    // 输出结果
    printf("\n最高成绩是%d,是第%d个学生\n", max[1], max[0]);
    printf("最低成绩是%d,是第%d个学生\n", min[1], min[0]);
    printf("10 名学生的 C 成绩的平均分为:%.2f\n", sum * 1.0 / 10);
    
    return 0;
}

3. 静态变量计算阶乘(Q536)

题目描述:

利用静态变量计算 n 的阶乘。

输入格式要求: "%d" 提示信息:"Input n:"
输出格式要求: "%d! = %ld\n"

程序运行示例:

复制代码
Input n:10
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
10! = 3628800
c 复制代码
#include <stdio.h>

int main()
{
    int n;
    long result = 1;
    
    printf("Input n:");
    scanf("%d", &n);
    
    // 循环计算并输出 1!到 n!
    for(int i = 1; i <= n; i++){
        result *= i;  // 累乘计算阶乘
        printf("%d! = %ld\n", i, result);
    }
    
    return 0;
}

4. 简单计算器(Q2169)

题目描述:

程序模拟简单运算器的工作:输入一个算式(没有空格),遇等号'='说明输入结束,输出结果。假设计算器只能进行加、减、乘、除运算,运算数和结果都是整数,4 种运算符的优先级相同,按从左到右的顺序计算。例如输入"1+2*10-10/2="后,输出 10。

输出格式要求: "%d" 出错提示信息:"错误的运算符:%c"

程序运行示例:

复制代码
1+2*10-10/2=    <===此行为输入
10              <===此行为输出
c 复制代码
#include <stdio.h>
#include <string.h>

int main()
{
    char cal[1000];
    int result = 0, i = 0;
    
    scanf("%s", cal);  // 输入算式
    
    // 解析第一个数字
    while(cal[i] >= '0' && cal[i] <= '9'){
        result *= 10;
        result += cal[i] - '0';
        i++;
    }
    
    // 依次解析运算符和数字
    while(i < strlen(cal)){
        char now;
        int num = 0;
        
        // 获取运算符
        if(cal[i] == '+' || cal[i] == '-' || cal[i] == '*' || cal[i] == '/' || cal[i] == '='){
            now = cal[i];
            i++;
        } else {
            printf("错误的运算符:%c", cal[i]);
            return 0;
        }
        
        // 获取下一个数字
        while(cal[i] >= '0' && cal[i] <= '9'){
            num *= 10;
            num += cal[i] - '0';
            i++;
        }
        
        // 执行运算
        switch(now){
            case '+':
                result += num;
                break;
            case '-':
                result -= num;
                break;
            case '*':
                result *= num;
                break;
            case '/':
                result /= num;
                break;
            case '=':
                printf("%d", result);
                return 0;
        }
    }
    return 0;
}

5. 奥运会参赛国排序(改错)(Q6387)

题目描述:

请用指针数组编程实现按奥运会参赛国国名,在字典中的顺序对其入场次序进行排序。假设参赛国不超过 150 个。

下面程序中存在比较隐蔽的错误,请通过分析和调试程序,发现并改正程序中的错误。

注意:

  1. 请将修改正确后的完整源程序拷贝粘贴到答题区内。
  2. 对于没有错误的语句,请不要修改,修改原本正确的语句也要扣分。
  3. 当且仅当错误全部改正,且程序运行结果调试正确,才给加 5 分。
  4. 经教师手工核对后,如果未用指针数组做函数参数编程,那么即使做对也不给分。
  5. 改错时不能改变程序原有的意图,不能改变函数原型。

原代码(有错误):

c 复制代码
#include  <stdio.h>
#define   MAX_LEN  10
#define   N         150
void SortString(char *ptr[], int n);
main()
{
    int    i, n;
    char   *pStr[N];
    printf("How many countries?\n");
    scanf("%d",&n);     // 错误 1:要加 while(getchar()!='\n')跳过多余字符
    printf("Input their names:\n");
    for (i=0; i<n; i++)
    {
        gets(pStr[i]);  // 错误 2:未分配内存空间
    }
    SortString(pStr[i], n);  // 错误 3:应该传入 pStr,不是 pStr[i]
    printf("Sorted results:\n");
    for (i=0; i<n; i++)
    {
        puts(pStr[i]);
    }
}

void SortString(char *ptr[], int n)
{
    int    i, j;
    char  temp;  // 错误 4:没有定义长度
    for (i=0; i<n-1; i++)
    {
        for (j = i+1; j<n; j++)
        {
            if (ptr[j] < ptr[i]);  // 错误 5:字符串之间的比较要用 strcmp
            {
                temp = ptr[i];  // 错误 6:字符串之间的复制要用 strcpy,多了;
                ptr[j] = ptr[i];// 错误 7:i 和 j 的位置要互换
                ptr[j] = temp;  // 错误 8:要用 strcpy
            }
        }
    }
}

改正后的代码:

c 复制代码
#include  <stdio.h>
#include  <stdlib.h>
#include  <string.h>
#define   MAX_LEN  10
#define   N         150

void SortString(char *ptr[], int n);

int main()
{
    int    i, n;
    char   *pStr[N];
    
    printf("How many countries?\n");
    scanf("%d", &n);
    while(getchar() != '\n');  // 修正 1:跳过缓冲区的换行符
    
    printf("Input their names:\n");
    for (i = 0; i < n; i++)
    {
        pStr[i] = (char *)malloc(MAX_LEN);  // 修正 2:为每个指针分配内存
        gets(pStr[i]);
    }
    
    SortString(pStr, n);  // 修正 3:传入指针数组 pStr
    
    printf("Sorted results:\n");
    for (i = 0; i < n; i++)
    {
        puts(pStr[i]);
        free(pStr[i]);  // 修正 4:释放分配的内存
    }
    
    return 0;
}

void SortString(char *ptr[], int n)
{
    int    i, j;
    char   temp[MAX_LEN];  // 修正 5:定义足够长度的临时变量
    
    for (i = 0; i < n - 1; i++)
    {
        for (j = i + 1; j < n; j++)
        {
            if (strcmp(ptr[j], ptr[i]) < 0)  // 修正 6:使用 strcmp 比较字符串
            {
                strcpy(temp, ptr[i]);      // 修正 7:使用 strcpy 复制字符串
                strcpy(ptr[i], ptr[j]);    // 修正 8:正确交换两个字符串
                strcpy(ptr[j], temp);
            }
        }
    }
}

主要错误总结:

  1. scanf 后要加 while(getchar()!='\n'); 跳过换行符
  2. 指针数组使用前要用 malloc 分配内存空间
  3. 调用排序函数应传入 pStr 而不是 pStr[i]
  4. temp 需要定义为数组 temp[MAX_LEN]
  5. 字符串比较要用 strcmp(),不能用<
  6. 字符串复制要用 strcpy(),不能用=
  7. 交换逻辑有误,应该是三句 strcpy
  8. 使用完后要 free 释放内存
相关推荐
丶小鱼丶2 小时前
数据结构和算法之【二分查找】
java·数据结构·算法
忡黑梨2 小时前
BUUCTF_reverse_[MRCTF2020]Transform
c语言·开发语言·数据结构·python·算法·网络安全
枳颜2 小时前
LeetCode 466:统计重复个数
数据结构·算法·字符串
TYFHVB122 小时前
2026六大主流CRM横评,五大核心维度深度解析
大数据·前端·数据结构·人工智能
爱和冰阔落2 小时前
【C++STL上】栈和队列模拟实现 容器适配器 力扣经典算法秘籍
数据结构·c++·算法·leetcode·广度优先
程序员-King.2 小时前
day162—递归—买卖股票的最佳时机Ⅱ(LeetCode-122)
算法·leetcode·深度优先·递归
Gorgous—l2 小时前
数据结构算法学习:LeetCode热题100-贪心算法篇(数组中的第K个最大元素、 前 K 个高频元素、数据流的中位数)
数据结构·学习·算法
一叶落4382 小时前
LeetCode 300. 最长递增子序列(LIS)详解(C语言 | DP + 二分优化)
c语言·数据结构·c++·算法·leetcode
Darkwanderor2 小时前
数据结构——trie(字典)树
数据结构·c++·字典树·trie树