程序设计方法第9讲-1_第1页
程序设计方法第9讲-1_第2页
程序设计方法第9讲-1_第3页
程序设计方法第9讲-1_第4页
程序设计方法第9讲-1_第5页
已阅读5页,还剩53页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第第9讲讲 指指 针针 指针是语言中的重要概念,也是语言的重要特色。指针是语言中的重要概念,也是语言的重要特色。 使用指针,可以使程序更加简洁、紧凑、高效。使用指针,可以使程序更加简洁、紧凑、高效。 9.1 指针和指针变量的概念指针和指针变量的概念 9.2 指针变量的定义与应用指针变量的定义与应用 9.3 数组的指针和指向数组的指针变量数组的指针和指向数组的指针变量 9.4 字符串的指针和指向字符串的指针变量字符串的指针和指向字符串的指针变量 9.5 返回指针值的函数返回指针值的函数 9.6 指针数组与主函数指针数组与主函数main()的形参的形参 9.7 函数的指针和指向函数的指针变量函数的

2、指针和指向函数的指针变量 9.1 指针和指针变量的概念指针和指针变量的概念 1.内存地址内存地址内存中存储单元的编号内存中存储单元的编号 1)计算机硬件系统的内存储器中,拥有大量的存储单元(容量为)计算机硬件系统的内存储器中,拥有大量的存储单元(容量为 字节)。字节)。 为了方便管理,必须为每一个存储单元编号,这个编号就是存储单元为了方便管理,必须为每一个存储单元编号,这个编号就是存储单元 的的“地址地址”。每个存储单元都有一个惟一的地址。每个存储单元都有一个惟一的地址。 2)在地址所标识的存储单元中存放数据。)在地址所标识的存储单元中存放数据。 注意:内存单元的地址与内存单元中的数据是两个完

