《C语言ppt课件第9章.ppt》由会员分享,可在线阅读,更多相关《C语言ppt课件第9章.ppt(47页珍藏版)》请在三一办公上搜索。
1、南昌大学计算中心,C语言程序设计,南昌大学计算中心,第9章 数组,数组是指一组相同类型数据的有序集合,由一个统一的数组名标识这一组数据。数组的每一个成员称作数组元素,用下标来标识数组元素在该数组中的位置。,南昌大学计算中心,9.1 一维数组的定义和一维数组元素的引用9.1.1 一维数组的定义类型名 数组名整型常量表达式,;,short a5;,15,67,3,26,98,南昌大学计算中心,9.1.2 一维数组元素的引用 数组名下标表达式如:double x8; 则x0、xj、xi+k均合法。注意:i+k是下标表达式而不是两个下标。说明:1、“下标表达式”可以是任何非负整型数据,取值范围是0(元
2、素个数-1)。 特别强调:在运行C语言程序过程中,系统并不自动检验数组元素的下标是否越界。因此在编写程序时,保证数组下标不越界是十分重要的。,南昌大学计算中心,2、1个数组元素,实质上就是1个变量,它具有和相同类型单个变量一样的属性,可以对它进行赋值和参与各种运算。3、一个数组不能整体引用,数组名中存放的是一个地址常量,它代表整个数组的首地址。例如:double x8, *p, q; p=x; q=x;,南昌大学计算中心,9.1.3 一维数组的初始化1、在定义语句中给所定义数组赋初值数据类型 数组名常量表达式初值表说明:1、初值放在赋值号后的花括号中,数值类型与说明类型一致,初值间用逗号隔开,
3、系统将自动按顺序从第一个元素开始依次给数组中元素赋值。如:int a8=0,1,2,3,4,5,6,7;2、“初值表”中的初值个数,可以少于元素个数,即允许只给前面的部分元素赋初值,其后的元素自动赋0。字符补0。如:int a10=0; /* 10个元素都赋初值0 */ char c5=; /* 后4个元素均赋0 */,南昌大学计算中心,3、当初值多于元素个数,编译时会出错。4、如果对数组的全部元素赋以初值,定义时可以不指定数组长度(长度由初值个数自动确定)。如果被定义数组的长度,与初值个数不同,则数组长度不能省略。如:int a=0,1,2,3,4;,南昌大学计算中心,#include ma
4、in() int ary10; int i, total, high; for(i=0; i high) high = aryi; for(i=0,total=0; i10; i+) total = total + aryi; ,定义,赋值,比较,南昌大学计算中心,9.2 一维数组和指针9.2.1 一维数组和数组元素的地址数组是一组相同类型数据的集合,数组中各个元素在内存占据连续的存储单元,每个内存单元都有相应的地址。数组所占内存单元的首地址称为数组的指针,数组元素所占内存单元的首地址称为数组元素的指针。因此,可以用指针变量来指向数组或数组元素。,南昌大学计算中心,C语言规定,数组名代表数组的
5、首地址,因此,数组名实际上也是指针,但它是一个固定不变的指针常量。如:int a5;a是数组名,也是指针,它永远指向数组的首地址,即不能将新地址赋给该指针。但可以通过形如a+k的形式(k是整数)来表达该数组其它元素的地址。如:for(k=0;k5;k+) scanf(“%d”,a+k);,南昌大学计算中心,若有语句: int a10; int *p; p=a; 则: for(k=0;k10;k+) scanf(“%d”,a+k);,for(k=0;k10;k+) scanf(“%d”,p);p+;,for(k=0;k10;k+) scanf(“%d”, p+);,for( ;p-a10;p+)
6、 scanf(“%d”,p);,南昌大学计算中心,数组和指针的关系,南昌大学计算中心,9.2.2 通过数组的首地址引用数组元素采用间接运算符“*”。如:,南昌大学计算中心,for(k=0;k10;k+) printf(“%4d”,ak);,for(k=0;k10;k+) printf(“%4d”,*(a+k);,南昌大学计算中心,9.2.3 通过指针引用一维数组元素若有语句: int a10, *p,k; p=a;,for(k=0;k10;k+) printf(“%4d”,ak);,for(k=0;k10;k+) printf(“%4d”, *(p+k);,for( k=0;k10;k+) p
7、rintf(“%4d”,*p);p+;,for( k=0;k10;k+) printf(“%4d”,*p+);,for( ;p-a10;p+) printf(“%4d”,*p);,南昌大学计算中心,9.2.4 用带下标的指针变量引用一维数组元素若有语句: int s10, *p,i; p=s;,南昌大学计算中心,练习:有如下说明:int a10=1,2,3,4,5,6,7,8,9,10,*p=a;则数值为9的表达式是_。*p+9*(p+8) *p+=9 p+8,南昌大学计算中心,练习:下面程序执行后的输出结果是_。#include int a=2,4,6,8;main() int i; int
8、 *p=a; for(i=0;i4;i+) ai=*p; printf(“%dn”,a2);6 B) 8 C) 4 D) 2,南昌大学计算中心,练习:设有定义语句:int x6=2,4,6,8,5,7,*p=x,i;要求依次输出x数组6个元素中的值,不能完成此操作的语句是_。for(i=0;i6;i+) printf(“%2d”,*(p+);for(i=0;i6;i+) printf(“%2d”,*(p+i);for(i=0;i6;i+) printf(“%2d”,*p+);for(i=0;i6;i+) printf(“%2d”,(*p)+);,南昌大学计算中心,练习:下面程序执行后的输出结果
9、是_。#include int a=2,4,6,8;main() int i; int *p=a; for(i=0;i4;i+) ai=*p+; printf(“%dn”,a2);6 B) 8 C) 4 D) 2,南昌大学计算中心,练习:下面程序执行后的输出结果是_。main() int a10=1,2,3,4,5,6,7,8,9,10,*p=a; printf(“%dn”,*(p+2);3 B) 4 C) 1 D) 2,南昌大学计算中心,练习:有如下程序段:int a10=1,2,3,4,5,6,7,8,9,10;int *p=则b的值是_。5 B) 6 C) 9 D) 8,南昌大学计算中心
10、,练习:下面程序执行后的输出结果是_。main() int a5=2,4,6,8,10,*p,*k; p=a; k=4 B) 22 C) 24 D) 46,南昌大学计算中心,练习:下面程序执行后的输出结果是_。main() int a=1,2,3,4,5,6,7,8,9,10,11,12; int *p=a+5; *q=NULL; *q=*(p+5); printf(“%d %dn”,*p,*q);运行后报错 6 66 12 5 5,南昌大学计算中心,9.3 函数之间对一维数组和数组元素的引用9.3.1 数组元素作实参数组元素作实参时,对应的形参必须是类型相同的变量,所以用法与普通变量一致,传
11、递实参后并不能改变数组元素的值。9.3.2 数组名作实参数组名本身就是一个地址值,因此对应的形参应当是一个指针变量,可以通过传递改变数组元素的值。例题见书上例9.2。注意:被调用函数定义部分可以有三种写法:如:arrin(int *a) arrin(int a ) arrin(int aM) M是一个符号常量,南昌大学计算中心,9.3.3 数组元素地址作为实参数组元素地址作实参也要求对应的形参应当是一个指针变量,可以通过传递改变数组元素的值。见书上例9.3,南昌大学计算中心,9.3.4 函数的指针形参和函数体中数组的区别若有以下程序,程序中定义了fun函数,形参a指向主函数中的w数组,函数体内
12、定义了一个b数组,函数把b数组的起始地址作为函数值返回,企图使主函数中的指针p指向函数体内b数组的开头。#define N 10int *fun(int aN,int n) int bN; return b; main() int wN,*p; p=fun(w,N); ,南昌大学计算中心,以上程序涉及几个概念:1、函数fun中,形参a可以写成aN,a,*a,它是一个指针变量,在调用fun函数时,系统只为形参a开辟一个存储单元,并把main函数中w数组首地址存进去,使它指向w数组地址。2、函数fun的函数体定义了一个b数组,在调用fun函数时,系统为它开辟了一串连续存储单元,它是一个地址常量。3
13、、在fun函数执行完毕后,系统释放a,b所占存储单元,而b的值作为fun函数返回值,指针变量p将不指向任何对象而成为“无向指针”。,南昌大学计算中心,练习:若有以下调用语句,则不正确的fun函数的首部是_。main() int a50,n; fun(n, . .void fun(int m,int x)void fun(int s,int h41)void fun(int p,int *s)void fun(int n,int a),南昌大学计算中心,练习:下面程序执行后的输出结果是_。void func(int *a,int b) b0=*a+6; main() int a,b5; a=0;
14、b0=3; func(6 B) 7 C) 8 D) 9,南昌大学计算中心,练习:下面程序执行后的输出结果是_。f(int b,int n) int i,r=1; for(i=0;i=n;i+) r=r*bi; return r; main() int x,a=2,3,4,5,6,7,8,9; x=f(a,3); printf(“%dn”,x);720 B) 120 C) 24 D) 6,南昌大学计算中心,9.5 二维数组的定义和二维数组元素的引用9.5.1 二维数组的定义类型名 数组名常量表达式1常量表达式2,;,short a23;,南昌大学计算中心,9.5.2 二维数组元素的引用数组名下标
15、表达式1 下标表达式2规则与一维数组元素的一样。1、行列下标下限为0,上限为n-12、一定要把两个下标分别放在两个方括号内3、第m行n列:am-1n-1,南昌大学计算中心,9.5.3 二维数组的初始化1、按行对二维数组初始化。如:int a23=1,1,1,4,4,4;若大括号或其中的数据不够,后面的元素自动赋0。如:int a34=1,2,3,4,5,6,7,8;如:int a34=1,2,3,4,5,6,7,8,92、按数组的存储顺序赋初值。如:int b22=1,2,3,4;表示将1初始化给b00,2初始化给b01,3初始化给b10,4初始化给b11。若数据不够,后面的元素自动赋0。,南
16、昌大学计算中心,9.5.4 通过赋初值定义二维数组的大小如果对数组元素全部赋初值,定义数组时行长度可以省略,列长度不能省略。如:int a3=1,2,3,4,5,6,8;若用以下形式:int b3=1,2,3,4;确定第一维的规则:若初值个数能被第二维常量除尽,则商数即为第一维大小。如:int b3=1,2,3,4,5,6; /* 第一维为2 */若初值个数不能被第二维除尽,则第一维大小=商数+1。如: int b3=1,2,3,4; /* 第一维为2 */,南昌大学计算中心,练习:定义如下变量和数组:int k;int a33=9,8,7,6,5,4,3,2,1;则下面语句的输出结果是_。f
17、or(k=0;k3;k+) printf(“%d”,akk);7 5 3 B) 9 5 1 C) 9 6 3 D) 7 4 1,南昌大学计算中心,9.5.5 二维数组的定义和数组元素引用举例(见书上例9.10)9.6 二维数组和指针9.6.1 二维数组和数组元素的地址可把二维数组看成一种特殊的一维数组。如:若有int a34;,a0是数组名,是元素a00的地址,a1是数组名, 是元素a10的地址,a0- a00,a01,a02,a03,a1- a10,a11,a12,a13,南昌大学计算中心,因此:二维数组a包含三个行元素:a0、a1、a2 。三个行元素的地址分别是:a、a+1、a+2。而a0
18、、a1、a2也是地址量,是一维数组名,即*(a+0)、*(a+1)、*(a+2)是一维数组首个元素地址。,南昌大学计算中心,二维数组元素的地址的表示:设有int a34;aij的地址可有5种表示:1、&aij2、ai+j3、*(a+i)+j4、&a00+4*i+j5、a0+4*i+j,南昌大学计算中心,9.6.2 通过地址引用二维数组元素若有int a34 , i, j;则a数组元素可有5种表达方式引用:1、aij2、*(ai+j)3、*(*(a+i)+j)4、*(&a00+4*i+j) 5、 (*(a+i)j,南昌大学计算中心,9.6.3 通过建立一个指针数组引用二维数组元素若有int *p
19、3,a34 , i, j;可通过指针数组p引用a数组元素:1、aij2、*(ai+j)3、*(*(a+i)+j)4、 (*(a+i)j,南昌大学计算中心,练习:若有以下的说明和语句,则在执行for语句后,*(*(pt+1)+2)表示的数组元素是_。int t33,*pt3,k;for(k=0;k3;k+) ptk=t20 t22t12 t21,南昌大学计算中心,9.6.4 通过建立一个行指针引用二维数组元素指向一维数组指针变量的定义形式:类型标识符 (*指针变量名)数组元素个数“*”表示其后的变量为指针类型,数组元素个数表示目标变量是一维数组,并说明一维数组元素的个数。由于“*”比“ ”的运算
20、级别低,“*指针变量名”作为一个说明部分,两边必须加括号。 “类型标识符”是定义一维数组元素的类型。如:int a34; int (*p)4; /*定义指向4个元素数组的指针*/ pa ;,南昌大学计算中心,例:若有以下说明和语句,则四个选项中是对c数组元素的正确引用的是_。int c45,(*cp)5;cp=c;cp+1*(cp+3)*(cp+1)+3*(*cp+2),南昌大学计算中心,例:输出二维数组中任一行任一列的值。main()int a341,3,5,7,9,11,13,15,17,19,21,23; int (*p)4,i,j; p=a; printf(input i,j:n);
21、scanf(d,d, 程序运行结果如下:input i,j:1,3a13=15,南昌大学计算中心,9.7 二维数组名和指针数组作为实参9.7.1 二维数组名作为实参时实参和形参之间的数据传递对应的形参必为指针,并且这个指针应指向数组,指向数组的指针变量为行指针。形如:fun(double (*a)N) fun(double aN) fun(double aMN)9.7.2 指针数组作为实参时实参和形参之间的数据传递由于指针数组中每个元素均为指针,因此对应的形参必须是一个指向指针的指针。形如:fun(double *aM) fun(double *a) fun(double *a),南昌大学计算中心,例:编写函数,把任意十进制数转换成二进制数。见9-14.doc例:编写函数,实现33矩阵行列互换。(两种方法)见9-15.doc,