C语言程序设计PPT课件第8章数组.ppt
第8章 数组,本章学习内容,对数组名特殊含义的理解 数组类型,数组的定义和初始化 向函数传递一维数组和二维数组 排序、查找、求最大最小值等常用算法,为什么使用数组(Array)?,【例8.1】要读入10人的成绩,然后求平均成绩需定义10个不同名整型变量,需要使用多个scanf()int score1,score2,score10;scanf(%d,保存大量同类型的相关数据,8.1一维数组的定义和初始化,一维数组的定义 存储类型 数据类型 数组名 整数1 整数2 整数n;,a9,a8,a7,a1,a0,int a10;定义一个有10个int型元素的数组系统在内存分配连续的10个int空间给此数组直接对a的访问,就是访问此数组的首地址,基类型,下标从0开始,8.1一维数组的定义和初始化,a9,a8,a7,a1,a0,int a10;数组大小必须是值为正的常量,不能为变量一旦定义,不能改变大小数组大小最好用宏来定义,以适应未来可能的变化#define SIZE 10 int aSIZE;,一维数组的定义 存储类型 数据类型 数组名 整数1 整数2 整数n;,8.1一维数组的定义和初始化,数组定义后的初值仍然是随机数一般需要我们来初始化 int a5=12,34,56,78,9;int a5=0;int a=11,22,33,44,55;,8.1一维数组的定义和初始化,数组的引用 数组名 下标数组下标(index)都是从0开始使用a0、a1、a2、a9这样的形式访问每个元素下标既可是常量,也可是整型表达式,允许快速随机访问,如ai可以像使用普通变量一样使用它们,如何使两个数组的值相等?,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;,原因:数组名表示数组的首地址,其值不可改变!,8.1一维数组的定义和初始化,【例8.2】编程实现显示用户输入的月份(不包括闰年的月份)拥有的天数,8.1一维数组的定义和初始化,下标越界是大忌!编译程序不检查是否越界下标越界,将访问数组以外的空间那里的数据是未知的,不受我们掌控,可能带来严重后果,【例8.3】当下标值小于0或超过数组长度时 会出现什么情况?,运行程序或单步执行观察变量变化情况可以看到,变量c和a的值因数组越界而被悄悄破坏了,1,2,3,4,5,6,1,2,0,7,8,9,10,11,8.2二维数组的定义和初始化,一维数组用一个下标确定各元素在数组中的顺序可用排列成一行的元素组来表示如 int a5;二维数组用两个下标确定各元素在数组中的顺序可用排列成i行,j列的元素组来表示如 int b23;n维数组用n个下标来确定各元素在数组中的顺序如 int c324;n3时,维数组无法在平面上表示其各元素的位置,【例】以下程序的运行结果是什么?int main()int a3=1,2,3,4,5,6,0;printf(%d,%d,%dn,a11,a21,a31);return 0;,1 2 34 5 06 0 00 0 0,结果:5,0,0,【例】若int a 3=1,2,3,4,5,6,7,则a数组的第一维大小是多少?,1 2 34 5 67 0 0,二维数组的初始化,数组的数据类型和存储类型,根据数组的数据类型,为每一元素安排相同长度的存储单元根据数组的存储类型,将其安排在内存的动态存储区、静态存储区或寄存器区用sizeof(a)来获得数组a所占字节数,short int a23;,a10,a11,a12,a00,a01,a02,存放顺序:按行存放先顺序存放第0行元素,再存放第1行元素,需知道数组每行列数才能从起始地址开始正确读出数组元素,二维数组的存储结构,二维数组实例,【例8.4】从键盘输入某年某月(包括闰年),编程输出该年的该月拥有的天数,8.3向函数传递一维数组,传递整个数组给另一个函数,可将数组的首地址作为参数传过去用数组名作函数参数只复制一个地址自然比复制全部数据效率高由于首地址相同,故实参数组与形参数组占用同一段内存在该函数内,不仅可以读这个数组的元素,还可以修改它们,简单变量和数组作函数参数的区别,【例8.5】计算平均分,计数控制的循环,【例8.5】计算平均分,计数控制的循环,【例8.6】计算平均分当输入负值时,表示输入结束,标记控制的循环负值作为输入结束标记,【例8.6】计算平均分当输入负值时,表示输入结束,标记控制的循环负值作为输入结束标记,【例8.7】计算最高分,#include#define N 40int ReadScore(int score);int FindMax(int score,int n);int main()int scoreN,max,n;n=ReadScore(score);printf(Total students are%dn,n);max=FindMax(score,n);printf(The highest score is%dn,max);return 0;,max(i=0),max(i=2),max(i=3),计算最大值算法,假设其中的一个学生成绩为最高maxScore=score0;对所有学生成绩进行比较,即 for(i=1;i maxScore则修改maxScore值为scorei 打印最高分maxScore,【例8.7】计算最高分,【例8.7】计算最高分,8.4排序和查找,排序(Sorting)算法交换法排序选择法排序,交换法排序,交换法排序,【例8.8】交换法从高到低排序,交换法排序 for(i=0;i scorei)交换成绩scorej和scorei,如何实现两数交换?,temp=scorej;scorej=scorei;scorei=temp;,70,50,70,【例8.8】交换法从高到低排序,void DataSort(int score,int n)/*交换法排序*/int i,j,temp;for(i=0;i scorei)/*从高到低*/temp=scorej;scorej=scorei;scorei=temp;,选择法排序,k=1,k=2,k=0,k=1,选择法排序,k=3,k=4,k=3,k=4,选择法排序,选择法排序 for(i=0;i scorek)记录此轮比较中最高分的元素下标 k=j;若k中记录的最大数不在位置i,则 交换成绩scorek和scorei,交换学号numk和numi;,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;,【例8.8】成绩从高到低顺序,8.4排序和查找,查找(Searching)算法顺序查找折半查找,【例8.10】顺序查找学号,int LinSearch(long num,long x,int n)int i;for(i=0;in;i+)if(numi=x)return(i);return(-1);,哈,找到了!,【例8.11】折半查找学号,哈,找到了!,10122 10124 10126 10128 10130,【例8.11】折半查找学号,唉,没找到!,10122 10124 10126 10128 10130,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);,若未按学号排序,则如何修改程序?,void DataSort(int score,long num,int n)/*选择法*/int i,j,k,temp1;long temp2;for(i=0;in-1;i+)k=i;for(j=i+1;jn;j+)if(numj numk)k=j;/*记录最大数下标位置*/if(k!=i)/*若最大数不在下标位置i*/temp1=scorek;scorek=scorei;scorei=temp1;temp2=numk;numk=numi;numi=temp2;,8.5向函数传递二维数组,实际传送的是数组第一个元素的地址,short a23;,8.5向函数传递二维数组,在声明二维数组形参时,不能省略数组第二维的长度(列数),为什么?想想数组在内存中是如何分布的?元素aij在数组a中的位置是:i*N+j 元素地址:首地址+偏移量,实际传送的是数组第一个元素的地址,short aMN;,偏移1*3+2,例8.12 计算每门课程的总分和平均分,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;,可省略数组第一维的长度不能省略第二维的长度,例8.12 计算每门学生的总分和平均分,void AverforStud(int scoreCOURSE_N,int sum,float aver,int n)int i,j;for(i=0;in;i+)sumi=0;for(j=0;jCOURSE_N;j+)sumi=sumi+scoreij;averi=(float)sumi/COURSE_N;,例8.12计算每门的总分和平均分,Questions and answers,