26_2_8 作业题

2 阅读7分钟

 

序号题目名称
1求两个整数的最大公约数(辗转相除法)
2打印九九乘法表
3打印 X 形图案(多组输入)
4输入 10 个整数求平均值
5输入 10 个整数逆序输出
6交换两个等长数组的内容
7矩阵转置(多组输入)
8打印空心正方形(多组输入)
9合并两个升序数组并输出
10规范输入输出(含缓冲区处理)

一、基础语法

核心概念

  • 变量声明与初始化、数据类型(int/double)
  • 运算符(算术 %、赋值 =、逻辑!=)
  • 函数设计原则(高内聚低耦合)

实战代码(求最大公约数)

#include <stdio.h>

int main() {
    // 1. 变量声明与初始化
    int a = 24, b = 18;
    int c = a % b; // 取模运算符
    
    // 2. 循环+运算符实现辗转相除法
    while(c != 0) {
        a = b;  // 赋值运算符更新变量
        b = c;
        c = a % b;
    } 
    printf("24和18的最大公约数:%d\n", b);
    

    return 0;
}

​

关键说明

  • % 是取模运算符,仅适用于整数,核心作用是求余数;
  • 辗转相除法核心逻辑:较大数 = 较小数 × 商 + 余数,反复用余数替换,直到余数为 0,此时较小数就是最大公约数。

二、循环结构

核心概念

  • for 循环(固定次数循环)、while 循环(条件循环)
  • 嵌套循环(循环内嵌套循环)
  • 循环变量控制(起始 / 终止 / 步长)

实战代码 1(九九乘法表)

#include <stdio.h>

int main() {
    // 嵌套for循环:外层控制行,内层控制列
    int i, j;
    for(i = 1; i <= 9; i++) { // 行:1~9
        for(j = 1; j <= i; j++) { // 列:1~当前行号(避免重复)
            printf("%d*%d=%d ", j, i, i*j);
        }
        printf("\n"); // 每行结束换行
    }
    return 0;
}

​

实战代码 2(打印 X 形图案)

#include <stdio.h>

int main() {
    // 多组输入:while循环+scanf判断EOF
    int rows;
    while(scanf("%d", &rows) != EOF) { // 输入2~20,Ctrl+Z/Ctrl+D结束
        // 嵌套循环打印图案
        for(int i = 0; i < rows; i++) { // 行
            for(int j = 0; j < rows; j++) { // 列
                // 核心条件:主对角线(i==j)+ 副对角线(i+j=rows-1)
                if(i == j || i + j == rows - 1) {
                    printf("*");
                } else {
                    printf(" ");
                }
            }
            printf("\n");
        }
    }
    return 0;
}

​

关键说明

  • 嵌套循环核心:外层循环控制 “行”,内层循环控制 “列”;
  • 多组输入终止:Windows 按Ctrl+Z,Linux/Mac 按Ctrl+Dscanf返回EOF表示输入结束。

三、数组操作

核心概念

  • 一维数组(存储一组同类型数据)、二维数组(矩阵)
  • 数组下标(从 0 开始)、数组长度计算(sizeof(数组)/sizeof(元素)
  • 数组遍历、逆序、交换、转置

实战代码 1(数组逆序 + 平均值)

#include <stdio.h>

int main() {
    // 1. 输入10个整数求平均值
    int arr_avg[10] = {0};
    int sum = 0;
    printf("输入10个整数:");
    for(int i = 0; i < 10; i++) {
        scanf("%d", &arr_avg[i]);
        sum += arr_avg[i]; // 累加求和
    }
    printf("平均值:%.2lf\n", sum * 1.0 / 10); // 1.0确保浮点运算
    
    // 2. 数组逆序输出
    printf("逆序结果:");
    for(int j = 9; j >= 0; j--) { // 从最后一个元素遍历到第一个
        printf("%d ", arr_avg[j]);
    }
    printf("\n");
    return 0;
}

​

实战代码 2(数组交换 + 矩阵转置)

#include <stdio.h>

int main() {
    // 1. 两个数组交换(同长度)
    int arrA[] = {1,2,3,4};
    int arrB[] = {5,6,7,8};
    int len = sizeof(arrA) / sizeof(arrA[0]); // 计算数组长度
    for(int i = 0; i < len; i++) {
        int tmp = arrA[i]; // 临时变量作为交换中介
        arrA[i] = arrB[i];
        arrB[i] = tmp;
    }
    printf("交换后arrA:");
    for(int i = 0; i < len; i++) printf("%d ", arrA[i]);
    printf("\n交换后arrB:");
    for(int i = 0; i < len; i++) printf("%d ", arrB[i]);
    
    // 2. 矩阵转置(行列互换)
    printf("\n\n输入矩阵行数n、列数m:");
    int n, m;
    while(scanf("%d %d", &n, &m) == 2) {
        int arr_matrix[n][m];
        // 输入矩阵
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                scanf("%d", &arr_matrix[i][j]);
            }
        }
        // 转置输出:原列→行,原行→列
        printf("转置结果:\n");
        for(int i = 0; i < m; i++) {
            for(int j = 0; j < n; j++) {
                printf("%d ", arr_matrix[j][i]);
            }
            printf("\n");
        }
    }
    return 0;
}

