(6.1.5)--第6章C语言程序设计.ppt
6 6 6 6利用数组处理批量数据第第第第章章章章为什么需要循环控制(1)数组是一组有序数据的集合。数组中各数据的排列是有一定规律的,下标代表数据在数组中的序号。(2)用数组名和下标即可唯一地确定数组中的元素。(3)数组中的每一个元素都属于同一个数据类型。数组用50个float型简单变量表示学生的成绩烦琐,如果有1000名学生怎么办呢?没有反映出这些数据间的内在联系,实际上这些数据是同一个班级、同一门课程的成绩,它们具有相同的属性。要向计算机输入全班50个学生一门课程的成绩解决方法S15数组名下标s15定义一维数组类型型说明符明符 数数组名名常量表达式常量表达式(1)数组名的命名规则和变量名相同,遵循标识符命名规则。(2)在定义数组时,需要指定数组中元素的个数,方括号中的常量表达式用来表示元素的个数,即数组长度。(3)常量表达式中可以包括常量和符号常量,不能包含变量。int a10;整型数组,即数组中的元素均为整型数组名为a数组包含10个整型元素a0a1a2a3a4a5a6a7a8a9相当于定义了10个简单的整型变量注意数组元素的下下标从从0开开始始,用“int a10;”定义数组,则最大下标值为9,不存在数组元素a10引用一维数组元素数数组名名下下标 只能引用数组元素而不能一次整体调用整个数组全部元素的值。数组元素与一个简单变量的地位和作用相似。“下标”可以是整型常量或整型表达式。注意定义数组时用到的“数组名常量表达式”和引用数组元素时用的“数组名下标”形式相同,但含义不同。int a10;/前面有int,这是定义数组,指定数组包含10个元素t=a6;/这里的a6表示引用a数组中序号为6的元素引用一维数组元素【例6.1】对10个数组元素依次赋值为0,1,2,3,4,5,6,7,8,9,要求按逆序输出。#includeint main()int i,a10;for(i=0;i=0;i-)/输出a9a0共10个数组元素printf(%d,ai);printf(n);return 0;第1个for循环使a0a9的值为09。第2个for循环按a9a0的顺序输出各元素的值。a0a1a2a3a4a5a6a7a8a90123456789一维数组的初始化(1)在定义数组时对全部数组元素赋予初值。将数组中各元素的初值顺序放在一对花括号内,数据间用逗号分隔。花括号内的数据就称为“初始化列表初始化列表”。(2)可以只给数组中的一部分元素赋值。定义a数组有10个元素,但花括号内只提供5个初值,这表示只给前面5个元素赋初值,系统自动给后5个元素赋初值为0。(3)给数组中全部元素赋初值为0。(4)在对全部数组元素赋初值时,由于数据的个数已经确定,因此可以不指定数组长度。但是,如果数组长度与提供初值的个数不相同,则方括号中的数组长度不能省略。为了使程序简洁,常在定义数组的同时给各数组元素赋值,这称为数组的初始化。int a10=0,1,2,3,4,5,6,7,8,9;int a10=0,1,2,3,4;int a10=0,0,0,0,0,0,0,0,0,0;int a10=0;/未赋值的部分元素自动设定为0或int a5=1,2,3,4,5;int a=1,2,3,4,5;或一维数组程序举例【例6.2】用数组来处理求Fibonacci数列问题。#include int main()int i;int f20=1,1;/对最前面两个元素f0和f1赋初值1for(i=2;i20;i+)fi=fi-2+fi-1;/先后求出f2f19的值for(i=0;i20;i+)if(i%5=0)printf(n);/控制每输出5个数后换行 printf(%12d,fi);/输出一个数printf(n);return 0;一维数组程序举例【例6.3】有10个地区的面积,要求对它们按由小到大的顺序排列。起泡排序法起泡排序法算法算法985420854209542089420589204589第一趟第二趟第三趟第四趟第五趟一维数组程序举例【例6.3】有10个地区的面积,要求对它们按由小到大的顺序排列。#include int main()int a10;int i,j,t;printf(input 10 numbers:n);for(i=0;i10;i+)scanf(%d,&ai);printf(n);for(j=0;j9;j+)/进行9次循环,实现9趟比较for(i=0;iai+1)/相邻两个数比较 t=ai;ai=ai+1;ai+1=t;printf(the sorted numbers:n);for(i=0;iai+1定义和引用二维数组有3个小分队,每队有6名队员,要把这些队员的工资用数组保存起来以备查。小例子队员1 队员2 队员3 队员4 队员5 队员6第第1分分队245618471243160023462757第第2分分队304520181725202024581436第第3分分队142711751046197614772018如果建立一个数组pay,它应当是二维的,第一维用来表示第几分队,第二维用来表示第几个队员。例如用pay2,3表示2分队第3名队员的工资,它的值是1725。二维数组常称为矩矩阵(matrix)。把二维数组写成行行(row)和列列(column)的排列形式,可以有助于形象化地理解二维数组的逻辑结构。定义二维数组类型型说明符明符 数数组名名常量表达式常量表达式常量表达式常量表达式二维数组可被看作一种特殊的一维数组:它的元素又是一个一维数组。例如,float a34;可以把a看作一个一维数组,它有3个元素:a0,a1,a2,每个元素又是一个包含4个元素的一维数组:a0 a00 a01 a02 a03 a1 a10 a11 a12 a13 a2 a20 a21 a22 a23float pay36;float型二维数组数组名为pay数组第二维有6个元素数组第一维有3个元素float a34,b510;/定义a为34(3行4列)的数组,b为510(5行10列)的数组float a3,4,b5,10;/在一对方括号内不能写两个下标二维数组的存储C语言中,二维数组中元素排列的顺序是按行存放的。float a34注意用矩矩阵形式形式(如3行4列形式)表示二维数组,是逻辑上的概念,能形象地表示出行列关系。而在内存内存中,各元素是连续存放的,不是二维的,是线性性的。a00 a01 a02 a03a10 a11 a12 a13a20 a21 a22 a23a00a01a02a03a10a11a12a13a20a21a22a23200020042008201220162020202420282032203620402044第0行元素第1行元素第2行元素多维数组多维数组元素在内存中的排列顺序为:第1维的下标变化最慢,最右边的下标变化最快。float a2,3,4;/定义三维数组a,它有2页,3行,4列float a2,3,4;在内存中的排列顺序为:a000 a001 a002 a003 a010 a011 a012 a013 a020 a021 a022 a023 a100 a101 a102 a103 a110 a111 a112 a113 a120 a121 a122 a123引用二维数组元素数数组名名下下标 下下标“下标”可以是整型常量或整型表达式。数组元素可以出现在表达式中,也可以被赋值,如:b12=a23/2;注意在引用数组元素时,下标值应在已定义的数组大小的范围内。严格区分在定定义数组时用的a34和引用引用元素时的a34的区别。前者用a34来定义数组的维数和各维的大小,后者a34中的3和4是数组元素的下标值,a34代表行序号为3、列序号为4的元素(行序号和列序号均从0起算)。int a34;/定义a为34的二维数组 a34=3;/不存在a34元素/数组a可用的“行下标”的范围为02,“列下标”的范围为03引用一维数组元素【例6.1】对10个数组元素依次赋值为0,1,2,3,4,5,6,7,8,9,要求按逆序输出。#includeint main()int i,a10;for(i=0;i=0;i-)/输出a9a0共10个数组元素printf(%d,ai);printf(n);return 0;第1个for循环使a0a9的值为09。第2个for循环按a9a0的顺序输出各元素的值。a0a1a2a3a4a5a6a7a8a90123456789二维数组的初始化(1)分行给二维数组赋初值。(最清楚直观)(2)可以将所有数据写在一个花括号内,按数组元素在内存中的排列顺序对各元素赋初值。(3)可以对部分元素赋初值。(4)如果对全部元素都赋初值(即提供全部初始数据),则定义数组时对第1维的长度可以不指定,但第2维的长度不能省。在定义时也可以只对部分元素赋初值而省略第1维的长度,但应分行赋初值。可以用“初始化列表”对二维数组初始化。int a34=1,2,3,4,5,6,7,8,9,10,11,12;int a34=1,2,3,4,5,6,7,8,9,10,11,12;int a34=1,5,9;int a34=1,0,6,0,0,11;int a34=1,5,6;100050009000100006000011 0100056000000int a34=1,9;100000009000int a34=1,2,3,4,5,6,7,8,9,10,11,12;int a4=1,2,3,4,5,6,7,8,9,10,11,12;int a4=0,0,3,0,10;二维数组程序举例【例6.4】将一个二维数组行和列的元素互换,存到另一个二维数组中。#include int main()int a23=1,2,3,4,5,6;int b32,i,j;printf(array a:n);for(i=0;i=1;i+)/处理a数组中的一行中各元素for(j=0;j=2;j+)/处理a数组中某一列中各元素printf(%5d,aij);/输出a数组的一个元素bji=aij;/将a数组元素的值赋给b数组相应元素printf(n);printf(array b:n);/输出b数组各元素for(i=0;i=2;i+)/处理b数组中一行中各元素for(j=0;j=1;j+)/处理b数组中一列中各元素printf(%5d,bij);/输出b数组的一个元素printf(n);return 0;二维数组程序举例【例6.5】有一个34的矩阵,要求编程序求出其中值最大的那个元素的值,以及其所在的行号和列号。#include int main()int i,j,row=0,colum=0,max;int a34=1,2,3,4,9,8,7,6,-10,10,-5,2;/定义数组并赋初值max=a00;/先认为a00最大for(i=0;i=2;i+)for(j=0;jmax)/如果某元素大于max,就取代max的原值max=aij;row=i;/记下此元素的行号colum=j;/记下此元素的列号printf(max=%dnrow=%dncolum=%dn,max,row,colum);return 0;max=a00for i=0 to 2for j=0 to 3真假max=aijrow=icolum=j输出:max和row、columaijmax找最大最小找最大最小值打擂台算法打擂台算法算法算法 先思考一下在打擂台时怎样确定最后的优胜者。先找出任一人站在台上,第2人上去与之比武,胜者留在台上。再上去第3人,与台上的人(即刚才的得胜者)比武,胜者留台上,败者下台。以后每一个人都是与当时留在台上的人比武。直到所有人都上台比过为止,最后留在台上的就是冠军。字符数组定义字符数组用来存放字符数据的数组是字符数组。在字符数组中的一个元素内存放一个字符。char c10;c0=I;c1=;c2=a;c3=m;c4=;c5=h;c6=a;c7=p;c8=p;c9=y;c0c1c2c3c4c5c6c7c8c9Iamh appy由于字符型数据是以整数形式(ASCII代码)存放的,因此也可以用整型数组来存放字符数据。int c10;c0=a;/合法,但浪费存储空间字符数组的初始化如果在定义字符数组时不进行初始化,则数组中各元素的值是不可不可预料料的。如果花括号中提供的初值个数(即字符个数)大于数组长度,则出现语法错误。如果初值个数小于数组长度,则只将这些字符赋给数组中前面那些元素,其余的元素自动定为空字符(即0)。如果提供的初值个数与预定的数组长度相同,在定义时可以省略数组长度,系统会自动根据初值个数确定数组长度。也可以定义和初始化一个二维字符数组。对字符数组初始化,最容易理解的方式是用“初始化列表”,把各个字符依次赋给数组中各元素。char c10=I,a,m,h,a,p,p,y;/把10个字符依次赋给c0c9这10个元素char c10=c,p,r,o,g,r,a,m;char diamond55=,*,*,*,*,*,*,*,*;char c=I,a,m,h,a,p,p,y;/数组c的长度自动定为10c0c1c2c3c4c5c6c7c8c9cprogram0 *引用字符数组中的元素【例6.6】输出一个已知的字符串。#include int main()char c15=I,a,m,a,s,t,u,d,e,n,t,.;int i;for(i=0;i15;i+)printf(%c,ci);printf(n);return 0;【例6.7】输出一个菱形图。#include int main()char diamond5=,*,*,*,*,*,*,*,*;int i,j;for(i=0;i5;i+)for(j=0;j5;j+)printf(%c,diamondij);printf(n);return 0;字符串和字符串结束标志在C语言中,是将字符串作为字符数组来处理的。在实际工作中,人们关心的往往是字符串的有效长度而不是字符数组的长度。为了测定字符串的实际长度,C语言规定了一个“字符串结束标志”,以字符0作为结束标志。注意C系统在用字符数组存储字符串常量时会自动加一个0作为结束符。在定义字符数组时应估计实际字符串长度,保证数组长度始终大于字符串实际长度。如果在一个字符数组中先后存放多个不同长度的字符串,则应使数组长度大于最长的字符串的长度。C program 字符串是存放在一维数组中的,占10个字节,字符占9个字节,最后一个字节0是由系统自动加上的字符串和字符串结束标志printf(How do you do?n);在向内存中存储时,系统自动在最后一个字符n的后面加了一个0,作为字符串结束标志。在执行printf函数时,每输出一个字符检查一次,看下一个字符是否为0,遇0就停止输出。char c=I am happy;或 char c=I am happy;用一个字符串(注意字符串的两端是用双引号双引号而不是单引号括起来的)作为字符数组的初值。注意数组c的长度不是10,而是11。因为字符串常量的最后由系统加上一个0。char c=I,a,m,h,a,p,p,y,0;char c=I,a,m,h,a,p,p,y;char c10=China;数组c的前5个元素为:C,h,i,n,a,第6个元素为0,后4个元素也自动设定为空字符。China00000字符数组的输入输出#include int main()char c15=I,a,m,a,s,t,u,d,e,n,t,.;int i;for(i=0;i15;i+)printf(%c,ci);printf(n);return 0;(1)逐个字符输入输出。用格式符“%c”输入或输出一个字符。(2)将整个字符串一次输入或输出。用“%s”格式符,意思是对字符串(string)的输入输出。#include int main()char c=China;printf(%sn,c);return 0;(1)输出的字符中不包括结束符0。(2)用“%s”格式符输出字符串时,printf函数中的输出项是字符数组名,而不是数组元素名。(3)如果数组长度大于字符串的实际长度,也只输出到遇0结束。(4)如果一个字符数组中包含一个以上0,则遇第一个0时输出就结束。字符数组的输入输出char c6;scanf(%s,c);从键盘输入:China系统会自动在China后面加一个0结束符。char str15,str25,str35;scanf(%s%s%s,str1,str2,str3);如果利用一个scanf函数输入多个字符串,则应在输入时以空格空格分隔。从键盘输入:How are you?由于有空格字符分隔,作为3个字符串输入。str1:How00str2:are00str3:you?0char str13;scanf(%s,str);从键盘输入:How are you?由于系统把空格字符作为输入的字符串之间的分隔符,因此只将空格前的字符How送到str中。How0000000000字符数组的输入输出注意scanf函数中的输入项如果是字符数组名,不要再加地址符不要再加地址符&,因为在C语言中数组名代表该数组第一个元素的地址(或者说数组的起始地址)。若数组占6个字节。数组名c代表地址2000。可以用下面的输出语句得到数组第一个元素的地址。实际上是这样执行的:按字符数组名c找到其数组第一个元素的地址,然后逐个输出其中的字符,直到遇0为止。scanf(%s,&str);/str前面不应加&printf(%o,c);/用八进制形式输出数组c的起始地址printf(%s,c);/用八进制形式输出数组c的起始地址c数组2000C2001h2002i2003n2004a20050使用字符串处理函数输出字符串的函数puts(字符数字符数组)作用:将一个字符串(以0结束的字符序列)输出到终端。用puts函数输出的字符串中可以包含转义字符。在用puts输出时将字符串结束标志0转换成n,即输出完字符串后换行。#include int main()char str=ChinanBeijing;puts(str);return 0;输入字符串的函数gets(字符数字符数组)作用:从终端输入一个字符串到字符数组,并且得到一个函数值。该函数值是字符数组的起始地址。gets(str);/str是已定义的字符数组如果从键盘输入:Computer将输入的字符串Computer送给字符数组str(请注意,送给数组的共有9个字符,而不是8个字符),返回的函数值是字符数组str的第一个元素的地址。注意用puts和gets函数只能输出或输入一个字符串。puts(str1,str2);或 gets(str1,str2);字符串连接函数strcat(字符数字符数组1,字符数字符数组2)作用:把两个字符数组中的字符串连接起来,把字符串2接到字符串1的后面,结果放在字符数组1中,函数调用后得到一个函数值字符数组1的地址。字符数组1必须足够大,以便容纳连接后的新字符串。连接前两个字符串的后面都有0,连接时将字符串1后面的0取消,只在新串最后保留0。char str130=Peoples Republic of;char str2=China;printf(%s,strcat(str1,str2);输出:Peoples Republic of China连接前str1:Peoples Republic of 0 0 0 0 0 0 0 0 0str2:China连接后str1:Peoples Republic of China 0 0 0 0字符串复制函数strcpy(字符数字符数组1,字符串字符串2)作用:将字符串2复制到字符数组1中去。字符数组1必须定义得足够大,以便容纳被复制的字符串2。字符数组1的长度不应小于字符串2的长度。“字符数组1”必须写成数组名形式,“字符串2”可以是字符数组名,也可以是一个字符串常量。若在复制前未对字符数组1初始化或赋值,则其各字节中的内容无法预知,复制时将字符串2和其后的0一起复制到字符数组1中,取代字符数组1中前面的字符,未被取代的字符保持原有内容。不能用赋值语句将一个字符串常量或字符数组直接给一个字符数组。字符数组名是一个地址常量,它不能改变值,正如数值型数组名不能被赋值一样。可以用strncpy函数将字符串2中前面n个字符复制到字符数组1中去。将str2中最前面2个字符复制到str1中,取代str1中原有的最前面2个字符。但复制的字符个数n不应多于str1中原有的字符(不包括0)。char str110,str2=China;strcpy(str1,str2);或 strcpy(str1,China);执行后,str1:China00000str1=China;str1=str2;strncpy(str1,str2,2);字符串比较函数strcmp(字符串字符串1,字符串字符串2)作用:比较字符串1和字符串2。字符串比较的规则是:将两个字符串自左至右逐个字符相比(按ASCII码值大小比较),直到出现不同的字符或遇到0为止。(1)如全部字符相同,则认为两个字符串相等;(2)若出现不相同的字符,则以第1对不相同的字符的比较结果为准。比较的结果果由函数值带回。(1)如果字符串1与字符串2相同,则函数值为0。(2)如果字符串1字符串2,则函数值为一个正整数。(3)如果字符串1str2进行比较,因为str1和str2代表地址而不代表数组中全部元素,而只能用(strcmp(str1,str2)0)实现,系统分别找到两个字符数组的第一个元素,然后顺序比较数组中各个元素的值。测字符串长度的函数strlen(字符数字符数组)作用:测试字符串长度的函数。函数的值为字符串中的实际长度(不包括0在内)。#include#include int main()char str10=China;printf(%d,%dn,strlen(str),strlen(China);转换为大小写的函数strlwr(字符串字符串)作用:将字符串中大写字母换成小写字母。strupr(字符串字符串)作用:将字符串中小写字母换成大写字母。注意以上介绍了常用的8种字符串处理函数,它们属于库函数函数。库函数并非C语言本身的组成部分,而是C语言编译系统为方便用户使用而提供的公共函数。不同的编译系统提供的函数数量和函数名、函数功能都不尽相同,使用时要小心,必要时查一下库函数手册。在使用字符串处理函数时,应当在程序文件的开头用#include 把string.h文件包含到本文件中。字符数组应用举例【例6.8】输入一行字符,统计其中有多少个单词,单词之间用空格分隔开。string:用于存放字符串。i:计数器,用于遍历字符串中的每个字符。word:用于判断是否开始了一个新单词的标志。若word=0表示未出现新单词,如出现了新单词,就把word置成1。num:用于统计单词数。输入一个字符串给stringi=0当(c=stringi)0)真假word=0真假word=1num=num+1i=i+1输出:numc等于空格?word等于0?#include int main()char string81;int i,num=0,word=0;char c;gets(string);/输入一个字符串给字符数组stringfor(i=0;(c=stringi)!=0;i+)/只要字符不是0就循环if(c=)word=0;/若是空格字符,使word置0else if(word=0)/如果不是空格字符且word原值为0word=1;/使word置1num+;/num累加1,表示增加一个单词printf(There are%d words in this line.n,num);/输出单词数return 0;字符数组应用举例【例6.9】有3个字符串,要求找出其中“最大”者。#include#includeint main()char str320;/定义二维字符数组char string20;/定义一维字符数组,作为交换字符串时的临时字符数组int i;for(i=0;i0)/若str0大于str1strcpy(string,str0);/把str0的字符串赋给字符数组stringelse/若str0小于等于str1strcpy(string,str1);/把str1的字符串赋给字符数组string if(strcmp(str2,string)0)/若str2大于stringstrcpy(string,str2);/把str2的字符串赋给字符数组stringprintf(nthe largest string is:n%sn,string);/输出stringreturn 0;str0:Holland0000000000000str1:China000000000000000str2:America0000000000000读入3个字符串给str0,str1,str2YNstr0=stringstr1=stringYNstr2=string输出string中的字符串str0str1str2string(1)流程图和程序注释中的“大于”是指两个字符串的比较中的“大于”。(2)str0,str1,str2和string是一维字符数组,其中可以存放一个字符串。(3)strcpy函数在将str0,str1或str2复制到string时,最后都有一个0。因此,最后用%s格式输出string时,遇到string中第一个0即结束输出,并不是把string中的全部字符输出。