3、全不同的概念。注意:内存单元的地址与内存单元中的数据是两个完全不同的概念。 例:例: int a ;a = 12; 变量变量 a 内的内的“内容内容”(变量值)是(变量值)是12;变量值可由键盘等方法录入变量值可由键盘等方法录入 a变量的变量的地址地址 scanf(%d, printf(num=%dn, num); C编译程序编译到该变量定义语句时,将变量编译程序编译到该变量定义语句时,将变量num 登录到登录到“符号表符号表” 中。中。符号表符号表的关键属性有两个:一是的关键属性有两个:一是“标识符名(标识符名(id)” ,二是该标,二是该标 识符在内存空间中的识符在内存空间中的“地址(地址

4、(addr)” 。 为描述方便,假设系统分配给变量为描述方便,假设系统分配给变量num的的4字节存储单元为字节存储单元为 3000 至至 3003,则,则起始地址起始地址3000就是变量就是变量num在内存中的地址。在内存中的地址。 3.变量值的存取变量值的存取通过变量在内存中的地址进行通过变量在内存中的地址进行 系统执行系统执行“scanf(”%d“,”和和“printf(”num=%dn“, num);” 时,存取变量时,存取变量num值的方式可以有两种:值的方式可以有两种: (1)直接访问直接访问直接利用变量的地址进行存取直接利用变量的地址进行存取 1)上例中上例中scanf(“%d”,

5、 int *p; /* p是专门用于存放其他变量(是专门用于存放其他变量( num )地址的变量,(存放)地址的变量,(存放整型变量整型变量地址)地址)*/ p= /* p是变量,专门存放是变量,专门存放整形变量整形变量地址地址 (这里不要写成(这里不要写成 “ *p ”)*/ scanf(“%d”, p); scanf(“%d”, printf(“%dn”, *p) ; printf(“%dn”, num); 运行结果:运行结果: 12 (对应(对应scanf(“%d”, p);) 12(scanf(“%d”, ) 12( printf(“%dn”, num) ; ) 12( printf(

6、“%dn”, *p) ; ) p= num的首地址是 3000,将num地址 装入了指针变量 p 4000 4003 300012 pnum 3000 3003 图9-2 p= num的首地址是 3000 p指向了(首地址 为3000)变量num 4.指针与指针变量指针与指针变量 (1)指针)指针即地址即地址(指针变量的值,称为指针,这个值是(指针变量的值,称为指针,这个值是其他变量其他变量的地址)的地址) 一个变量的地址称为该变量的指针。通过变量的指针能够找到该变量。一个变量的地址称为该变量的指针。通过变量的指针能够找到该变量。 (2)指针变量)指针变量专门用于存储其它变量地址的变量专门用于

7、存储其它变量地址的变量 指针变量指针变量p的值就是变量的值就是变量num的地址。指针与的地址。指针与指针变量指针变量的区别的区别/关系,就是关系,就是 变量值与变量(名)的区别变量值与变量(名)的区别/关系。关系。 (3)为表示指针变量和它指向的变量之间的关系,用指针运算符)为表示指针变量和它指向的变量之间的关系,用指针运算符“*”表表 示。示。 例如,指针变量例如,指针变量p与它所指向的变量与它所指向的变量num的关系,的关系,(在上例中在上例中)表示为:表示为: *p,即,即*p等价于变量等价于变量num。而。而p等价于变量等价于变量 *p=3; )的作用相同:的作用相同: int *p

8、, num ; /*定义定义p为指针变量,定义为指针变量,定义num为指普通变量为指普通变量*/ /* int表示表示p指向整型变量,指向整型变量, “*”表示表示 p是指针型变量是指针型变量 */ num=3; /*将将3直接赋给普通变量直接赋给普通变量num*/ p= /*把把num的地址装入的地址装入p,使,使p指向指向num */ *p=3; /*将将3赋给指针变量赋给指针变量p所指向的变量所指向的变量*/ Return 指针指针变量的变量的概念概念 与与 小小 结结 : 指针指针:变量:变量a的地址,称为变量的地址,称为变量a的指针;即的指针;即 普通变量定义:普通变量定义:int

9、a; 指针变量定义:指针变量定义:int * p; 1 . 对指针变量,对指针变量,定义定义语句中各符号语句中各符号的说明的说明 类型符号类型符号“ * ” :说明:说明p 是指针变量是指针变量 基类型符号基类型符号 int :说明:说明p 存储整型变量的地址。存储整型变量的地址。(基类型,用于指针运算时的步长基类型,用于指针运算时的步长 单位,稍后可见单位,稍后可见) 变量名:变量名:p (不要用(不要用 “* P”作变量名,符号作变量名,符号“*”只是类型说明)。只是类型说明)。 2 . 对指针变量,对指针变量,引用引用语句中各符号的说明语句中各符号的说明 常用运算符号:常用运算符号: /

10、*定义定义*/ p= scanf(“%d”, p) ; printf(“%d”,* p) /*引用引用*/ 3. 对于指针变量的符号对于指针变量的符号“*”,出现在不同位置,其作用不同,出现在不同位置,其作用不同 (1)定义中:)定义中:“*”说明所定义的变量是指针变量说明所定义的变量是指针变量 (2)引用中:)引用中:“*” 是是指针运算符指针运算符,取指针变量指向的变量的数值取指针变量指向的变量的数值 9.2 指针变量的定义与应用指针变量的定义与应用 9.2.1 指针变量的定义与相关运算指针变量的定义与相关运算 案例案例9.1 指针变量的定义与相关运算示例。指针变量的定义与相关运算示例。

11、/*案例代码文件名:案例代码文件名:AL9_1.C*/ #include main() int num_int=12, *p_int; /*定义一个指向定义一个指向int型数据的指针变量型数据的指针变量p_int */ float num_f=3.14, *p_f; /*定义一个指向定义一个指向float型数据的指针变量型数据的指针变量p_f */ char num_ch=p, *p_ch; /*定义一个指向定义一个指向char型数据的指针变量型数据的指针变量p_ch */ p_int= /*取变量取变量num_int的地址,赋值给的地址,赋值给p_int */ p_f= /*取变量取变量nu

12、m_f的地址,赋值给的地址,赋值给p_f */ p_ch= /*取变量取变量num_ch的地址,赋值给的地址,赋值给p_ch */ printf(“num_int=%d, *p_int=%dn”, num_int, *p_int); printf(“num_f=%4.2f, *p_f=%4.2fn”, num_f, *p_f); printf(“num_ch=%c, *p_ch=%cn”, num_ch, *p_ch); AL9_1.C 程序演示程序演示 300012 p_int*p_int 3000 3003 图9-2 num_int 4000 4003 程序运行结果:程序运行结果: num

13、_int=12, *p_int=12 num_f=3.14, *p_f=3.14 num_ch=p, *p_ch=p 程序说明:程序说明: (1)头三行的变量定义语句)头三行的变量定义语句指针变量的定义指针变量的定义 与一般变量的定义相比,除变量名前多了一个星号与一般变量的定义相比,除变量名前多了一个星号“*” (指针变(指针变 量的定义标识符)外,其余一样:量的定义标识符)外,其余一样: 基基(数据)(数据)类型类型 *指针变量指针变量, *指针变量指针变量2; 注意:此时的指针变量注意:此时的指针变量p_int、p_f、p_ch,并未指向某个具体的变,并未指向某个具体的变 量(称指针是悬空

14、的)。使用悬空指针很容易破坏系统,导致系统瘫痪。量(称指针是悬空的)。使用悬空指针很容易破坏系统,导致系统瘫痪。 (2)中间三行的赋值语句中间三行的赋值语句取地址运算取地址运算() 取地址运算的格式:取地址运算的格式: 变量变量 例如,例如, point1 = ) 则则 1、 3、 (*point1)+: 即即a+ *point1+:等价:等价 *(point1+) 案例案例9.2 使用指针变量求解:输入使用指针变量求解:输入2个整数,按升序(从小到大排序)个整数,按升序(从小到大排序) 输出。输出。 /*案例代码文件名:案例代码文件名:AL9_2.C*/ main() int num1,nu

