第6章 第4、5节:数组的应用举例(课件)-《C语言程序设计》(电子工业出版社)上好课

2026-04-30
| 48页
| 54人阅读
| 0人下载
精品

内容正文:

4.4、4.5节:数组的应用举例 C语言程序设计 电子工业出版社 理解数组基本概念、定义和使用方法 掌握数组在排序、查找等常见算法中的应用 运用数组解决简单编程问题,如小游戏与管理系统 培养使用循环结构遍历和操作数组的能力,提升逻辑思维 体会“有序”思想在数据处理中的重要性 培养严谨的编程习惯和解决实际问题的信心 知识目标 能力目标 素养目标 01 01 01 学习目标 目录 Part 01 教学导入 Part 02 知识讲授 Part 03 师生互动 Part 04 课堂练习 Part 05 课堂小结 教学导入:“杂乱无章”的烦恼 情景提问 同学们,想象一下这是学校的图书馆,所有书籍都杂乱无章地堆在一起。 ❓ 想找一本《C语言程序设计》,最快需要多久? ❓ 想统计不同作者的书籍数量,又该如何高效完成? 核心思考 这种混乱无序的状态,是不是让信息的查找、统计和管理变得异常困难?我们该如何解决? 教学导入:秩序的创造者——数组 就像图书管理员会把书分门别类、整齐地摆放在书架上一样,在C语言中,我们也有一个强大的工具来管理一组相同类型的数据——它就是数组 (Array)。 ▍什么是数组? 一个有序的、相同数据类型元素的集合。它就像一个编号的储物柜,每个柜子(元素)都有一个唯一的门牌号(下标)。 ▍为什么需要数组? 统一管理:将相关数据组织在一起,逻辑清晰。 高效访问:通过下标可以快速定位到任何一个元素。 循环操作:利用循环结构,轻松地遍历和处理所有元素。 教学导入:数组 数组是有序的元素序列。在C语言中,它是用来存储一系列相同类型数据的集合,是编程中最基础的数据结构之一。 数据类型严格统一 数组内只能存放同一种类型的数据,例如全为整数(int)或全为字符(char),不可混合。 内存空间连续存储 数组的所有元素在计算机内存中占据一块连续的地址空间,这保证了访问的高效性。 通过下标索引访问 每个元素对应唯一索引(下标),从 0 开始计数。如 score[0] 代表第一个元素,score[1] 代表第二个。 图:数组元素在内存中有序且连续的排列模型 知识讲授 数组的应用举例 C语言趣味程序实例6 项目开发实例 第一部分 C语言趣味程序实例6 知识讲授 知识讲授:谜语博士的难题(问题分析) ▍ 谜题背景设定 这个世界里存在两个族群:诚实族永远说真话,说谎族永远说假话。谜语博士在一次游历中遇到了 A、B、C 三位居民,并向他们询问了族别信息。 ▍ 三位居民的陈述 A:“我们之中有两个来自诚实族。” B:“我们之中只有一个是诚实族的。” C:“对,确实只有一个是诚实族的。” 💡 待解核心问题 请结合逻辑学原理,根据以上三人的陈述,推理并判断出 A、B、C 三人分别属于哪个族群。 知识讲授:谜语博士的难题(算法分析) 变量定义与建模 设变量 a, b, c 分别代表三人。 1= 诚实族 (说真话),0= 说谎族 (说假话)。将自然语言问题转化为数学模型。 逻辑规则转化 基于陈述建立逻辑约束: 诚实则陈述为真,说谎则陈述为假。 例:A诚实时总和为2,说谎时总和≠2。 算法策略:穷举法 仅存在 2³=8 种组合可能。 遍历所有组合,逐一验证是否满足所有逻辑约束,筛选出唯一解。 知识讲授:谜语博士的难题(程序代码) 程序文本:谜语博士的难题 #include<stdio.h> main() { int a,b,c; for(a=0;a<=1;a++) for(b=0;b<=1;b++) for(c=0;c<=1;c++) if((a&&a+b+c==2||!a&&a+b+c!=2) &&(b&&a+b+c==1||!b&&a+b+c!=1) &&(c&&a+b+c==1||!c&&a+b+c!=1)) { printf("A is a %s. ",a?"honest":"lier"); printf("B is a %s. ",b?"honest":"lier"); printf("C is a %s. ",c?"honest":"lier"); } } 知识讲授:谜语博士的难题(代码分析) 核心逻辑:穷举法遍历 使用三层 `for` 循环 (a=0~1, b=0~1, c=0~1) 遍历所有 8 种身份组合,将所有可能性纳入程序检查范围。 关键条件:逻辑表达式翻译 将每个人的陈述转化为逻辑判断。例如:若 A 诚实(a=1),则总人数需为 2; 若 A 说谎(a=0),则总人数不为 2。同理构建 B 和 C 的条件,三者需同时满足。 程序执行:输出正确解 当找到满足所有逻辑条件的 a、b、c 组合时,程序立即输出三人的最终身份结果。 知识讲授:谜语博士的难题(运行结果) 知识讲授:求车速(问题分析) ▍ 问题描述 一辆以固定速度行驶的汽车,司机在上午10点看到里程表上的读数是一个对称数(即这个数从左向右读和从右向左读是一样的),读数为95859。 两小时后,里程表上出现了一个新的对称数。请计算:这辆车的行驶速度是多少?新的对称数又是多少? 核心思考点: 如何将数字分解并高效判断其对称性? ▍ 解题核心思路 问题分析 明确“对称数”定义,目标是找到大于95859的下一个最小对称数,并利用差值计算速度。 算法设计 从95860开始进行循环递增,逐个检查每个数字是否符合对称数的特征,找到即停止。 数据结构辅助 将数字分解后存入数组,利用数组的索引特性,方便快速比较首尾对应位置的数字。 知识讲授:求车速(程序流程图) 知识讲授:求车速(代码实现) 程序文本:求车速 #include<stdio.h> main() { int t,a[5]; /*数组a存放分解后的5个数字 */ long int k,i; for(i=95860;;i++) /*以95860为初值,循环试探*/ { for(t=0,k=100000;k>=10;t++) { a[t]=(i%k)/(k/10); /*保存分解后的数字*/ k/=10; } if((a[0]==a[4])&&(a[1]==a[3])) { printf("里程表上出现的新的对称数为:"); printf("%d%d%d%d%d ",a[0],a[1],a[2],a[3],a[4]); printf("该车的车速为:%.2f ",(i-95859)/2.0); break; } } } 知识讲授:求车速(运行结果) 课堂问答 Q1: 字符数组和普通数组有什么区别? 字符数组是数组的一种特殊形式,其元素类型为 char,专门用于存储字符数据。普通数组可以存储 int、float 等多种类型的数据。 Q2: 为什么需要字符串结束标志 '\0'? '\0' 用于标识字符串的结束,使得程序能够正确识别字符串的长度和范围,避免访问数组越界。 课堂问答 Q3: 如何计算一个字符串的长度? 核心方法是使用 C 标准库中的strlen()函数,它会从字符串的起始位置开始逐个计数,直到遇到终止符 '\0' 时停止,返回的数值不包含 '\0' 本身。当然,也可以通过编写自定义循环遍历字符的方式来手动实现长度计算。 Q4: 数组在排序算法中扮演了什么角色? 数组作为存储待排序数据的容器,为排序算法提供了操作的实体对象。其连续存储和随机访问的特性,使得交换和比较元素变得高效,是实现排序逻辑的理想数据结构。 课堂练习 ▍ 题目描述 输入一行字符,编写程序对其中的英文字母、阿拉伯数字、空格以及其他特殊符号的出现个数进行分别统计。 ▍ 核心思想:ASCII码映射 利用字符的ASCII码特性,定义长度为128的数组 `char_count[128]`。将字符的ASCII码值作为数组下标,元素值作为对应字符的计数。 `char_count['A']++` ➜ 统计大写字母 'A' 出现的次数 `char_count['5']++` ➜ 统计阿拉伯数字 '5' 出现的次数 课堂练习 程序文本:字符统计 #include <stdio.h> main() { int char_count[128] = {0};char ch;int letter=0,digit=0,space=0,other=0,i; printf("请输入一行字符: "); while ((ch = getchar()) != ' ') char_count[(int)ch]++; for (i = 65; i <= 90; i++) letter += char_count[i]; for (i = 97; i <= 122; i++) letter += char_count[i]; for (i = 48; i <= 57; i++) digit += char_count[i]; space = char_count[32]; // 统计空格:空格的ASCII码为32 for (i = 0; i < 128; i++) other += char_count[i]; other=other-letter-digit-space; printf(" ===== 字符统计结果 ===== "); printf("英文字母个数:%d ", letter); printf("阿拉伯数字个数:%d ", digit); printf("空格个数:%d ", space); printf("其他特殊符号个数:%d ", other); } 课堂练习 第二部分 知识讲授 项目开发实例 知识讲授:学生成绩管理系统(成绩排序) ▍核心目标 针对班级内20名学生的成绩数据,执行从高到低的排序操作,将杂乱的数据转化为有序序列,从而实现对学习情况的快速可视化分析。 ▍关键要素 数据来源:包含20名学生成绩的原始数组集合 核心操作:对数组元素进行数值大小的比较与交换 执行规则:严格遵循“降序”规则 。 ▍流程可视化示意 Step 01. 原始输入 [65, 92, 78, 88, 95, 60, 72, ...] Step 02. 逻辑处理 执行排序算法 ➜ 比较数值大小 ➜ 交换位置 Step 03. 最终输出 [95, 92, 88, 78, 72, 65, 60, ...] (降序排列) 知识讲授:学生成绩管理系统(成绩排序) 核心问题:如何对数组中的数据进行排序? 选择排序法 💡 核心思想:每次从未排序部分中找到最大值,与未排序部分的第一个元素交换位置。 🍎 过程比喻:如同从一堆苹果中,每次挑出最大的那个,放到篮子最前面。 📝 演示:[64,25,12,22,11] → 选64 → [64,25,12,22,11] → 选25 → 选22... 冒泡排序法 💡 核心思想:重复比较相邻元素,若顺序错误则交换,使最大值逐步“浮”到数组末端。 🫧 过程比喻:想象气泡在水中上升,最大的元素会慢慢“浮”到数组的末端位置。 📝 演示:[64,25,12,22,11] → 比较交换 → [25,12,22,11,64] (最大值到位) 知识讲授:学生成绩管理系统(成绩排序) 程序文本:选择排序法 #include<stdio.h> #define N 20 main() { int score[N]; int i,j,tmp,min; printf("请输入%d名学生的成绩: ",N); for(i=0;i<N;i++) scanf("%d",&score[i]); for(i=N-1;i>=0;i--) { min=i; for(j=0;j<i;j++) if(score[j]<score[min]) min=j; if(min!=i) { tmp=score[i]; score[i]=score[min]; score[min]=tmp; } } printf("学生成绩从高到低顺序为: "); for(i=0;i<N;i++) printf("%d ",score[i]); printf(" 最高成绩为%d ",score[0]); printf("最低成绩为%d ",score[N-1]); } 知识讲授:学生成绩管理系统(成绩排序) 知识讲授:学生成绩管理系统(成绩排序) 程序文本:冒泡排序法 #include<stdio.h> #define N 20 main() { int score[N];int i,j,tmp,change; printf("请输入%d名学生的成绩: ",N); for(i=0;i<N;i++)scanf("%d",&score[i]); for(i=0;i<N;i++) { change=0; for(j=0;j<N-1-i;j++) {if(score[j]<score[j+1]) {tmp=score[j]; score[j]=score[j+1]; score[j+1]=tmp; change=1;} } if(change==0) break; } printf("学生成绩从高到低顺序为: "); for(i=0;i<N;i++) printf("%d ",score[i]); printf(" 最高成绩为%d ",score[0]); printf("最低成绩为%d ",score[N-1]); } 知识讲授:学生成绩管理系统(成绩排序) 知识讲授:学生成绩管理系统(成绩添加和查找) 🎯 核心目标 开发一个交互式程序,实现对学生成绩的 动态管理,打造可持续使用的管理工具。 录入成绩 支持添加新学生的三门课程成绩,建立完整档案。 打印成绩 格式化显示所有学生成绩表,并自动计算平均分。 查询成绩 通过学号作为索引,快速检索并展示特定学生的信息。 循环操作 提供可视化菜单界面,允许用户重复执行各项功能。 知识讲授:学生成绩管理系统(成绩添加和查找) 核心问题:如何高效地组织和管理多个学生的多门课程成绩? 数据结构设计:二维数组 定义:使用二维数组student_scores[N][4]存储。 • 行(N):代表单个学生 | • 列(4):前3列为单科成绩,第4列为平均分 学号 课程1 课程2 课程3 平均分 01 85 90 88 87.67 02 92 81 76 83.00 扩展性思考与优化 固定数组的局限:内存浪费 若定义 N=50 的数组,但实际只有20名学生,剩余的30个空间将被闲置,造成不必要的资源开销。 进阶方案:动态内存分配 在C语言等开发中,使用 malloc / realloc 函数,根据实时的学生人数动态调整数组大小,实现内存资源的按需分配。 知识讲授:学生成绩管理系统(成绩添加和查找) ▍ 程序主流程逻辑 🔄 启动循环:显示菜单 → 等待用户输入 (0/1/2/3) 01. 添加成绩 (Add) 输入分数 → 计算平均分 → 存入数组 → 自动返回菜单 02. 查询成绩 (Search) 输入目标学号 → 遍历查找数据 → 格式化显示详情 03. 退出 / 显示所有 (Exit / Show) 输入 0 结束循环 | 输入 3 遍历输出全部学生成绩 ▍ 核心代码实现机制 循环控制:do-while 结构 “先斩后奏”模式,保证菜单至少显示一次。根据用户输入的 '0' 来终止循环。 分支选择:switch-case 语句 解析用户输入的整数指令,高效分发到添加、查询、显示或退出的对应处理逻辑块。 数据管理:Array + Count 计数器 利用 count 变量动态跟踪录入人数,将成绩数据有序存入 student_scores 二维数组中。 知识讲授:学生成绩管理系统(成绩添加和查找) 程序文本:学生成绩管理系统(成绩添加和查找) #include<stdio.h> #define n 50 main() { int score[50][3]={78,90,84,67,90,65,78,83,91,73,92,75,61,59,76}; int avg[50]={84,74,84,80,65}; int i,j,choose,num=5,k; while(1) { printf(" "); printf("\t|-----------------student-----------------| "); printf("\t|\t1.添加学生成绩 | "); printf("\t|\t2.根据学号查找学生成绩 | "); printf("\t|\t3.显示学生成绩表 | "); printf("\t|\t4.退出系统 | "); printf("\t|-----------------------------------------| "); printf("choose(0-3):"); scanf("%d",&choose); 知识讲授:学生成绩管理系统(成绩添加和查找) 程序文本:学生成绩管理系统(成绩添加和查找) switch(choose) { case 0:printf("退出系统 ");return;break; case 1:printf("请依次输入第%d名学生三门课程的成绩: ",num+1); for(i=0;i<3;i++) scanf("%d",&score[num][i]); avg[num]=(score[num][0]+score[num][1]+score[num][2])/3; num++;printf("添加成功 ");break; case 2:printf("请输入要查询的学生学号:"); scanf("%d",&k); printf("学号\t课程1\t课程2\t课程3\t平均 "); printf("%d\t",k); for(i=0;i<3;i++)printf("%d\t",score[k-1][i]); printf("%d ",avg[k-1]);break; case 3: printf("学号\t课程1\t课程2\t课程3\t平均 "); for(i=0;i<50;i++) { if(avg[i]==0)break; else { printf("%d\t",i+1); for(j=0;j<3;j++)printf("%d\t",score[i][j]); printf("%d ",avg[i]); } }break; } } } 知识讲授:学生成绩管理系统(成绩添加和查找) 知识讲授:学生成绩管理系统(姓名排序) 核心目标 根据学生姓名的拼音顺序进行排序,并为排序后的学生分配唯一的学号。 核心问题:如何对字符串(姓名)进行排序? 数据结构:二维字符数组 student_names[N][20] 存储姓名 排序规则:逐字符比较 ASCII 码值大小 核心工具:C标准库函数 strcmp(str1, str2) 进行比较 ▍ 排序过程概念示意 01. 无序输入 (Input) ["Zhang San", "Li Si", "Wang Wu"] 02. 有序输出 (按拼音排序) ["Li Si", "Wang Wu", "Zhang San"] ↓ 自动分配学号: 001, 002, 003 💡 提示:strcmp 返回值决定了交换逻辑 知识讲授:学生成绩管理系统(姓名排序) 程序文本:学生成绩管理系统(姓名排序) #include<stdio.h> #include<string.h> main() { char name[10][20],tmp[20]; int i,j,max,large; printf("请依次输入10名学生的姓名: "); for(i=0;i<10;i++) gets(name[i]); for(i=9;i>=0;i--) { strcpy(tmp,name[i]); max=i; for(j=0;j<i;j++) { large=strcmp(tmp,name[j]); if(large<0){ strcpy(tmp,name[j]); max=j; } } if(strcmp(tmp,name[i])!=0) {strcpy(tmp,name[i]);strcpy(name[i],name[max]);strcpy(name[max],tmp); } } printf("学生信息如下: "); printf("学号\t\t姓名 "); for(i=0;i<10;i++) { printf("%d\t\t",i+2012000); puts(name[i]); } } 知识讲授:学生成绩管理系统(姓名排序) 项目总结与回顾 本次开发实例,我们通过三个项目逐步构建了一个学生成绩管理系统,层层递进地掌握了C语言处理不同类型数据的核心技术点: 成绩排序 ✦ 核心技术栈 熟练掌握一维数组的遍历操作;应用选择排序、冒泡排序等经典算法处理数值。 🎯 解决的问题 实现对学生成绩等数值型数据的高效排序与统计分析。 增查管理 ✦ 核心技术栈 运用二维数组存储结构化数据;结合菜单驱动循环与分支语句实现交互逻辑。 🎯 解决的问题 实现对学生信息的动态录入、存储以及条件查询功能。 姓名排序 ✦ 核心技术栈 使用二维字符数组管理字符串;熟练调用strcmp、strcpy等标准库函数处理文本。 🎯 解决的问题 完成对非数值类型(学生姓名)的字典序排序与处理。 课堂问答 Q1: 在C语言中,数组的下标是从几开始的? 在C语言中,数组的下标(索引)是从 0 开始的。这意味着第一个元素的下标是0,第二个是1,依此类推。 Q2: 如何初始化一个一维数组? 可以在定义数组时直接赋值,例如 int scores[5] = {90, 85, 88, 92, 76};。如果提供的初始值数量少于数组大小,剩余元素会被自动初始化为0。 课堂问答 Q3: 二维数组的行和列,哪一个在内存中变化更快? 在C语言中,二维数组在内存中是按行优先存储的。这意味着同一行内的元素在内存中是连续的,列的变化比行的变化更快。 Q4: 数组名在表达式中通常代表什么? 在大多数表达式中,数组名会被转换为一个指向该数组第一个元素的指针。例如,arr 和 &arr[0] 的值通常是相等的。 练习题1:执行以下程序的输出结果是( ) #include <stdio.h> main() { int a[5] = {1,2,3,4,5},i, t; for(i=0; i<2; i++) { t = a[i]; a[i] = a[4-i]; a[4-i] = t; } for(i=0; i<5; i++) printf("%d ", a[i]); } 答案:5 4 3 2 1 解析:循环执行两次,实现首尾元素交换。第 1 次交换:a[0] ↔ a[4],数组变为 5,2,3,4,1。第 2 次交换:a[1] ↔ a[3],数组变为 5,4,3,2,1。最终输出:5 4 3 2 1 课堂练习 练习题2:执行以下程序的输出结果是( ) #include <stdio.h> main() { int a[6] = {3,1,4,1,5,9}; int i, s = 0; for(i=1; i<5; i++) { if(a[i] % 2 == 1) s += a[i]; } printf("%d", s); } 答案:7 解析:循环遍历下标 1~4 的元素:1,4,1,5。只累加奇数:1 + 1 + 5 = 7。最终输出:7 课堂练习 练习题2:执行以下程序的输出结果是( ) #include <stdio.h> main() { int a[4] = {5,8,3,6}; int i, m; m = a[0]; for(i=1; i<4; i++) { if(a[i] < m) m = a[i]; } printf("%d", m); } 答案:3 解析:先把 m 初始化为第一个元素 5 依次比较: 8 > 5,不更新 3 < 5,m 变为 3 6 > 3,不更新 最终 m 是数组最小值,输出:3 课堂练习 课堂小结 课堂小结 本堂课核心知识点回顾 · 数组基础 数组的本质 相同类型数据的有序集合,通过唯一的下标索引进行快速访问。 一维数组 用于存储一维线性序列数据,如班级成绩列表、字符串字符序列。 二维数组 用于存储表格状或矩阵数据,如学生成绩统计表、二维坐标系点位。 ▍ 核心应用场景 数据管理:成绩系统、通讯录存储 算法基石:冒泡/快速排序、二分查找 统计分析:字符频次、数据极值计算 逻辑游戏:猜数字、迷宫路径存储 核心编程思想 利用数组的有序性和可遍历性,将复杂的批量数据处理问题,分解为对单个元素的重复操作,实现“化繁为简”。 📝 课后思考:尝试使用数组结合循环,实现一个简单的班级平均分计算程序 课后任务 基础题 数组逆序存放与输出 编写程序,输入10个整数存入数组,将数组元素逆序存放后输出。 示例:输入 1 2 3 4 5 → 输出 5 4 3 2 1 进阶题 成绩管理系统功能升级 基于课堂案例,为系统新增两个核心功能: • 支持按姓名删除学生记录 • 统计并显示全班的平均分、最高分、最低分 挑战题 算法实践:插入排序 深入研究并手动实现插入排序算法。 原理:构建有序序列,对未排序数据,在已排序序列中从后向前扫描,找到对应位置并插入。 谢谢观看 THANKS $

资源预览图

第6章 第4、5节:数组的应用举例(课件)-《C语言程序设计》(电子工业出版社)上好课
1
第6章 第4、5节:数组的应用举例(课件)-《C语言程序设计》(电子工业出版社)上好课
2
第6章 第4、5节:数组的应用举例(课件)-《C语言程序设计》(电子工业出版社)上好课
3
第6章 第4、5节:数组的应用举例(课件)-《C语言程序设计》(电子工业出版社)上好课
4
第6章 第4、5节:数组的应用举例(课件)-《C语言程序设计》(电子工业出版社)上好课
5
第6章 第4、5节:数组的应用举例(课件)-《C语言程序设计》(电子工业出版社)上好课
6
所属专辑
由于学科网是一个信息分享及获取的平台,不确保部分用户上传资料的 来源及知识产权归属。如您发现相关资料侵犯您的合法权益,请联系学科网,我们核实后将及时进行处理。