​

关键说明

  • 数组长度计算:sizeof(数组)是数组总字节数,sizeof(数组[0])是单个元素字节数,相除得元素个数;
  • 数组交换必须用临时变量,直接arrA[i] = arrB[i]; arrB[i] = arrA[i]会导致数据覆盖;
  • 矩阵转置核心:arr[j][i]替代arr[i][j](行下标和列下标互换)。

四、算法应用

核心概念

  • 双指针法(合并有序数组)
  • 边界判断(空心正方形)
  • 贪心思想(每次取最小元素)

实战代码 1(合并两个升序数组)

#include <stdio.h>

int main() {
    int n, m;
    printf("输入两个数组长度n m:");
    scanf("%d %d", &n, &m);
    
    int arr1[1000] = {0}, arr2[1000] = {0};
    // 输入两个升序数组
    for(int i = 0; i < n; i++) scanf("%d", &arr1[i]);
    for(int i = 0; i < m; i++) scanf("%d", &arr2[i]);
    
    // 双指针法:p1指向arr1,p2指向arr2
    int p1 = 0, p2 = 0;
    printf("合并结果:");
    while(p1 < n && p2 < m) {
        if(arr1[p1] < arr2[p2]) { // 取较小元素输出
            printf("%d ", arr1[p1]);
            p1++; // 指针后移
        } else {
            printf("%d ", arr2[p2]);
            p2++;
        }
    }
    // 输出剩余元素(其中一个数组已遍历完)
    while(p1 < n) { printf("%d ", arr1[p1]); p1++; }
    while(p2 < m) { printf("%d ", arr2[p2]); p2++; }
    
    return 0;
}

​

实战代码 2(打印空心正方形)

#include <stdio.h>

int main() {
    int rows;
    while(scanf("%d", &rows) != EOF) { // 输入3~20
        for(int i = 0; i < rows; i++) { // 行
            for(int j = 0; j < rows; j++) { // 列
                // 边界判断:第一行/最后一行/第一列/最后一列打印*
                if(i == 0 || i == rows - 1 || j == 0 || j == rows - 1) {
                    printf("* ");
                } else {
                    printf("  "); // 非边界打印空格
                }
            }
            printf("\n");
        }
    }
    return 0;
}

​

关键说明

  • 双指针法核心:两个指针分别遍历两个有序数组,每次取最小值,时间复杂度O(n+m),效率最高;
  • 空心图形核心:只打印 “边界”,内部用空格填充,重点是边界条件的判断(i==0/i==rows-1/j==0/j==rows-1)。

五、输入输出

核心概念

  • scanf(输入)、printf(输出)
  • 格式符(%d整数、%lf浮点数、%.2lf保留 2 位小数)
  • 输入缓冲区处理(避免残留数据影响)
  •     函数设计原则(高内聚低耦合)
    - 高内聚:一个函数/模块只做一件事(如该段代码仅求最大公约数)
    - 低耦合:模块间尽量少依赖(如该段代码不依赖其他函数)

实战代码(规范输入输出)

#include <stdio.h>

int main() {
    // 1. 基本输入输出
    int num;
    printf("输入一个整数:");
    scanf("%d", &num);
    printf("你输入的整数:%d\n", num);
    
    // 2. 浮点输出(保留2位小数)
    double avg = 123.456;
    printf("保留2位小数:%.2lf\n", avg); // 输出123.46
    
    // 3. 多组输入后清空缓冲区
    int a;
    while(scanf("%d", &a) != EOF) {
        printf("输入的数:%d\n", a);
    }
    while(getchar() != '\n'); // 清空缓冲区,避免影响后续输入
    
    return 0;
}

​

关键说明

  • 格式符易错点:%f用于float%lf用于double%1f是错误写法(应为%.1f);
  • 多组输入后必须清空缓冲区:getchar()逐个读取缓冲区残留字符,直到换行符,避免后续scanf读取到残留的\n

总结

表格

知识点核心考点高频应用场景
基础语法运算符、变量作用域数值计算、条件判断
循环结构嵌套循环、多组输入打印图案、批量处理数据
数组操作下标遍历、长度计算、转置 / 交换矩阵处理、数据统计
算法应用双指针法、边界判断有序数组合并、图形打印
输入输出格式符、缓冲区处理所有需要交互的场景