15、m2; int *num1_p= printf(“Input the first number: ”); scanf(“%d”,num1_p); printf(“Input the second number: ”); scanf(“%d”,num2_p); printf(“num1=%d, num2=%dn”, num1, num2); if( *num1_p *num2_p ) /*如果如果num1num2,则,则交换指针交换指针*/ pointer= num1_p, num1_p= num2_p, num2_p=pointer; printf(“min=%d, max=%dn”, *nu

16、m1_p, *num2_p); printf(“num1=%d, num2=%dn”, num1, num2); AL9_2.C 程序演示程序演示 num1_p 语句:语句: 通过指针变量,间接访问变量的值。通过指针变量,间接访问变量的值。 9.2.2 指针变量作函数参数指针变量作函数参数 1.指针变量,既可以作为函数的形参,也可以作函数的实参。指针变量,既可以作为函数的形参,也可以作函数的实参。 2.指针变量作实参时,与普通变量一样,也是指针变量作实参时,与普通变量一样,也是“值传递值传递”,即将指针变量的值,即将指针变量的值 (一个地址)传递给被调用函数的形参(必须是一个指针变量)。(一个

17、地址)传递给被调用函数的形参(必须是一个指针变量)。 注意:被调用函数不能改变实参指针变量的值,但可以改变实参指针变量所指注意:被调用函数不能改变实参指针变量的值,但可以改变实参指针变量所指 向的变量的值。向的变量的值。 案例案例9.3 使用函数调用方式改写使用函数调用方式改写案例案例9.2,要求实参为指针变量。,要求实参为指针变量。 /*案例代码文件名:案例代码文件名:AL9_3.C*/ /*/ /*exchange()功能:功能:交换交换2个个形参形参指针变量指针变量所指向的所指向的变量变量的的值值 */ /*形参:形参:2个,均为指向整型数据的指针变量个,均为指向整型数据的指针变量 */

18、 /*返回值:无返回值:无 */ /*/ void exchange(int *pointer1, int *pointer2) int temp; temp=*pointer1, *pointer1=*pointer2, *pointer2=temp; /*主函数主函数main()*/ main() int num1,num2; int *num1_p= printf(“Input the first number: ”); scanf(“%d”, num1_p); printf(“Input the second number: ”); scanf(“%d”, num2_p); print

