《C语言新教材PPT课堂课件-第7章数组》由会员分享,可在线阅读,更多相关《C语言新教材PPT课堂课件-第7章数组(47页珍藏版)》请在金锄头文库上搜索。
1、第第第第七七七七章章章章 数数数数组组组组 前面所用到的数据均为基本类型(整、实、字符),为了丰富数据类型 ,须提供强有力的数据表达方式。C语言提供了一种构造类型数据由基本类型按某一规则组合在一起。 其中数组:同一种(基本)类型按一定顺序组合在一起的数据类型。7.17.1 一维数组的定义和引用7.1.1 一一维维数数组组的的定定义义1. 数组名的命名方法同变量名的命名一样。2. C语言用方括号 表示数组元数个数。形式: 类型说明符 数组名常量表达式;例例: int a 20; float x 100;3. 常量表达式表示元素的个数,即数组长度。例例: int a20; 表示有20个元素,且元素
2、从0开始编排:a0,a1,a 19 4. 常量表达式为常量和符号常量。不允许有变量,其表达式的值代表了元素的个数。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,
4、13;2 一维数组的初始化 由于一维数组是顺序存储在内存中,数组名代表了数组在内存的起始地址,而每个数组元素字节数相同,因此,根据数组元素序号可以求得数组各元素在内存的地址,并实现对数组元素进行随机存取。 下面是找出最大与最小数的代码: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分别记录最大、最小元素的下标。 打印:格式字符串中第一
5、个d用输出项第一项变量 j 的值替换,后面三个d分别用max、k、min的值替换,其余字符原样输出。 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
6、 ) min=ai; /* 把当前最小值送min,下标送k */ k=i;printf(“max: a%d=%d, min: a%d=%d”, j,max,k,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;i1
7、1;i+) printf(“%d ”, ai); 7.2 7.2 二二维维数数组组的的定定义义和和引引用用7.2.1 二二维维数数组组的的定定义义1. 不可将定义写为int a4,10。形式 类型说明符 数组名常量表达式 常量表达式例例: 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. 二维
8、数组的存放方式为: 按行存放。由此可推广 至三维、n维数组的定义和存放。 即: 最右边的下标变化最快。4. 初始化: 按行给二维数组赋初值: int a34=1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12; 可以去掉其中的 。 可以对部分元素赋初值,但需表达清楚。如: int 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
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 二二维维数数组组元元素素的的引引用用形式: 数组名下标下标 其中的下标为整型表达式,但不得越界。 与一维数组元素一样,二维数组元素相当于同类型的简单变量。看下面的例子:例7.4 二维数组的输入输出。#include main( )int a23, j,
10、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”); /*输出一行后换行,再输出下一行*/ 7.2.3 二二维维数数组组的的存存储储结结构构和和初初始始化化1 二维数组的存储结构 系统为数组在内存中分配一片连续的内存空间,将二维数组诸元素按行的顺序存储在所
11、分配的内存区域。 如有以下定义: int a23; 对数组a,先存储第一行元素:a00,a01,a02,再存第二行元素:al0,a11,a12。下图表示出了数组a元素顺序与存储结构。 第一行第二行 程序如下:#include main( ) int i, j ;int a44;for( i=0; i4; i+ ) for(j=0; j4; j+) scanf(“ %d ”, &aij);例1 从键盘上输入16个整数,保存在44的二维数组中,输出数组偶数行和偶数列中的所有元素。 for( i=0; i4; i+ ) for( j=0; j4; j+ ) if (i%2=0 | j%2=0) pr
12、intf( “%-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。应该注意的是初始值在花括号中的顺序与初值个数不能错。 (2)根据二维数组的特点,分行给二维数组赋初值。如: int a32=0, 1, 2, 3, 4
13、, 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)给全部元素赋初值时,可以不指定第一维大小,但是第二维大小必须指定。如: int a2=0, 1, 2, 3, 4, 5;定义了一
14、个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=aki;for(i=0; iM; i+)
15、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
16、 , m , , a, , 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?”; 系统将双撇号括起来的字符依次赋给字符数
17、组的各个元素,并自动在末尾补上字符串结束标志字符0,并一起存到字符数组中,s的长度为14实际字符只有12个,其存储示意图如下图所示。s0 s1 s137.3.3 字字符符串串和和字字符符串串结结束束标标志志 在C语言中,将字符串作为字符数组来处理。也就是用一个一维的字符数组存放一个字符串。字符串结束标志是0,有了字符串的结束标志,字符数组的长度就显得不那么重要了,在程序中往往依靠检测0的位置来判定字符串是否结束,而不是根据数组的长度来决定字符串长度的。格式符: %c 逐个输入/输出字符。 %s 整个串一次输入/输出。1.输出 (1) 用%s格式 用 %s 输出时,不输出 0 . 在printf
18、中须直接写数组名. char c =I am a student; printf(%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(s
19、trcmp(str1,str2)=0) printf(“yes”); 6. strlen(字字符符数数组组) strlen函数它是测试字符串长度的函数。函数的值为字符串中的实际长度,不包括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”,
20、s,s1); /*从键盘上输入字符串,将How给s,将do给sl*/ printf(“s=%s,sl=%s”,s,s1);puts(“n”);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;
21、gets(s1);gets(s2);if (strcmp(s1,s2)!=0)if (strlen(s1)strlen(s2) strcat(s1,s2);puts(s1);else strcat(s2,s1); puts(s2);输入:you Thank 输出:Thank you7.5 7.5 数数组组作作为为函函数数的的参参数数7.5.1 数数组组元元素素做做函函数数实实参参 数组元素作函数的参数与一般变量作函数参数相同,要注意的是,数组元素作参数时候,值的传递方式仍是单向的值传递。 由于这方面在函数一章讲述较多,这里重点讲第二节。7.5.2 将将数数组组名名作作函函数数参参数数 此时形参
22、与实参都应使用数组名,分别在被调函数与主调函数中说明数组类型,并且要求实参与形参数组的类型相同,维数相同。在进行参数传递时是“地址传递”,即实参数组的首地址传给形参数组,而不是将实参数组的每个元素一一送给形参的各数组元素。思路: 把相邻两数比较,若前面数大,则两数交换位置,直至最后一个元素被处理,最大的元素就“沉”到最下面,即在最后一个元素位置。这样,如有n个元素,共进行n-1轮,每轮让剩余元素中最大的元素“沉”到下面,从而完成排序。 程序如下:下面给出一个程序设计中的经典例子。例例:用冒泡法将10个数按由小到大排序。 #include #define N 80main( )int aN;in
23、t i, m; void sort(int b , int k);void print(int b , int k);printf(“n Input m(80): ”);scanf(“%d”, &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
24、=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) putchar(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
25、 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