《C语言项目开发教程PPT 第3章.ppt》由会员分享,可在线阅读,更多相关《C语言项目开发教程PPT 第3章.ppt(101页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、 数数 组组数组是在程序设计中,为了处理方便,把具有相同类型的若干变量按有序的形式组织起来的一种形式。这些按序排列的同类数据元素的集合称为数组。数组是一种高效的数据组织方式,几乎所有的高级程序设计语言都支持数组。一个数组可以分解为多个数据元素,而同数组中每个数据元素的类型应该是一致的。这些数组元素可以是基本数据类型或构造类型。在内存中,数组使用连续的存储空间,各元素相邻存放,引用某一个元素时只要给出数组名和该元素在数组中的位置信息即可。元素的位置称为下标,数组按下标的个数可以分为一维数组、二维数组,二维以上的数组称为多维数组。任务3.1 学生信息管理系统之成绩排序任务目标了解一维数组的概念,比
2、较实用一维数组存储数据和直接使用基本数据类型存储相比的优点。了解一维数组的定义、初始化以及元素引用方法。了解一维数组的使用方法。了解排序算法,掌握几种排序算法的思想和代码实现。可以使用一维数组实现简单的应用。实现学生成绩排序程序。3.1.1 一维数组的定义和引用在数组使用之前,首先要对其进行定义。一维数组的定义方式为:类型说明符 数组名 常量表达式类型说明符是任意一种基本数据类型或者构造数据类型,例如int、float、char等。类型说明符限制了数组元素的取值类型。数组名是一个标志符,应遵循C语言中标志符的命名规则取名。方括号是必须的,且不能换成其他符号。常量表达式表示组数中数据的个数,也称
3、数组的长度。常量表达式可以是常量和符号常量,但是不能包含变量。允许在同一个类型说明符后跟多个数组的定义,这些数组为同一类型,以逗号隔开,最后一个数组后加分号。如,“int x10;”表明定义一个长度为10的int类型的数组。“float score5;”为定义一个float类型数据的长度为5的数组。使用数组时应注意以下几点:(1)对于同一个数组中的所有元素,其数据类型都是相同的。(2)各个数组元素在数组中是有序排列的,即有先后次序关系。(3)数组中元素可以是基本数据类型,也可以是其他类型,如数组类型元素。(4)数组定义的时候必须指明数组的长度,即“int a”这种定义是不正确的。(5)数组长度
4、必须是一个确定的值,即常量或常量表达式,而不可以为变量。例如下面定义是错误的:“int n;int an;”,即使该变量已经有确定的取值也不可以,而“int n=10;int an;”也是不正确的。数组元素是组成数组的基本单元。下标是元素子数组中的顺序号,是从0开始的。数组元素用数组名和数组下标共同表示,其形式为:数组名下标其中下标必须为整型值,可以是整型常量、整型变量或整型表达式。如,“int a10;”表示定义一个长度为10的整型数组,数组的下标从0开始,取值范围为09,“a5”表示数组a中第6个数值,“a5=5”表示将数组a中第6个值赋值为5。另外a0,ai,ai+j,ai+等都是合法的
5、数组元素。但是下标的范围不能超出数组的长度范围,而“a10”则为非法数据。那么使用数组在实际案例中有什么优点呢?来看下面的例子。如果一个班有10个学生,要求输入每个学生的C语言成绩,然后将成绩依次输出。【案例3-1】输入并读取学生成绩。/不使用数组#include void main()int s1,s2,s3,s4,s5,s6,s7,s8,s9,s10;printf(请输入学生成绩n);scanf(%d%d%d%d%d%d%d%d%d%d,&s1,&s2,&s3,&s4,&s5,&s6,&s7,&s8,&s9,&s10);printf(输入的学生成绩为:n);printf(%d%d%d%d%
6、d%d%d%d%d%dn,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10);程序中定义了10个变量,分别用来存储录入的10个学生的成绩。上面的程序并没有什么太大的问题,但是假设需要记录的学生成绩数目为100个、1000个甚至上万个呢?显然不可能定义成千上万个变量来分别存储数据,这样不但需要使用特别多的变量名,在数据访问的时候也会很麻烦。数组的应用很好地解决了上述问题。用数组实现上述程序,源代码如下:/使用数组存储#include#define N 10void main()int sN;printf(请输入学生成绩n);int i;for(i=0;i=N-1;i+)scanf(%
7、d,&si);/读取数据并赋值给数组s的第i+1个元素 printf(输入的学生成绩为:n);for(i=0;i=N-1;i+)printf(%d,si);/输出数组s中第i+1个元素的值 printf(n);程序运行结果如下:请输入学生成绩68 94 31 75 83 92 85 60 77 88输入的学生成绩为:68 94 31 75 83 92 85 60 77 88 从上述分析可以看出,对于大量同类型且相关联的数据,数组是一种方便且简单的处理方式。使用预定义#define N 10的方式定义N的值,如果要输入的数据变成100个或者1000个,则只要将N的值改变即可,使用方便。通过面的案
8、例还可以看出,数组通常和循环结构一起使用。通过每次改变数组下标的形式,来依次处理数组中的每一个元素。相反的,不能直接使用数组名来实现对整个数组的访问,即下面的书写形式是错误的:scanf(%d,&s);printf(%d,s);下标的取值范围为0N-1。“s0”表示数组s中的第一个元素,“sN-1”表示数组中的最后一个即第N个元素。在C语言中,系统并不自动检测数组元素的下标是否越界,但是引用越界的元素可能访问违法数据,造成较严重的后果,所以编写程序时一定要注意数组下标不越界。在C语言中,数组作为一个整体,并不能参加数据运算,而只能对单个数据元素进行处理。3.1.2 一维数组的初始化定义数组时给
9、数组元素赋值,称为数组的初始化。和普通的数据类型一样,定义数组之后数组内是没有初始值的。除了在使用的时候给数组元素赋值之外,也可以在定义的时候对数组进行初始化。和赋值不同的是,数组元素的初始化是在编译的时候运行的,而数组元素的赋值是在运行过程中进行的。在编译时候进行初始化可以减少运行时间,提高运行效率。数组初始化的一般形式如下:类型说明符 数组名 常量表达式=初始值列表其中左边部分为数组的定义,右边部分为给出了数组元素的若干取值,即为各元素的初值,各数值之间用逗号隔开。数组初始化可以分为两种形式,分别为给所有元素赋初值和给部分元素赋初值。给所有元素赋初值的形式如下:int a5=1,2,3,4
10、,5;这个语句首先定义了一个长度为5的整型数组a,同时对a的元素取值进行初始化。初始化时根据里的值依次对每个数组元素进行赋值,赋值后结果为:a0=1,a1=2,a2=3,a3=4,a4=5。在给数组元素中所有值初始化的情况下,可以不指定数组的长度,系统会根据初始值的个数自动计算数组长度。但如果 内初值的个数不等于数组的长度,则数组长度信息不能省略。如上面的初始化可以写为:int a=1,2,3,4,5;给部分元素赋值形式如下:int a5=1,2,3;表示定义一个长度为5的数组,并对数组的前三个元素赋值。赋值后结果为:a0=1,a1=2,a2=3。而后面的元素自动赋值为0。或者可以对数组中不连
11、续的元素赋值,此时不赋值的地方应写0。例如:int a5=0,2,0,3;赋值结果为a0=0,a1=2,a2=0,a3=3,a4=0。nt a5=0,0,0,1,2;赋值结果为:a0=0,a1=0,a2=0,a3=1,a4=2。但是下面的赋值形式是错误的:int a5=1,2,3,4;在数组初始化时还应该注意下面几点:不能对整个数组进行初始化,而应对数组中的每个元素依次进行初始化。如下面的形式是错误的:int a5=1;初始化时初始值的个数可以小于数组的长度,但是不能超出数组的长度。数组初始化之后还可以在后续的操作过程中对元素值进行修改【案例3-2】定义一维数组,赋初值为1,3,5,7,9并输
12、出该数组。#include void main()printf(数组a为:n);int a5=1,3,5,7,9;int i;for(i=0;i5;i+)printf(%dt,ai);printf(n);程序定义一个长度为5的整型数组a,并对其赋初值。程序运行结果如下:数组a为:1 3 5 7 93.1.3 一维数组的使用一维数组的使用非常广泛,在很多场合都需要将待处理的数据用一维数组的形式存储。其中最常见的应用为数据遍历、查找、排序等【案例3-3】读取学生成绩,并计算成绩最高分和最低分。/求学生成绩最高分和最低分#include#define N 10void main()int score
13、N;/存储学生成绩信息 int max,min;/分别存储最高成绩和最低成绩 int i;printf(请依次输入10个学生的成绩n);for(i=0;iN;i+)scanf(%d,&scorei);max=score0;min=score0;for(i=0;imax)max=scorei;/依次比较求对高成绩 if(scoreimin)min=scorei;/依次比较求最低成绩 printf(输入的学生成绩为:n);for(i=0;iN;i+)printf(%d,scorei);printf(n其中最高成绩为%d,最低成绩为%dn,max,min);程序运行结果如下:请依次输入10个学生的成
14、绩78 43 90 99 65 59 78 89 84 69输入的学生成绩为:78 43 90 99 65 59 78 89 84 69其中最高成绩为99,最低成绩为43上述程序中,依次读取学生成绩信息并存到数组中,以进行后续处理。在计算最大值时,首先假设score0为最大值,把score0的值赋给max。然后通过for循环,将max与score数组中的每一个值即score0score9进行比较,若比max大,则将该下标变量对应的数组元素的值赋给max,否则继续比较。在对数组中所有元素都比较一轮之后,max为数组中的最大值。最低分的求法相同。求成绩最高分的关键为将max 与数组中的每一个元素进
15、行比较,最终得到整个数组中元素的最大值。这种处理方法,即读取数组中每一个元素,对其值根据应用进行不同的处理,称为数组的遍历。数组遍历一般用于求数组中最大最小值、平均值、读取数组所有元素值、对数组中所有元素进行处理等。数组的遍历一般采用for 循环的方式,通过数组下标的改变,依次对数组中的每一个元素进行处理【案例3-4】查找数据。查询数据是数组中常用的一个操作。典型的数据查找的方法为顺序查找,即当确定要查找的数据时,将该数据依次和数组中的第0个数据一直到最后一个数据进行匹配,若找到相同的数据,则查找成功;若查找成功后数组中还有后续其他元素,则跳过后续元素,无须对其处理;若查找到最后一个数据元素后
16、仍为找到要查找的数据,则查找失败。顺序查找的代码实现如下:/顺序查找#include#define N 10void main()int aN;int i,x;printf(请依次输入%d个正整数:n,N);for(i=0;iN;i+)scanf(%d,&ai);printf(请输入要查找的数据:n);scanf(%d,&x);for(i=0;iamin:在amin和alast 范围内继续查找。(3)xlast 为止。【案例3-5】二分查找法。/二分查找#include#define N 10void main()int aN;int i,x;int first,last,min;printf
17、(请输入%d个按从小到大顺序排列的正整数:n,N);for(i=0;iN;i+)scanf(%d,&ai);printf(请输入要查找的数据:n);scanf(%d,&x);first=1;last=N;while(firstamin)first=min+1;else last=min-1;if(firstlast)printf(查找失败n);程序运行结果如下:请输入10个按从小到大顺序排列的正整数:4 7 12 18 21 26 29 32 45 83请输入要查找的数据:21查找成功!21为数组中第5个数二分法要求所输入的数据需按正确的顺序输入,若不满足此要求则会发生查找错误,如:请输入10
18、个按从小到大顺序排列的正整数:3 42 51 23 5 9 23 12 19 10请输入要查找的数据:12查找失败要解决这一问题,可以在读取用户输入的数据的时候进行检查,看输入是否合法,如可将读取数据部分换成如下代码:int tmp=0;for(i=0;iai)printf(输出数据错误!程序结束!n);return;else tmp=ai;这时程序运行结果如下:请输入10个按从小到大顺序排列的正整数:3 5 4输出数据错误!程序结束!注意,对于大部分程序来说,输入数据检查都是必要的。如果对输入的数据不做任何规范和限制,如在需要输入整数时输入字符、在需要输入正数时输入负数、没有按规定的要求如按
19、序输入数据等,都会对程序造成较大的影响。所以,在读取数据时对数据类型和大小等进行检查,看是否满足程序要求,这是很必要的。注意,对于大部分程序来说,输入数据检查都是必要的。如果对输入的数据不做任何规范和限制,如在需要输入整数时输入字符、在需要输入正数时输入负数、没有按规定的要求如按序输入数据等,都会对程序造成较大的影响。所以,在读取数据时对数据类型和大小等进行检查,看是否满足程序要求,这是很必要的。使用二分法查找数据,如上例中有10个数据,则需要最多比较3次即可查找成功或确定要查找的数据不在数组内,顺序查找则需要平均5次比较才可查找完毕。但是数组长度N 为100、1000、10000的时候呢?在
20、处理大量数据时,二分法所需要的比较次数远远小于顺序查找法,程序效率较高。但是二分法的缺点是所处理的数组元素必须是已排序的。二分法的思想为每次把数组分为两部分,以排除法的形式逐渐缩小查找范围。那么是否每次都可以将数组分成三等分呢?此时查找效率如何?读者可尝试实现“三分法”,并分析查找结束时的平均比较次数以及在数据量非常大时和二分法比较哪个效率更高。数组的另外一个重要的应用为数组元素排序。下面先介绍一种最简单的排序算法,即选择排序。选择排序的思想为:每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。即首先从数组中选择一个最大的元素,
21、将该元素和数组的最后一个位置N 的元素交换,然后再从前N-1个元素中选出最大的,和N-1位置的元素交换,重复这个过程,直到整个数组完成排序为止。例如对一个长度为5的待排序数组:初始数组为5 9 2 6 1首先遍历该数组,选出最大的元素放在最后的位置,一次选择后结果如下:第一次选择后为5 1 2 6 9重复上述过程,直到排序结束。每次选择后结果分别如下:第二次选择后为5 1 2 6 9第三次选择后为2 1 5 6 9第四次选择后为1 2 5 6 9选择排序的代码实现如下实例3-6所示。【案例3-6】选择排序。/选择排序#include#define N 10void main()int aN;i
22、nt i,j,tmp;int max;/记录数组中元素最大值所在的下标 printf(请输入%d个待排序的正整数:n,N);for(i=0;i=0;i-)max=i;/选择最大值 for(j=0;jamax)max=j;if(max!=i)/交换数据 tmp=ai;ai=amax;amax=tmp;printf(排序后的数组为:n);for(i=0;iN;i+)printf(%d,ai);printf(n);程序运行结果如下:请输入10个待排序的正整数:32 16 9 21 56 83 26 5 19 13排序后的数组为:5 9 13 16 19 21 26 32 56 83对于一个数组长度为
23、N的数组,要完成排序则需要对数组进行N 次选择,每次选择都需要对数组进行一次遍历过程。另外一种常用的排序方法为冒泡排序。冒泡排序的基本概念是:依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。至此第一趟结束,将最大的数放到了最后。在第二趟:仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再小于第2个数),将小数放前,大数放后,一直比较到倒数第二个数(倒数第一的位置上已经是最大的),第二趟结束,在倒数第二的位
24、置上得到一个新的最大数(其实在整个数列中是第二大的数)。如此下去,重复以上过程,直至最终完成排序。例如有一个长度为5的数组:初始数组为:5 9 2 6 第一次冒泡时,首先比较前两个数5和9,顺序正确,继续比较9和2,将9和2互换,然后继续比较9和6,直到比较到最后两个数为止。第一次冒泡后:5 2 6 1 9重复上述过程,直到完成排序为止。第二次冒泡后:2 5 1 6 9第三次冒泡后:2 1 5 6 9第四次冒泡后:1 2 5 6 9对于一个数组长度为N 的数组,要完成排序则需要对数组进行N-1次冒泡操作,每次冒泡过程都需要对数组进行一次遍历。可以发现,对下面的数组进行冒泡排序:初始数组为9 2
25、 3 5 7 第一次冒泡后:2 3 5 7 9 这时数组已经排序好。后续的冒泡过程中数组元素顺序不再发生改变,即后续的第二次、第三次和第四次冒泡结果都和第二次相同,也就是说后续的操作时不必要的。可以在程序中设计,如果发现在一次冒泡中数组元素顺序完全不变,则说明数组已经排序好,可以终止操作。请尝试自己编写冒泡排序算法。3.1.4 任务实现1问题描述为了更好地查看和分析学生信息,通常需要对学生成绩进行排序。要求对班里20名同学的成绩进行排序,排序后的成绩按从高到低的顺序排列。2要点解析首先依次读取学生成绩信息,将学生成绩以数组的形式存储。然后在数组内对学生成绩进行排序,并给出最高成绩和最低成绩。排
26、序算法可以选择使用已学过的选择排序和冒泡排序两种方式。选择排序的排序过程为:(1)遍历数组,选出数组中元素的最小值,将这个元素与数组中最后一个位置N的元素交换,最后一个元素为已排序的,前面N-1个元素是未排序的。(2)对前面未排序部分的元素进行遍历,选出其中的最小值,将其放在已排序部分的第一个位置。(3)重复上述过程,共经N-1次选择后,排序结束。冒泡排序的排序过程为:(1)比较第一个数和第二个数,如果顺序不正确则交换,然后比较第二个和第三个数,依次类推,直到完成一轮冒泡。第一次冒泡结束后,数组中的最大值应在最后一个位置。(2)对前N-1个数组元素继续进行冒泡操作。(3)重复上述过程,直到排序
27、结束。3程序实现用选择排序法实现该程序,源代码如下:/选择排序#include#define N 20void main()int scoreN;int i,j,tmp;int min;/记录数组中元素最小值所在的下标 printf(请输入%d个学生的成绩:n,N);for(i=0;i=0;i-)min=i;/选择最大值 for(j=0;ji;j+)if(scorejscoremin)min=j;if(min!=i)/交换数据 tmp=scorei;scorei=scoremin;scoremin=tmp;printf(学生成绩从高到低顺序为:n);for(i=0;iN;i+)printf(%
28、d,scorei);printf(n最高成绩为%dn,score0);printf(最低成绩为%dn,scoreN-1);程序运行结果如下:请输入20个学生的成绩:77 63 94 84 82 93 99 58 64 6673 78 82 90 36 96 81 75 77 69学生成绩从高到低顺序为:99 96 94 93 90 84 82 82 81 7877 77 75 73 69 66 64 63 58 36最高成绩为99最低成绩为36用冒泡排序实现该程序,源代码如下:/冒泡排序#include#define N 20void main()int scoreN;int i,j,tmp;
29、int change;/用来标记一次冒泡中是否有元素位置变化 printf(请输入%d个学生的成绩:n,N);for(i=0;iN;i+)scanf(%d,&scorei);for(i=0;iN-1;i+)change=0;for(j=0;jN-1-i;j+)if(scorejscorej+1)tmp=scorej;scorej=scorej+1;scorej+1=tmp;change=1;if(change=0)break;printf(学生成绩从高到低顺序为:n);for(i=0;iN;i+)printf(%d,scorei);printf(n最高成绩为%dn,score0);printf
30、(最低成绩为%dn,scoreN-1);程序运行结果如下:请输入20个学生的成绩:77 63 94 84 82 93 99 58 64 6673 78 82 90 36 96 81 75 77 69学生成绩从高到低顺序为:99 96 94 93 90 84 82 82 81 78 77 77 75 73 69 66 64 63 58 36最高成绩为99最低成绩为36任务3.2 学生信息管理系统之成绩添加和查找任务目标了解二维数组的概念,二维数组的适用范围和特点。了解二维数组的定义、初始化以及元素引用方法。了解二维数组使用过程中应注意的问题。可以使用二维数组实现简单的应用。使用二维数组实现学生成
31、绩的添加和查找任务。3.2.1 二维数组的定义和引用具有两个下标的数组称为二维数组。二维数组和矩阵的形式相对应。二维数组定义的一般形式为:类型说明符 数组名 常量表达式1 常量表达式2其中类型说明符和数组名的定义和一维数组中的相同。常量表达式1表示一维下标的长度,常量表达式2表示二维下标的长度。例如:int a34;定义了一个3行4列的数组,数组名为a。二维数组的元素也称为双下标变量,其引用形式为:数组名下标1下标2其中,下标应为整型变量或者整型表达式。例如:a12表示a数组中第1行第2列的元素。数组a34中共有12个元素,分别为:a00、a01、a02、a03a10、a11、a12、a13a
32、20、a21、a22、a23二维数组在概念上是二维的,即下标在两个方向上变化。但是在实际存放时二维数组的元素是连续编址的,也就是说存储单元是按照一维线性排列的。在一维存储器中存放二维数组有两种存放方式:一种是按行存放,即先存完第一行再存第二行;另一种是按列存放,即先存第一列然后再存第二列。在C语言中,二维数组是按行排列的。可以将二维数组a看成一个一维数组,数组中元素分别为:a0、a1、a2,但是数组元素不是简单的数据类型,而是含有4个元素的一维数组。【案例3-7】学生信息存储。编写程序,实现读取学生的学号和成绩信息,并输出。程序源代码如下:#include#define N 5void mai
33、n()int inf2N;int i,j;printf(请依次输入%d个学生的学号和成绩n,N);for(i=0;iN;i+)scanf(%d,&inf0i);scanf(%d,&inf1i);printf(学生信息如下:n);printf(学号 成绩n);for(i=0;iN;i+)for(j=0;j2;j+)printf(%d ,infji);printf(n);程序运行结果如下:请依次输入5个学生的学号和成绩1 782 943 684 815 60学生信息如下:学号 成绩1 782 943 684 815 60程序中使用双重循环,在内循环中读取一个同学的学号和成绩,外循环中依次读取每个同
34、学的信息。可以尝试用一维数组实现上述程序,并比较二维数组和一维数组使用范围。3.2.2 二维数组的初始化二维数组的初始化有两种基本形式,分别为:(1)按行分段赋值,其基本形式为:类型说明符 数组名行常量表达式列常量表达式=第0行初始值,第一行初始值第n行初始值其中,等号左边的部分为二维数组的定义,等号右边依次分段给出各行元素的初始值,各段之间用逗号隔开,即将第一段中的数值依次赋值给第一行各元素。第二段中的数值依次赋值给第二行各元素,依次类推,直到初始化完毕。例如:int a23=1,2,3,4,5,6;其对应的初始矩阵a为:(2)按列顺序赋值,其基本形式为:类型说明符 数组名行常量表达式列常量
35、表达式=初始值其中,等号左边的部分为二维数组的定义,等号右边部分内的初始值连续依次地给出各元素的初始值,各元素之间用逗号隔开。即,按二维数组元素的存放顺序,将初始值列表中的数据依次赋值给各个元素,在C语言中,顺序为按行优先顺序。例如:int a32=1,2,3,4,5,6;等价于:int a32=1,2,3,4,5,6;在二维数组初始化过程中要注意:(1)初始化时允许初始值个数小于数组的长度。此时:若按顺序赋值法初始化,可以只给出数组的前半部分元素的初值。若按分段赋值法初始化,可以只给出每段的前半部分元素的初值。未赋值部分元素自动赋值为0。例如:int a23=1,2,3,4;对于二维数组为:
36、int a23=12,3;对于二维数组为:(2)初始化时如对所有的元素赋值,则定义时可以不指定数组第一维的长度,系统会根据初始值个数和第二位长度自动计算第二位长度;如果所赋初值的个数不等于所定义的数组的长度,则不可省略。例如:int a32=1,2,3,4,5,6;可以写成:int a 2=1,2,3,4,5,6;(3)初始值的个数不能大于数组的长度。例如:错误:int a23=1,2,3,4,5,6,7,8;错误:int a23=1,2,3,45,67,8;(4)初始值应和数组的第一维数和第二维数分别对应。例如:错误:int a23=1,2,3,4,5,6;(5)一般循环语句对二维数组进行赋
37、值和输出,并常采用嵌套循环的方式。例如:int a56;for(int i=0;i5;i+)for(int j=0;j6;j+)scanf(%d,&aij);这里外层循环对于二维数组的行,每次循环对于数组的一行;内层循环对于二维数组的一列。【案例3-8】已知5名同学的三门课成绩,提供查询功能,可以查选任意同学的任意门课成绩。#include#define N 5void main()int score35=78,90,84,67,90,65,78,83,91,73,92,75,61,59,76;int n,k;printf(输入要查选的学生学号,范围为15:);scanf(%d,&n);pri
38、ntf(输入要查询的课程,1为语文,2为数学,3为英语:);scanf(%d,&k);printf(成绩为%dn,scorek-1n-1);程序运行结果如下:输入要查选的学生学号,范围为15:4输入要查询的课程,1为语文,2为数学,3为英语:3成绩为593.2.3 二维数组的使用二维数组的使用范围和矩阵类似,主要用于同一个对象含有多个相同性质和数据类型的参数时,如一个学生有多门成绩,每门课成绩的数据类型都相同。【案例3-9】编写代码实现矩阵的转置。/矩阵的转置#include void main()int a45;int i,j;printf(请输入一个4行5列的矩阵,按行输入n);for(i
39、=0;i4;i+)for(j=0;j5;j+)scanf(%d,&aij);printf(转置后的矩阵为:n);for(i=0;i5;i+)for(j=0;j4;j+)printf(%dt,aji);printf(n);程序运行结果如下:请输入一个4行5列的矩阵,按行输入5 8 1 6 29 0 4 6 37 5 0 4 63 9 6 0 1转置后的矩阵为:5 9 7 38 0 5 91 4 0 66 6 4 02 3 6 1使用二维数组还可以实现其他类似的矩阵操作,如矩阵的加减法、矩阵乘法等。【案例3-10】矩阵的加法。/矩阵的加法#include void main()int a45,b4
40、5;int c45;int i,j;printf(请输入第一个4行5列的矩阵,按行输入n);for(i=0;i4;i+)for(j=0;j5;j+)scanf(%d,&aij);printf(请输入第二个4行5列的矩阵,按行输入n);for(i=0;i4;i+)for(j=0;j5;j+)scanf(%d,&bij);for(i=0;i4;i+)for(j=0;j5;j+)cij=aij+bij;printf(矩阵之和为:n);for(i=0;i4;i+)for(j=0;j5;j+)printf(%dt,cij);printf(n);程序运行结果如下:请输入第一个4行5列的矩阵,按行输入6 9
41、 0 2 38 0 1 6 47 9 3 1 54 6 0 3 2请输入第二个4行5列的矩阵,按行输入7 0 5 0 10 2 0 3 58 0 2 0 69 1 0 0 2矩阵之和为:13 9 5 2 48 2 1 9 915 9 5 1 1113 7 0 3 4【案例3-11】读取五位同学三门【案例3-11】读取五位同学三门课的成绩,并计算每门课的平均成绩。#include#define N 5void main()int score3N;int avg3;int sum;int i,j;printf(请依次输入每门课%d个学生的成绩:n,N);for(i=0;i3;i+)printf(第
42、%d门课:,i+1);sum=0;for(j=0;jN;j+)scanf(%d,&scoreij);sum=sum+scoreij;avgi=sum/N;printf(学生信息如下:n);printf(学生t课程1t课程2t课程3n);for(i=0;iN;i+)printf(%d,i);for(j=0;j3;j+)printf(t%d,scoreji);printf(n);printf(平均t%dt%dt%dn,avg0,avg1,avg2);程序运行结果如下:请依次输入每门课5个学生的成绩:第1门课:78 90 76 82 67第2门课:80 85 77 92 71第3门课:83 91 6
43、9 96 82学生信息如下:学生 课程1 课程2 课程3 0 78 80 83 1 90 85 91 2 76 77 69 3 82 92 96 4 67 71 82平均 78 81 84注意,输入的时候是按行读入,每次读取一门课5个学生的成绩,而在输出的时候是按列输出的,每次输出一个学生的成绩。通过比较可以发现,使用一维数组处理学生信息时只能管理学生一门课的成绩,如存在多门课时,则需要多个一维数组来处理,而是用二维数组,则可以一次管理多门课程成绩。3.2.4 任务实现1问题描述编写程序,实现简单的学生成绩添加和查询功能。假定第一次输入的学生成绩学号为1,第二次输入的学生学号为2,依次类推。每
44、个学生有三门功课,需要记录每门课的成绩,以及计算学生的平均成绩。程序应实现以下功能:(1)录入学生考试成绩。(2)打印这次考试中每个学生的成绩。(3)根据学号查询学生的成绩。(4)可以继续添加学生成绩信息。2要点解析定义一个二维数组,一行表示一个学生的成绩,每列表示一门功课的成绩。首先要提供一个菜单供用户选择功能,再根据用户选择的功能来完成相应的功能。因为要实现添加学生成绩功能,事先并不知道学生的个数,所以不能定义明确的二维数组。可以定义一个较大的二维数组,如规定学生成绩不超过50个,则可定义一个50行的二维数组,并可以逐一添加新的学生成绩信息。由于不能动态地定义数组的长度,因而采用定义一个最
45、大长度数组的方式解决事先不确定数组长度的问题,但是这样当数据信息较少时,会浪费较多的存储空间。3程序实现#include#define N 50void main()int score503=78,90,84,67,90,65,78,83,91,73,92,75,61,59,76;int avg50=84,74,84,80,65;int i,j;int choose;int num=5,k;while(1)printf(nn);printf(t|-STUDENT-|n);printf(t|t 1.添加学生成绩|n);printf(t|t 2.根据学号查找学生成绩|n);printf(t|t 3
46、.显示学生成绩表|n);printf(t|t 0.退出系统|n);printf(t|-|nn);printf(choose(03):);scanf(%d,&choose);switch(choose)case 0:printf(退出系统n);return;break;case 1:printf(请依次输入第%d名学生三门课的成绩:n,num+1);for(i=0;i3;i+)scanf(%d,&scorenumi);avgnum=(scorenum0+scorenum1+scorenum2)/3;num+;printf(添加成功n);break;case 2:printf(请输出要查询的学生学
47、号:);scanf(%d,&k);printf(学号t课程1t课程2t课程3t平均n);printf(%dt,k);for(i=0;i3;i+)printf(%dt,scorek-1i);printf(%dn,avgk-1);break;case 3:printf(学号t课程1t课程2t课程3t平均n);for(i=0;i50;i+)if(avgi=0)break;else printf(%dt,i+1);for(j=0;j3;j+)printf(%dt,scoreij);printf(%dn,avgi);break;程序运行结果如下:|-STUDENT-|1.添加学生成绩|2.根据学号查找学
48、生成绩|3.显示学生成绩表|0.退出系统|-|choose(03):3学号 课程1 课程2 课程3 平均1 78 90 84 842 67 90 65 743 78 83 91 844 73 92 75 805 61 59 76 65|-STUDENT-|1.添加学生成绩|2.根据学号查找学生成绩|3.显示学生成绩表|0.退出系统|-|choose(03):1请依次输入第6名学生三门课的成绩:89 93 76添加成功|-STUDENT-|1.添加学生成绩|2.根据学号查找学生成绩|3.显示学生成绩表|0.退出系统|-|choose(03):3学号 课程1 课程2 课程3 平均1 78 90 8
49、4 842 67 90 65 743 78 83 91 844 73 92 75 805 61 59 76 656 89 93 76 86|-STUDENT-|1.添加学生成绩|2.根据学号查找学生成绩|3.显示学生成绩表|0.退出系统|-|choose(03):2请输出要查询的学生学号:4学号 课程1 课程2 课程3 平均4 73 92 75 80|-STUDENT-|1.添加学生成绩|2.根据学号查找学生成绩|3.显示学生成绩表|0.退出系统|-|choose(03):0退出系统任务3.3 学生信息管理系统之姓名排序任务目标初步认识字符数组。掌握字符数组的概念、定义、引用和初始化方法。掌握
50、字符数组的输入和输出方法。掌握常用的字符数组处理函数。完成学生姓名排序程序。3.3.1 字符数组当数组中元素的数据类型为字符型时,称这种数组为字符数组。一维字符数组的定义形式为:char 数组名 常量表达式;例如:“char s3;”表示定义一个数组名为s的一维字符数组,数组中包含3个元素,每一个元素可以存放一个字符。一维字符数组的引用格式类似于整型数组,其形式如下:数组名下标;例如上面例子中定义的长度为3的一维字符数组中的三个字符元素分别为:s0、s1、s2。下标同样是从0开始。在C 语言中用字符数组来存放字符串。使用字符串时即定义一个字符数组,将字符数组中的元素连起来形成一个字符串。字符数