19、f(“num1=%d, num2=%dn”, num1, num2); if( *num1_p *num2_p ) /* 即即num1num2)*/ exchange(num1_p, num2_p); /*指针变量作实参指针变量作实参*/ /*输出排序后的输出排序后的num1和和num2的值的值*/ printf(“min=%d, max=%dn”, num1, num2); AL9_3.C 程序演示程序演示 案例案例9.3 与与案例案例9.2的主要区别是的主要区别是 通过函数通过函数exchange()的调用,交换的调用,交换2个形参指针变量所指向的变量的值个形参指针变量所指向的变量的值 。

20、 功能:功能: /*在函数在函数exchange()的调用中,实参把地址传给形参,形参指针的调用中,实参把地址传给形参,形参指针 变量所指向的(变量)存储单元地址与实参指针变量所指向的(变量)变量所指向的(变量)存储单元地址与实参指针变量所指向的(变量) 存储单元地址是同一单元。存储单元地址是同一单元。 其效果是:交换其效果是:交换2个形参指针变量所指向的变量的值个形参指针变量所指向的变量的值 ,实参指针变量所,实参指针变量所 指向的变量的值指向的变量的值 也随之交换。也随之交换。 原因是:实参、形参指向的是同一地址单元原因是:实参、形参指向的是同一地址单元 num2_p 或者:或者: int

21、 array10, *pointer; pointerarray; 注意注意:数组名代表数组在内存中的起始地址(与第:数组名代表数组在内存中的起始地址(与第1个元素的地个元素的地 址相同),所以可以用数组名给指针变量赋值。址相同),所以可以用数组名给指针变量赋值。 3.数组元素的引用数组元素的引用 数组元素的引用,既可用下标法,也可用指针法。使用下标法,数组元素的引用,既可用下标法,也可用指针法。使用下标法, 直观;而使用指针法,能使目标程序占用内存少、运行速度快。直观;而使用指针法,能使目标程序占用内存少、运行速度快。 9.3.2 通过指针引用数组元素通过指针引用数组元素 如果有如果有“ i

22、nt a 10,*p=a ;” ,则:,则: (1)p+i和和a+i都是数组元素都是数组元素a i的地址,如的地址,如图图9-6(见下一页)(见下一页) 所示。所示。 实际地址为实际地址为p+i*d,d为每个数组元素所占的字节数。为每个数组元素所占的字节数。 (2)*(p+i)和和*(a+i)就是数组元素就是数组元素a i。实际上,在编译时,对。实际上,在编译时,对 数组元素数组元素a i就是处理成就是处理成*(a+i)。 (3)指向数组的指针变量,也可将其看作是数组名,因而可按)指向数组的指针变量,也可将其看作是数组名,因而可按 下标法来使用。例如,下标法来使用。例如,p i等价于等价于*(

23、p+i)。 注意注意:p+1指向数组的下一个元素,而不是简单地使指针变量指向数组的下一个元素,而不是简单地使指针变量p 的值的值+1。其实际变化为。其实际变化为p+1*size(size为一个元素占用的字节数)。为一个元素占用的字节数)。 例如,假设指针变量例如,假设指针变量p的当前值为的当前值为1000,则,则p+1为为1000+1*4=1004, 而不是而不是1001。如。如图图9-6(见下一页)(见下一页)所示所示 定义定义字 节 数字 节 数 d d/ / 步长步长 假设:假设:p p 指向地址为指向地址为 10001000;i = 1 i = 1 时时 基类型基类型指针类型说明符指针

24、类型说明符变量名变量名p + i p + i 表示的地址为表示的地址为:p + p + i di d charchar * *p p 1 110011001 intint2/42/41002/10041002/1004 floatfloat4 410041004 元素元素起始起始地址地址 a0 10001000 a1 10041004 a2 10081008 a3 10121012 a i 10161016 a5 10201020 a6 10241024 a7 10281028 a8 10321032 a9 10361036 a 数组数组 如果有如果有“ int a 10,*p=a ;” ,则

25、:,则: (1)p+i和和a+i都是数组元素都是数组元素a i的地址,的地址, 如图所示。如图所示。 实际地址为实际地址为p+i*d,d为每个为每个 数组元素所占的字节数。数组元素所占的字节数。 (2)*(p+i)和和*(a+i)就是数组元素就是数组元素a i。 实际上,在编译时,对数组元素实际上,在编译时,对数组元素a i就是就是 处理成处理成*(a+i)。 (3)指向数组的指针变量,也可将其看)指向数组的指针变量,也可将其看 作是数组名,因而可按下标法来使用。例作是数组名,因而可按下标法来使用。例 如,如,p i等价于等价于*(p+i)。(有条件。(有条件:p=a ;) 等价元素等价元素a

26、 i 。 * * ( p + i ) * * ( p + 9 ) p 10001000 p +1, a+1 p + i , a + i printf(“Input 10 numbers: ”); for(i=0; i10; i+) scanf(“%d”, p+i);/*使用指针变量来输入数组元素的值使用指针变量来输入数组元素的值*/ printf(“array10: ”); for(i=0; i10; i+) printf(“%d ”, *(p+i);/*使用指向数组的指针变量输出数组元素的值使用指向数组的指针变量输出数组元素的值*/ printf(“n”); AL9_5.C 程序演示程序演示

27、 程序运行情况:程序运行情况: Input 10 numbers: 0 1 2 3 4 5 6 7 8 9 array10: 0 1 2 3 4 5 6 7 8 9 说明:说明: (1)指针变量指针变量的值是可以改变的,所以必须注意其的值是可以改变的,所以必须注意其当前当前 值值,否则容易出错。,否则容易出错。 (2)指向数组的指针变量,可以指向数组以后的内存单)指向数组的指针变量,可以指向数组以后的内存单 元,虽然没有实际意义。元,虽然没有实际意义。 (3)对指向数组的指针变量()对指向数组的指针变量(px和和py)进行算术运算进行算术运算 和和关系运算关系运算的含义的含义 1)可以进行的)

