[工学]第6章数组.ppt_第1页
[工学]第6章数组.ppt_第2页
[工学]第6章数组.ppt_第3页
[工学]第6章数组.ppt_第4页
[工学]第6章数组.ppt_第5页
已阅读5页,还剩71页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

2019/5/8,1,第6章 数组,本章主要教学内容,数组类型 向函数传递一维数组和二维数组 排序、查找、求最大最小值等常用算法 用字符数组存取字符串 使用字符串处理函数处理字符串,2019/5/8,2,为什么使用数组(Array)?,【例】要读入10人的成绩,然后求平均成绩 需定义10个不同变量,需要使用多个scanf() int score1,score2,score10; scanf(“%d“, ,保存大量同类型的相关数据,2019/5/8,3,数组的用处,保存大量同类型的相关数据 如矩阵运算,表格数据等,C的数据类型: 基本类(简单类)字符型/整型/实型/枚举型 构造类(组合类)数组/结构体/共用体 指针类 空类型(void),2019/5/8,4,基本类型单个出现的变量,每个变量可以代表一个确定的数据(变量值),且具有一定属性。 如 static int x,y; 但变量间不存在确定的相互关系。 构造类型由基本类型按一定规则组成。其中 数组:由一组有序数据(数组元素)组成。 每个元素:有相同类型,统一数组名; 用下标(index)确定其顺序;但可以取各自值。,关于变量,2019/5/8,5,数组的定义、引用和初始化,同变量一样,数组也必须“先定义,后使用” 定义内容: 数组名(同变量名:字母、下划线、数字;字母或下划线开头;长度32) 类型(存储属性/数据类型) 大小(维数/元素个数) 定义的一般形式: 类型 数组名常量表达式常量表达式,数组长度(数组元素最大个数),例: int a10,2019/5/8,6,说 明,a,a9,a8,a7,a1,a0,int a10; 定义一个有10个元素的数组,每个元素的类型均为int 使用a0、a1、a2、a9这样的形式访问每个元素。它们与普通变量没有任何区别 系统会在内存分配连续的10个int空间给此数组 数组下标可以是整型表达式 直接对a的访问,就是访问此数组的首地址,2019/5/8,7,数组长度必须是常量表达式常量或符号常量,其值必须为正,不能为变量。,注 意,数组大小最好用宏来定义,以适应未来可能的变化 #define SIZE 10 int aSIZE; 数组大小定义好后,将永远不变,元素编号从0开始,a0表示第1个元素,a9表示第10个元素(最后一个),2019/5/8,8,判断对错?,int n=5; int an;,#define N 5 int aN;,正确: int a10,b54; char name8,ch23; static float x8*2+1,table234; #define NUM 40; int aNUM,bNUM+2;,2019/5/8,9,数组的引用,数组的下标都是从0开始 对数组每个元素的使用与普通变量无异 可以用任意表达式作为下标,动态决定访问哪个元素 for (i=0; iSIZE; i+) ai = 2 * i; 下标越界是大忌! 使用大于最大下标的下标,将访问数组以外的空间。那里的数据是未知的,可能带来严重后果 sizeof可以用来获得数组所占存储空间的大小,2019/5/8,10,【例】当下标值超过数组长度时会如何?,变量c和a的值因数组越界而被悄悄破坏了,1,2,3,4,5,6,1,2,0,7,8,9,10,11,2019/5/8,11,数组的引用需要注意的问题,数组元素和普通变量一样,可出现在任何合 法的C表达式中,也可作为函数参数 数组不能整体引用,每次只能引用一个元素 避免引用时下标越界,score(5) matrix2,3 score=1,2,3,4,5,引用非法!,2019/5/8,12,数组的初始化,数组定义后的初值仍然是随机数,一般需要我们来初始化 int a5 = 12, 34, 56 ,78 ,9 ; int a5 = 0 ; int a = 11, 22, 33, 44, 55 ; 初始化列表中的初值的个数不能多于数组元素的个数,但可以少于数组个数(自动赋初值0),2019/5/8,13,一维数组的输入和输出,只能逐个对数组元素进行操作(字符数组例外),输入方法:,int a10,i;,输入第i个数组元素:,scanf(“%d“,输入整个数组元素:,for (i=0;i10;i+) scanf(“%d“,输出方法:,输出第i个数组元素:,printf(“%d“,ai);,输出整个数组元素:,for (i=0;i10;i+) printf(“%d“,ai);,2019/5/8,14,如何使两个数组的值相等?,main() int a4 = 1,2,3,4, b4; b = a; ,解决方法 方法1:逐个元素赋值 b0=a0; b1=a1; b2=a2; b3=a3; 方法2:通过循环赋值 int i; for (i=0;i4;i+) bi = ai; ,原因: 数组名表示数组的首地址,其值不可改变!,2019/5/8,15,一维数组的定义和初始化举例,【例】编程实现显示用户输入的月份(不包括闰年的月份)拥有的天数,2019/5/8,16,【例】兔子生崽问题P201,Fibonacci数列 1,2,3,5,8,13,21,34,55,89,144,233,,2019/5/8,17,#include #define YEAR_MONTH 12 main() int fYEAR_MONTH+1 = 0,1,2; int month; for (month=3; month=YEAR_MONTH; month+) fmonth = fmonth-1 + fmonth-2; for (month=1; month=YEAR_MONTH; month+) printf(“%dt“, fmonth); printf(“nsum = %dn“, fYEAR_MONTH); ,【例】兔子生崽问题P201,2019/5/8,18,【例】打印最高分和学生的序号(P204),从键盘输入学生人数n; 从键盘输入所有学生的学号和成绩分别存入数组num和score 假设其中的一个学生成绩为最高,同时记录其学号,即令 maxScore = score0 maxNum = num0; 对所有学生成绩进行比较,即 for (i=1; i maxScore, 则修改maxScore值为scorei, 并记录其学号maxNum = numi; 打印最高分maxScore及其学号maxNum;,2019/5/8,19,#include #define ARR_SIZE 40 main() float scoreARR_SIZE, maxScore; int n, i; long maxNum, numARR_SIZE; printf(“Please enter total number:“); scanf(“%d“, ,【例】,2019/5/8,20,向函数传递一维数组,传递整个数组给另一个函数,可将数组的首地址作为参数传过去 用数组名作函数参数 只复制一个地址自然比复制全部数据效率高 由于首地址相同,故实参数组与形参数组占用同一段内存 在该函数内,不仅可以读这个数组的元素,还可以修改它们,2019/5/8,21,简单变量和数组作函数参数的区别,2019/5/8,22,编写函数实现两数互换(swapi.c),void swap(int x,int y) int temp; temp = x; x = y; y = temp; ,main() int a, b; a = 15; b = 8; swap(a, b); printf(“a=%d,b=%d“,a,b); ,能否实现互换?,2019/5/8,23,swap(int a) int temp; temp=a0; a0=a1; a1=temp; main() int a2; printf(“input values of a0 and a1:“); scanf(“%d%d“, ,数组名作为函数参数 实现两数互换(swap_arr),2019/5/8,24,【例】求最大值,#include #define ARR_SIZE 40 float FindMax(float arr,int n); main() float scoreARR_SIZE, maxScore; int n, i; printf(“Please enter total number:“); scanf(“%d“, ,float FindMax(float arr, int n) float max; int i; max = arr0; for (i=1; i max) max = arri; return max; ,2019/5/8,25,排序和查找,排序(Sorting)算法 交换法排序 选择法排序,2019/5/8,26,排序算法交换法排序(1),交换法排序示意图,84 83 88 87 61,第1轮,不换,84 83 88 87 61,交换,88 83 84 87 61,不换,88 83 84 87 61,不换,88 83 84 87 61,第2轮,88 83 84 87 61,交换,88 84 83 87 61,交换,88 87 83 84 61,不换,88 87 83 84 61,2019/5/8,27,交换法排序示意图,第3轮,88 87 83 84 61,交换,88 87 84 83 61,不换,88 87 84 83 61,第4轮,88 87 84 83 61,不换,88 87 84 83 61,排序结果:88 87 84 83 61,排序算法交换法排序(2),2019/5/8,28,交换法排序算法描述(P205例6.3),for (i=0; i scorei) “交换成绩scorej和scorei“, “交换学号numj和numi“; ,排序算法交换法排序(3),2019/5/8,29,【例】交换法从高到低排序,void DataSort(int score, int n) /*交换法排序*/ int i, j, temp; for (i=0; i scorei) /*从高到低*/ temp = scorej; scorej = scorei; scorei = temp; ,2019/5/8,30,选择法排序示意图,排序算法选择法排序(1),84 83 88 87 61,第1轮,84 83 88 87 61,k=2,84 83 88 87 61,84 83 88 87 61,88 83 84 87 61,第2轮,88 83 84 87 61,88 83 84 87 61,k=3,88 83 84 87 61,k=3,88 87 84 83 61,i=0 k=0,k=2,k=2,i=0 k=2,ki,交换ak和ai,i=1 k=1,i=1 k=3,ki,交换ak和ai,k=2,2019/5/8,31,选择法排序示意图,第3轮,88 87 84 83 61,88 87 84 83 61,k=2,88 87 84 83 61,i=2 k=2,i=2 k=2,k=i,不交换ak和ai,第4轮,88 87 84 83 61,i=3 k=3,i=3 k=3,k=i,不交换ak和ai,排序结果:88 87 84 83 61,排序算法选择法排序(2),2019/5/8,32,排序算法选择法排序(3),选择法排序算法描述(P213),for (i=0; i scorek) 记录此轮比较中最高分的元素下标 k = j; 若k中记录的最大数不在位置i,则 “交换成绩scorej和scorei“, “交换学号numj和numi“; ,2019/5/8,33,void DataSort(int score, long num, int n) /*选择法*/ int i, j, k, temp1; long temp2; for (i=0; i scorek) k = j; /*记录最大数下标位置*/ if (k != i) /*若最大数不在下标位置i*/ temp1 = scorek; scorek = scorei; scorei = temp1; temp2 = numk; numk = numi; numi = temp2; ,2019/5/8,34,排序和查找,查找(Searching)算法 顺序查找 折半查找,2019/5/8,35,【例】顺序查找学号,int LinSearch(long num, long x, int n) int i; for (i=0; in; i+) if (numi = x) return (i); return (-1); ,哈,找到了!,2019/5/8,36,折半查找示意图,查找算法折半查找(1),数组下标 0 1 2 3 4 99011 99013 99015 99017 99019,第1次循环,查找值x=99017,xamid low=mid+1,99011 99013 99015 99017 99019,第2次循环,x=amid 找到,条件:low=high,折半查找示意图,查找算法折半查找(1),2019/5/8,37,折半查找示意图,查找算法折半查找(2),数组下标 0 1 2 3 4 99011 99013 99015 99017 99019,第1次循环,查找值x=99016,xamid low=mid+1,99011 99013 99015 99017 99019,第2次循环,xamid high=mid-1,99011 99013 99015 99017 99019,第3次循环,不满足low=high,循环结束,未找到!,2019/5/8,38,int BinSearch(long num, long x, int n) int low, high, mid; low = 0; high = n - 1; while (low nummid) low = mid + 1; else if (x nummid) high = mid - 1; else return (mid); return(-1); ,若未按学号排序, 则如何修改程序?,2019/5/8,39,二维数组,学生成绩表,2019/5/8,40,二维数组的定义,格式: 数据类型 数组名常量表达式常量表达式,int a23;,a为23(2行3列)的数组,注意下标范围,a0 a1,a,- a00 a01 a02,- a10 a11 a12,2019/5/8,41,short int a23;,a10,a11,a12,a00,a01,a02,存放顺序:按行存放 先顺序存放第0行元素,再存放第1行元素,需知道数组每行列数才能从起始地址开始正确读出数组元素,二维数组的存储结构,2019/5/8,42,二维数组的初始化,int a23=1,2,3,4,5,6 int a23=1,2,3,4,5,6 int a 3=1,2,3,4,5,6 int a 3=1,2,3,4,5,6,0,第二维长度不可省略!,1 2 3 4 5 0 6 0 0 0 0 0,说明:静态/外部数组未初始化,默认初值是0(数值)或空格(字符),2019/5/8,43,二维数组的引用,(设已有定义int a26,x,y ,i=0,j=0;) a13=4; /*下标为常量*/ scanf(“%d”, /*下标为一个复杂的整型表达式*/ 错误: a2,3=1,2019/5/8,44,数组的输入和输出只能逐个对数组元素进行操作(字符数组例外),int b23,i,j;,二维数组的输入输出,2019/5/8,45,二维数组实例,【例】从键盘输入某年某月(包括闰年),编程输出该年的该月拥有的天数,2019/5/8,46,向函数传递二维数组,在声明二维数组形参时,不能省略数组第二维的长度(列数),为什么? 想想数组在内存中是如何分布的? 元素aij在数组a中的位置是: i * N + j 元素地址:首地址 + 偏移量,实际传送的是数组第一个元素的地址,short aMN;,偏移1*3+2,2019/5/8,47,【例】,某班考试科目为数学(MT),英语(EN)和物理(PH),有最多不超过30人参加考试。要求按如下格式输出学号、各科分数、总分和平均分。 格式: No. MT EN PH SUM AVER 1 97 87 92 276 92 2 92 91 90 273 91 ,2019/5/8,48,算法描述: step1:输入参加考试的学生人数; step2:输入每个学生的学号numi及三门课的成绩scoreij; step3:对每个学生计算总分sumi和平均分averi; step4:对每个学生打印学号、三门课的成绩、总分和平均分。,【例】,2019/5/8,49,【例】 计算总分和平均分,void Total(int scoreCOURSE, int sum, float aver, int n) int i, j; for (i=0; in; i+) sumi = 0; for (j=0; jcourse; j+) sumi = sumi + scoreij; averi = (float) sumi / course; ,可省略数组第一维的长度 不能省略第二维的长度,2019/5/8,50,#include #define STUD 30 #define COURSE 3 main() int n, scoreSTUDCOURSE,sumSTUD; long numSTUD; float averSTUD; n=Input(num,score); Total(num,score,sum,aver,n); Print(num,score,sum,aver,n); ,【例】 主函数,2019/5/8,51,【例】计算每门课程的总分和平均分,void AverforCourse(int scoreCOURSE_N, int sum, float aver, int n) int i, j; for (j=0; jCOURSE_N; j+) sumj = 0; for (i=0; in; i+) sumj = sumj + scoreij; averj = (float) sumj / n; ,2019/5/8,52,字符串与字符数组,2019/5/8,53,字符串的存储,C语言并没有为字符串提供任何专门的表示法,完全使用字符数组和字符指针来处理 字符数组 每个元素都是字符类型的数组 char str80;,数组的最后一个元素必须是0,2019/5/8,54,字符数组的初始化,用字符型数据对数组进行初始化 char str6 =C,h,i,n,a,0; 用字符串常量直接对数组初始化 char str6 = “China“; char str6 = “China“; char str=“China”,数组定义长度 大于或等于包括0 在内的字符个数,2019/5/8,55,字符数组的输入输出,逐个输入输出:,一次性输入输出:,char s10;,for (i=0; si!=0; i+) putchar(si); putchar(n);,scanf(“%s“,s); printf(“%s“,s);,gets(s); puts(s);,for (i=0; i=9; i+) scanf(“%d”, ,2019/5/8,56,int i; scanf(“%d“, 不能读入带空格的字符串 例:输入 C language,则数组中仅存有C 这种用法很不安全。当用户的输入多于10个(含10个),str数组将越界,char str10;,字符串的访问和输入/输出,2019/5/8,57,字符串的访问和输入/输出,gets()函数,调用格式:,说明:,(1)该函数专用于输入字符串。,(2)函数参数只能用数组名。,gets(字符数组名);,(3)gets函数接收换行符之前所有 的字符。,2019/5/8,58,scanf(“%s“,str); printf(“%s“,str);,char str10;,字符串的访问和输入/输出,gets(str); puts(str);,按字符串整体输入/输出,2019/5/8,59,【例】输入一个人名,把它显示在屏幕上,Why?,2019/5/8,60,【例】输入一个人名,把它显示在屏幕上,2019/5/8,61,【例】使用函数gets(),输入一个带有空格的人名,然后把它显示在屏幕上,2019/5/8,62,1、用printf函数加%s控制,char str =“This is a book.“; printf(“%s“,str);,例:,2、用puts函数,调用格式:,其中:,参数可以是字符串常量/字符串变量。,字符串的输出,2019/5/8,63,puts()与printf()的不同,1、puts()函数专门用于字符串输出,printf()函数用于各种类型数据输出,2、puts()函数输出后自动换行。,printf()函数必须用“n“强行换行。,建议:,多种类型的混合输入输出时,选用scanf和printf;,当大量文字信息输入输出时,使用gets和puts。,2019/5/8,64,字符串处理函数,#include ,strcpy(目的字符串,源字符串);,string copy,strlen(字符串);,string length,strcat(目的字符串,源字符串);,string combination,strcmp(字符串1,字符串2);,string comparison,2019/5/8,65,计算字符串长度,#include ,strlen(字符串);,string length,char str10 = “China“; printf(“%d“, strlen(str); 打印结果是 5,6,还是10?,2019/5/8,66,len = strlen(str); for (i=0; ilen; i+) putchar(stri); putchar(n);,计算字符串长度,#include ,strlen(字符串);,string length,2019/5/8,67,字符串复制,#include ,strcpy(目的字符串,源字符串);,string

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论