c语言程序设计第7章数组.ppt_第1页
c语言程序设计第7章数组.ppt_第2页
c语言程序设计第7章数组.ppt_第3页
c语言程序设计第7章数组.ppt_第4页
c语言程序设计第7章数组.ppt_第5页
已阅读5页,还剩55页未读 继续免费阅读

下载本文档

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

文档简介

第7章 数组,本章要点 (1)数值型数组(一维、二维) (2)一维数组与指针运算 (3)数组作函数的参数。 本章难点 (1)一维数组、多维数组的说明、赋值、输入输出方法。 (2)数组的有关算法,特别是排序的算法。 (3)利用指针实现数组的相关运算。,数组是具有相同的数据类型且按一定次序排列的一组变量的集合体,构成一个数组的这些变量称为数组元素。数组有一个统一的名字叫数组名。 与高中的数列类似: 数列a: a1,a2,a3,a4,ai,an 有一个下标 数列a: a1,1,a1,2,a1,3,a1,4,ai,j, 有二个下标 数组a: a1,a2,a3,ai,an,a0 a1 a2 an-1,7.1 数组说明 下标,7.1.1 数组的说明 当需要处理大量的同类型数据时,利用数组是非常方便的。 C语言规定,程序中用到的数组也必须先进行说明(定义)。 说明一维数组的方式如下 类型说明符 数组名常量表达式; 例如, int a5,b18; double xy20; 共说明了3个一维数组:整型一维数组a,共包括5个元素(a0a4),数组中的每一个元素均为整型;整型一维数组b,共包括18个元素(b0b17),其中的每一个元素也都为整型;双精度实型一维数组xy,共包括20个元素(xy0xy19),其中的每一个元素均为双精度实型。,关于数组的说明要注意以下几个问题:,(1)数组名的命名规则与变量名相同。 (2)说明数组大小的常量表达式必须为整型,并且只能用方括号括起来。 (3)说明数组大小的常量表达式可以是符号常量、常量,但不能是变量。 const int i=3; int ai; (4)数组元素的下标是从0开始的,到n-1,共含有n个元素。例如, int a4; 说明了一个长度为4的整型一维数组,在这个数组中的4个元素分别为a0、 a1、a2、a3,其中并不包含元素a4。,7.1.2 数组引用,数组必须先说明,后引用(使用),在C语言中,只能逐个引用数组元素,不能一次引用数组中的全部元素。 数组元素的表示形式为 数组名下标 下标可以是整形常量或整形表达式。例如, b0=b3*2+b1-b2*2,【例】数组元素的引用。 main() int i,a5; for(i=0;i=0;i-) /*这个for循环完成对数组元素的输出*/ printf(“%2d“,ai); 运行结果如下: 4 3 2 1 0,7.1.3 数组的初始化,即对数组元素的第一次赋值。 (1)在说明数组时对数组元素赋以初值。例如, int a5=0,1,2,3,4; 将数组元素的初值依次放在一对花括弧内。经过上面的说明和初始化之后,a0=0,a1=1,a2=2,a3=3,a4=4。对数组元素赋初值后,在程序中还可以用其他方式(如赋值语句、输入函数等)重新赋值。 a1=51; a2=62; a3=43; a4=24; (2)只给一部分数组元素赋值。例如, int a5=0,1; 说明a数组有5个元素,但花括弧内只提供2个初值,这表示只给前面2个元素赋初值,后3个元素值为0。 a0=0、a1=1、a2=0、a3=0、a4=0。 注意:如果使用int a5;仅表示定义了一个长度为5的数组,系统不会将其初始化为0值,其值是不确定的。,(3)如果想使一个数组中全部元素值为0,可以写成, int a5=0,0,0,0,0; 或int a10=0; (4)在对全部数组元素赋初值时,可以不指定数组长度。例如, int a =1,2,3,4,5;或者 int a5=1,2,3,4,5; (5) 静态数组 static int a5; 若数组没有被初始化,则元素自动设置为0 .,例 计算并输出全班30个学生C语言程序设计课程的平均成绩以及每个人的成绩与平均成绩之差。,#include #define N 30 main( ) int i; float xN,sum,average; sum=0; printf(“input %d scores:n“,N); for (i=0;iN;i+) scanf(“%f“, ,练习 1、利用随机函数对一维数组赋值,之后输出该数组。 (数组长度自定) #include #include #include #define N 10 main( ) int i,xN; srand(time(0); for(i=0;iN;i+) xi=rand()%101; printf(“%4d“,xi); ,2、找出一个数组中最大的元素值。,#include #include #include #define N 10 main( ) int i,xN,max; srand(time(0); for(i=0;iN;i+) xi=rand()%101; printf(“%4d“,xi); ,max=x0; for(i=1;iN;i+) if(maxxi)max=xi; printf(“nmax=%d“,max); ,3、把数组右循环移动1位。,#include #include #include #define N 10 main( ) int i,xN,t; srand(time(0); printf(“原始数组:“); for(i=0;iN;i+) xi=rand()%101; printf(“%4d“,xi); ,/右移 t=xN-1; for(i=N-2;i=0;i-) xi+1=xi; x0=t; printf(“n右移后数组:“); for(i=0;iN;i+) printf(“%4d“,xi); ,4、把一个数组倒序。,#include #include #include #define N 10 main( ) int i,xN,k,t; srand(time(0); printf(“原始数组:“); for(i=0;iN;i+) xi=rand()%101; printf(“%4d“,xi); ,/倒序 k=N/2-1; for(i=0;i=k;i+) t=xi;xi=xN-1-i;xN-1-i=t; printf(“n倒序后数组:“); for(i=0;iN;i+) printf(“%4d“,xi); ,7.1.4 数组的运算(排序与查找),1起泡法排序 例4 用起泡法对10个数排序(由小到大)。 #include #include #define N 10 void main() int aN; int i,j,t; for(i=0;iaj+1) /*相邻二数相比*/ t=aj;aj=aj+1;aj+1=t; /*交换相邻二数*/ printf(“the sorted nmber:n“); for(i=0;iN;i+) /*输出所有数组元素*/ printf(“%3d“,ai); ,for(i=0;iaj+1) /*相邻二数相比*/ t=aj;aj=aj+1;aj+1=t; /*交换相邻二数*/,#include #define N 10 int main() int x =88,i,location; int arrayN=-65,0,21 ,58,78,90,98,106,124; printf(“插入数值前:n“); for(i=0;iN-1;i+) printf(“%5d“,arrayi); printf(“n“);,for(i=N-2;i=0;i-) if(arrayix) arrayi+1=arrayi; else break; arrayi+1=x; printf(“插入数值后:n“); for(i=0;iN;i+) printf(“%5d“,arrayi); printf(“n“); return 0; ,3. 顺序查找(不要求数组有序) #include #define N 8 void main() int aN=6,5,3,7,1,4,9,8,x,i, find=0; scanf(“%d“, ,4.折半查找法(只能对有序数列进行查找) #define N 10 /*N代表数据的个数*/ main() int aN=1,4,7,13,16,19,28,36,49,60; int mid,bot,top,x,find; scanf(“%d“,1.把两个长度相同的数组的对应元素相加。 2.从数组a中删除一个值为x的元素。,练习,for(i=0;i=0;j-) sj+1=sj; else for(j=i+1;jN;j+) sj-1=sj; break; if(i=N) printf(“no existn“); else for(i=0;iN;i+) printf(“%4d“,si); return 0; ,#include #define N 10 /从数组a中删除一个值为x的元素。 int main() int sN =3,5,4,1,9,6,10,56,34,12; int x,i,j; printf(“input x:“); scanf(“%d“,int x,*px; px= 则表示px指向x。 通过px访问x称为间接访问。,地址的存储与使用,补充内容(第6章),( 1)& 取地址运算符。 (2)* 指针运算符或间接访问运算符。 *(&x)=3 *px=3 x=3 三者等价。,指针的说明和引用,注意以下几点: (1) 则 &r、&a0、&ai是正确的,而&(2*r)、&a、&k是非法操作。 (2)如果px指向x,则*px可以出现在x可以出现的任何位置,因为*px即表示x。,(3)(*px)+相当于x+。如果没有括号,成为*px+,即为*(px+) ,因为+和*为同一优先级别,结合方向为自右向左,因此它表示先对px进行*运算,得到x的值,然后使px的值增1,这样px就不再指向x了.(4)指针变量只能指向同一类型的变量。例如下列用法是错误的: int *p; float y; p=,7.2 一维数组与指针运算,7.2.1 一维数组的数组名 一维数组的数组名表示的是该数组中第一个数组元素的存储地址。 数组名是一个指针常量,而不是指针变量,因此数组名的值是不能修改的。 int num5; nt grade5; int *ptr; ptr=num; 则表示ptr指向数组num的起始位置。 grade = num;是非法的。,7.2.2一维数组的下标与指针,若有: int a10,*p; p=a; 则: ai *(a+i) *(p+i) pi 是等价的。 p可以+,而a不能+。,例子 编程实现一维数组array10 = 98,124,58,78,90,587,21,0,-65,106的求和,要求使用间接访问表达式表示数组元素。,#include #define N 10 int main( ) int arrayN = 98,124,58,78,90,587,21,0,-65,106; int sum = 0; for(int i=0;iN;i+) sum += *(array+i); printf(“sum = %5dn“,sum); return 0; ,sum += *(p+i); /也可以换成*p+,int *p=array;,例子 编程实现一维数组array10 = 98,124,58,78,90,587,21,0,-65,106的求和,要求使用间接访问表达式表示数组元素。,#include #define N 10 int main( ) int arrayN = 98,124,58,78,90,587,21,0,-65,106; int sum = 0; for(int *p=array;parray+N;p+) sum += *p; printf(“sum = %5dn“,sum); return 0; ,例子使用指针实现冒泡排序法,将具有10 个数组元素的一维整型数组array10 = 98,124,58,78,90,587,21,0,-65,106按照由大到小的排序进行排序,输出排序前后的数组。,#include #define N 10 int main( ) int arrayN = 98,124,58,78,90,587,21,0,-65,106; int i,t,*p=array; for(i=0;iN-1;i+) for(p=array;parray+N-1-i;p+) if(*p*(p+1) t=*p;*p=*(p+1);*(p+1)=t; for(p=array;parray+N;p+) printf(“%5d“,*p); return 0; ,例子编写程序,实现一维数组A10元素值循环左移3 位(要求用指针实现)。,#include #define N 10 int main() int arrayN = 98,124,58,78,90,587,21,0,-65,106; int i,t,*p=array; for(i=1;i=3;i+) t=*array; for(p=array+1;p=array+N-1;p+) *(p-1)=*p; *(p-1)=t; for(p=array;parray+N;p+) printf(“%5d“,*p); return 0; ,7.2.3 数组作函数的参数,1. 数组元素作函数的参数 数组元素作函数的参数与普通变量作函数的参数本质相同。数组元素作函数实参时,仅仅是将其代表的值作为实参处理。 数组中元素作为函数的实参,与简单变量作为实参一样,结合的方式是单向的值传递。,【例】数组元素作函数的参数。,#include “stdio.h“ float max(float n,float z) /* 函数有二个形参n,z */ if(nz) return n; else return z; void main() float m,a=3.2,180,2.3,35,56,67,68,45,-34,10; int k; m=a0; for(k=1;k10;k+) /*循环9次*/ m=max(m,ak); /*调用9次函数,实参m和ak给形参n,z*/ printf( “%.2fn“,m); /*输出m和值 */ 特别注意:数组元素只能作为函数的实参,不能作为函数的形参。,2. 数组名作函数参数,数组名代表数组的首地址,在数组名作为函数的参数时,形参和实参都应该是数组名(或是指针)。在函数调用时,实参给形参传递的数据是实参数组的首地址,即实参数组和形参数组完全等同,是存放在同一存储空间的同一个数组,形参数组和实参数组共享存储单元。如果在函数调用过程中形参数组的内容被修改了,实际上也是修改了实参数组的内容。,有四种形式: (1)实参与形参都用数组名。 (2)实参用数组名,形参用指针变量。 (3)实参与形参都用指针变量。 (4)实参用指针变量,形参用数组名。,例:编写一个输出一维数组的函数,在主程序中调用该函数。 形参:void pntarray(int b,int N) /(int *b,int N) 实参: pntarray(array,N) /(p,N) 其中:array为数组名,p为指向数组array的指针,void output(int b,int n) int *ptr; for(ptr=b;ptrb+n;ptr+) printf(“%5d“,*ptr); printf(“n“); ,void maopao(int b,int n) int i,temp,*px; for(i=0;in-1;i+) for(px=b;pxb+n-1-i;px+) if(*px*(px+1) temp=*px; *px=*(px+1);*(px+1)=temp; ,int find(int b,int n,int x) int flag=0,bot,top,mid; bot=0;top=n-1; while(bot=top) mid=(bot+top)/2; if(*(b+mid)=x) flag=1;break; else if(x*(b+mid) bot=mid+1; else top=mid-1; return flag; ,void main() int arrayN=96,35,12,58,78,90,587,21,0,-65; int x; output(array,N);/调用output函数输出排序前数组 maopao(array,N);/调用maopao函数对数组排序 output(array,N);/调用output函数输出排序后数组 printf(“input data:“); scanf(“%d“, ,#include #define N 10,7.3 多维数组,为了表示具有两个下标的元素组成的二维数据队列,如距阵或需要两个以上的下标的元素,则使用多维数组, 维即元素的下标具有的下标个数,称为数组的维数。,7.3.1 多维数组的说明、引用和存储结构,1多维数组的说明 说明二维数组的一般形式如下: 类型说明符 数组名常量表达式1常量表达式2; 例如,说明语句 int a23, b43; 注意不能写成:int a2,3, b4,3;,例:int a5,逻辑结构,物理结构,地址 内存 元素,100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119,a0 a1 a2 a3 a4,例:int a5 5,逻辑结构,物理结构,地址 内存 元素,在C语言中,两维数组是按行的顺序存放的。,100,101 102,103 104,105 106,107 108,109 110,111 112,113 114,115 116,117 118,119 120,121 122,123 124,125 126,127 196,197 198,199,上三角 找出数组下标的关系。,2多维数组的引用 二维数组元素的表示形式为: 数组名下标下标 例如:a23。 下标可以是整型表达式,例如a2-12*2-1,不要写成a2,3、a2-1,2*2-1形式。 例如:b12=a23/2 使用数组元素时,应该注意下标值应在已定义的数组大小的范围内(下标都是从0开始的)。下列用法是错误的。 int a34; a34=3; 注意:只能逐个引用二维数组中的元素;不能一次引用二维数组中的全部元素。,7.3.2 多维数组的初始化,二维数组与一维数组一样,也可以对二维数组进行初始化。 在对二维数组进行初始化时要注意以下几点。 (1)在分行给二维数组赋初值 int a34=1,2,3,4,5,6,7,8,9,10,11,12; int a34=1,2,3,4,5,6; (2)在给全部元素赋初值时,说明语句中可以省略第一维的长度说明(但一对方括号不能省略)。例如下列三个语句是等价的: int a34=11,22,33,44,55,66,77,88,99,10,11,12; int a34=11,22,33,44,55,66,77,88,99,10,11,12; int a 4=11,22,33,44,55,66,77,88,99,10,11,12; (3)在分行赋初值时也可以省略第一维的长度说明。例如下列两个语句是等价的: static int a34=11,22,44,55; static int a 4=11,22,44,55; 并且,下列两个语句也等价: static int a34=11,22,33,44,55; static int a 4=11,22,33,44, 55,;,例. 利用随机函数给数组赋值,然后按行输出。,#include “stdio.h“ #include “stdlib.h“ #include “time.h“ main() int a55; int i,j; srand (time(0); for (i=0;i5;i+) for (j=0;j5;j+) aij=rand(); for(i=0;i5;i+) for(j=0;j5;j+) printf(“%6d“,aij); printf(“n“); ,例 求下列两个矩阵的和矩阵C=A+B,#include “stdio.h“ #include “stdlib.h“ #include “time.h“ main() int a55,b55,c55; int i,j; srand(time(0); for (i=0;i5;i+) for (j=0;j5;j+) aij=rand( ); bij=rand( ); for(i=0;i5;i+) for(j=0;j5;j+) cij=aij+bij; printf(“%6d“,cij); printf(“n“); ,例 求下列两个矩阵的乘积矩阵C=AB。,#include “stdio.h“ void main() int i,j,k,c23; int a24=1,2,3,4,5,6,7,8; int b43=1,5,9,2,6,10,3,7,11,4,8,12; for(i=0;i2;i=i+1) /*矩阵相乘,外for循环2次表示行*/ for(j=0;j3;j=j+1) /*内循环3次表示每行几列*/ cij=0; for(k=0;k4;k=k+1) cij=cij+aik*bkj; /*求某一项的值*/ for(i=0;i2;i=i+1) /*输出每个新的数组元素*/ for(j=0;j3;j=j+1) printf(“%6d“,cij); printf(“nnn“); ,【例】有一个34的矩阵,要求编程序求出其中值最大的那个元素的值,以及其所在的行号和列号。,#include “stdio.h“ void main() int i,j,row=0,colum=0,max; int a34=1,2,3,4,5,6,7,8,9,13,14,12; max=a00; /*把第一个元素的值给max*/ for(i=0;imax) /*循环一次,数组元素的值与max比较*/ max=aij ; /*比较后的大数给max */ row=i; /*把当时比较后大的元素的行给row*/ colum=j; /*把当时比较后大的元素列给colum*/ printf(“max=%d,row=%d,colum=%dn“,max,row,colum); ,【例】编程实现将从1开始的36个自然数按行赋给二维数组a【6,6】,之后求该数组以主对角线为分割的上三角形元素的平方根之和。,想一想:如何按列赋值,如何求下三角形,如何求以次对角线分割的上、下三角形?,#include #include void main() int a66,i,j,k=1; double s=0; for(i=0;i6;i+) for(j=0;j6;j+) aij=k; k+; printf(“%4d“,aij); printf(“n“); for(i=0;i6;i+) for(j=i;j6;j+) s=s+sqrt(aij); printf(“%.3f“,s); ,【例】编程求二维数组a【6,6】各行元素值之和。,#include #include void main() int a66,i,j,b6; for(i=0;i6;i+) for(j=0;j6;j+) aij=i+j; printf(“%4d“,aij); printf(“n“); for(i=0;i6;i+) bi=0; for(j=0;j6;j+) bi=bi+aij; printf(“%4d“,bi); ,想一想:如何求各列元素值之和,如何求每行、每列元素的最大值?,二维数组的数组名(1),1. 一维数组的数组名 例:int a10; 则a表示整个数组的首地址,也就是a0的地址,即&a0。 a+i :表示第i个元素的地址。 *(a+i):表示第i个元素的值(即ai)。,二维数组的数组名(2),2. 二维数组的数组名 例:int a45; 则表示a有元素4个,即a4。 每个ai又含有5个元素,这又是一个一维数组。 可以把ai看成是一个一维数组b。即b5 a+i: 二维数组a的第i个元素的地址,即第i行的地址。是一个整体。 *(a+i): 是第i行第0个元素的地址,即数组b的首地址。,【例】输出以下的杨辉三角形(要求输出10行)。,#include “stdio.h“ #define N 10 void main() int i,j,aNN; for (i=0;iN;i+) for(j=0;j=i;j+) if(j=0|i=j) aij=1; else aij=ai-1j-1+ai-1j; for (i=0;iN;i+) for(j=0;j=i;j+) printf(“%6d“,aij); printf(“n“); printf(“n“); ,计算公式: aij=ai-1j-1+ai-1j 除第一列和对角线元素,7.5 使用内存动态分配实现动态数组,通常情况下,运行中的很多存储要求在编写程序时无法确定,因此需要一种机制,可以根据运行时的实际存储需要分配适当的存储空间,用于存放那些在程序运行中才能确定存储大小的数据。C 提供了动态存储管理机制,允许程序动态申请和释放存储空间。,7.5.1 动态内存分配的步骤,1. 了解需要多少内存空间; 2. 利用C 提供的动态分配函数来分配所需要的内存空间; 3. 使指针指向获得的存储空间,以便用指针在该空间内实施运算或操作; 4. 使用完毕所分配的内存空间后,释放这一空间。,7.5.2 动态内存分配函数,需要的头文件:stdlib.h (1)动态存储分配函数malloc( ) void * malloc(unsigned size) 功能:在内存的动态存储区中分配一个连续空间,其长度为size。如果申请才成功返回一个指向所分配内存空间的起始地址的指针,否则返回NULL(值为0)。 调用形式:(类型说明符 *) malloc (size),例: int size=50; int *p = (int *)malloc(size* sizeof(int) ); if(p=NULL) printf(“Not enough space to allocate!n“); exit(-1); 在调用函数malloc()时,最好利用函数sizeof()来计算存储块的大小,不要直接写整数,因为不同平台的数据类型所占存储空间大小可能不相同。 虽然这里存储空间是

温馨提示

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

评论

0/150

提交评论