28、可以进行的算术运算算术运算,只有以下几种只有以下几种: pxn, px+/+px, px-/-px, px-py pxn:将指针从当前位置向前(:将指针从当前位置向前(+n)或回退()或回退(-n)n 个个数据单位数据单位,而不是,而不是n个字节。显然,个字节。显然,px+/+px和和px-/-px 是是pxn的特例(的特例(n=1)。)。 px - py:两指针变量两指针变量的的值值之之差差,其意义是,其意义是两指针之间两指针之间 的的数据(数据(数组数组元素元素的的)个数)个数,而而不是不是指针的指针的地址之差。地址之差。 思考题:思考题: 若有以下定义和语句,且若有以下定义和语句,且0i

29、10,则对数组元素的错误引,则对数组元素的错误引 用是用是: int a=1,2,3,4,5,6,7,8,9,10, int *p=a,i; A *(a+i) B ap-a C p+i D *( for( ; i5;i+)(*q)+; main() int a5=1,2,3,4,5,i; f(a); for(i=0;i5;i+)printf(“%d,”,ai); 程序运行后的输出结果是( ) A)2,2,3,4,5, B)6,2,3,4,5, C)1,2,3,4,5, D) 2,3,4,5,6, 2007年4月 2、以下程序的输出结果是、以下程序的输出结果是 _ int fun(int*x,

30、int n) if(n=0) return x0; else return x0+fun(x+1,n-1); main() int a=1,2,3,4,5,6,7; printf(“%dn”,fun(a,3); 10 2007年9月 1、若在定义语句:、若在定义语句:inta,b,c,*p=之后,接着执行以下选项中的之后,接着执行以下选项中的 语句,则能正确执行的语句是语句,则能正确执行的语句是 A)scanf(“%d”,a,b,c); B)scanf(%d%d%d,a,b,c); C)scanf(“%d”,p); D)scanf(%d, 2007年9月 2、有以下程序、有以下程序 #incl

31、ude voidfun(int *a, intn)/*函数功能是将函数功能是将a所指数组元素从大到小排序所指数组元素从大到小排序*/ intt,i,j; for(i=0;in-1;i+) for(j=i+1;jn;j+) if(aiaj) t=ai;ai=aj;aj=t; main() intc10=1,2,3,4,5,6,7,8,9,0,i; fun(c+4,6); for (i=0;i10;i+) printf(%d,ci);printf(n); 程序运行的结果是程序运行的结果是 A)1,2,3,4,5,6,7,8,9,0, B)0,9,8,7,6,5,1,2,3,4, C)0,9,8,7

