哈工大计算机c语言考研期中期末考试必备c5.ppt
- 文档编号:18809358
- 上传时间:2023-11-26
- 格式:PPT
- 页数:137
- 大小:1.32MB
哈工大计算机c语言考研期中期末考试必备c5.ppt
《哈工大计算机c语言考研期中期末考试必备c5.ppt》由会员分享,可在线阅读,更多相关《哈工大计算机c语言考研期中期末考试必备c5.ppt(137页珍藏版)》请在冰点文库上搜索。
哈尔滨工业大学计算机学院,2003年8月,C语言程序设计,傅忠传,第五章数组和指针,本章的学习难点,1.数组的概念及其使用。
3.指针的概念以及数组与指针之间的关系。
2.字符数组以及字符串处理函数在字符串处理操作中的应用。
本章目录,数组指针指针和数组间的联系指针数组*指向指针的指针*带参数的main函数和命令行参数*动态数组的实现*关于面向过程的程序设计*关于防御性程序设计*关于程序质量的重要性,数组,数组类型的应用场合定义、初始化和引用一维数组应用举例一维数组名作函数参数二维数组及二维数组作函数参数应用举例字符数组6.1.字符数组与字符串的关系6.2.字符数组的输入输出6.3.字符串处理函数*6.4.字符数组应用举例1、2,数组类型的应用场合,排序算法与数组两个数由小到大排序:
三个数由小到大排序:
十个数由小到大排序:
一百个数由小到大排序:
数组,数组的概念,数组,由若干个相同类型的相关数据项按顺序存储在一起,构成数组(array);数组实际上是同种类型、有序的数据的集合。
数组名,如果用一个统一的名字标识这组数据,那么这个名字就称为数组名。
数组元素,构成数组的每一个数据项称为数组的元素(element)。
说明,同一数组中的元素必须具有相同的数据类型,而且这组数据在内存中将占据一段连续的存储单元。
数组定义的通用格式,格式,类型数组名下标1下标2下标n;,其中:
类型为数组元素的基类型,即每个元素的类型。
下标值n表示为所在维的数组元素个数,该维的数组下标的上界是n-1;C语言中数组下标下界始终为。
维数是下标的个数。
数组分类,一维数组,二维数组与多维数组,一维数组的定义一维数组的初始化一维数组的引用,二维数组的定义二维数组的初始化二维数组的引用,定义、初始化、引用,一维数组的定义,格式,类型数组名常数表达式;,举例,inta10;/各元素都为整形。
定义一个包括10个整形元素的一维数组。
元素为:
a0、a1、a2a9,注明,数组名定名规则和变量名相同,遵循标识符定名规则。
数组名后使用方括号括起来的常数表达式,不能用圆括号。
inta(10);,常数表达式表示元素的个数,即数组长度,而不是数组的上界。
上例不能使用a10越界错误!
常数表达式中可以包括常量和符号常量,不能包括变量。
如变长数组:
设n为整形。
动态数据结构scanf(%d,数组必须先定义,然后使用。
一维数组元素在内存中的排列顺序是线性排列即连续存储的。
一维数组元素的引用,使用说明,C规定只能逐个引用数组元素,而不能一次引用整个数组。
引用形式,数组名下标,其中:
下标可为整形常量或整形表达式。
举例,a0=a5+an+3-a2*3,使用循环语句完成数组的赋值与输出。
main()inti,a10;for(i=0;i=0;i-)printf(%3d,ai);,注明,在数组的引用中,其下标值必须要落在0与n-1之间越界错误!
下标越界也不自动监测。
一个数组元素实质上就是一个变量名,数组元素和变量一样使用。
数组元素下标的括号必须是方括号。
一维数组的初始化,在定义数组时,对数组元素赋初值。
inta10=0,1,2,3,4,5,6,7,8,9a0=0;a1=1;a2=2;a9=9,可以只给一部分元素赋初值。
inta10=0,1,2,3,4a0=0;a1=1;a2=2;a3=3;a4=4初值只赋前5个元素。
如想使一个数组全部为值n,可为:
inta10=0,0,0,0,0,0,0,0,0,0与fortran语言不同,不能为:
inta10=0*10,在对全部数组元素赋初值时,可以不指定数组长度,例如:
inta5=1,2,3,4,5可以写成:
inta=1,2,3,4,5,当数组被说明为静态(static)存储类型或外部存储类型(即在所有函数外部定义)时,则在不显式给出初值的情况下,数组元素将在程序编译阶段自动初始化为0。
staticinta4等价于staticinta4=0,0,0,0,二维数组的定义,格式,类型数组名常数表达式1常数表达式2;,举例,inta34;,可看成3行*4列矩阵:
inta04inta14inta24;每行都是一个包含4个元素的一维数组。
二维数组的排列顺序,元素为:
a00a01a02a03a10a11a12a13a20a21a22a23,按行存储,多维数组,格式,类型数组名常数1常数2常数m;,举例,inta224;,存储顺序,a000a001a002a003a010a011a012a013a100a101a102a103a110a111a112a113,按行存储,二维数组元素的引用,引用形式,数组名下标1下标2,其中:
下标可为整形常量或整形表达式。
举例,a23=a12+b7/2,注明,在数组的引用中,其下标值必须要落在该维的上下界之内。
一个数组元素实质上就是一个变量名,数组元素和变量一样使用。
在数组inta34中,a34=5因为3和4已超出上界。
在数组inta34中,a21不能写成a2,1只能写成a21。
二维数组的初始化,分行给二维数组赋初值。
inta34=1,2,3,4,5,6,7,8,9,10,11,12;也可将所有数据写在一个花括号内,按数组存储顺序对各元素赋值。
inta34=1,2,3,4,5,6,7,8,9,10,11,12,如果对全部元素赋初值(即提供全部初始数据),则定义数据时对第一维长度可以不指定,但第二维长度不能省。
inta34=1,2,3,4,5,6,7,8,9,10,11,12;等价于inta4=1,2,3,4,5,6,7,8,9,10,11,12;,一维数组应用举例,冒泡法排序Fibonacci级数(作业)*折半查找,Fibonacci级数,用数组来处理求Fibonacci的前20项。
例如:
1,1,2,3,5,8,13,21,34,65,,#includemain()inti;staticintf20=1,1;for(i=2;i20;+i)fi=fi-1+fi-2;for(i=0;i20;+i)if(i%5=0)printf(n);printf(%12d,fi);,冒泡法排序,用冒泡法对10个数排序(由小到大)。
482759,248579,245879,245789,245789,245789,482759,482759,482579,482579,428579,冒泡程序,t=aj;aj=aj-1;aj-1=t,注:
可以使用a0,折半查找,1,5,6,9,11,17,25,34,38,41,下界low,上界up,中值mid,共有10个已排好序的数据:
查找9。
折半查找程序,#includemain()intup=9,low=0,mid,found=0,find;inta10=1,5,6,9,11,17,25,34,38,41;scanf(%d,一维数组名作函数参数,使用简单变量作函数参数,能由实参向形参传递一个数据。
使用数组名作函数参数,属于“地址调用”能由主调函数向被调函数传递数组的首地址,并能由被调函数向主调函数传递多个数据。
数组名作为函数参数,传递方式,属于赋地址调用,将实参数组首地址传给虚参,虚参也是一数组名。
虚参要求,必须是数组名。
实参要求,可为另一数组名。
哑实结合,哑实数组具有相同的首地址,即哑实数组第一个元素占用同一存储单元,以后各元素按顺序一一结合。
函数传值(数组名)示意图,地址值,主调函数,实参,地址值,被调函数,实参,实参,形参,调用时,地址值,地址值,形参,形参,执行调用函数,地址值,地址值,从被调用函数返回,修改,已改变,数组名作参数的说明,用数组名作函数参数时,应该在主调函数和被调函数分别定义数组实参数组、形参数组,不能只在一方定义,并且实参数组与形参数组类型必须一致。
2.在被调函数中声明的形参数组的大小n,实际上不起任何作用,因为C编译对形参数组的大小不做检查,只将实参首地址传给形参数组。
3.实参数组和形参数组,既可同名,也可不同名,因它们的数组名代表的是数组的首地址,所以经过“由实参向形参的单向值传递”后,它们便指向了内存中的同一段连续的存储单元。
4.若在被调函数中改变形参数组的元素值,则实参数组中的元素值也会随之发生改变。
注意这种改变不是形参传给实参造成的(C语言不允许这种反向的值传递),而是由于形参和实参两个数组在内存中因指向同一地址而共享同一段内存造成的。
选择出运行结果,#defineMAX10intaMAX,i;main()printf(n);sub1();sub3(a);sub2();sub3(a);sub2()intaMAX,i,max=5;for(i=0;imax;i+)ai=i;sub1()for(i=0;iMAX;i+)ai=i+i;sub3(inta)inti;for(i=0;iMAX;i+)printf(%d,ai);printf(n);,02468101214161801234,B)01234024681012141618,C)012345678901234,D)024681012141618024681012141618,D)024681012141618024681012141618,aMAX,intaMAX,求平均值1,有一个一维数组score,内放10个学生成绩,求平均成绩。
#includefloataverage(floatarray10);/*声明*/main()floatscore10,aver;inti;printf(input10scores:
n);for(i=0;i10;i+)scanf(%f,floataverage(floatarray10)inti;floataver,sum=0;for(i=0;i10;i+)sum=sum+arrayi;aver=sum/10;return(aver);,求平均值1,/*定义*/,二维数组名作函数参数,转置矩阵(作业)*杨辉三角形*魔幻矩阵*读程序、写结果*矩阵行列转换,魔幻矩阵,函数f中的形参a为一个1010的二维数组,n的值为5,一下程序段的运行结果为。
f(inta1010,intn)inti,j,k;j=n/2+1;a1j=1;i=1;for(k=2;kn)i=i+2;j=j-1;elseif(in)j=1;if(aij=0)aij=k;elsei=i+2;j=j-1;aij=k;,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,输出运行结果,写出以下的程序运行结果。
main()inta33=1,3,5,7,9,11,13,15,17;sum=func(a);printf(nsum=%dn,sum);func(inta3)inti,j,sum=0;for(i=0;i3;i+)for(j=0;j3;j+)aij=i+j;if(i=j)sum=sum+aij;return(sum);,Sum=6,矩阵行列转换,将一个二维数组行和列元素互换,存到另一个数组中。
main()inta23,b32,i,j;for(i=0;i=1;i+)for(j=0;j=2;j+)scanf(%d,转置矩阵,求55阶矩阵A的转置矩阵。
#includemain()inta55=1,2,25,i,j,t;for(i=0;i=4;i+)for(j=0;j=i;j+)t=aij;aij=aji;aji=t;for(i=0;i=4;i+)for(j=0;j=4;j+)Printf(“%d,%c”,aij,j-4?
:
n);,#includemain()inta55=1,2,25,i,j,t;for(i=0;i=4;i+)for(j=0;j=4;j+)t=aij;aij=aji;aji=t;for(i=0;i=4;i+)是否正确?
for(j=0;j=4;j+)printf(%d,%c,aij,j-4?
:
n);,思考题:
求矩阵中最大元素的值及其所在位置?
杨辉三角形,打印出以下的杨辉三角形。
111211331464115101051,用一维数组,用二维数组,二维数组实现,#includemain()inta1111,i,j,n;a11=1;a21=1;a22=1;scanf(%d,一维数组实现,#includemain()inta11,i,j,k,n,ij,m;scanf(%d,字符数组的定义,格式,char数组名常数1常数2;,举例,charc10;,c0=I;c1=;c2=a;c3=m;c4=;c5=h;c6=a;c7=p;c8=p;c9=y;,字符数组的初始化,将逐个字符赋给数组中各元素。
charc10=I,a,m,h,a,p,p,y;花括号中初值的个数大于数组长度,则按语法错误处理。
字符数组的引用,说明,引用字符数组中的一个元素,即得到一个字符。
举例,输出一个字符串。
main()charc10=I,a,m,h,a,p,p,y;inti;for(i=0;i=9;i+)printf(%c,ci);printf(n);,字符串和字符串结束标志,提示,在C语言中无字符串数据类型,将字符串作为字符数组处理。
有效字符串,字符数组中,第一个字符串结束标志(0)前的字符串,称为有效字符串。
举例,有效字符串为:
China存储字符串China时,a后自动加0。
字符数组赋初值补充,由于字符串在内存中存储时,后边自动加0,字符数组初始化可为:
charc=Iamhappy;,也可为:
charc=Iamhappy;,与下面的语句等价吗?
charc=I,a,m,h,a,p,p,y;,字符数组赋初值补充,用二维字符数组可存放多个字符串,第二维的长度表示字符串的长度,不能省略,应按最长的字符串长度设定;第一维的长度代表要存储的字符串的个数,可以省略。
charweekday710=Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday;可写成:
charweekday10=Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday;不能写成:
charweekday=Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday;,字符数组与字符串的关系,1.字符串是采用字符数组来表示的,只是在有效字符串后自动加字符串结束标志0。
2.字符数组不是字符串,只有当字符型一维数组中的最后一个元素值为0时,它才构成字符串。
3.对于一个字符串常量,那么这个字符串常量本身代表的就是该字符串在内存中所占连续存储单元的首地址,是一个地址常量。
4.如果将字符串赋值给了一个一维数组,那么这个一维数组的名字就代表这个首地址。
字符串的输入和输出,利用循环,逐个字符输入输出。
用格式赋%c输入或输出一个字符。
将整个字符串一次输入或输出。
用格式赋%s输入或输出一个字符串。
字符串输入,字符串输出,scanf函数对数组元素逐个进行输入。
charc10;for(i=0;i10;i+)scanf(%c,字符串输入,举例,charc10;scanf(%s,c);,说明,scanf函数中的输入项c是字符数组名,不要再加China,从键盘上输入的字符串应短于已定义的字符数组的长度;否则,系统错。
charc10;scanf(%s,c);China,逐个字符输出,遇字符串结束符0,输出结束。
for(i=0;ci!
=0;i+)printf(%c,ci);,字符串输出,举例,charc=China;printf(%sn,c);,说明,结果:
China,输出字符不包括结束符0,只作为结束标志,输出遇0时,输出结束。
用%s格式符输出字符串时,printf函数中的输出项是字符数组名,而不是数组元素名。
printf(%s,c0);printf(%s,c);,如果数组长度大于字符串实际长度,也只输出到遇0结束。
charc10=China;printf(%s,c);China,如果一个字符数组中包含一个以上的0,则遇第一个0时就结束。
charc10=China;printf(%s,c);China,字符串处理函数,puts函数,gets函数,!
strcat函数,!
strcpy函数,!
strcmp函数,!
strlen函数,strlwr函数,strupr函数,#include,输出字符串函数-puts,功能,将一个字符串输出到终端。
格式,puts(,举例,charc=ChinanBeijing;puts(c);,ChinaBeijing,读取字符串函数-gets,功能,从终端输入一个字符串到字符数组。
格式,举例,charc10;gets(c);,China,说明,送给字符数组的是6个字符,而不是5个字符。
函数返回值为字符数组c的起始地址。
用puts和gets函数只能输入或输出一个字符串,而不能写成:
puts(c1,c2,c3);gets(c1,c2,c3);,字符串连接函数-strcat,功能,将字符串str2连接到字符串str1后面。
格式,举例,返回目的字符串str1的首地址,charc110=abc,c210=xyz;strcat(c1,c2);,说明,str1必须足够大,以便容纳连接后的新字符串。
连接前两个字符串的后面都有0,连接时将str1后面的0取消,只在新串最后保留一个0。
字符串复制函数-strcpy,功能,格式,举例,返回目的字符串str1的首地址,charc110=abc,c210=xyz;strcpy(c1,c2);,说明,str1必须足够大,以便容纳复制后的新字符串。
str1必须写成数组名形式,str2可以是字符数组名,也可以是字符串常量。
例如:
strcpy(str1,China);,将字符串str2复制到字符串str1中去。
复制时,连同字符串str2后面的0一起复制到字符数组str1中。
不能用赋值语句将一个字符串常量,或字符数组直接给一个字符数组赋值。
str1=abcd;str1=str2;,字符串比较函数-strcmp,功能,对str1和str2进行比较,当str1=str2,函数值为0;str1str2,函数值为正整数;str1str2,函数值为负整数。
格式,integer:
strcmp(,举例,charc110=abc,c28=abd;strcmp(c1,c2);值为负数,说明,不能用str1=str2来判str1和str2相等。
字符串长度函数-strlen,功能,测试有效字符串长度。
格式,integer:
strlen(,举例,charc10=China;strlen(c);结果不是10和6,而是5,说明,也可以直接测试字符串常量。
strlen(China);,字符串小写函数-strlwr,功能,将字符串中大写字母转换成小写字母。
格式,举例,charc10;strlwr(c);,说明,此函数将str中的大写字母转换成小写字母,同时将str的指针返回。
charc10=China;strlwr(c);结果为:
china,字符串大写函数-strupr,功能,将字符串中小写字母转换成大写字母。
格式,举例,charc10;strupr(c);,说明,此函数将str中的小写字母转换成大写字母,同时将str的指针返回。
charc10=China;strupr(c);结果为:
CHINA,字符数组程序举例-1,输入一个字符串,统计其中字符的个数,再把它们颠倒过来,然后输出。
解法1,解法2,解法3,解法1,#includemain()charc120,c;intn,i;scanf(%s,c1);n=strlen(c1)-1;for(i=0;i=n;i+)c=c1i;c1i=c1n-i;c1n-i=c;printf(n=%dnstring=%sn,n+1,c1);,正确吗?
解法2,#includemain()charc120,c;intn,i;scanf(%s,c1);n=strlen(c1)-1;for(i=0;i=n/2;i+)c=c1i;c1i=c1n-i;c1n-i=c;printf(n=%dnstring=%sn,n,c1);,#includemain()charc120,c;intn,i,j;scanf(%s,c1);n=strlen(c1)-1;for(i=0;in;i+,n-)c=c1i;c1i=c1n;c1n=c;printf(n=%dnstring=%sn,n,c1);,解法3,字符数组程序举例-2,有三个字符串,要求找出最大者。
数据结构:
C0,C1,C2,#includemain()charc320,str20;inti;for(i=0;i=2;i+)gets(ci);strcpy(str,c0);if(strcmp(str,c1)0)strcpy(str,c1);if(strcmp(str,c2)0)strcpy(str,c2);printf(nthelargeststring:
n%sn,str);,指针,5.2.1.指针的概念5.2.2.为什么引入指针的概念5.2.3.变量的指针与变量的指针作为函数参数5.2.4.字符指针*5.2.5.字符指针作为函数参数,指针的概念,1.什么是变量的地址?
什么是变量的内容?
2.什么是直接寻址?
什么是间接寻址?
3.取地址运算符&与间接访问运算符*?
变量的地址与变量的内容,以一个整形变量为例:
申请变量a,第一个字节的地址2002即为变量a的地址。
存储476,0000000111011100即为变量a的内容。
直接寻址,2002,2003,内容,一般变量的寻址方式采用直接寻址:
&a,变量地址a,本质:
变量是通过变量地址来访问变量内容的。
直接按变量名来存取变量内容的访问方式,称为直接寻址。
间接访问,i_pointer=初始化,*i_pointer的值为3,*i_pointer,专门用于存放地址型数据的变量i_pointer就是指针变量。
通过指针变量来间接存取它所指向的变量的访问方式,称为间接寻址。
一般采用指针间接访问变量:
inti,*i_pointer;,取地址运算符,格式,得到某一变量存储空间的首地址。
&V,功能,举例,intA;,2002,2003,变量A,内容,&A的运算结果是2002。
即是变量A的首地址。
间接访问运算符,格式,将指针P所指变量的内容取出来。
*P间接访问运算符(假设变量P为指针变量),功能,举例,intA,*p;设P为指向整形的指针变量,2002,2003,变量A,内容,*P的运算结果是476。
即是变量A的内容。
p=p初始化,指针P,*P和变量A作用是等价的。
为什么引入指针的概念,指针提供通过变量地址访问变量的手段。
指针为C的动态内存分配系统提供支持。
指针为动态数据结构(例如链表、队列、二叉树等)提供支持,操作系统的编写。
指针可以改善某些子程序的效率。
现实中地址的例子:
Email地址、寝室号、手机GPS定位系统(关机),本质:
变量是通过变量地址来访问的。
进一步说明指针重要性,任意从键盘输入两个整数,编程将其交换后再重新输出。
(输出结果是否正确),进一步说明指针重要性,main()voidswap(intx,inty);inta,b;printf(Pleaseentera,b:
);scan
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 哈工大 计算机 语言 考研 期中 期末考试 必备 c5