Presentation is loading. Please wait.

Presentation is loading. Please wait.

C语言程序设计 课程 第5章 数组 主讲:李祥 博士、副教授 单位:软件学院软件工程系.

Similar presentations


Presentation on theme: "C语言程序设计 课程 第5章 数组 主讲:李祥 博士、副教授 单位:软件学院软件工程系."— Presentation transcript:

1 C语言程序设计 课程 第5章 数组 主讲:李祥 博士、副教授 单位:软件学院软件工程系

2 预习检查 什么是数组 如何访问数组元素 答案: 1、按 顺序存储 的 同类型数据 集合 2、数组元素是通过下标来访问的,如 A[8]

3 学习目标 重点 了解 掌握 一维数组的定义、 初始化和引用 二维数组的定义、 1 3 什么是数组 2 数组作为函数参数

4 5.1 一维数组 案例导入: 最值问题可谓是经典中的经典了,说它是每个程序员都该掌握的知 识一点也不为过。本案例要求先输入数组的大小和各个数组元素,然 后求出数组中的最大值和最小值以及它们所在的位置,最后把它们依 次输出到屏幕上。

5 5.1 一维数组 本案例是应用一维数组的典型案例。C语言中规定,只能逐个引用数组中的元素,而不能引用整个数组。所以在对数组元素进行判断时,只能通过循环对数组元素逐个引用,通过判断每一个元素值的大小,找出其中最大和最小的元素。 为了更好地完成此案例,请先认真学习一维数组的相关知识。

6 5.1 一维数组 一维数组的定义与初始化 一维数组指的是只有一个下标的数组,它用来表示一组具有相同类型的 数据。
在C语言中,一维数组的定义方式如下所示: 元素类型 数组长度 类型说明符 数组名[常量表达式];

7 5.1 一维数组 一维数组的定义与初始化 完成数组的定义后,只是对数组中的元素开辟了一块内存空间。这时,如果想使用数组操作数据,还需要对数组进行初始化。数组初始化的常见的方式有三种,具体如下: 第1种 直接对数组中的所有元素赋值 int i[5]={1,2,3,4,5}; 第2种 只对数组中的一部分元素赋值 int i[5]={1,2,3}; 第3种 对数组全部元素赋值但不指定长度 int i[]={1,2,3,4};

8 5.1 一维数组 一维数组的定义与初始化 1、数组的下标是用方括号括起来,不是圆括号。 2、数组的命名同变量的命名规则相同。
3、数组定义中,常量表达式的值可以是符号常量。

9 5.1 一维数组 一维数组的引用 在程序中,经常需要访问数组中的一些元素,这时可以通过数组名和下标来引 用数组中的元素。
一维数组元素的引用方式如下所示: 数组名[下标];

10 5.1 一维数组 一维数组的引用 数组的下标都有一个范围,即“0~[数组长度-1]” 假设数组的长度为6,其下标范围为0~5。当访问数组中的元素时,下标不能超出这个范围,否则程序会报错。

11 5.1 一维数组 案例设计 1 2 3 先输入数组的大小; 利用for循环依次输入数组中的各个元素;
分别求出数组元素中的最大值和最小值,并输出到屏幕上。