32、,6,5,4,3,2,1, D)1,2,3,4,9,8,7,6,5,0, 2007年9月 3、有以下程序、有以下程序 #include voidfun(intn, int*p) intf1,f2; if(n=1|n=2)*p=1; else fun(n-1,fun(n-2,*p=f1+f2; main() ints; fun(3,printf(%dn,s); 程序的运行结果是程序的运行结果是 A)2 B)3 C)4 D)5 2008年4月 1、以下定义语句中正确的是、以下定义语句中正确的是 A)int a=b=0;B)char A=65+1,b=b; C)float a=1,*b= D)dou

33、ble a=0.0;b=1.1; 2、有以下程序、有以下程序 #include main() int a =1,2,3,4, y, *p= -p;y=*p;printf(y=%dn,y); 程序运行的结果是程序运行的结果是 A)y=0B)y=1C)y=2D)y=3 2008年4月 3、有以下程序有以下程序 #include voidfun(int *s, int n1, int n2) inti, j, t; i=n1; j=n2; while(ij)t=si; si=sj; sj=t; i+; j-; main() inta10=1,2,3,4,5,6,7,8,9,0, k; fun(a,0

34、,3);fun(a,4,9);fun(a,0,9); for(k=0;k10;k+)printf(%d,ak);printf(n); 程序运行得结果是程序运行得结果是 A)0987654321B)4321098765 C)5678901234D)0987651234 2008年4月 4、以下程序的输出结果是【、以下程序的输出结果是【 3 5 】。】。 #include voidswap(int *a, int *b) int *t; t=a; a=b; b=t; main( ) int i=3, j=5, *p= swap(p,q);printf(%d %dn,*p,*q); 2008年4月

35、5、以下程序的输出结果是【、以下程序的输出结果是【 4 】。】。 #include main( ) inta5=2,4,6,8,10, *p; p=a;p+; printf(%d,*p); 2008年9月 1、若有定义语句:、若有定义语句:doublex5=1.0,2.0,3.0,4.0,5.0,*p=x;则错误引则错误引 用用x数组元素的是数组元素的是 A)*pB)x5C)*(p+1)D)*x 2、以下程序的输出结果是【、以下程序的输出结果是【9】 #include main( ) int j, a =1,3,5,7,9,11,13,15, *p=a+5; for(j=3; j; j-) s

36、witch(j) case 1: case 2:printf(%d,*p+);break; case 3:printf(%d,*(-p); 9 9 11 2008年9月 3、以下程序的输出结果是【、以下程序的输出结果是【10】 #include #defineN5 intfun( int*s,inta,intn) intj;*s=a;j=n; while(a!=sj)j-; returnj; main() intsN+1;intk; for(k=1;k=N;k+)sk=k+1; printf(%dn,fun(s,4,N); 3 2009年3月 1、若有定义语句、若有定义语句:double x,

37、y,*px,*py;执行了执行了px=py=之后之后,正正 确的输入语句是确的输入语句是 A)scanf(“%f%f”,x,y); B)scanf(%f%f C)scanf(“%lf%le”,px,py); D)scanf(“%lf%lf”,x,y); 2009年3月 2、 有以下程序有以下程序 #include voidfun(int*a, int*b) int*c; c=a; a=b; b=c; main() intx=3,y=5,*p= fun(p,q);printf(%d,%d,*p,*q); fun(printf(%d,%dn,*p,*q); 程序运行后输出的结果是程序运行后输出的结

