高级语言程序设计(C语言版 第2版)-基于计算思维能 课件 第6、7章-数组及期应用、指针及其应用_第1页
高级语言程序设计(C语言版 第2版)-基于计算思维能 课件 第6、7章-数组及期应用、指针及其应用_第2页
高级语言程序设计(C语言版 第2版)-基于计算思维能 课件 第6、7章-数组及期应用、指针及其应用_第3页
高级语言程序设计(C语言版 第2版)-基于计算思维能 课件 第6、7章-数组及期应用、指针及其应用_第4页
高级语言程序设计(C语言版 第2版)-基于计算思维能 课件 第6、7章-数组及期应用、指针及其应用_第5页
已阅读5页,还剩466页未读 继续免费阅读

下载本文档

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

文档简介

高级语言程序设计高级语言程序设计——基于计算思维能力培养高级语言程序设计——基于计算思维能力培养第6章数组及其应用主要内容一维数组向函数传递一维数组基于数组的常用算法一维数组的应用二维数组主要内容字符串字符数组的初始化字符数组的输入/输出字符串处理函数字符串应用举例本章思维导图问题的提出计算机是如何存储批量数据,并对它们进行处理的?数组具有相同数据类型的集合,特别适合存储和处理批量数据。一维数组6.16.1.1一维数组的定义与引用一维数组的定义:数据类型

数组名[数组大小];可为基本数据类型或构造数据类型与变量命名

规则相同必须为整型常量

表达式例如:inta[5];

定义了5个int型变量,分别用a[0]..a[4]表示,它们在内存占用连续的内存单元。实际编程时通常定义常量来表示数组的大小,例如:#defineN100inta[N];数组一旦定义,在程序执行期间其位置和大小不能再发生变化。编程时应根据需要处理的数据规模来定义合适的数组大小。

例如,一个年级共有5个班级,每个班级的人数为30~60人不等,如果需要分别对每个班级学生的成绩排序,则程序中定义存储分数的数组大小应按班级的最大人数来确定。一维数组的引用:C语言采用“数组名[下标]”的方式来引用每个数组元素,对长度为N的数组元素,其下标范围是从0至N-1。C语言的数组名记录了数组在内存中的起始地址,因此数组名为一个常量,即a==&a[0]。

&a[i]可等价地表示为a+i,操作系统是通过计算a+i得到a[i]的地址来访问a[i]的。一维数组的引用:

下标可以是常量或变量或整型表达式,但要保证在有效的数组下标范围内。例如:#defineN10inta[N],i=0;a[2+3]=6; //将a[5]赋值为6a[i++]=10; //将a[0]赋值为10后,i自增1(1)将数组的每个元素清0的代码为:for(i=0;i<N;i++)

a[i]=0;(2)从键盘输入每个数组元素值的代码为:for(i=0;i<N;i++)

scanf("%d",&a[i]) //或写成scanf("%d",a+i);(3)求数组的所有元素之和的代码为:sum=0;for(i=0;i<N;i++) sum=sum+a[i];(4)从后向前依次输出数组元素的代码为:for(i=N-1;i>=0;i--) printf("%5d",a[i]); 【例6.1】编写程序,输入10个学生的考试分数,求学生的平均分和超过平均分的学生人数。【分析】可以定义大小为10的数组来存放学生的分数,计算学生的平均分,再通过循环统计成绩超过平均分的学生人数。#include<stdio.h>#defineN10intmain(){doublea[N],sum=0,ave;inti,counter=0;printf("请输入%d个学生分数:\n",N);

for(i=0;i<N;i++) //输入分数scanf("%lf",&a[i]);for(i=0;i<N;i++) //求和 sum+=a[i];