12 5.1 一维数组 案例代码 #include <stdio.h> int main()
{ int a[50]; //定义数组存放元素 int MAX, MIN;//定义最大值和最小值变量 int i, n; int j = 0; int k = 0; printf("Please input the size of array:\n"); scanf("%d", &n);//输入数组的元素个数 printf("Please input the elements of the array one by one:\n"); for (i = 0; i < n; i++)//依次输入数组中的元素 scanf("%d", &a[i]); MIN = a[0];//数组首元素默认为最小值 for (i = 1; i < n; i++)//找出数组元素中的最小值 if (a[i] < MIN)//如果有比MIN小的元素 MIN = a[i];//就把此元素赋值给MIN j = i + 1; //将存储最小值的位置赋给j } MAX = a[0]; //数组首元素默认为最大值 for (i = 1; i < n; i++)//找出数组元素中的最大值 { if (a[i] > MAX)//如果有比MAX大的元素 MAX = a[i];//就把此元素赋值给MAX k = i + 1; //将存储最大值的位置赋给k } printf(“The position of the MIN is:%d\n”, j); //输出最小值所在的位置 printf("The MIN is:%d\n", MIN);printf("The position of MAX is:%d\n", k); //输出最大值所在的位置 printf("The MAX is:%d\n", MAX); return 0;

13 脚下留心 数组的非法操作 1、用一个已经初始化的数组对另一个数组赋值 int x[3] = {7,8,9}; int y[3];
y = x; 2、对数组进行整体输入输出 int x[3] = {7,8,9}; printf("%d",x);

14 脚下留心 数组的非法操作 3、数组与数组不能进行比较 int x[3] = {1,2,3}; int y[3] = {4,5,6};
if(x < y){…} 4、数组与数组不能进行运算 int x[5] = {5,6,7,8,9}; int y[5] = {2,3,4,5,6}; x+=y;

15 5.1 一维数组 案例应用: 说到投票,想必大家都不会感到陌生。从小学竞选班长开始就有投 票这种形式了。准确地说,投票是选举或表决议案的一种方式,投票 者将所要选的人的姓名写在票上,投入票箱。可以填写投票人自己的 姓名,也可以不写,不写则成为不记名投票。 投票在某种程度上反映 了大家的意愿,是一种相对公平的处理问题的方法。 当然,我们在这里不会涉及到表决议案,只是要投票选出一位学生 会主席。 案例要求用编程的方法实现投票的过程。已知有三位候选人要参加 竞选,先输入参与投票的人数和投票的内容,最终统计出三位候选人 的最终得票,然后根据每个人总票数的高低来决定谁当选学生会主席。

16 5.1 一维数组 此案例同案例1一样都是应用一维数组的典型案例,请根据刚刚学过的知识,认真学习此案例,强化一维数组的知识,为将来学习二维数组打下扎实的基础。

17 5.1 一维数组 案例设计 1 2 3 4 5 定义存储投票内容的数组变量,及存储三位候选人的变量;
输入参与投票的人数和投票的内容,将内容储存到数组中; 3 对存储到数组中的元素进行判断,统计出各候选人的票数; 4 根据三位各自的票数,判断胜利者是谁; 5 最终将胜出者输出到屏幕上。

18 5.1 一维数组 案例关键代码 //请输入投票者(选民)的数量 int i, n, array[50];
printf("Please input the number of electorates:(<50)\n"); scanf("%d", &n);//请输入1或2或3来支持不同的选举人 printf("Please input 1 or 2 or 3 to support the electors:\n"); for (i = 0; i < n; i++) scanf("%d", &array[i]); //输入所有投票的内容 for (i = 0; i < n; i++)//统计每个人的的票数 { if (array[i] == 1) a1++;//如果给1号投票则a1自加1 else if (array[i] == 2) a2++; //如果给2号投票则a2自加1 else if (array[i] == 3) a3++; //如果给3号投票则a3自加1 } printf("a1: %d, a2: %d, a3: %d\n", a1, a2, a3); //得票情况一览 int i, n, array[50]; //分别定义三位候选人 int a1 = 0; int a2 = 0; int a3 = 0;

19 5.2 二维数组 所谓魔方阵,古代又称为“纵横图”,就是指由自然数组成的方阵。 什么是方阵呢?若一个矩阵是由n个横列与n个纵行所构成,共有n×n 个小方格,则称这个方阵是一个n阶方阵。方阵中的每个元素都不相等, 且每行和每列以及主副对角线上的各元素之和都相等。 案例要求编程实现一个5行5列的魔方阵。

20 5.2 二维数组 魔方阵是5行5列的,如果用刚刚学会的一维数组解决是很麻烦的,所以我们在此引入一个新的概念——二维数组。把魔方阵存储在一个二维数组中,可以让我们更方便地解决此问题。接下来请认真学习二维数组的知识。

21 5.2 二维数组 二维数组的定义与初始化 二维数组的定义方式与一维数组类似,其语法格式如下: 行下标 列下标
类型说明符 数组名[常量表达式1][常量表达式2];

22 5.2 二维数组 二维数组的定义与初始化 完成二维数组的定义后,需要对二维数组进行初始化,初始化二维数组 的方式有四种,具体如下: 第1种
按行给二维数组赋初值 int a[2][3] = {{1,2,3},{4,5,6}}; 第2种 将所有的数组元素按行顺序写在一个大括号内 int a[2][3] = {1,2,3,4,5,6}; 第3种 对部分数组元素赋初值 int b[3][4] = {{1},{4,3},{2,1,2}}; 第4种 对全部数组元素置初值,则第一个下标可省略 int a[ ][3] = {1,2,3,4,5,6};

23 5.2 二维数组 二维数组的引用 二维数组的引用方式同一维数组的引用方式一样,也是通过数组名和下 标的方式来引用数组元素,其语法格式如下:
数组名[下标][下标];

24 5.2 二维数组 案例设计 1 2 3 4 案例代码(详见教材代码实现)
假设当前数的下标为(x,y),则下一个数的放置位置为当前位置的右上方; 2 如果当前数在第1行,则将下一个数放在最后一行的下一列上; 3 如果当前数在最后一列上,则将下一个数放在上一行的第一列上; 4 如果下一个数的位置已经被占用,则下一个数直接放在当前位置的正下方。 案例代码(详见教材代码实现)

25 多学一招 多维数组 在计算机中,除一维数组和二维数组外,还有三维,四维,……等多维数组,它们用在某些特定程序开发中,多维数组的定义与二维数组类似,其语法格式具体如下: 数组类型修饰符 数组名 [n1][n2]…[nn];

26 5.3 数组作为函数参数 转眼又迎来了一年一度的校园十大歌手比赛,选手们个个积极应战, 奋力抢夺冠军的宝座。如今最终得分已经揭晓,但是并没有按照升序 顺序排列好,为了知晓冠军、亚季和季军的得主,案例要求通过编程 将拼到最后的这十位歌手的得分从低到高进行排序。

27 5.3 数组作为函数参数 首先将每位歌手的得分存储到一维数组中,其次构建一个排序函数,使用该函数实现对一维数组的排序,因此需要将一维数组作为函数参数传入函数。 排序算法有很多种,在这里我们选择使用冒泡排序算法进行排序。冒泡排序算法是非常优秀的排序算法,通过本案例的学习,读者应尽量掌握该算法的实现原理。同时读者需要了解如何将一维数组作为函数参数传递到函数中。下面先来讲解这两个相关知识。

28 5.3 数组作为函数参数 数组作为函数参数 在程序中,为了方便对数组的操作,经常会定义一些操作数组的功能函 数,这些函数往往会将数组作为函数参数。 在数组作为函数参数时,必须要保证形参与实参的数组是相同的类型, 且有明确的数组说明,如数组维数、数组大小等。 数组作为 函数参数 一维数组大小为5 func(int arr[5]); func(int arr[], int n); 一维数组 数组大小为n

29 5.3 数组作为函数参数 冒泡排序 在冒泡排序的过程中,不断地比较数组中相邻的两个元素,较小者向上浮, 较大者往下沉,整个过程和水中气泡上升的原理相似,接下来,分步骤讲 解冒泡排序的整个过程,具体如下:

30 5.3 数组作为函数参数 冒泡排序 第1步 从第一个元素开始,将相邻的两个元素依次进行比较,直到最后两个元素完成比较。如果前一个元素比后一个元素大,则交换它们的位置。整个过程完成后,数组中最后一个元素自然就是最大值。 第2步 除了最后一个元素,将剩余的元素继续进行两两比较,过程与第一步相似,这样就可以将数组中第二大的数放在倒数第二个位置。 第3步 依次类推,持续对越来越少的元素重复上面的步骤,直到没有任何一对元素需要比较为止。

31 5.3 数组作为函数参数 案例设计 1 2 3 4 5 自定义一个冒泡排序算法的函数,参数为数组名和数组大小;
在主函数中定义一个一维数组来存储各位歌手的得分; 3 使用for循环分别录入各位歌手的得分; 4 调用冒泡排序算法函数对得分进行排序; 5 使用for循环在屏幕上输出排序后的结果。

32 5.3 数组作为函数参数 案例代码 #include <stdio.h> //冒泡排序 int main()
void BubbleSort(int s[], int n)//函数参数:数组与数组大小 { int i, j, temp; for (i = 0; i < n - 1; i++) //从i=0开始,共进行n-1轮排序 {//每轮排序都使一个较大的值到达较大的位置 for (j = 0; j < n - i - 1; j++) //每轮两两比较的数据逐层递减 if (s[j] > s[j + 1])//符合条件则交换,将两个元素进行交换 temp = s[j]; s[j] = s[j + 1]; s[j + 1] = temp; } int main() { int i; //用于循环控制 int a[10];//定义一个数组a来储存歌手的得分 printf("Please input the final score of the ten singers:\n"); for (i = 0; i < 10; ++i) scanf("%d", &a[i]); //依次输入各个得分 BubbleSort(a, 10); //调用冒泡排序的函数 printf("After Quick Sort:\n"); printf("%d ", a[i]); //依次输出排序后的各个得分 printf("\n"); return 0; }

33 5.4 数组综合应用 1、打印输出杨辉三角 杨辉三角,又称贾宪三角形、帕斯卡三角形,是二项式系数在三角 形中的一种几何排列。案例要求通过编程在屏幕上打印出杨辉三角的 前10行。 其前10行样式如下所示。 1 1 1

34 5.4 数组综合应用 对杨辉三角的图形规律进行总结,结论如下: (1)第n行的数字有n项; (2)每行的端点数为1,最后一个数也为1;
(3)每个数等于它左上方和上方的两数之和; (4)每行数字左右对称,由1开始逐渐增大。

35 5.4 数组综合应用 案例设计 1 2 3 4 案例代码(详见教材代码实现) 先定义一个二维数组;
定义双重for循环,外层循环负责控制行数,内层循环负责控制列数; 3 根据规律给数组元素赋值; 4 最后用双重for循环将二维数组中的元素打印出来,即把杨辉三角输出到屏幕上。 案例代码(详见教材代码实现)

36 5.4 数组综合应用 2、找出兔子藏身之所 一只小兔子躲进了10个环形分布的洞中的一个。狼在第一个洞中 没有找到兔子,就隔一个洞,到第三个洞去找;也没有找到,就隔两 个洞,到第六个洞去找;以后每次多一个洞去找小兔子……这样下去, 如果一直找不到兔子,请问兔子可能在哪个洞中?

37 5.4 数组综合应用 如果将每个洞都定义为一个变量,那就需要定义10个同类型的变量,此时如果使用数组来存储这些变量,会非常方便。定义一个包含10个元素的数组分别表示10个洞,用穷举法来找兔子。由于是环形分布的洞,当计数大于10时,需要将计数与10取余,从而找到对应的洞;在查找的过程中,把已查找但未找到兔子的洞做上标记,剩下的就是兔子可能藏身的洞了。

38 5.4 数组综合应用 案例设计 用数组记录每个洞对应标记。在查找之前,将所有洞都标记为1,表示该洞尚未查找;查找的过程中,若正在查找的洞里没有兔子,将其标记为0。数组标记为1的洞是尚未被查找过的、兔子可能藏身的洞。所以步骤如下: 1 先设置数组中所有元素的初值为1; 2 然后用for循环穷举搜索,假设最大搜索次数为500次; 3 如果在洞中没有找到兔子,就把找过的洞置为0; 4 遍历数组中所有元素,如果其值仍为1,则兔子可能藏在这个洞中。 案例代码(详见教材代码实现)

39 5.4 数组综合应用 3、通过编程实现矩阵转置 案例要求 矩阵转置在数学上的定义为: 设A为m×n阶矩阵(即m行n列),第i 行第j 列的元素是a(i,j)。 定义A的转置为这样一个n×m阶矩阵B:满足B=a(j,i),即 b (i,j)=a (j,i) (B的第i行第j列元素是A的第j行第i列元素),记作AT=B。 简单的矩阵转置如下图所示:

40 5.4 数组综合应用 解决矩阵问题时通常都先把矩阵放在一个二维数组中,当矩阵发生变化时,二维数组中的对应元素也同样发生变化。
我们知道,如果要遍历二维数组中的每一个元素,可以使用循环结构。在这里使用双层for循环实现矩阵转置。

41 5.4 数组综合应用 案例设计 1 2 3 4 案例代码(详见教材代码实现) 先分别输入数组的行数和列数;
输入数组中的每个元素,元素个数为刚刚输入的行数与列数的乘积; 3 通过for循环进行转置; 4 最终将统计出的结果输出到屏幕上。 案例代码(详见教材代码实现)

42 5.4 数组综合应用 3、模拟双色球开奖 双色球是中国福利彩票目前最火的一种玩法。而彩票是以抽签给 奖方式进行筹款或敛财所发行的凭证,并非是赌博,每天都有上亿的 彩民关注着双色球的开奖结果。 其彩票投注区分为红色球号码区和蓝色球号码区,每注投注号码由 6个红色球和1个蓝色球号码组成。红色球号码从1~33中选择,蓝色球 号码从1~16中选择。每期开出的红色球号码不能重复,但是蓝色球可 以使红色球中的一个。 案例要求编写程序模拟双色球的开奖过程,由程序随机产生6个红 色球号码和1个蓝色球号码并把结果输出到屏幕上。

43 5.4 数组综合应用 由案例描述可知,显然需要用到第三章中学过的随机数知识。但是需要注意“每期开出的红色球号码不能重复”,而使用随机函数可能会产生重复的号码,因此在编程时需要判断新生成的红色球号码是否与已经生成了。如果号码与已生成的红色球号码重复了,则需要重新生成新的红色球号码。 可以使用for循环来实现随机生成6个不同红色球号码的功能,用数组保存生成的6个红色球号码,而且需要在for循环中每次都要判断是否出现了重复的号码。由于蓝色球号码只有一个,且允许与红色球号码重复,因此可以直接用随机函数生成。

44 5.4 数组综合应用 案例设计 1 2 3 4 先使用系统定时器的值作为随机数种子,为随机数的生成做好准备;
之后分别随机生成6个红色球号码和1个蓝色球号码; 3 用外层for循环生成6个红色球号码; 4 最后把红色球号码和蓝色球号码分别打印到屏幕上。

45 5.4 数组综合应用 #include <stdio.h> #include <stdlib.h>
#include <time.h> 5.4 数组综合应用 案例代码(详见教材代码实现) int main() { srand((unsigned int)time(NULL)); //使用系统定时器的值作为随机数种子 int i = 0; int j = 0; int temp; //定义一个临时变量,总来暂时保存随机数 int red[6];//定义red数组,保存随机生成的红色球号码 int blue; //定义blue整型变量,保存随机生成的蓝色球号码 for (i = 0; i < 6;)//随机生成6个红色球号码 temp = rand() % ; for (j = 0; j < i; j++) {//依次判断数组中的已生成红色球号码是否与新生成的号码相同 if (red[j] == temp)//如果相同,则重新生成新的红色球号码 break; //跳出内层for循环 } if (j == i) red[i] = temp;//将新生成的红色球号码保存在red数组中 i++;//增加红色球的数量 blue = rand() % ; //随机产生蓝色球号码 printf("Red : "); for (i = 0; i < 6; i++) { printf("%d ", red[i]);//依次输出数组中的红色球号码 } printf("\n"); printf("Blue : %d\n", blue); //输出蓝色球号码 return 0;

46 本章小结 本章首先对一维数组的定义、初始化、引用进行了详细的讲解,然后讲解了二维数组的相关知识及多维数组的定义方式,最后讲解了数组作为函数参数的用法。案例中涉及到了求最值、数列排序算法等方面的知识,灵活掌握这些基本知识有助于后面知识点的学习。


Download ppt "C语言程序设计 课程 第5章 数组 主讲:李祥 博士、副教授 单位:软件学院软件工程系."

Similar presentations


Ads by Google