第5章数组和字符串数组属于构造类型,使用数组可以有效地组织循环,能简化算法设计、简化编程。第0列第1列第2列第0行第1行a[0][0]a[0][1]a[0][2]a[1][0]a[1][1]a[1][2]2.数组元素数组的成员,用数组名加下标表示。a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]5.1数组的概念数组是同类型变量的集合。数组具有如下特征:①类型数组的类型就是所有数组元素的数据类型;②数组名各元素共用同一个名称;③维数一维数组有一个下标,二维数组有两个下标。1.数组①维界只能是整常数表达式(含符号常数);②数组的下标从0开始;③多个相同类型的数组可以在一个语句中定义。数据类型数组名维界1.数组的定义[存储类型]数据类型数组名[expn][expn-1]…[exp2][exp1]intdata[10];//一维数组floata[3][4];//二维数组charstr1[30];//一维字符型数组charstr2[10][80];//二维字符型数组5.2数组的定义和初始化a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]b[0][0]b[0][1]b[0][2]b[1][0]b[1][1]b[1][2]c[0][0]c[0][1]……c[0][6]c[1][0]c[1][1]……c[1][6]【例】inta[8];floatb[2][3];charc[2][7];2.数组的存储结构数组占用一片连续的存储单元,数组中的各个元素依次存放。数组名就是这一片存储单元的首地址。一维数组:各个元素顺序存放。二维数组:先按行的顺序,然后按列的顺序依次存放各个元素。每个元素占用存储单元的多少,取决于数组的数据类型,同一个数组的各个元素占用相同数量的存储单元。字符型数组:各个字符依次存放,每个字符占1字节。(1)一维数组初始化把初值顺序放在等号右边的花括号中,各常量之间用逗号隔开。intata[10]={50,60,70,80,90,100,101,102,103,104};floattable[5]={1,2.5,3.6,4.7,5};(2)二维数组初始化把全部初值放在一对花括号中,每一行的初值又分别放在一对内嵌的花括号中。inta[4][3]={{1,2,3},{4,5,6},{7,8,9},{10,11,12}};其中代表每一行的内层花括号也可以省略,直接写成inta[4][3]={1,2,3,4,5,6,7,8,9,10,11,12};3.数组的初始化对数组初始化的几点说明:①如果赋初值的花括号中的常数个数少于数组元素个数,则编译程序会自动以零来补足。intx[6]={1,2,3,4};相当于intx[6]={1,2,3,4,0,0};inta[4][3]={{1,2},{4,5}};相当于inta[4][3]={1,2,0,4,5,0,0,0,0,0,0,0};②花括号中的初值可以缺省,但逗号不能省略,缺省的值将被视为0。floatarray[5]={,2.5,,3.5,};相当于floatarray[5]={0,2.5,0,3.5,0};③当花括号中给出初值的个数多于定义的数组元素个数时,将出错。inta[4]={1,2,3,4,5};编译时会显示错误信息。①用字符常数初始化charstr[12]={'T','h','e',’'','s','t','r','i','n','g','.','\0'};charlanguage[5][8]={{'B','A','S','I','C','\0'},{'F','O','R','T','R','A','N','\0'},{'P','A','S','C','A','L','\0'},{'C','\0'},{'C','O','B','O','L','\0'}};②直接用字符串常量初始化charstr[12]={Thestring.};或charstr[12]=Thestring.;charLanguage[5][8]={BASIC,FORTRAN,PASCAL,C,COBOL};(3)字符型数组的初始化①C语言允许通过初始化方式隐含规定数组的大小。inta[]={0,1,2,3,4,5,0};等价于inta[7]={0,1,2,3,4,5,0};②用初始化方法隐含规定多维数组的大小时,只能省略最左边的维界表达式。例如对二维数组,只能省略第一个方括号中的表达式,写成:inta[][3]={{1,2,3},{4,5},{6},{7}};等价于inta[4][3]={{1,2,3},{4,5},{6},{7}};不能写成:inta[4][]={{1,2,3},{4,5},{6},{7}};或inta[][]={{1,2,3},{4,5},{6},{7}};4.利用初始化隐含规定数组的大小③用初始化方法隐含规定字符型数组的大小,可以免除乏味的统计字符个数的工作。例如charstr[]={'T','h','e','','s','t','r','i','n','g','.','\0'};charstr[]=Thestring.;编译系统会根据初值给出的字符个数自动确定其维界是12。charlanguage[][8]={BASIC,FORTRAN,PASCAL,C,COBOL};编译系统会根据初始化中字符串常量的个数自动确定该数组的第二维维界是5。5.3数组的基本操作(1)用“数组名[下标表达式]”的形式来引用一维数组元素。下标的下限是0,而上限不能超过该数组定义时的维界值减1。(2)用“数组名[下标表达式1][下标表达式2]”的形式来引用二维数组元素,其中,“下标表达式1”表示行下标,“下标表达式2”表示列下标,二者必须分别放在两个方括号内。(3)可以用与上面类似的形式来引用一维或二维字符型数组的元素,即字符串中的一个字符。数组的基本操作包括数组元素的引用、数组的赋值、数组的输入输出等。1.数组元素的引用①只能逐个对数组元素赋值,不能直接对数组名赋值。inti,a[5];a[0]=100,a[1]=120,a[2]=200,a[3]=250,a[4]=500;②如果所赋的值有某种规律,就可以借助于循环来简化程序的编制。intb[2][3],i,j;for(i=0;i2;i++)for(j=0;j3;j++)b[i][j]=i+j;2.数组的赋值③对字符型数组,只能对每个元素用字符常量赋值。charst[4];st[0]='A';st[1]='B';st[2]='C',st[3]='\0';为了解决直接用字符串对字符型数组赋值的问题,可用字符串处理函数实现。#includestring.hstrcpy(st,”ABC”);①一维数组,一般用单重循环实现对各个元素逐个输入和输出。floatx[10];inti;for(i=0;i10;i++)scanf(%f,&x[i]);for(i=0;i10;i++)printf(%f,x[i]);3.数组的输入和输出按行的顺序输入inta[3][4],i,j;for(i=0;i3;i++)for(j=0;j4;j++)scanf(%d,&a[i][j]);按列的顺序输入inta[3][4],i,j;for(j=0;j4;j++)for(i=0;i3;i++)scanf(“%d”,&a[i][j]);按矩阵形式输出#includestdio.hvoidmain(){inti,j;inta[3][4]={1,3,5,7,9,2,4,6,8,10,12,11};for(i=0;i3;i++){for(j=0;j4;j++)printf(%d,a[i][j]);printf(\n);}}②二维数组的输入输出用二重循环实现。【例】将10个元素的整形数组a分两行输出,每行5个数。#includestdio.hvoidmain(){inti,a[10]={1,2,3,4,5,6,7,8,9,10};for(i=0;i10;i++){printf(%2d,a[i]);if(i%5==4||i==9)printf(\n);}}程序中的if语句可以改用条件表达式:#includestdio.hvoidmain(){inti,a[10]={1,2,3,4,5,6,7,8,9,10};for(i=0;i10;i++)printf(%2d%c,a[i],i%5==4||i==9?'\n':'');}③字符型数组的输入和输出用“%s”控制scanf()和printf()输入和输出字符串。#includestdio.hvoidmain(){inti;charch[10];for(i=0;i9;i++)scanf(%c,&ch[i]);for(i=0;ch[i]!=’\0’;i++)printf(%c,ch[i]);}#includestdio.hvoidmain(){charch[10];scanf(%s,ch);printf(%s,ch);}输出有异常字符?可以超出数组长度?用gets()和puts()实现。用gets()接收字符串的显著特点是遇到回车键才认为输入结束。gets(字符型数组名);puts(字符型数组名);【例】英文句子的输入输出。#includestdio.hvoidmain(){charword[80];printf(Inputastatement:);gets(word);puts(word);}【例】二维字符型数组的输入和输出。#includestdio.hvoidmain(){inti;charcountry[3][8];printf(请输入国家名称:);for(i=0;i3;i++)gets(country[i]);for(i=0;i3;i++)puts(country[i]);}【例】统计某班某门课考试成绩各分数档人数。5.4数组的应用1.数据统计#includestdio.hvoidmain(){inta[11]={0},i;floatx;for(i=1;i=30;i++){scanf(%f,&x);a[(int)x/10]+=1;//存放各分数档人数}printf(0-910-1020-2930-3940-4950-5960-6970-7980-8990-99100\n);for(i=0;i11;i++)printf(%3d,a[i]);}5.4.1数值数组的应用【例】试编程找出二维数组a[3][4]中最大和最小的元素,并指出它们所在的行号和列号。#includestdio.hmain(){inta[4][5],i,j,max,max_row,max_col;intmin,min_row,min_col;printf(输入二维数组如下:\n);for(i=0;i4;i++)for(j=0;j5;j++)scanf(%d,&a[i][j]);max=a[0][0];max_row=0;max_col=0;min=a[0][0];min_row=0;min_col=0;for(i=0;i4;i++)for(j=0;j5;j++){if(maxa[i][j])max=a[i][j],max_row=i,max_col=j;if(mina[i][j]){min=a[i][j],min_row=i,min_col=j;}}printf(输出结果如下:\n);printf(max=%d,row=%d,column=%d\n,max,max_row,max_col);printf(min=%d,row=%d,column=%d\n,min,min_row,min_col);}输入数据max=a[0][0],row1=0,column1=0min=a[0][0],row2=0,column2=0输出结果maxa[i][j]mina[i][j]max=a[i][j],row1=i,column1=jmin=a[i][j],r