ave=sum/N; //求平均分printf("平均分为:%.2f\n",ave);for(i=0;i<N;i++) //统计超过平均分的学生人数if(a[i]>ave) counter++;printf("超过平均分的学生人数为:%d人.\n",counter);return0;}请输入10个学生分数:98786790877687568845↙平均分为:77.20超过平均分的学生人数为:6人.数组下标越界错inta[10],i;该地址与&a[10]相同for(i=0;i<=10;i++) a[i]=0;将使程序出现死循环非法访问内存单元错误将scanf("%d",&a[i]);写成scanf("%d",a[i]);6.1.2一维数组的初始化未指定存储类型的数组默认为auto型数组,与普通的auto变量一样,分配给数组的内存里的数据是不确定的。可通过单步调试观察数组初始值。6.1.2一维数组的初始化inta[10]={1,2,3,4,5,6,7,8,9,10};将a[0]~a[9]依次初始化为1~10。inta[10]={1,2,3,4,5}; 将a[0]~a[4]被初始化为1~5,而a[5]~a[9]均被初始化为0。6.1.2一维数组的初始化如果初始化列表超出了数组的大小,则将产生编译错误。例如:inta[3]={1,2,3,4};将产生编译错误。6.1.2一维数组的初始化如果在定义数组时进行初始化且省略数组的长度,则编译器将根据初始化列表的元素个数自动确定数组的长度。例如:inta[]={2,4,6,8,10};此时,数组a的长度为5。6.1.2一维数组的初始化1.以下能定义长度为10的一维数组a且能正确进行初始化的语句是()。inta[10]=(0,0,0,0,0);inta[10]={};inta[]={0};inta[10]={10*1};ABCD提交单选题5分【例6.2】利用数组求斐波那契数列前20项的值。f(0)=1 n=0f(1)=1 n=1f(n)=f(n-1)+f(n-2) n≥210112345619f2358#include<stdio.h>#defineN20intmain(){longlongintfib[N]={1,1};inti;for(i=2;i<N;i++)fib[i]=fib[i-1]+fib[i-2];for(i=0;i<N;i++){if(i%10==0)printf("\n");//每行输出10个元素printf("%8ld",fib[i]);}return0;}2.写出下面程序的运行结果。

[填空1]

作答#include<stdio.h>intmain(){inta[]={1,2,3,4},i,j,s=0;j=1;for(i=3;i>=0;i--){s=s+a[i]*j;j=j*10;}printf("s=%d\n",s);return0;}填空题10分主要内容一维数组向函数传递一维数组基于数组的常用算法一维数组的应用练习题向函数传递

一维数组6.26.2向函数传递一维数组1、数组元素作为函数参数与普通变量作函数参数一样,为

单向值传递【例6.3】数组元素作为函数实参示例。#include<stdio.h>#defineN5voidswap(intx,inty){inttemp;temp=x; x=y;y=temp;}intmain(){inta[N]={1,2};printf("%d\t%d\n",a[0],a[1]);swap(a[0],a[1]); printf("%d\t%d\n",a[0],a[1]);return0;} 12122、数组名作为函数实参函数类型函数名(数据类型

数组名[],intn);

或函数类型函数名(数据类型数组名[长度]);当函数参数为数组时,可将数组名作为函数实参。voidfun1(inta[],intn){ inti; for(i=0;i<n;i++) … }可访问长度为n的数组元素,n可由参数传入。调用形式:fun1(b,10);voidfun2(inta[10]){ inti; for(i=0;i<10;i++) … }函数中只对数组的前10个元素进行处理。调用形式:fun2(b);【例6.4】数组名作函数参数示例。#include<stdio.h>#defineM5#defineN10voidfun(inta[],intn){inti;for(i=0;i<n;i++)a[i]=i+1;}【例6.4】数组名作函数参数示例。intmain(){inta[M]={0},b[N]={0},i;fun(a,M);fun(b,N-2);for(i=0;i<M;i++)printf("%4d",a[i]);printf("\n");for(i=0;i<N;i++)printf("%4d",b[i]);return0;}函数调用fun(a,M);数组名代表数组首地址函数调用fun(a,M);函数调用fun(b,N-2);函数调用fun(b,N-2);3、定义数组输入、输出头文件#include<stdio.h>#include<stdlib.h>#include<time.h>voidinput(inta[],intn) {inti;printf("请输入%d个整数(整数间用空格分隔):\n",n);for(i=0;i<n;i++)scanf("%d",a+i);}数组输入函数voidprint(inta[],intn){inti;printf("\n数组的内容是:\n");for(i=0;i<n;i++){if(i%10==0)printf("\n"); printf("%6d",a[i]);}printf("\n");}数组输出函数voidinit(inta[],intn){inti;srand(time(0));for(i=0;i<n;i++)a[i]=rand()%1000+1;//用1~1000的数赋值给数组元素}应用随机函数填充数组将三函数存入Array.h中。在编写程序时可以通过#include“Array.h”指令来使用以上三个函数。#include"Array.h"#defineN10intmain(){inta[N];input(a,N);print(a,N);return0;}该程序文件应与Array.h文件存于同一文件夹下4.若用数组名作为函数调用时的实参,则实际上传递给形参的是()。数组的第一个元素值数组元素的个数数组中全部元素的值数组首地址ABCD提交单选题5分主要内容一维数组向函数传递一维数组基于数组的常用算法一维数组的应用练习题基于数组的常用算法及其应用6.36.3基于数组的常用算法及其应用顺序查找1数据删除2数据插入3简单选择排序5冒泡排序6数据倒置7寻找最大值4二分查找86.3.1顺序查找表的查找顺序检索序号班级名称姓名学号022级网络工程聂加望2208066047122级网络工程潘杰2208066048222级网络工程秦彪2208066049322级网络工程邱强22080660514

