【文档说明】计算机二级C++九一课件.ppt,共(42)页,551.500 KB,由小橙橙上传
转载请保留链接:https://www.ichengzhen.cn/view-5089.html
以下为本文档部分文字说明:
第九章数组(一)第1页,共42页。回顾指针•2.int**p,*a,b=10;•p=&a;•a=&b;&a&bb10pa第2页,共42页。真题:1.有以下程序:#include<stdio.h>main(){intn,*p=NULL;*p=&n;printf(“inputn:”);
scanf(“%d”,&p);printf(“outputn:”);printf(“%d\n”,p);}该程序想通过指针p为变量n读入数据并输出,但有多处错误。以下语句正确的是;Aintn,*p=NULL;B*p=&n;Cscanf(“%d”
,&p);Dprintf(“%d\n”,p);第3页,共42页。•思考:用变量存储一系列数据,如学号?•用inti=001,j=002,h=003…….w=024…?•如何简化解决,开辟一系列空间用变量可以连续存放一系列数据或字符第4页,共42页。为什么要使用数组3-3
数组内存12065984数组的元素容器中保存的物品日常生活中的容器程序中的数组第5页,共42页。声明一维数组数据类型数组名[size];类型说明符int、char、float…数组名常量表达式:数组大小intnum[50];charlist[20];doublepressure
_level[6];#defineLIMIT20...intemp_codes[LIMIT];第6页,共42页。inta[8];1.int是类型名,只能存放整型2.a是数组名3.数组a中有8个元素,分别为a[0],a[1]…a[7].即下标从0开始4.执行完此语句的结果是
:为数组a分配8个连续的单元,每个单元占4个字节理解:数组a中有8个变量,变量名称依次为a[0],a[1]…a[7].第7页,共42页。内存a[0]a[1]a[2]a[3]a[4]146899.1.3初始化一维数组inta[5]={1,4,6,8,9};相当于:a[0]
=1;a[1]=4….说明:1.inta[5]={1}合法,没有初始化的变量a[1]-a[4]自动赋初值为02.inta[5]={1,4,6,8,9,3};不合法即:数组的大小>=元素的个数a其他的初始化情况:intarr[10]={10,9,8,7,6,5,4,
3,2,1,0};//错误!越界了intarr[10]={9,8,7,5};//正确,后面的6个元素未初始化9.1.4通过赋初值定义数组的大小intarr[]={9,8,7};//正确:元素个数为3(思考)intarr[]={};//错误
,到底是几个元素?第8页,共42页。内存为一维数组动态赋值floatprice[4];printf(“Enterpricesof4books\n”);for(i=0;i<=3;i++){scanf(“%f”,
&price[i]);}price[0]price[1]price[2]price[3]price12.341002.1017.511.12第9页,共42页。问题描述:求一组数中的最大值和最小值。数组应用1voidmain(){intn
um[5],max,min,i;printf("请输入5个数:\n");for(i=0;i<5;i++)scanf("%d",&num[i]);max=num[0];min=num[0];for(i=1;i<5;i++){if(max<nu
m[i])max=num[i];if(min>num[i])min=num[i];}printf("\n最大值为:%d",max);printf("\n最小值为:%d\n",min);}读入5个值保存在数组中求最大值和最小值演示学生用书示例3第10页,共42页。问题描述:输入1
0个数,保存在一个数组中,在数组中查找某个数,给出是否找到的信息。如果找到了,要求输出该数在数组中所处的位置;如果找不到,输出“没有找到!”。数组应用2#defineN10……for(i=0;i<N;i++)scanf("%d",&num[i]);printf("\n请输入要查找的数:")
;scanf("%d",&search);for(i=0;i<N;i++){if(num[i]==search)break;}if(i<N)printf("\n在数组的第%d个位置找到了数字%d!\n",i+1,search);elseprintf("\n没
有找到!\n");……读入10个值保存在数组中在数组中查找,一旦找到,通过break语句跳出循环演示学生用书示例4第11页,共42页。一维数组和指针•回顾指针:存放一个变量地址的变量(指向一个变量)ip例如:in
t*p,i=4,j;p=&i;j=*p第12页,共42页。9.2一维数组和指针•C语言中,数组名可以认为是一个存放地址值的指针变量名,其中的地址值是数组第一个元素的地址。•例如:inta[2];数组名a可以认为是一个指针变量名,存的是数组的第一个元素a[0]的值
•注意:floata[10],*p,x;a=&x;//不合法,声明一个数组的同时,a中就确定了永远指向a数组的首地址a++;不合法第13页,共42页。•在数组中给指针赋初值:int*p,a[2];p=&a[0];合法p
=a;合法通过指针从终端读入数据;for(p=a,k=0;k<10;k++){scanf(“%d”,p),p++};通过数组从终端读入数据;for(k=0;k<10;k++)scanf(“%d”,&a[k])功能相同,都是
使指针变量p指向a数组的首地址a[0]a[1]a[2]a[3]a[4]…….p第14页,共42页。9.2.3通过数组的首地址引用数组元素1.inta[7];a相当于是指针变量,是数组元素的首地址。则:a值相当于&a[0]a+1相当于&a[1]…思考:
*a,*(a+1)代表什么呢?*&a[0],*&a[1]代表什么呢?故:*a和*&a[0]即为a[0]*(a+1)和*&a[1]即为a[1]*(a+k)和*&a[k]即为a[k]第15页,共42页。9.2.3通过指针引用数组元素•1.inta[7],*p;p=a;p=&a[0];
则:对于数组元素a[0],可以用*p引用;a[1]可以用*(p+1)引用,a[k]可以用*(p+k)引用第16页,共42页。int*p,s[10],i;p=s;总结:表示数组s中的第i个元素:s[i],*(p+i),*(s+i),*&s[i],p[i]表示数组s中的第i个元素地址:
&s[i],p+i,s+i,注意:虽然数组名s可以看做一个指针变量,但是s是不可变的,而p是可变的。即s++,s=p…都是不合法的第17页,共42页。例inta[]={1,2,3,4,5,6,7,8,
9,10},*p=a,i;数组元素地址的正确表示:(A)&(a+1)(B)a++(C)&p(D)&p[i]数组名是地址常量p++,p--()a++,a--()a+1,*(a+2)()第18页,共42页。例:输出数组中的全部元素有三种方法:(1
)main(){inta[10];inti;for(i=0;i<10;i++)scanf(“%d”,&a[i]);printf(“\n”);for(i=0;i<10;i++)printf(“%d”,a[i]);}2)main(){inta[10];
inti;for(i=0;i<10;i++)scanf(“%d”,&a[i]);printf(“\n”);for(i=0;i<10;i++)printf(“%d”,*(a+i));}3)main(){inta[10];int*p,i;for(i=0;i<10;i++)scanf(“%d”,
&a[i]);printf(“\n”);for(p=a;p<(a+10);p++)printf(“%d”,*p);}第19页,共42页。9.3函数之间对一维数组和数组元素的引用1、数组元素作实参当调用函数时,数组元素可以作为实参传送给形参,和普通变量一样,即传值调用。形
参的改变不会影响实参的值2、数组名作实参数组名也可以作为实参传送,数组名本身是一个地址值,因此是地址值的传递。形参的改变会影响实参的值第20页,共42页。•例题9.2编写程序,通过一个函数给主函数中定义的数组输入若干大约或等于0的整数,用负数作为结束标志;调用另一个函
数输出该数组中的数据。分析:main{声明一个数组s;调用一个子函数1给数组赋值;调用一个子函数2输出数组的值}子函数1{当大于等于0时一直输入;}子函数2{依次输出数组元素的值}值传递?地址传递?值传递?地址传递?需要有一个变
量,来计算输入数据的个数,并返回第21页,共42页。#include<stdio.h>#defineM100voidarrout(int*,int)voidarrint(int*)main(){ints[M],k;k=arrin(s);(数组名作为
实参)arrout(s,k);}intarrin(int*a){inti=0,x;scanf(“%d”.&x);while(x>=0){*(a+i)=x;i++;scanf(%d”.&x);}returni;}当数组名作为实参时,对应的形参除了是指针外,还可
以用另外两种形式。上例中的函数调用arrin(s);对应的函数首部可以写成以下三种形式:(1)arrin(int*a)(2)arrin(inta[])(3)arrin(inta[M])第22页,共42页。voidarrout(int*a,intn){inti;fo
r(i=0;i<n;i++)printf(”%4d”,*(a+i));printf(“\n”);}解释:printf(((i+1)%5==0?“%4d\n”:“%4d”,*(a+i));使5个一行输出第23页,共42页。数组元素地址作为实参9.3编写函数,对具有10个元素
的char类型数组,从下标为4的元素开始,全部设置为*,其余不变假设已知元素分别为ABCDEFGHIJ思路:定义一个char类型数组存放元素定义一个指针变量,指向下标为4的元素的地址;通过指针变量的变化,来修改元素为*输出变化
后的元素第24页,共42页。#include<stdio.h>#defineM10#defineB4,voidsetstar(char*,int);voidarrout(char*,int);main(){charc[M]={„A‟,‟B‟,‟C‟,‟C
‟,‟D‟,‟E‟,‟F‟,‟G‟,‟H‟,‟I‟,‟J‟};setstar(&c[4],M-B);arrout(c,M);}voidsetstar(char*a,intn){intI;for(i=0;i<n;i++)*(a+i)=„*‟;}Voidarrout(char
*a,intn){inti;for(i=0;i<n;i++)printf(“%c”,a[i]);}传递的是数组元素的地址第25页,共42页。应用举例•例题9.4定义一个含有15个元素的数组,编写函数:1.调用C库函数中的随机函数给所有元素赋以0-49的随机数(数组x)2.输
出数组元素中的值3.按顺序对每隔三个数求一个和数,并传回主函数(数组w)4.最后输出所有求出的和值附:头文件stklib.h中随机函数n=rand()%xn可以得到0——x-1的随机数,所以得到0-49的随机数即用rand()%
50第26页,共42页。#include<stdio.h>#include<stdlib.h>#defineSIZE15#defineN3main(){intx[SIZE],w[SIZE/N]={0};getrand(x,SIZE);//产生15个随机数放入x数组中priarr(x,SIZE);/
/输出15个随机数getave(x,w,SIZE);//每3个数求一个和,放入w数组priarr(w,SIZE/N);//输出5个和数}第27页,共42页。•例题9.5将数组中的数按倒序重新存放,在操作时,只能借助一个临时存储单
元而不能另外开辟数组。•思路:第一个与最后一个借助临时存储单元交换,依次类推1020304050607080临时存储单元计数器i计数器j直到i=j停止第28页,共42页。程序如下:#include<st
dio.h>#defineNUM8voidpriout(ints[],intn){inti;for(i=0;i<n;i++)printf(%4d”,s[i]);printf(“\n”);}voidinvert(int*a,intn
)//逆序排列{inti,j,t;i=0;j=n-1;while(i<j)//直到i=j时交换结束{t=a[i];a[i]=a[j];a[j]=t;//交换过程i++;j--;//i向后移动j向前移动}}main(){inta[NUM]={10,20,….};printf(“输出原始数据:
”);priout(a,NUM);invert(a,NUM);printf(“输出逆序后的据:”);priout(a,NUM);}第29页,共42页。•例题9.6已知整型数组中的值在0-9范围内,统计每个整数的个数。假设一组数:64761479256181即统计1的个数,2的个数…9个数思路
:{声明数组,输入数组元素(运用随机函数);对数组进行元素统计,将统计结果存放另一个数组中;输出统计结果;}第30页,共42页。假设已经获得M个数据元素存于数组a中声明一个数组c[N],存放统计结果;即c[0]里存放0的个数,c[1]存放1的个数…相当于c[0]里存放a[i]=0时的个数;c[1
]存放a[i]=1的个数…for(i=0;i<N;i++)c[i]=0;for(i=0;i<M;i++)c[a[i]]++;64761479256181c[6]=1;c[4]=1;c[7]=1;c[6]=2;c[4]=2;c[7]=2….第31页,共42页。•例题9.7.已知存放在a数组中的数
不相重合,在a数组中找出和x值相同的元素的位置,若找到,则输出该值和值在数组a中的位置,没找到输出相应的信息。•思路:1.通过终端设备(键盘)生成数组a2.输入一个数x3.查找数组a,是否有与x相等的
值,有则输出该值和值在数组a中的位置,没有输出没找到。第32页,共42页。•1.通过终端设备(键盘)生成数组aintarrin(int*a){inti;n;do{printf(“确定输入数组元素的个数:”)scanf(“%d”,&n);}while((n<
1)||(n>=NUM));//确定元素的个数>0&&<=NUMprintf(“开始输入n个数据“);for(i=0;i<n;i++)scanf(“%d”,a+i);returnn;}下标到n,但是只在n-1之前放置元
素,对于a[n]作为辅助空间第33页,共42页。3.查找数组a,是否有与x相等的值,有则输出该值和值在数组a中的位置,没有输出没找到。•intsearch(int*a,intx,intn){inti,p;i=0;a
[n]=x;//将x放入辅助空间while(x!=a[i])i++;if(i==n)p=-1;elsep=I;returnp;}………a[n]a[0]a[n-1]xi第34页,共42页。#defintNUM30main(){inta[NUM],
x,n,p;n=arrin(a);printf(“输入要查找的元素x”);scanf(“%d”,&x);p=search(a,x,n);if(p!=1)printf(“%d的下标是:%d”,x,p);e
lseprintf(“没有找到与x值一样的元素”);}第35页,共42页。获得随机数voidgetrand(int*a,intn){inti;for(i=0;i<n;i++)a[i]=ranf()%50;}第36页,共42页。输出15个随机数voidpri
arr(int*a,intn){intii;for(i=0;i<n;i++){printf(“%5d”,a[i]);if((i+1)%5==0)printf(“\n”);//使每5个一行输出}printf(“\n”);}第37页,共42页。每三个求和,放入数组w中voidgetave(in
t*a,int*b,intn){inti,j,sum;for(sum=0;i=0,j=0;i<=n;i++){sum+=a[i];if((i+1)%3==0)//每三个一组求和{b[j]=sum;//将和放入新数组中sum=0;//置零,重新累加接下来的三个数j++;}
}}第38页,共42页。•9.8怎样删除数组元素?21222324252627如何删除25?删除实质上是通过移动数组元素中的值来实现.for(i=k;i<n-1;i++0)a[i]=a[i+1];k=5….第39页,共42页。例
题9.9用选择法对数组中的数进行排序•选择排序法的思想:从数组0至n-1中扫描一次选出最小的放到首位,再从1至n-1找出最小的放到第二位,依次类推a[0]a[1]a[2]a[3]a[4]a[5]即574286变量p记录最小数位置m记录最小值
第一次扫描1.开始p=0,m=52.m与a[1]比较,5<7,故m=5,p=0;3.m与a[2]比较,5>4,故m=4,p=2;4.m与a[3]比较,4>2,故m=2,p=3;5.m与a[4]比较,2<8,故m=2,p=3;6.
m与a[5]比较,2<6,故m=2,p=3;此时知最小值为m=2,位置在p=3,再将最小值放到首位即a[0]与a[3]交换,此过程可用如下代码实现:第40页,共42页。第一次扫描代码:j=0;//j用来控制扫描次数,也代表了每次扫描的初始位置p=j;//初始化for(i=j+1
;i<NUM,i++)//i用来控制比较的次数if(m>a[i]){p=i;m=a[p];}if(a[p]>a[i])p=i;t=a[j];a[j]=a[p];a[p]=t;知m代表最小元素,p代表最小元素下标,故m=a[p];则上述程序可以简化如上。结果;a[0]a[1]a[2]a[3]a
[4]a[5]即274586第二次扫描代码:即从a[1]开始,故j=1j=1;//j用来控制扫描次数,也代表了每次扫描的初始位置p=j;//初始化for(i=j+1;i<NUM,i++)//i用来控制比较的次数if(a[p]>a[i]){p=i;}t=a[j];a[j]=a[p]
;a[p]=t;依次类推三次,四次。。。第41页,共42页。思考可以用一个for循环控制扫描次数故排序程序为:voidarrsort(int*a,intn){inti,j,p,t;for(j=0;j<n-
1;j++){p=j;for(i=j+1;i<n;,i++)//i用来控制比较的次数if(a[p]>a[i])p=i;if(p!=i)//即最小值的位置不在扫描的初始位置时才有必要交换{t=a[j];a[j]=a[p];a[p]
=t;}}}#defineNUM6main(){inta[NUM]={5,7,4,2,8,6};arrout(a,NUM);arrsort(a,NUM);…..第42页,共42页。