38、果是 A)3,5,5,3 B)3,5,3,5 C)5,3,3,5 D)5,3,5,3 2009年3月 3、有以下程序、有以下程序 #include voidf(int*p, int*q); main( ) intm=1, n=2, *r= f(r,printf(%d,%d,m,n); voidf(int*p, int*q) p=p+1; *q=*q+1; 程序运行后的输出结果是程序运行后的输出结果是 A)1,3 B)2,3 C)1,4 D)1,2 2009年3月 4、以下函数按每行、以下函数按每行8个输出数组中的数据个输出数组中的数据 #include voidfun(int*w, intn)

39、 inti; for(i=0;in;i+) _ printf(%d,wi); printf(n); 下划线出应填入的语句是下划线出应填入的语句是 A)if(i/8=0) printf(“n”); B)if(i/8=0) continue; C)if(i%8=0) printf(n); D)if(i%8=0) continue; 2009年3月 5、若有以下定义、若有以下定义 int x10,*pt=x; 则对数组元素的正确引用是则对数组元素的正确引用是 A)* intfun(int*k) b=*k+b; return (b); main() inta10=1,2,3,4,5,6,7,8, i;

40、 for(i=2;i4;i+)b=fun(printf(%d,b); printf(n); 程序运行后的输出结果是程序运行后的输出结果是 A)10 12 B)8 10 C)10 28 D)10 16 2009年9月 1、有以下程序、有以下程序 #include main( ) intm=1,n=2,*p= r=p;p=q;q=r; printf(%d,%d,%d,%dn,m,n,*p,*q); 程序运行后的输出结果是程序运行后的输出结果是 A)1,2,1,2 B)1,2,2,1 C)2,1,2,1 D)2,1,1,2 9.3.4 2维数组的指针及其指针变量维数组的指针及其指针变量 1. 2维数

41、组的指针维数组的指针 假设有如下数组定义语句:假设有如下数组定义语句: int a34=1,3,5,7,9,11,13,15,17,19,21,23; (1)从)从2维数组角度看,数组名维数组角度看,数组名a代表数组的起始地址,代表数组的起始地址, 是一个以行为单是一个以行为单 位进行控制的行指针:位进行控制的行指针: a+i:行指针值,指向:行指针值,指向2维数组的第维数组的第i行。行。 *(a+i):等价于:等价于ai,(列)指针值,指向第,(列)指针值,指向第i行第列(控制由行转为列,行第列(控制由行转为列, 但仍为指针)。但仍为指针)。 *(*(a+i):数组元素:数组元素ai0的值。

42、的值。 用用a作指针访问数组元素作指针访问数组元素aij的格式:的格式: *(*(a+i)j) 注意注意:行指针是一个级指针,如图所示。:行指针是一个级指针,如图所示。 (2)从)从1维数组角度看,数组名维数组角度看,数组名a和第和第1维下标的每一个值,维下标的每一个值, 共同构成共同构成 一组新的一组新的1维数组名维数组名a0、a1、a2,它们均由,它们均由4个元素组成。个元素组成。 a+1 a2 a1 a0 a 23211917 1513119 7531= = = a+2 2000 2016 2032 a0 a0+1 a0+3 a2000*(a1+2),*(*(a+1)+2) 13 a0,