522级网络工程唐重喜2208066054012查询姓名为谭青的同学22级网络工程谭青2208066053

34422级网络工程谭青2208066053

顺序检索序号班级名称姓名学号022级网络工程聂加望2208066047122级网络工程潘杰2208066048222级网络工程秦彪2208066049322级网络工程邱强2208066051

522级网络工程唐重喜2208066054012422级网络工程谭青2208066053

3456查询姓名为邹婕的同学【例6.5】编写一个函数:intseqSearch(inta[],intn,intkey),在数组中查找值为key的数组元素,若查找成功,则返回其在数组中的下标,否则返回检索失败的信息。【分析】由于数组在内存中的下标为0~n-1,因此,当查找失败时可以用-1作为函数的返回值。据此,可以写出基于数组的顺序查找算法。#include"Array.h"#defineN100intseqSearch(inta[],intn,intkey){inti=0;while(i<n&&a[i]!=key)//由前向后依次查找i++;if(i<n) returni;else return-1;}intmain(){inta[N],x,pos;init(a,N); //构造测试数组print(a,N);printf("请输入要查找的数:\n");scanf("%d",&x);pos=seqSearch(a,N,x);

if(pos!=-1)printf("a[%d]=%d\n",pos,a[pos]);elseprintf("查找失败!");return0;}如果要从后向前查找,如何实现?22级网络工程秦彪220806604922级网络工程邱强220806605122级网络工程谭青2208066053

22级网络工程秦彪220806604922级网络工程邱强220806605122级网络工程谭青2208066053

表的删除序号班级名称姓名学号22级网络工程聂加望220806604701234122级网络工程潘杰2208066048

删除48号学生(潘杰)信息6.3.2数据删除【例6.6】编写一个函数intdelData(inta[],intn,intpos),在数组中删除a[pos]的元素值。30511021631742253364376687743N-1删除数组元素删除第pos个位置的元素intdelData(inta[],intn,intpos){}pos6677109…ni9#include"Array.h"#defineN10intdelData(inta[],intn,intpos){inti;if(pos>=0&&pos<n){ for(i=pos+1;i<n;i++) a[i-1]=a[i]; returnn-1; }elsereturnn; }判断删除位置是否合法后续元素依次前移删除成功,元素减少1个删除失败,元素仍为n个intmain(){ inta[N],n,pos;

init(a,N); //构造测试数组 print(a,N); printf("请输入要删除的位置:\n"); scanf("%d",&pos);

n=delData(a,N,pos); //在数组中删除a[pos] print(a,n); return0;}数组的内容是:34870350931655514543756246480请输入要删除的位置:2↙数组的内容是:34870931655514543756246480如果要根据输入的数据值来删除与其相等的元素,该如何实现?如果数组中存在多个相同的待删除数据,如何将其全部删除?22级网络工程秦彪220806604922级网络工程邱强220806605122级网络工程谭青2208066053

表的插入序号班级名称姓名学号22级网络工程聂加望220806604722级网络工程秦彪220806604922级网络工程邱强220806605122级网络工程谭青2208066053

01234122级网络工程潘杰2208066048

