《C语言新教材PPT课堂课件-第7章数组.ppt》由会员分享,可在线阅读,更多相关《C语言新教材PPT课堂课件-第7章数组.ppt(47页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第七章第七章 数组数组 前面所用到的数据均为基本类型(整、实、字符),为了丰富数据类型,须提供强有力的数据表达方式。C语言提供了一种构造类型数据由基本类型按某一规则组合在一起。其中数组:同一种(基本)类型按一定顺序组合在一起的数据类型。7.17.1 一维数组的定义和引用7.1.1 一维数组的定义一维数组的定义1.数组名的命名方法同变量名的命名一样。2.C语言用方括号 表示数组元数个数。形式:类型说明符 数组名常量表达式;例例:int a 20;float x 100;3.常量表达式表示元素的个数,即数组长度。例例:int a20;表示有20个元素,且元素从0开始编排:a0,a1,a 19 4.
2、常量表达式为常量和符号常量。不允许有变量,其表达式的值代表了元素的个数。7.1.2 一维数组的引用一维数组的引用 2.引用方式:数组名下标 代表了一个元素,等价一个同类型的变量。3.一般地,一维数组各元素分配在连续地内存单元之中。1.须象使用变量那样,先定义,后使用例例:a 05+a1 6 为正确的算术表达式例7.1 数组元素的引用 main()int i,a10;for(i=0;i=0;i-)printf(“%d”,ai);7.1.3 一维数组的存储结构和初始化一维数组的存储结构和初始化1 一维数组的存储结构 C编译系统为所定义的数组变量在内存中分配一片连续的存储单元,诸元素按数组下标从小到
3、大连续排列,每个元素占用相同的字节数。例如,定义数组a如下:int a5;数组a的存储示意图如下图所示:1000a0(a)a1a2a3a41006a0(b)8824123a1a2a3a4(1)在定义数组时对所有数组元素赋初值。例如:int a5=8,8,2,4,123;(2)给数组部分元素赋初值 int a57,6;表明只给前2个元素赋初值,即a07,al6,其他元素自动赋0值。(3)对全部元素赋初值时,可以不指定数组长度,C 编译系统自动根据初值个数来决定数组长度。例如:int a=l,3,5,7,9,11,13;2 一维数组的初始化 由于一维数组是顺序存储在内存中,数组名代表了数组在内存的
4、起始地址,而每个数组元素字节数相同,因此,根据数组元素序号可以求得数组各元素在内存的地址,并实现对数组元素进行随机存取。下面是找出最大与最小数的代码:for(i=0;i5;i+)if(maxai)min=ai;/*把当前最小值送min,下标送k*/k=i;例7.2:从键盘上输入5个数,输出最大、最小元素的值以及它们的下标。在上面的for循环语句中max、min与所有元素一一比较,比max大的元素值赋给max,比min小的赋给min,同时用变量j,k分别记录最大、最小元素的下标。打印:格式字符串中第一个d用输出项第一项变量 j 的值替换,后面三个d分别用max、k、min的值替换,其余字符原样输
5、出。printf(“max:a%d=%d,min:a%d=%d”,j,max,k,min);详细源代码如下:#define N 5#include main()int i,j,k,max,min;static int a5;for(i=0;i5;i+)scanf(“%d”,&ai);max=min=a0;/*假定第一个元素既是最大的,也是最小的*/j=k=0;/*对分别记录最大,最小元素下标的变量j,k初始化*/for(i=0;i5;i+)if(maxai)min=ai;/*把当前最小值送min,下标送k*/k=i;printf(“max:a%d=%d,min:a%d=%d”,j,max,k,
6、min);例7.3 用起泡法对10个数排序(由小到大)main()int i,j,t,a11;printf(“input 10 numbers:n”);for(i=1;i11;i+)scanf(“%d”,&ai);for(j=1;j=9;j+)for(i=1;iai+1)t=ai;ai=ai+1;ai+1=t;printf(“the sorted numbers:n”);for(i=1;i11;i+)printf(“%d ”,ai);7.2 7.2 二维数组的定义和引用二维数组的定义和引用7.2.1 二维数组的定义二维数组的定义1.不可将定义写为int a4,10。形式 类型说明符 数组名常量
7、表达式 常量表达式例例:int a4 10;float b8 20;2.可将二维数组的元素看成为若干个特殊的一维数组。如:int b3 4;则:有三个特殊的一维数组b0,b1,b2,每一个又有四个元素:b00,b01,b02,b03,b10,b11,b12,b13,b20,b21,b22,b23,b30,b31,b32,b33,3.二维数组的存放方式为:按行存放。由此可推广 至三维、n维数组的定义和存放。即:最右边的下标变化最快。4.初始化:按行给二维数组赋初值:int a34=1,2,3,4,5,6,7,8,9,10,11,12;可以去掉其中的。可以对部分元素赋初值,但需表达清楚。如:int
8、 a34=1,2,3,8。则相当于 1 2 0 0 3 0 0 0 8 0 0 0请看一下这个例子:int M34=1,2,3,4,5,6,7,8,9;想一下这句语句的结果是什么。(假设数组的起始内存地址是:0100H)则相当于 1 2 3 0 4 5 6 0 7 8 9 0可通过赋初值决定数组大小。如为二维,则只可省略第一维的大小.int a 4=1,2,3,12;现在,我们再来看一个使用第二种初始化方法的例子。int M34=1,2,3,4,5,6,7,8,9;请想一下它的结果。请注意这两个例子间的差别。则相当于 1 2 3 4 5 6 7 8 9 0 0 07.2.2 二维数组元素的引用
9、二维数组元素的引用形式:数组名下标下标 其中的下标为整型表达式,但不得越界。与一维数组元素一样,二维数组元素相当于同类型的简单变量。看下面的例子:例7.4 二维数组的输入输出。#include main()int a23,j,k;printf(“n Input array a:”);for(j=0;j2;j+)for(k=0;k3;k+)scanf(“%d”,&ajk);printf(n Output array a:n“);for(j=0;j2;j+)for(k=0;k3;k+)/*循环三次,输出一行共三个元素*/printf(“%4d”,ajk);printf(“n”);/*输出一行后换行
10、,再输出下一行*/7.2.3 二维数组的存储结构和初始化二维数组的存储结构和初始化1 二维数组的存储结构 系统为数组在内存中分配一片连续的内存空间,将二维数组诸元素按行的顺序存储在所分配的内存区域。如有以下定义:int a23;对数组a,先存储第一行元素:a00,a01,a02,再存第二行元素:al0,a11,a12。下图表示出了数组a元素顺序与存储结构。第一行第二行 a00 a01 a02 a10 a11 a12 程序如下:#include main()int i,j;int a44;for(i=0;i4;i+)for(j=0;j4;j+)scanf(“%d”,&aij);例1 从键盘上输入
11、16个整数,保存在44的二维数组中,输出数组偶数行和偶数列中的所有元素。for(i=0;i4;i+)for(j=0;j4;j+)if(i%2=0|j%2=0)printf(“%-4d”,aij);printf(“n”);如果输入为:0 1 2 34 5 6 78 9 10 1112 13 14 15输出结果如下:0l23468910111214几点注意:(1)将数组所有元素初始值按相应顺序写在一个花括号内,各初值用逗号分隔,按数组元素排列顺序给各元素赋值。如:int a32=0,l,2,3,4,5;这使得:a00=0,a01=1,a10=2,al1=3,a20=4,a21=5。应该注意的是初始
12、值在花括号中的顺序与初值个数不能错。(2)根据二维数组的特点,分行给二维数组赋初值。如:int a32=0,1,2,3,4,5;赋初始值的结果与上面一种方法相同。显然这种方式比上种方式更直观,符合二维数组的特点,初始值与元素关系(行、列)清楚,不易出错。(3)可以对部分元素赋初值。int a34=1,3,5,即相当于:int a34=1,0,0,0,3,0,0,0,5,0,0,0例2.用如下的44矩阵初始化数组a44,求其转置矩阵并输出之。123 4567 8 910 11 1213 14 15 16转置 成1 59 132 610 143 711 154812 16 (4)给全部元素赋初值时
13、,可以不指定第一维大小,但是第二维大小必须指定。如:int a2=0,1,2,3,4,5;定义了一个32(三行两列)数组a。int a2=l,2,0,5;定义了一个32的数组a。思路:转置矩阵是将原矩阵的元素按行列互换所形成的矩阵,使用二维数组来处理矩阵问题是很方便的,而二维数组常常用二重循环来实现,内循环处理列,外循环处理行。程序如下:#define M 4#define N 4#include main()int i,k;int aMN=1,2,3,4,5,6,7,8,9,10,11,12,3,14,15,16;int bMN;for(i=0;iM;i+)for(k=0;kN;k+)bik
14、=aki;for(i=0;iM;i+)for(k=0;kN;k+)printf(“%5d”,bik);printf(“n”);输出结果为:l 5 9 132 6 10 143 7 l l 154 8 12 167.3 7.3 字符数组字符数组7.3.1字符数组的定义与初始化字符数组的定义与初始化1.初始化:直接给出字符串中的各字符 char a4=G,o,o,d;用来存放字符数据的数组是字符数组。字符数组中的一个元素存放一个字符。类型名数组名大小 char c10;若字符多于元素个数,则语法错,反之,后而补0可以去掉定义时的大小设置,而通过自动赋值决定长度(大小)char x=I,a,m,a,
15、s,t,u,d,e,n,t;前面说过,字符串常量用“”表示,且由 0结尾.static char x=I am a student.;则长度为15+1=16,其中x15存放 0,其中 亦可省略。2.字符数组的引用 每一个字符数组元素相当于一个字符变量。7.3.2字符串的概念及存储字符串的概念及存储 在C语言中,没有字符串类型,自然不能使用字符串变量,但可以使用字符串常量,也即是字符串。在对字符串进行处理时,字符串存放在字符数组中。例如:chars14=“How are you?”;Howare you0 系统将双撇号括起来的字符依次赋给字符数组的各个元素,并自动在末尾补上字符串结束标志字符0,
16、并一起存到字符数组中,s的长度为14实际字符只有12个,其存储示意图如下图所示。s0 s1 s137.3.3 字符串和字符串结束标志字符串和字符串结束标志 在C语言中,将字符串作为字符数组来处理。也就是用一个一维的字符数组存放一个字符串。字符串结束标志是0,有了字符串的结束标志,字符数组的长度就显得不那么重要了,在程序中往往依靠检测0的位置来判定字符串是否结束,而不是根据数组的长度来决定字符串长度的。格式符:%c 逐个输入/输出字符。%s 整个串一次输入/输出。1.输出 (1)用%s格式 用%s 输出时,不输出 0.在printf中须直接写数组名.char c=I am a student;p
17、rintf(%s,c);7.3.4 字符数组的输入输出字符数组的输入输出 若数组长度大于字符串长度,则遇到 0 即停止输出 static char c10=china;printf(%s,c);输出时遇到第一个0即结束。char word=H,e,l,l,o,!;for(i=0;i字符串2,函数值为一正整数。(3)如果字符串1字符串2,函数值为一负整数。注意:对两个字符串比较,不能用以下形式:if(str1=str2)printf(“yes”);而只能用比较函数进行比较的。如:if(strcmp(str1,str2)=0)printf(“yes”);6.strlen(字符数组字符数组)strl
18、en函数它是测试字符串长度的函数。函数的值为字符串中的实际长度,不包括0在内。7.strlwr(字符串字符串)strlwr函数的作用时将字符串中大写字母换成小写字母。8.strupr(字符串字符串)strupr函数的作用是将字符串中小写字母换成大写字母。7.3.6 字符串数组举例字符串数组举例例:字符串输入。程序如下:#include main()char s20,s120;scanf(“%s”,s);printf(“%s n”,s);scanf(“%s%s”,s,s1);/*从键盘上输入字符串,将How给s,将do给sl*/printf(“s=%s,sl=%s”,s,s1);puts(“n”
19、);gets(s);puts(s);程序运行结果:How do you do?HowHow do you do?SHow,S1doHow do you do?How do you do?例中使用了scanf()与gets()两个函数来实现字符串的输入,要注意它们的差别,根据需要来选用。例:从键盘上输入两个字符串,若不相等,将短的字符串连接到长的字符串的末尾并输出。#include#include main()char s180,s280;gets(s1);gets(s2);if(strcmp(s1,s2)!=0)if(strlen(s1)strlen(s2)strcat(s1,s2);puts
20、(s1);else strcat(s2,s1);puts(s2);输入:you Thank 输出:Thank you7.5 7.5 数组作为函数的参数数组作为函数的参数7.5.1 数组元素做函数实参数组元素做函数实参 数组元素作函数的参数与一般变量作函数参数相同,要注意的是,数组元素作参数时候,值的传递方式仍是单向的值传递。由于这方面在函数一章讲述较多,这里重点讲第二节。7.5.2 将数组名作函数参数将数组名作函数参数 此时形参与实参都应使用数组名,分别在被调函数与主调函数中说明数组类型,并且要求实参与形参数组的类型相同,维数相同。在进行参数传递时是“地址传递”,即实参数组的首地址传给形参数组
21、,而不是将实参数组的每个元素一一送给形参的各数组元素。思路:把相邻两数比较,若前面数大,则两数交换位置,直至最后一个元素被处理,最大的元素就“沉”到最下面,即在最后一个元素位置。这样,如有n个元素,共进行n-1轮,每轮让剩余元素中最大的元素“沉”到下面,从而完成排序。程序如下:下面给出一个程序设计中的经典例子。例:例:用冒泡法将10个数按由小到大排序。#include#define N 80main()int aN;int i,m;void sort(int b,int k);void print(int b,int k);printf(“n Input m(80):”);scanf(“%d”
22、,&m);/*输入要排序的元素的个数*/for(i=0;im;i+)scanf(“%d”,&ai);/*输入m个元素到数组a中*/sort(a,m);print(a,m);void sort(int b,int k)int i,j,t,flag;for(j=0;jk-1;j+)flag=0;for(i=0;ibi+1)t=bi;/*相邻元素交换位置*/bi=bi+1;bi+1=t;flag=1;/*有元素交换位置,标志置1*/if(flag=0)break;/*没有交换元素,结束循环*/void print(int b,int k)int i;for(i=0;ik;i+)if(i%4=0)pu
23、tchar(n);printf(“%-6d”,bi);输入:Input m(80):81 20 -4 0 81 53 44 -24输出:-24 -4 0 120 44 53 81例7.17 输出如下的杨辉三角形(输出不超过10行)。111 1211331146411510105 1 程序如下:#include#define N 10main()int i,j,n,bNN;void yanghui(int a N,int n);/*函数声明*/printf(“Enter n:”);scanf(“%d”,&n);yanghui(b,n);/*调用函数生成杨辉三角形*/for(i=0;in;i+)for(j=0;j=i;j+)printf(“%-4d”,bij);printf(“n”);void yanghui(int aN,int n)int i,j;for(i=0;in;i+)/*生成三角形边上元素*/ai0=1;/*即:0列与i行i列的元素为1*/aii=1;for(i=2;in;i+)for(j=1;ji;j+)aij=ai-1j-1+ai-1j;输入:Enter n:8输出:l1 l1 2 l1 3 3 l1 4 6 4 l1 5 10 10 5 l1 6 15 20 15 6 11 7 2l 35 35 2l 71
限制150内