43、*(a+0),*a2000*a 1 a+1, 注意注意:“*指针变量指针变量”外的括号不能缺外的括号不能缺,否则成了指针数组,否则成了指针数组数数 组的每个元素都是一个指针组的每个元素都是一个指针指针数组(本章第指针数组(本章第6节介绍)。节介绍)。 (2)赋值赋值 行指针变量行指针变量 2维数组名维数组名 | 行指针变量行指针变量; 案例案例9.6 使用行指针和列指针两种方式输出使用行指针和列指针两种方式输出2维数组的任一元素。维数组的任一元素。 (1) 使用行指针使用行指针 /*案例代码文件名:案例代码文件名:AL9_6_1.C*/ /*程序功能:使用行指针输出程序功能:使用行指针输出2维

44、数组的任一元素维数组的任一元素*/ main() int a34=1,2,3,4,5,6,7,8,9,10,11,12; int (*pointer)4, row, col; pointer=a; printf(“Input row = ”); scanf(“%d”, printf(“Input col = ”); scanf(“%d”, printf(“a%1d%1d=%dn”,row,col, *(*(pointer+row)+col); 程序运行情况:程序运行情况: Input row = 1 Input col = 2 array12 = 7 思考题:本题也可以直接使用数组名思考题:本

45、题也可以直接使用数组名a作指针,应如何修改?作指针,应如何修改? (2)使用列指针)使用列指针 /*案例代码文件名:案例代码文件名:AL9_6_2.C*/ /*程序功能:使用列指针输出程序功能:使用列指针输出2维数组的任一元素维数组的任一元素*/ main() int a34=1,2,3,4,5,6,7,8,9,10,11,12; int *pointer, row, col; /*定义一个定义一个(列列)指针变量指针变量pointer*/ pointer=a0; /*给给(列列)指针变量指针变量pointer赋值赋值*/ printf(“Input row = ”); scanf(“%d”,

46、 printf(“Input col = ”); scanf(“%d”, printf(“a%1d%1d = %dn”, row, col, *(pointer+(row*4+col); 程序演示程序演示 3. 2维数组指针作函数参数维数组指针作函数参数 一维数组的地址可以作为函数参数传递,多维数组的地一维数组的地址可以作为函数参数传递,多维数组的地 址也可以作为函数参数传递。在用指针变量作形参以接受址也可以作为函数参数传递。在用指针变量作形参以接受 实参数组名传递来的地址时,有两种方法:实参数组名传递来的地址时,有两种方法:用指向变量用指向变量 的指针变量的指针变量 用指向一维数组的指针变量

47、。用指向一维数组的指针变量。 2008年9月 1、有以下程序、有以下程序 #include intfun( int (*s)4, int n, int k) int m, i; m=s0k; for(i=1;im)m=sik; returnm; main() int a44=1,2,3,4,11,12,13,14,21,22,23,24,31,32,33,34; printf(%dn,fun(a,4,0); 程序的运行结果是程序的运行结果是 A)4B)34C)31D)32 9.3.5 动态数组的实现动态数组的实现 在程序运行过程中,数组的大小是不能改变的。这种数在程序运行过程中,数组的大小是不

48、能改变的。这种数 组称为组称为静态数组静态数组。静态数组的缺点是:对于事先无法准。静态数组的缺点是:对于事先无法准 确估计数据量的情况,无法做到既满足处理需要,又不确估计数据量的情况,无法做到既满足处理需要,又不 浪费内存空间。浪费内存空间。 所谓所谓动态数组动态数组是指,在程序运行过程中,根据实际需要是指,在程序运行过程中,根据实际需要 指定数组的大小。指定数组的大小。 在在C语言中,可利用内存的申请和释放库函数,以及指向语言中,可利用内存的申请和释放库函数,以及指向 数组的指针变量可当数组名使用的特点,来实现动态数数组的指针变量可当数组名使用的特点,来实现动态数 组。组。 动态数组的本质是

49、动态数组的本质是:一个指向数组的指针变量。:一个指向数组的指针变量。 案例案例9.7 动态数组的实现。动态数组的实现。 /*案例代码文件名:案例代码文件名:AL9_7.C*/ /*程序功能:实现动态数组程序功能:实现动态数组*/ #include #include main() int *array=NULL, num, i; printf(“Input the number of element: ”); scanf(“%d”, /*申请动态数组使用的内存块申请动态数组使用的内存块*/ array=(int *)malloc( sizeof(int) * num ); if ( array=

50、NULL ) /*内存申请失败:提示,退出内存申请失败:提示,退出*/ printf(“out of memory, press any key to quit”); exit(0); /*exit():终止程序运行,返回操作系统:终止程序运行,返回操作系统*/ /*提示输入提示输入num个数据个数据*/ printf(“Input %d elements: ”, num); for (i=0; inum; i+) scanf(“%d”, /*输出刚输入的输出刚输入的num个数据个数据*/ printf(“%d elements are: ”, num); for (i=0; inum; i+) printf(“%d,”, arrayi);

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论