插入48号学生(潘杰)信息6.3.2数据插入数组元素的插入算法305110216317422543653766877961196x43536677iN-1数组元素的插入算法在第pos个位置插入值为x的结点intinsertData(inta[],intn,intpos,intx){}pos9101112305110216317422543653…66…7796963343536677100N-1intinsertData(inta[],intn,intpos,intx){}pos空间已满怎么办?插入位置不合法怎么办?pos数组元素的插入算法【例6.7】编写一个函数insertData(inta[],intn,intpos,intx),在具有n个元素的数组中的pos位置插入一个值为x的元素。intinsertData(inta[],intn,intpos,intx){inti;if(pos>=0&&pos<=n) //判断位置是否合法 { for(i=n-1;i>=pos;i--)//元素后移

a[i+1]=a[i]; a[pos]=x; //数据插入n++; //元素个数加1 }returnn;}intmain(){ inta[N],n,pos,x; init(a,10); //构造测试数组 print(a,10); printf("请输入要插入的位置和数据:\n"); scanf("%d%d",&pos,&x); n=insertData(a,10,pos,x);//在数组的pos处插入x print(a,n); return0;}为什么旧款手机短信容量受限?若采用顺序表实现,则电话薄、短信容量受限!户口簿住址变动登记序号发送方发送时间短信内容1138791000012013.7.810:22亲,………

数组存储短信息某商场搞促销,当日购物金额最多者,可返10%购物款。6.3.3寻找最大数若当日客户购物金额存储在数组中,任务的关键就是在数组中找出最大数?【例6.8】编写一个函数intfindMax(inta[],intn),在具有n个元素的数组中查找最大数作为函数的返回值。intfindMax(inta[],intn){inti,maxData=a[0];for(i=1;i<n;i++)if(a[i]>maxData)

maxData=a[i];returnmaxData;}假设初始时a[0]为最大数搜索剩余的n-1个元素发现更大数,则替换intmain(){ inta[N],maxData; init(a,N); //构造测试数组 print(a,N);

maxData=findMax(a,N);//在数组中找最大数 printf("maxData=%d\n",maxData); return0;}若要求返回数组中最大值的位置(下标),查找函数如何修改?intfindMax(inta[],intn){inti,maxIndex=

; //记录初始位置for(i=1;i<n;i++)if(a[i]>

)

//记录新位置return

//返回最大数位置

}若要找最小数位置如何修改?0a[maxIndex]maxIndex=i;maxIndex;学号姓名成绩2208066001聂加望902208066002潘杰882208066003秦彪922208066004邱强78…6.3.5数据排序排序方法排序方法简单选择排序274924160822简单选择排序0 1 2 3 4 52222274949找第1个最大数274924160822简单选择排序0 1 2 3 4 5找第2个最大数16272727274924160822简单选择排序0 1 2 3 4 5找第3个最大数162224274924160822简单选择排序0 1 2 3 4 5找第4个最大数274924160822简单选择排序0 1 2 3 4 5找第5个最大数274924160822简单选择排序0 1 2 3 4 5n个数,共需重复n-1次。若每次找出的是最小数,则可实现升序排列。简单选择排序简单选择排序简单选择排序【例6.9】编写一个函数voidselectSort(inta[],intn),采用简单选择排序法对具有n个元素的数组按升序排序。voidselectSort(inta[],intn){inti,j,minIndex,temp;for(i=0;i<n-1;i++) {minIndex=i; //初始最小值位置for(j=i+1;j<n;j++)//在a[i..n-1]中找最小数if(a[j]<a[minIndex])minIndex=j;【例6.9】编写一个函数voidselectSort(inta[],intn),采用简单选择排序法对具有n个元素的数组按升序排序。if(minIndex!=i)//若最小数不在第i个位置,则交换{ temp=a[i];a[i]=a[minIndex];a[minIndex]=temp;}}}intmain(){inta[N];input(a,N); //输入待排序数据selectSort(a,N); //排序print(a,N); //输出排序后数组return0;}请输入10个整数(整数间用空格分隔):201080706050100304090↙数组的内容是:

102030405060708090100IntelCorei502450MCPU2.5GHZ

4G内存Win7实验

采用选择法对不同规模数据进行升序排列。数据量时间(秒)2100.0472110.0522120.1272130.1532140.4362151.7242166.56721724.992218100.3110.0470.05224.992100.316.3基于数组的常用算法及其应用顺序查找1数据删除2数据插入3简单选择排序5冒泡排序6数据倒置7寻找最大值4二分查找8274924160822观察现象观察现象272416082249一趟冒泡a[0]<a[1],无须交换一趟冒泡a[1]>a[2],交换a[1]与a[2]一趟冒泡a[2]>a[3],交换a[2]与a[3]一趟冒泡a[3]>a[4],交换a[3]与a[4]一趟冒泡a[4]<a[5],无须交换一趟冒泡a[5]>a[6],交换a[5]与a[6]一趟冒泡a[6]>a[7],交换a[6]与a[7]一趟冒泡最大数在a[7]一趟冒泡算法实现for(i=0;i<n-1;i++) //共需两两比较n-1次if(a[i]>a[i+1]) //发现逆序,则交换{ temp=a[i];a[i]=a[i+1];a[i+1]=temp;}一趟冒泡一趟冒泡的过程可用下面的代码实现:冒泡排序272416082249冒泡排序272416082249冒泡排序n>1一趟冒泡n--truefalsevoidbubbleSort(inta[],intn){inti,temp;while(n>1)

//参与冒泡的元素个数大于1{for(i=0;i<n-1;i++)//一趟冒泡if(a[i]>a[i+1]){temp=a[i];a[i]=a[i+1];a[i+1]=temp;}

n--;

//参与冒泡的数据个数减1}}IntelCorei502450MCPU2.5GHZ

4G内存Win7实验

采用冒泡法对不同规模数据进行升序排列。数据量时间(秒)2100.0472110.0592120.0902130.3222140.9212153.68321614.67721758.781218233.120.0470.05958.781233.12改进冒泡排序算法数据已有序改进冒泡排序算法当数据已有序时,如何提前结束冒泡过程?voidbubbleSort(inta[],intn){inti,temp;boolflag=true; //flag==true表示未排好序while(n>1&&flag) {flag=false;for(i=0;i<n-1;i++) //一趟冒泡if(a[i]>a[i+1]){temp=a[i];a[i]=a[i+1];a[i+1]=temp;

flag=true;}

n--;//参与冒泡的数据个数减1}}单击倒置6.3.6数据倒置案例1:火车时刻表发车时间查询。【例6.11】设计一个函数voidreverse(inta[],intn),将数组进行首尾倒置。9995算法演示:1002013024035046057068090n-1ai…j1095算法演示:9902013024035046057068090n-1ai…j1095算法演示:9902013024035046057068090n-1ai…j【例6.11】设计一个函数voidreverse(inta[],intn),将数组进行首尾倒置。循环终止条件:i>=j10209909519028037046055064030n-1ai…jvoidreverse(inta[],intn){inti=0,j=n-1,temp;while(i<j){temp=a[i]; //交换a[i]与a[j]a[i++]=a[j];a[j--]=temp;}}【例6.11】设计一个函数voidreverse(inta[],intn),将数组进行首尾倒置。如何用递归算法实现?课后习题:编写函数,采用递归法实现数组首尾倒置。voidreverse(inta[],intleft,intright)9995算法演示:1002013024035046057068090n-1aleft…right1095算法演示:9902013024035046057068090n-1aleft…rightaleftright递归出口请大家课后实现!顺序查找“瞎子”找真币假币假币假币假币假币假币顺序查找效率分析对于具有n个元素的顺序表查找成功情况下:

最好情况1次;最坏情况n次。等概率情况的平均查找次数:查找失败情况下:

n次。顺序查找

超市若有10000种不同货品,每扫描一个条码时需要在10000种不商品中寻找这件商品的名称和价格。若1秒内查询1000次,查完全部货物耗时10秒。怎样提高检索效率?顺序查找幸运52——猜价格123456….4096查询关键字150020486.3.7二分查找查询关键字150010246.3.7二分查找查询关键字150015366.3.7二分查找二分检索序号班级名称姓名学号022级网络工程聂加望2208066047122级网络工程潘杰2208066048222级网络工程秦彪2208066049322级网络工程邱强22080660514

522级网络工程唐重喜2208066054l=0查询学号为2208066053的同学22级网络工程谭青2208066053

422级网络工程谭青2208066053

r=5midl=3mid序号班级名称姓名学号022级网络工程聂加望2208066047122级网络工程潘杰2208066048222级网络工程秦彪2208066049322级网络工程邱强22080660514

522级网络工程唐重喜2208066054l=0查询学号为2208066052的同学422级网络工程谭青2208066053

r=5midl=3mid二分检索序号班级名称姓名学号022级网络工程聂加望2208066047122级网络工程潘杰2208066048222级网络工程秦彪2208066049322级网络工程邱强22080660514

522级网络工程唐重喜2208066054查询学号为2208066052的同学422级网络工程谭青2208066053

r=3l=3mid二分检索序号班级名称姓名学号022级网络工程聂加望2208066047122级网络工程潘杰2208066048222级网络工程秦彪2208066049322级网络工程邱强22080660514

522级网络工程唐重喜2208066054查询学号为2208066052的同学422级网络工程谭青2208066053

r=3l=4mid查找失败二分检索【例6.12】设计函数intbinSearch(inta[],intn,intkey),采用二分查找算法在升序排列的数组a中查找值为key的元素所在的位置。intbinSearch(inta[],intn,intkey){intleft=,right=

,mid;while(left<=right) { mid=;//二分 if(a[mid]==key)

//查找成功 return; elseif(key<a[mid])right=;elseleft=; } return; //查找失败}0n-1(left+right)/2midmid-1mid+1-1二分检索递归程序如何实现?主要内容一维数组向函数传递一维数组基于数组的常用算法一维数组的应用练习题6.3.8一维数组应用实例1.进位制转换算法演示:222826838072376543210算法演示:215826838076543210723算法演示:215826838076543210723编程提示:按照先进后出,后进先出来组织数据的结构等为“栈”。【例6.13】编写一个程序,实现无符号十进制数m到R进制数的转换功能(一般R取16,8或2)。voiddtoR(unsignedintm,intr){intstack[32]; inttop=0;printf("%d=(",m);while(m) //进位制转换{stack[top++]=m%r;m=m/r;}【例6.13】编写一个程序,实现无符号十进制数m到R进制数的转换功能(一般R取16,8或2)。top--;while(top>=0)//从后向前输出数组内容{ //转换为对应的ASCII字符形式输出printf("%c",stack[top]>9?stack[top]+'A'-10:stack[top]+'0');top--;}printf(")%d\n",r);}intmain(){unsignedintm;printf("请输入要转换的十进制正整数:");scanf("%u",&m);dtoR(m,2); //转换成二进制数dtoR(m,8); //转换成八进制数dtoR(m,16); //转换成十六进制数return0;}请输入要转换的十进制正整数:215↙215=(11010111)2215=(327)8215=(D7)162.

筛法求素数基本思想:

把从1开始的、某一范围内的正整数从小到大顺序排列,1不是素数,首先把它筛掉。

剩下的数中选择最小的数是素数,然后去掉它的倍数。依次类推,直到筛子为空时结束。以求1~30以内的素数为例:123456789101112131415161718192021

2223242526272829301不是素数,去掉。剩下的数中2最小,是素数,去掉2的倍数。下一个最小的数是3,是素数,去掉3的倍数。…求出的素数为:2357111317192329【例6.14】编写一个程序用筛法输出1~N之内的所有素数。【分析】具体实现时,可以定义一个大小为N+1的数组,利用下标1~N来表示N个整数,而用a[i]=1来表示i是素数,a[i]=0来表示i不是素数。#include<stdio.h>#defineN200intmain(){intprime[N+1]={0};inti,j,counter=0; //counter为素数计数器for(i=2;i<=N;i++)prime[i]=1; //初始时,将2~N设为素数for(i=2;i<=N;i++)if(prime[i]==1) //i是素数{printf("%5d",i);counter++;if(counter%10==0)printf("\n");for(j=i;j<=N;j+=i)//将i的倍数全部设为非素数prime[j]=0;}return0;}二维数组6.46.4二维数组序号数学C语言英语08090781928867288928039988904991009057989876.4.1二维数组的定义、引用及初始化1.二维数组的定义数据类型

数组名[常量表达式1][常量表达式2];行数列数例如:

inta[3][4];2.二维数组的引用二维数组可通过行下标与列下标来引用,与一维数组相同,行列下标可以是常量、变量或表达式,但要保证其在有效的范围内。inta[2][4];a[0][1]=1;for(j=0;j<4;j++) a[0][j]=j;printf("%d",a[2][4]);实际编程中,常通过双重循环结构来实现对整个二维数组的访问。for(i=0;i<3;i++){for(j=0;j<4;j++)scanf("%d",&a[i][j]);}二维数组的输入for(i=0;i<3;i++){for(j=0;j<4;j++) printf("%5d",a[i][j]);printf("\n"); }二维数组的输出3.二维数组的初始化(1)采用分行赋值。3.二维数组的初始化(2)若在初始化列表中省略每一行的{},按初始化列表从前向后按行优先的顺序对数组进行赋值,不足部分自动赋值为0。3.二维数组的初始化(3)在对二维数组进行初始化时,可省略数组的行数,编译器会根据初始化列表的项数自动确定数组的行数。inta[][4]={1,2,3,4,5,6,7,8,9};3.二维数组的初始化将使数组共有4行。inta[][4]={{1,2,3},{4,5,6},{7,8,9,10},{11}};123045607891011000注意:在定义二维数组时不能省略列的定义。10.下列选项中正确的二维数组定义与初始化语句是()。inta[][]={1,2,3,4,5,6};inta[2][]={1,2,3,4,5,6};inta[][3]={1,2,3,4,5,6};inta[2,3]={1,2,3,4,5,6};ABCD提交单选题5分11.已知inti,x[3][3]={1,2,3,4,5,6,7,8,9};,则下面语句

for(i=0;i<3;i++)

printf("%d",x[i][2-i]);的输出结果是()。147159357369ABCD提交单选题5分12.若定义了intb[][3]={1,2,3,4,5,6,7};,则b数组的行数是()。234无确定值ABCD提交单选题5分6.4.2二维数组应用实例【例6.15】编写一个程序,定义一个二维数组,从键盘输入该数组的值,然后查找该数组中最大数和其所在的位置并输出。【分析】采用双重循环对二维数组进行搜索。#include<stdio.h>#defineM4#defineN5intmain(){inta[M][N],i,j;intmaxData,row,col;printf("请输入%d行%d列的矩阵:\n",M,N);for(i=0;i<M;i++)for(j=0;j<N;j++)scanf("%d",&a[i][j]);

maxData=a[0][0]; //maxData用于记录最大值row=col=0;//row,col分别记录最大值所在的行与列for(i=0;i<M;i++)for(j=0;j<N;j++)

if(a[i][j]>maxData){maxData=a[i][j]; row=i;col=j;}printf("maxData=a[%d][%d]=%d\n",row,col,maxData);return0;}【例6.16】编程在屏幕上输出n行杨辉三角形,n由键盘输入。(1)每行的第1个与最后一个数均为1;(2)其它各数等于它上一行左边列和上一行上一列的两数之和。#include<stdio.h>#defineN15intmain(){inta[N][N],n;inti,j;printf("请输入需输出的杨辉三角行数(小于等于15):");scanf("%d",&n);for(i=0;i<n;i++){a[i][0]=a[i][i]=1;//两端为1

for(j=1;j<i;j++) a[i][j]=a[i-1][j-1]+a[i-1][j];}for(i=0;i<n;i++){ for(j=0;j<=i;j++) //输出一行 printf("%-5d",a[i][j]); printf("\n"); //换行}return0;}【例6.17】有M名学生,学习N门课程,已知所有学生的各科成绩,编程实现,分别求每位学生的总分和每门课程的平均成绩。如何存储,如何计算?请输入1号学生的3门课程成绩:7086.590↙请输入2号学生的3门课程成绩:778267↙请输入3号学生的3门课程成绩:567092↙请输入4号学生的3门课程成绩:969088↙-------------------------------------------------------学号总分成绩1成绩2成绩3-------------------------------------------------------1246.5070.0086.5090.002226.0077.0082.0067.003218.0056.0070.0092.004274.0096.0090.0088.00-------------------------------------------------------成绩1平均分:74.75成绩2平均分:82.13成绩3平均分:84.25行数和列数比学生数、课程数多1第0行存放课程的平均分,第0列存放学生的总分。#include<stdio.h>#defineM4#defineN3intmain(){floatscore[M+1][N+1];inti,j;for(i=1;i<=M;i++)//键盘输入学生成绩{printf("请输入%d号学生的%d门课程成绩:",i,N);for(j=1;j<=N;j++)scanf("%f",&score[i][j]);}输入学生成绩信息for(i=1;i<=M;i++){score[i][0]=0;//第i位学生的总分存到第i行第0列for(j=1;j<=N;j++) score[i][0]+=score[i][j];}

求每位学生的总分for(j=1;j<=N;j++){score[0][j]=0;for(i=1;i<=M;i++)score[0][j]+=score[i][j];score[0][j]/=M;}

每门课程的平均成绩存到所在列的第0行。求每门课程的平均成绩printf("------------------------------------------\n");printf("学号\t总分\t成绩1\t成绩2\t成绩3\n");printf("------------------------------------------\n");for(i=1;i<=M;i++){printf("%d\t",i);for(j=0;j<=N;j++)printf("%.2f\t",score[i][j]);printf("\n");}输出学生成绩表printf("------------------------------------------\n");for(j=1;j<=N;j++)printf("成绩%d平均分:%.2f:\n",j,score[0][j]);return0;}输出各门课程的平均成绩向函数传递

二维数组6.56.5向函数传递二维数组当二维数组作为函数的形参时,对应的实参应该是二维数组名。此时,实参向形参传递的是二维数组的首地址,函数中对形参数组的访问实际上是对实参数组的访问。1234567815263748【例6.17】设计函数transpose,将M行N列的矩阵a转置为N行M列的矩阵b。矩阵B矩阵A#include<stdio.h>#defineM2#defineN4/*@函数名称:transpose入口参数:inta[M][N]@函数功能:将M行N列的矩阵a转置为N行M列的矩阵b@出口参数:数组b*/voidtranspose(inta[M][N],intb[N][M]){inti,j;for(i=0;i<M;i++)for(j=0;j<N;j++) b[j][i]=a[i][j];}intmain(){inta[M][N]={1,2,3,4,5,6,7,8};intb[N][M]={0};inti,j;for(i=0;i<M;i++) //输出矩阵a{for(j=0;j<N;j++) printf("%4d",a[i][j]);printf("\n");}

transpose(a,b);

//矩阵转置for(i=0;i<N;i++) //输出矩阵b{for(j=0;j<M;j++) printf("%4d",b[i][j]);printf("\n");}}可否设计一个通用的二维数组输出函数,来分别输出数组a与数组b的内容?print(a,M,N); print(b,N,M); 方案1:将print函数定义为:结论:二组数组形参不能省略列!voidprint(inta[][],intm,intn){inti,j;for(i=0;i<m;i++){for(j=0;j<n;j++)printf("%-4d",a[i][j]);printf("\n");}}编译时出现“error:arraytypehasincompleteelementtype”的错误提示,指示函数的数组形参定义存在问题。方案2:

把函数首部改为:voidprint(inta[][N],intm,intn),函数体不变,再次编译,编译错误消失。print(a,M,N)print(b,N,M)ArrayA:12345678ArrayB:

15371256方案3:

把函数首部改为voidprint(inta[][M],intm,intn),函数体不变。print(a,M,N)print(b,N,M)ArrayA:12343456ArrayB:15263748C语言规定,在定义二维数组为形参时,形参数组的行可以省略,但不能省略二维数组的列。调用该函数时实参数组要求与形参数组具有相同的列(行可以不同)。voidprint(inta[][N],intm) {inti,j;for(i=0;i<m;i++){for(j=0;j<N;j++)printf("%-4d",a[i][j]);printf("\n");}}该函数只能用于输出列为N的二维数组。行参数【例6.18】设计print(inta[][N],intm)函数,输出行为m列为N的二维数组。#defineN3voidprint(inta[][N],intm) {inti,j;for(i=0;i<m;i++){for(j=0;j<N;j++)printf("%-4d",a[i][j]);printf("\n");}}行参数intmain(){inta[2][N]={{1,2,3},{4,5,6}};intb[3][N]={1,2,3,4,5,6,7,8,9};printf("Arraya:\n");print(a,2);printf("Arrayb:\n");print(b,3);return0;}要设计能处理任意行、任意列的二维数组的

函数,需要用到指针相关知识。主要内容字符串字符数组的初始化字符数组的输入/输出字符串处理函数字符串应用举例字符串及

字符数组6.66.6.1字符串字符串(常量)是用双引号括起来的若干字符序列。"MynameisTony.""Iamfine\nThankyou."C语言用'\0'('\0'是ASCII为0的字符,注意它与'0'的区别)来作为字符串结束标识。结束标识结束标识“China”占用6个字节该串占用17个字节6.6.1字符串6.6.2字符数组的初始化用字符初始化列表初始化部分单元charb[10]={'C','h','i','n','a'};6.6.2字符数组的初始化若省略数组大小,则自动根据字符初始化列表的项数决定数组大小。chara[]={'C','h','i','n','a'};6.6.2字符数组的初始化C语言没有提供专门的字符串类型,而是采用字符数组存储字符串,因此,字符数组有时也称为字符串变量。用字符初始化列表初始化所有单元chara[5]={'C','h','i','n','a'};6.6.2字符数组的初始化用字符串常量给字符数组初始化时,字符串结束符需要占用一个字节单元,同时可以省略{}chara[]={"Hello"};与chara[]="Hello";等价具有'\0'结束的字符数组可视为字符串变量。6.6.3字符数组的输入/输出chara[10];scanf("%s",a); //输入字符串printf("%s",a); //输出字符串(2)用格式控制符%s,按字符串方式进行输入或输出。数组名scanf视空格、Tab和回车等字符为字符串的输入结束符。例如,当输入Howareyou?时,仅"How"被存入数组a,遇空格结束输入,并自动在w后面放上'\0',如下所示。How\0

printf("%s",a);从数组a的首地址开始输出字符串,遇'\0'结束输出('\0'本身不输出),输出完成后光标不换行。6.6.3字符数组的输入/输出字符数组的输入/输出有三种方式:(1)通过循环语句用逐个输入或输出数组元素。chara[10];inti;for(i=0;i<10;i++) scanf("%c",&a[i]); //或a[i]=getchar();for(i=0;i<10;i++) printf("%c",a[i]); //或 putchar(a[i]);6.6.3字符数组的输入/输出(3)用字符串输入函数gets、字符串输出函数puts进行字符串输入与输出,两个函数均在stdio.h中定义。chara[10];gets(a); puts(a);输入字符串存入a数组,遇回车符结束输入,并在字符串的最后存入'\0'。输出字符串a,遇'\0'结束输出并换行。6.6.3字符数组的输入/输出【例6.19】从键盘输入一个英文字符串,将其中的小写字母转换成大写字母后输出。#include<stdio.h>intmain(){chars[80];inti=0;printf("Pleaseinputastring:\n");gets(s);while(s[i]!='\0'){if(s[i]>='a'&&s[i]<='z')s[i]=s[i]-32; //小写字母转大写字母i++; }puts(s);}15.字符数组s不能作为字符串使用的是()。chars[]="happy";chars[]={"happy"};chars[6]={'h','a','p','p','y'};chars[4]={'h','a','p','p','y'};ABCD提交单选题5分【例6.20】从键盘输入三个字符串,分别计算三个字符串的长度后输出(含首尾空格)。【分析】可以用一个3行的二维字符数组来存放三个字符串,每行存放一个字符串。每行字符串'\0'前面的字符个数就是该字符串的长度。#include<stdio.h>intmain(){chars[3][80]

温馨提示

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

评论

0/150

提交评论