C语言程序设计ppt课件第9章

上传人:博****1 文档编号:570208629 上传时间:2024-08-02 格式:PPT 页数:105 大小:649KB
返回 下载 相关 举报
C语言程序设计ppt课件第9章_第1页
第1页 / 共105页
C语言程序设计ppt课件第9章_第2页
第2页 / 共105页
C语言程序设计ppt课件第9章_第3页
第3页 / 共105页
C语言程序设计ppt课件第9章_第4页
第4页 / 共105页
C语言程序设计ppt课件第9章_第5页
第5页 / 共105页
点击查看更多>>
资源描述

《C语言程序设计ppt课件第9章》由会员分享,可在线阅读,更多相关《C语言程序设计ppt课件第9章(105页珍藏版)》请在金锄头文库上搜索。

1、C C语言程序设计语言程序设计The C Programming Language华中科技大学计算机学院曹计昌8/2/20241华中科技大学计算机学院9.1 9.1 指针的概念与指针的使用指针的概念与指针的使用 9.1.1 9.1.1 指针的概念指针的概念 数据(变量、常量)(根据类型)占有一定数数据(变量、常量)(根据类型)占有一定数目的连续存储单元;目的连续存储单元;数据的连续存储单元首地址称为数据的地址。数据的连续存储单元首地址称为数据的地址。变量的地址称为指针,存放地址数据的变量称变量的地址称为指针,存放地址数据的变量称为指针变量。为指针变量。指针也是一种变量,也要占用一定的内存单元。

2、指针也是一种变量,也要占用一定的内存单元。指针的特殊之处在于它存放的是另一个变量所指针的特殊之处在于它存放的是另一个变量所占存储单元的起始地址。占存储单元的起始地址。 8/2/20242华中科技大学计算机学院指针变量的类型由其基类型决定指针变量的类型由其基类型决定. .基类型是指针变量所指基类型是指针变量所指( (即所指向即所指向) )变量的数据变量的数据类型。类型。因此,称指向某种类型变量的指针为该类型的因此,称指向某种类型变量的指针为该类型的指针。指针。 如:指向整型变量的指针称为整型指针,指向如:指向整型变量的指针称为整型指针,指向字符型变量的指针称为字符指针等。字符型变量的指针称为字符

3、指针等。不管是何种类型的指针不管是何种类型的指针, ,所占的存储与机器字所占的存储与机器字长相当长相当. .如如:16:16位机位机, ,指针占指针占2 2字节字节, ,思考思考: : 为什么指针指针有类型为什么指针指针有类型? ?指针变量的类型指针变量的类型8/2/20243华中科技大学计算机学院ptrptr指向指向x x 如果整型如果整型变量量x x的地址是的地址是0xFEC00xFEC0,x x的的值是是0xABCD0xABCD,整型指整型指针ptrptr的地址是的地址是0xFEBC0xFEBC,整型指,整型指针ptrptr指向整型指向整型变量量x x的内存存的内存存储和指向情况可以由下

4、和指向情况可以由下图描述:描述:0xFEBC0xFEBC,ptrptr之址之址C0C00xFEBD0xFEBDFEFE0xFEC00xFEC0,x x的低字节的低字节CDCD0xFEC10xFEC1ABAB0xFEC20xFEC20xFEC30xFEC30xFEC40xFEC48/2/20244华中科技大学计算机学院9.1.2 9.1.2 指针的声明指针的声明声明指针的一般形式:声明指针的一般形式: T *T *标识符标识符1 1,* *标识符标识符2 2,, *, *标识符标识符n n; 其中,其中,T T是数据类型。是数据类型。* *是指针说明符,用于将是指针说明符,用于将其说明的标识符说

5、明为指针类型。标识符其说明的标识符说明为指针类型。标识符1 1,标,标识符识符2 2,标识符,标识符n n是是T T类型的指针的名字类型的指针的名字. .例例9.19.1:char *pc1,*pc2;char *pc1,*pc2; intint *pi; *pi; float *pf; float *pf; 8/2/20245华中科技大学计算机学院 指针变量也可以在声明的时候对其进行初指针变量也可以在声明的时候对其进行初始化,但必须用所指变量的地址进行初始化。始化,但必须用所指变量的地址进行初始化。初始化后的指针将指向以初值为地址的变量。初始化后的指针将指向以初值为地址的变量。 例例9.2

6、9.2 声明指针并初始化。声明指针并初始化。 intint x=10,*p=&x; x=10,*p=&x; 错误的声明错误的声明: : intint *p=& *p=&x,xx,x=10;=10;8/2/20246华中科技大学计算机学院例例9.3 9.3 给出以下一些复杂声明,给出以下一些复杂声明,解释其含义。解释其含义。1.int (*p1)3;2.double *p25;3.char (*fp)(int,int);4.int *pf(float a);5.int (*fp_ary2)(char *,int *);8/2/20247华中科技大学计算机学院9.1.3 9.1.3 指针的使用指针

7、的使用 在声明指针变量的前提下,指针的使用首在声明指针变量的前提下,指针的使用首先要获取变量的地址作为指针值,然后要将该先要获取变量的地址作为指针值,然后要将该指针值赋给指针变量,建立指针变量与被指变指针值赋给指针变量,建立指针变量与被指变量间的指向关系。接下来就是如何通过指针变量间的指向关系。接下来就是如何通过指针变量来间接访问和操作指针所指的变量。量来间接访问和操作指针所指的变量。8/2/20248华中科技大学计算机学院 1. 1. 取地址运算符取地址运算符- -单目单目& & 单目单目& &在在C C中表示取地址运算。该表达式的一般使中表示取地址运算。该表达式的一般使用形式是:用形式是:

8、 & &右操作数右操作数 根据表达式的操作语义可知,右操作数必须是根据表达式的操作语义可知,右操作数必须是一个左值表达式。如果右操作数的类型是一个左值表达式。如果右操作数的类型是T T,则表,则表达式达式& &右操作数的类型是右操作数的类型是T *T *。 8/2/20249华中科技大学计算机学院 2. 2. 指针的赋值指针的赋值 指针的声明只是创建了指针变量,获得了指指针的声明只是创建了指针变量,获得了指针变量的存储,但并没有给出指针变量指向那个针变量的存储,但并没有给出指针变量指向那个具体的变量,此时指针的值是不确定的随机值,具体的变量,此时指针的值是不确定的随机值,指针处于指针处于“无所

9、指无所指”的状态。例如:用的状态。例如:用 intint *p; *p;语句来说明语句来说明p p是一个整型指针变量时,是一个整型指针变量时,p p的值是不的值是不确定的随机值。此时称确定的随机值。此时称p p为悬挂指针。为悬挂指针。 8/2/202410华中科技大学计算机学院例例9.5 9.5 设有下面说明:设有下面说明: intint i,*pi; i,*pi; char c,*pc; char c,*pc; float x5,*pf; float x5,*pf;则:则:npi=&i; pi=&i; 取整型变量取整型变量i i的地址赋给整型指针变量的地址赋给整型指针变量pi.pi.npc=

10、&c; pc=&c; 取出字符变量取出字符变量c c的地址赋给字符指针变量的地址赋给字符指针变量pc.pc.npf=&x0;pf=&x0;和和pf=x;pf=x;的作用相同,均表示将的作用相同,均表示将x x数组的起数组的起始地址赋给指针变量始地址赋给指针变量pf, pf, 使使pfpf指向指向x x数组的第一个元数组的第一个元素素x0x0。n数组名数组名x x的数据类型是的数据类型是float *float *,并且标识,并且标识x x数组的起数组的起始地址始地址, ,因此语句因此语句pf=x;pf=x;合法有效。合法有效。8/2/202411华中科技大学计算机学院 3. 3. 间访运算符单

11、目间访运算符单目* *n声明指针的目的是希望通过指针实现对内存中变量声明指针的目的是希望通过指针实现对内存中变量的快速访问,必须使用单目的快速访问,必须使用单目* *这个间访运算符才能这个间访运算符才能实现利用指针对内存变量的访问。间访的含义是间实现利用指针对内存变量的访问。间访的含义是间接访问。单目接访问。单目* *运算实际上是单目运算实际上是单目& &运算的逆运算运算的逆运算. .n使用单目使用单目* *间访变量的一般形式是:间访变量的一般形式是: * *操作数操作数n“* *操作数操作数”称为称为间访表达式间访表达式,它的操作语义是引,它的操作语义是引用以操作数之值为地址的变量。操作数也

12、可以是表用以操作数之值为地址的变量。操作数也可以是表达式,但其值必须是地址值。达式,但其值必须是地址值。n间访表达式的值是一个左值,代表指针所指的变量。间访表达式的值是一个左值,代表指针所指的变量。而指针所指的变量的类型就是间访表达式运算结果而指针所指的变量的类型就是间访表达式运算结果的类型。的类型。 8/2/202412华中科技大学计算机学院例例9.6 9.6 间访运算符的基本操作举例。间访运算符的基本操作举例。设有声明和赋值:设有声明和赋值:char char chch= =a a,*pc=&,*pc=&chch; * *pc=pc=b b; 并且假设字符变量并且假设字符变量chch的地址

13、是的地址是0x1b2a0x1b2a,试问,试问chch,pcpc,以及,以及* *pcpc的值是什么?的值是什么?8/2/202413华中科技大学计算机学院4. 4. 无值型指针无值型指针 类型为类型为void *void *的指针称为无值型指针或的指针称为无值型指针或voidvoid指针。指针。C C语言规定,任何类型的指针都可以语言规定,任何类型的指针都可以将其值赋给将其值赋给voidvoid指针,但是不能对指针,但是不能对voidvoid指针执指针执行间访操作,即对行间访操作,即对voidvoid指针施行指针施行“* *”操作属于操作属于非法操作。非法操作。intint x=1,* x=

14、1,*pxpx=&x;=&x;char char chch=a,*pc=&=a,*pc=&chch,*pc1;,*pc1;void *void *vpvp; ;则:则:vpvp= =pxpx; ; vpvp=pc;=pc; pc1=(char *) pc1=(char *)vpvp; ; * *vpvp=b; /* =b; /* 非法非法 * */ /8/2/202414华中科技大学计算机学院9.2 9.2 指针运算指针运算 指针允许进行算术运算、赋值运算和关系运算。指针允许进行算术运算、赋值运算和关系运算。通过指针运算可以快速定位到指定的内存单元,提通过指针运算可以快速定位到指定的内存单元,

15、提高程序的执行效率。高程序的执行效率。9.2.1 9.2.1 指针的算术运算指针的算术运算1. 1. 指针的移动指针的移动指针的移动指指针在原有位置的基础上,通过加一个指针的移动指指针在原有位置的基础上,通过加一个整数实现指针的前移(地址增大的方向)或者通过整数实现指针的前移(地址增大的方向)或者通过减一个整数实现指针的后移。当然,如果加减的是减一个整数实现指针的后移。当然,如果加减的是一个负数,则移动的方向刚好和前面相反。一个负数,则移动的方向刚好和前面相反。 8/2/202415华中科技大学计算机学院例例9.9 9.9 指针的算术运算应用举例指针的算术运算应用举例( (演示演示EX9_9)

16、EX9_9)。#include #include stdio.hstdio.h void void main(voidmain(void) ) intint iary5=0,1,2,3,4; iary5=0,1,2,3,4; intint * *pxpx=&iary0;=&iary0; printf(displayprintf(display the address and the address and the value of the elements:n); the value of the elements:n); for(;for(;pxpx &iary0+5 &iary0+5;px

17、+);px+) printf(pxprintf(px=%p *=%p *pxpx=%=%dn,pxdn,px,*,*pxpx);); pxpx=&iary0;=&iary0; printf(afterprintf(after executing executing pxpx=&iary0:n);=&iary0:n); printf(px=%p *px=%dn,px,*px);printf(px=%p *px=%dn,px,*px);8/2/202416华中科技大学计算机学院 pxpx+=3;+=3; printf(afterprintf(after pxpx plus 3:n); plus 3

18、:n); printf(px=%p *px=%dn,px,*px);printf(px=%p *px=%dn,px,*px); px-=2;px-=2; printf(after px minus 2:n); printf(after px minus 2:n); printf(px=%p *px=%dn,px,*px); printf(px=%p *px=%dn,px,*px); printf(*(+px)=%dn,*(+px); printf(*(+px)=%dn,*(+px); printf(px=%p *px=%dn,px,*px); printf(px=%p *px=%dn,px,*

19、px); printf(*(px+)=%dn,*(px+); printf(*(px+)=%dn,*(px+); printf(px=%p *px=%dn,px,*px); printf(px=%p *px=%dn,px,*px); printf(*(-px)=%dn,*(-px); printf(*(-px)=%dn,*(-px); printf(px=%p *px=%dn,px,*px); printf(px=%p *px=%dn,px,*px); printf(*(px-)=%dn,*(px-); printf(*(px-)=%dn,*(px-); printf(px=%p *px=%d

20、n,px,*px); printf(px=%p *px=%dn,px,*px); 8/2/202417华中科技大学计算机学院 9.2.2 9.2.2 指针的赋值运算和关系运算指针的赋值运算和关系运算1. 1. 指针的赋值运算指针的赋值运算 指针的初始化和基本赋值操作前面指针的初始化和基本赋值操作前面已有叙述。下面主要进行一些归纳并给出已有叙述。下面主要进行一些归纳并给出应用的例子,其中利用指针的赋值运算以应用的例子,其中利用指针的赋值运算以及类型强制来突破语言的一些制约因素的及类型强制来突破语言的一些制约因素的编程算法和思想可以在底层软件开发时借编程算法和思想可以在底层软件开发时借鉴,达到汇编

21、级别开发的自由度。鉴,达到汇编级别开发的自由度。8/2/202418华中科技大学计算机学院指针的赋值运算规则:指针的赋值运算规则:(1) (1) 同类型的指针才可以直接使用赋值操作符进行同类型的指针才可以直接使用赋值操作符进行赋值操作赋值操作。如:。如: intint a3=1,2,3,*p=a,*q=p; a3=1,2,3,*p=a,*q=p;(2) (2) 如果要实现如果要实现不同基本类型指针之间的赋值运算,不同基本类型指针之间的赋值运算,必须使用类型强制必须使用类型强制。利用指针的赋值运算以及类。利用指针的赋值运算以及类型强制可以实现一些型强制可以实现一些特殊操作特殊操作。 8/2/20

22、2419华中科技大学计算机学院n例例9.11 一个长整型数占一个长整型数占4个字节,其个字节,其中每个字节又分成高中每个字节又分成高4位和低位和低4位。试位。试从长整型数的低字节开始,依次取出每从长整型数的低字节开始,依次取出每个字节的高个字节的高4位和低位和低4位并以位并以ASCII码码的形式进行显示。的形式进行显示。8/2/202420华中科技大学计算机学院例例9.119.11( (演示演示EX9_11)EX9_11)#include stdio.h“ void main(void) long x=0x1234ABCD,k; char *p=(char *)&x; /* 类型强制,类型强制

23、,x被视为被视为4字节字符数组被字节字符数组被p所指所指 */ char up_half,low_half; /* up_half存高存高4位,位,low_half存低存低4位位 */ for(k=0;k4;k+) low_half=(*p)&0x0f; /* 取低取低4位位 */if(low_half4)&0x0f; /* 取高取高4位位 */if(up_half10) up_half|=0; /* 高高4位二进制转换成位二进制转换成ASCII码码0-9 */else up_half=(up_half-10)+A; /* 高高4位二进制转换成位二进制转换成ASCII码码A-F */p+; /

24、* 指向整型数指向整型数x下一个字节下一个字节*/printf(%c %cn,up_half,low_half); 8/2/202421华中科技大学计算机学院2 2 指针的关系运算指针的关系运算n指针的关系运算指对指针施行诸如:指针的关系运算指对指针施行诸如: , ,=,以及,以及!=!=这样一些比较操作。这样一些比较操作。n指针属于一种派生类型,它属于何种类型的指针要指针属于一种派生类型,它属于何种类型的指针要受所指变量的类型,即指针的基类型的限制。受所指变量的类型,即指针的基类型的限制。n不同类型的变量在内存中分配的存储不同;对于不不同类型的变量在内存中分配的存储不同;对于不同的数据类型,

25、定义于其上的操作和运算也不尽相同的数据类型,定义于其上的操作和运算也不尽相同。因此,尽管所有指针的值都是二进制正整数,同。因此,尽管所有指针的值都是二进制正整数,从关系运算的操作语义上看,允许不同类型的指针从关系运算的操作语义上看,允许不同类型的指针进行比较没有实际意义,并且只会给语言和程序带进行比较没有实际意义,并且只会给语言和程序带来副作用。来副作用。n因此,因此,C C语言规定指针的关系运算只能限于同类型指语言规定指针的关系运算只能限于同类型指针,不同类型指针之间的关系运算被视为非法操作。针,不同类型指针之间的关系运算被视为非法操作。 8/2/202422华中科技大学计算机学院9.3 9

26、.3 指针作为函数的参数指针作为函数的参数 9.3.1 9.3.1 形参指针对实参变量的影响形参指针对实参变量的影响 例例9.12 9.12 被调用函数中对形参的修改无法影响调用函被调用函数中对形参的修改无法影响调用函数中实参变量的值举例数中实参变量的值举例( (演示演示EX9_12)EX9_12) 。#include #include stdio.hstdio.h void swap( void swap( intint u,intu,int v v ) ) intint t; t;printf(inprintf(in function swap, before function swap,

27、 before swap,uswap,u=%d =%d and v=%and v=%dn,u,vdn,u,v););t=t=u;uu;u= =v;vv;v=t;=t;printf(inprintf(in function swap, after function swap, after swap,uswap,u=%d and =%d and v=%v=%dn,u,vdn,u,v);); 8/2/202423华中科技大学计算机学院( (演示演示EX9_12)EX9_12)void void main(voidmain(void) ) intint x,yx,y; ;printf(inputpri

28、ntf(input two integers for x and y two integers for x and y please!n);please!n);scanf(%d%d,&x,&yscanf(%d%d,&x,&y););printf(inprintf(in function main, before function main, before swap,xswap,x=%d =%d and y=%and y=%dn,x,ydn,x,y););swap(x,yswap(x,y););printf(inprintf(in function main, after function ma

29、in, after swap,xswap,x=%d =%d and y=%and y=%dn,x,ydn,x,y);); 8/2/202424华中科技大学计算机学院程序运行中的输入以及运行结果为:程序运行中的输入以及运行结果为:input two integers for x and y please!input two integers for x and y please!10 2010 20(键盘输入)(键盘输入)in function main, before in function main, before swap,xswap,x=10 and y=20=10 and y=20in

30、 function swap, before in function swap, before swap,uswap,u=10 and v=20=10 and v=20in function swap, after in function swap, after swap,uswap,u=20 and v=10=20 and v=10in function main, after in function main, after swap,xswap,x=10 and y=20 =10 and y=20 8/2/202425华中科技大学计算机学院( (演示演示EX9_13)EX9_13)例例9.

31、13 9.13 以指针作为函数的参数实现变量值以指针作为函数的参数实现变量值的交换。的交换。#include #include stdio.hstdio.h void swap( void swap( intint *p1,int *p2 *p1,int *p2 ) ) intint t; t;t=*p1;*p1=*p2;*p2=t;t=*p1;*p1=*p2;*p2=t; 8/2/202426华中科技大学计算机学院void void main(voidmain(void) ) intint x,yx,y; ;printf(inputprintf(input two integers for

32、x and y two integers for x and y please!n);please!n);scanf(%d%d,&x,&yscanf(%d%d,&x,&y););printf(beforeprintf(before swap,xswap,x=%d and =%d and y=%y=%dn,x,ydn,x,y););swap(&x,&yswap(&x,&y););printf(afterprintf(after swap,xswap,x=%d and =%d and y=%y=%dn,x,ydn,x,y);); 8/2/202427华中科技大学计算机学院程序运行中的输入以及运行结

33、果为:程序运行中的输入以及运行结果为:input two integers for x and y please!input two integers for x and y please!12 4512 45before before swap,xswap,x=12 and y=45=12 and y=45after after swap,xswap,x=45 and y=12 =45 and y=12 8/2/202428华中科技大学计算机学院 对于数组,由于数组名标识的数组的起始地址,对于数组,由于数组名标识的数组的起始地址,故可直接作为指针类型的实参;除此之外,都必故可直接作为指针类型

34、的实参;除此之外,都必须以须以& &变量名的形式给出变量的地址作为实参,变量名的形式给出变量的地址作为实参,以保证在被调用函数中能够操作调用函数中的对以保证在被调用函数中能够操作调用函数中的对应变量。应变量。例例9.14 将键盘输入的所有数字串逐个的转换为整将键盘输入的所有数字串逐个的转换为整数,并且依次存放于一个数组中。数字串前面可数,并且依次存放于一个数组中。数字串前面可以加以加+、-号,各数字串之间至少用一个空格分开,号,各数字串之间至少用一个空格分开,用回车结束输入。用回车结束输入。 演示并解释演示并解释p267 p267 例例9-149-14 9.3.2 指针作为函数形参的应用指针作

35、为函数形参的应用8/2/202429华中科技大学计算机学院#include ctype.h#define NUMBER 100int getint(int *pn);int getint(int *pn) int c,sign; while(isspace(c=getchar() ;/* 跳过前导空格跳过前导空格 */ if(!isdigit(c) & c!=EOF & c!= + & c!= -) /* 若输入为非数字、非若输入为非数字、非EOF、也不是、也不是+、-号,显示出错号,显示出错 */printf(input error!n);return 0; sign = (c=-) ?-1

36、:1; /* 处理符号处理符号 */ if(c=+ | c=-) c=getchar(); /* 跳过跳过+、-号号 */ for(*pn=0;isdigit(c);c=getchar() *pn=10 * *pn+(c-0); /* 将数字串转换为对应整数将数字串转换为对应整数 */ *pn *= sign; /* 处理整数的符号处理整数的符号 */ return c;void main(void) int aNUMBER,i,j,k; printf(input integers ends with Entern); for(i=0;i NUMBER & (k=getint(&ai)!= n

37、;) if(k) i+; for(j=0;jb?a:b (求两个数中较大数求两个数中较大数)ne2=ce1?c:e1 (求三个数中最大数求三个数中最大数)=c(ab?a:b)?c:(ab?a:b)n对于对于de2?d:e2,将将e2代入可求四个数中最大数代入可求四个数中最大数n学习要注意方法学习要注意方法,学习要注意抽象学习要注意抽象,学习要注意应用学习要注意应用.8/2/202434华中科技大学计算机学院例例9.15 任意位数的超长数据的加法运算。任意位数的超长数据的加法运算。#include stdio.h“ (演示演示EX9_15)#include ctype.h#define N 20

38、 /* N表示参与运算数据最长的长度 */void shift(int *a,int n);void shift(int *a,int n) int k,len,sft; len=N-1-n; /* 数据的长度 */ sft=N-len; /* 右对齐移位的位数 */ for(k=0;klen;k+) /* 右对齐移位 */ *(a+k)=*(a+k+sft); for(k=len;kN;k+) /* 右对齐移位的位数 */ *(a+k)=0; /* 对没有存放数据的位填充零 */8/2/202435华中科技大学计算机学院求求: 12345678901234567+98765432109876

39、543void main(void) int xN,yN,zN+1,i,carry=0,flag; for(i=0;i=0 & isdigit(*(x+i)=getchar()/* 处理被加数处理被加数 */ *(x+i-)-=0; /* 数字字符转换为对应的十进制数数字字符转换为对应的十进制数 */ if(i=0) shift(x,i); /* 数据长度小于数据长度小于N,右对齐移位,右对齐移位 */ i=N-1; while(i=0 & isdigit(*(y+i)=getchar()/* 处理加数处理加数 */ *(y+i-)-=0; /* 数字字符转换为对应的十进制数数字字符转换为对应

40、的十进制数 */ if(i=0) shift(y,i); /* 数据长度小于数据长度小于N,右对齐移位,右对齐移位 */8/2/202436华中科技大学计算机学院for(i=0;i=0;i-) /* 输出结果。和中的前导字符输出结果。和中的前导字符0不输出不输出 */ if(flag=0 & *(z+i)!= 0) flag=1; if(flag=1) putchar(*(z+i);putchar(n);8/2/202437华中科技大学计算机学院2 2以指针变量为数组首地址时一以指针变量为数组首地址时一维数组的指针表示维数组的指针表示n一般的,为了用指针变量表示数组中的元素,应该先声明一一般的

41、,为了用指针变量表示数组中的元素,应该先声明一个数组,再声明一个与数组名类型相同的指针变量,然后通个数组,再声明一个与数组名类型相同的指针变量,然后通过初始化或者赋值操作使指针变量值向数组中的元素。这样过初始化或者赋值操作使指针变量值向数组中的元素。这样就可以指针变量来快速访问数组中的其他元素。就可以指针变量来快速访问数组中的其他元素。n例如例如,先声明指针变量先声明指针变量, 然后通过赋值语句将数组的起始地址然后通过赋值语句将数组的起始地址赋给指针变量,使指针变量指向数组中下标为赋给指针变量,使指针变量指向数组中下标为0的元素。的元素。 int a6,*p;p=a;或者或者p=&a0;n也可

42、以在声明指针变量的同时用数组名或者数组中打头元素也可以在声明指针变量的同时用数组名或者数组中打头元素的地址对其初始化。的地址对其初始化。int a6,*p=a; 或者,或者,int a6,*p=&a0;n一般地,此时称指针变量一般地,此时称指针变量p指向数组指向数组a。 8/2/202438华中科技大学计算机学院例例9.16 9.16 显示输出指向数组显示输出指向数组a a的指针变量的指针变量p p的地址、值,数组名的地址、值,数组名a a的值,的值,a0a0的地址。数组的地址。数组a a中每个元素的地址和值,以及中每个元素的地址和值,以及p p依次指依次指向数组中各个元素时的取值和所指元素的

43、值。向数组中各个元素时的取值和所指元素的值。#include stdio.hvoid main(void) int i,a5=1,2,3,4,5,*p=a; printf(address of p is %pn,&p); printf(value of p is %pn,p); printf(value of a is %pn,a); printf(address of a0 is %pn,&a0); for(i=0;i5;i+) printf(&a%d=%pta%d=%dn,i,&ai,i,ai); for(i=0;i5;i+) printf(i=%dtp=%pt*p=%dn,i,p,*p)

44、; p+; 运行结果见运行结果见P2728/2/202439华中科技大学计算机学院3. 3. 指向数组元素的指针变量的运指向数组元素的指针变量的运算操作算操作n指向数组的指针变量的运算操作可以分为三类。指向数组的指针变量的运算操作可以分为三类。n一是对指针变量或由指针变量组成的地址表达式进行一是对指针变量或由指针变量组成的地址表达式进行运算,目的是快速定位到数组中的指定元素。运算,目的是快速定位到数组中的指定元素。n二是间访操作,即访问指针变量或由指针变量组成的二是间访操作,即访问指针变量或由指针变量组成的地址表达式所指向的数组元素。地址表达式所指向的数组元素。n三是对间访后的数组元素施行运算

45、。三是对间访后的数组元素施行运算。n这些运算中往往涉及这些运算中往往涉及+和和*操作,操作,+和和*操作在操作在C中中位于第二优先级,结合性是右结合,当两者同时出现位于第二优先级,结合性是右结合,当两者同时出现的时候需要严格通过结合性来进行分析判断。的时候需要严格通过结合性来进行分析判断。 8/2/202440华中科技大学计算机学院设有说明:设有说明:char s20,*pc;char s20,*pc;对于字符指针对于字符指针pc,pc,下面的操作合法:下面的操作合法: pc=s 对字符指针变量对字符指针变量pc赋值,使其指向字符数组赋值,使其指向字符数组s(即即s0).pc+i 结果为结果为

46、pc后面第后面第i个元素的地址。个元素的地址。*(pc+i) 结果为结果为pc后面第后面第i个元素。个元素。*+pc 结果为结果为pc加加1之后所指元素。之后所指元素。+*pc 结果为结果为pc所指元素加所指元素加1。*pc+ 结果为结果为pc所指元素,然后所指元素,然后pc加加1。(*pc)+ 结果为结果为pc所指元素,然后所指元素,然后pc所指元素加所指元素加1。&pc 结果为字符指针变量结果为字符指针变量pc的地址,类型为的地址,类型为char * 8/2/202441华中科技大学计算机学院n对于数组名对于数组名s,下面的操作合法:下面的操作合法:s+i 结果为数组结果为数组s中第中第i

47、个元素的地址(即个元素的地址(即si的地址)。的地址)。*(s+i) 结果为数组结果为数组s中第中第i个元素个元素si。+*s 结果为元素结果为元素s0加加1。(*s)+ 结果为元素结果为元素s0的值,然后的值,然后s0加加1。n由于数组名由于数组名s是地址常量,因此下面的操作非法:是地址常量,因此下面的操作非法:s=pc 非法非法.数组名数组名s是地址常量,不能进行赋值是地址常量,不能进行赋值操作。操作。 &s 非法非法.数组名数组名s是地址常量,不能取地址。是地址常量,不能取地址。 *+s 非法非法.不能对数组名不能对数组名s进行前缀进行前缀+操作。操作。 *s+ 非法非法.不能对数组名不

48、能对数组名s进行后缀进行后缀+操作操作 8/2/202442华中科技大学计算机学院9.4.2 9.4.2 一维数组参数的指针表示一维数组参数的指针表示n 一维数组参数的指针表示是讨论在定义函一维数组参数的指针表示是讨论在定义函数时如何用指针表示函数的形参,以及在调数时如何用指针表示函数的形参,以及在调用函数时如何用指针表示函数的实参。用函数时如何用指针表示函数的实参。n对于形如对于形如intint f(intf(int a) a) 的函数,调用的函数,调用时应该用一个整型数组时应该用一个整型数组x x的数组名的数组名x x,或者数,或者数组打头元素的地址组打头元素的地址&x0&x0作为实参。数

49、组名作为实参。数组名x x和打头元素的地址和打头元素的地址&x0&x0的类型都是的类型都是intint * *。n所以,一维数组作为函数的参数时,形参和所以,一维数组作为函数的参数时,形参和实参的类型都应该是数组元素类型的指针。实参的类型都应该是数组元素类型的指针。n因此,可以用数组元素类型的指针变量来表因此,可以用数组元素类型的指针变量来表示形参和实参。示形参和实参。8/2/202443华中科技大学计算机学院例例9.17 9.17 用指针变量表示一维数组参数,计算两个向量的数用指针变量表示一维数组参数,计算两个向量的数量积(向量的数乘)。量积(向量的数乘)。见见P274P274 #inclu

50、de stdio.h#define SIZE 3double scalar(double *a,double *b,int n);void main(void) double xSIZE,ySIZE,*px,*py; for( px=x;pxx+SIZE;px+ ) /* x+SIZE是元素是元素xSIZE的地址的地址 */ scanf(%lf,px); getchar(); for( py=y;py&ySIZE; ) /* &ySIZE是是y+SIZE */ scanf(%lf,py+ ); px=x;py=y; printf(the scalar of vector x and vecto

51、r y is %lfn,scalar( px,py,SIZE ); double scalar(double *a,double *b,int n) double s,*p; printf(the vector a isn); for( p=a;pa+n; ) printf(%lft, *p+ ); printf(nthe vector b isn); for( p=b;pb+n; ) printf(%lft,*p+);/* b+n是元素是元素bn的地址的地址 */ printf(n); for( s=0,p=a;pa+n; ) /* a+n是元素是元素an的地址的地址 */ s+=( (*p

52、+)*(*b+) ); return s; 8/2/202444华中科技大学计算机学院9.4.3 9.4.3 用指向数组基本元素的指针表示多维数组用指向数组基本元素的指针表示多维数组n用指向数组基本元素的指针变量访问数组元素指:用指向数组基本元素的指针变量访问数组元素指:如果数组基本元素的数据类型为如果数组基本元素的数据类型为T T,则指向数组基,则指向数组基本元素的指针的数据类型为本元素的指针的数据类型为T *T *。一旦该指针指向。一旦该指针指向了一个对应数组的元素,就可以了一个对应数组的元素,就可以( (象用数组名一样象用数组名一样来来?)?)用该指针来表示数组元素。同时对该指针还可用该

53、指针来表示数组元素。同时对该指针还可以施行运算,使它指向数组中的其它元素。以施行运算,使它指向数组中的其它元素。n对于二维整型数组对于二维整型数组uMNuMN ,设有声明:,设有声明:intint *p=&u00;*p=&u00;则其则其uijuij 元的地址可以写成元的地址可以写成 ( (p+ip+i* *N+jN+j) )。而用指针。而用指针p p间访其间访其uijuij 元的形式为:元的形式为: * *( (p+ip+i* *N+jN+j) )。n对于三维整型数组对于三维整型数组vLMNvLMN ,设有声明:,设有声明:intint *p=&v000;*p=&v000; 则其则其vijk

54、vijk 元的地址可以写元的地址可以写成成( (p+ip+i*M*M*N+jN+j* *N+kN+k) )。而用指针。而用指针p p间访其间访其vijkvijk 元的形式为:元的形式为: * *( (p+ip+i*M*M*N+jN+j* *N+kN+k) )。 8/2/202445华中科技大学计算机学院例例9.18 9.18 用指向数组基本元素的指针变量实现三维数组元素的输入和输出。用指向数组基本元素的指针变量实现三维数组元素的输入和输出。 #include “stdio.h” 见见P274#define I 2 #define J 3#define K 4void main(void) in

55、t vIJK,*p,n=1; int i,j,k; p=&v000; /* 使使p指向三维数组指向三维数组v的打头的基本元素的打头的基本元素 */ for(i=0;iI;i+) for(j=0;jJ;j+) /* 访问数组访问数组v的的vijk元素元素*/for(k=0;kK;k+) *(p+i*J*K+j*K+k)=n+; for(i=0;iI;i+)for(j=0;jJ;j+) /* vij也是指向基本元素的指针也是指向基本元素的指针 */for(k=0;kK;k+) printf(%4d,*(vij+k) ); printf(n); printf(n); 8/2/202446华中科技大学

56、计算机学院9.5 9.5 指针数组指针数组 9.5.1 9.5.1 指针数组的声明及使用指针数组的声明及使用1. 1. 指针数组的声明指针数组的声明n声明指针数组的一般形式是:声明指针数组的一般形式是: cvcv T * T * cvcv 标识符标识符 常量表达式常量表达式=初值表初值表 ;n其中,其中,T T是数据类型,表示数组元素为是数据类型,表示数组元素为T T类型的指针,类型的指针,可以指向可以指向T T类型的变量。类型的变量。cvcv是是constconst、volatilevolatile或者或者const volatileconst volatile,它是可选项。标识符是指针数组

57、,它是可选项。标识符是指针数组名。常量表达式是指针数组的大小。名。常量表达式是指针数组的大小。“=初值表初值表 ”是可选项,用于初始化指针数组。是可选项,用于初始化指针数组。8/2/202447华中科技大学计算机学院nchar *pstr2=123,456; 该声明语句说明该声明语句说明pstr是一个有是一个有2个元素的字符指针数组。其个元素的字符指针数组。其中,中,p0指向字符串指向字符串123,p1指向字符串指向字符串456,p0和和p1的类型都是的类型都是char *。例如声明语句:。例如声明语句:nconst int x=1,y=2; const int *ps2; ps0=&x; p

58、s1=&y; 其中,第其中,第1个声明语句说明变量个声明语句说明变量x,y已经初始化,其值不已经初始化,其值不可更改;也称可更改;也称x,y为常量。第为常量。第2个声明语句说明个声明语句说明ps是由是由2个个指向整型常量的指针组成的指针数组;简称为指向常量的指向整型常量的指针组成的指针数组;简称为指向常量的整型指针数组。并且通过赋值使整型指针数组。并且通过赋值使ps0指向指向x,ps1指向指向y。显然,指针数组显然,指针数组ps的元素所指的对象不能修改;但的元素所指的对象不能修改;但ps的元的元素本身可以修改,使之指向其他对象。素本身可以修改,使之指向其他对象。nchar *const sp2

59、=abcd,1234; 该声明语句说明该声明语句说明sp的元素为常量,即常量指针,不能修改,的元素为常量,即常量指针,不能修改,但但sp的元素所指变量可以修改。的元素所指变量可以修改。nconst char *const p2=left,right; 它说明它说明p是一个指向常量字符串的字符型常量指针数组。此是一个指向常量字符串的字符型常量指针数组。此时,时,p的元素本身不能修改,的元素本身不能修改,p的元素所指对象也不能修改。的元素所指对象也不能修改。 8/2/202448华中科技大学计算机学院例例9.19 9.19 理解指针数组含义的编程举例。理解指针数组含义的编程举例。见见P277P27

60、7 #include stdio.hvoid main(void) int x=1,y=2,z=3,i; int *p3; p0=&x;p1=&y;p2=&z; printf(&x=%ptx=%dn,&x,x); printf(&y=%pty=%dn,&y,y); printf(&z=%ptz=%dn,&z,z); for(i=0;icopy c:copy abc.txtabc.txt def.txtdef.txt就就是一个命令行是一个命令行 n声明具有命令行参数的声明具有命令行参数的mainmain函数的一般形式是:函数的一般形式是: 类型类型 main(intmain(int argc,c

61、harargc,char * *argvargv) /函数体函数体 8/2/202453华中科技大学计算机学院例例9.26 9.26 回显命令行参数并显示命令行参数个数的程序实例。回显命令行参数并显示命令行参数个数的程序实例。#include #include stdio.hstdio.h void void main(intmain(int argcargc, char* , char* argvargv) intint n=0; n=0;while(nwhile(n argcargc) printf(printf(“%s%s”, , argvnargvn);); (nargc-1)?pri

62、ntf( ):printf(n show I like C programming.C: show I like C programming. argcargc5 5显示:显示:show I like C+ programming.show I like C+ programming.the number of command-line arguments are 5 the number of command-line arguments are 5 8/2/202455华中科技大学计算机学院9.7 9.7 函数的指针函数的指针9.7.1 9.7.1 函数指针的声明函数指针的声明n声明函数指

63、针的一般形式是:声明函数指针的一般形式是: 类型类型 (*(*函数指针名函数指针名)()(形参表形参表) ); 其中,其中,(*(*函数指针名函数指针名) )表示括号内的标识符是一个表示括号内的标识符是一个函数指针。类型则表示函数指针所指函数的返回函数指针。类型则表示函数指针所指函数的返回类型,形参表表示函数指针所指函数的形式参数类型,形参表表示函数指针所指函数的形式参数的类型与个数。的类型与个数。n函数指针要通过初始化或赋值使其指向特定的函函数指针要通过初始化或赋值使其指向特定的函数,然后才能通过函数指针来调用它所指的函数。数,然后才能通过函数指针来调用它所指的函数。对函数指针赋值的一般形式

64、是:对函数指针赋值的一般形式是: 函数指针名函数指针名= =函数名;函数名;8/2/202456华中科技大学计算机学院例例9.29 9.29 函数指针的应用举例。函数指针的应用举例。#include #include stdio.hstdio.h void f1(int x)void f1(int x) printf(functionprintf(function f1 is called!n); f1 is called!n); printf(x=%dn,x);printf(x=%dn,x); void f2(int void f2(int x,intx,int y) y) printf(f

65、unctionprintf(function f2 is called!n); f2 is called!n); printf(xprintf(x=%=%dtydty=%=%dn,x,ydn,x,y);); 8/2/202457华中科技大学计算机学院void void main(voidmain(void) ) void (*pf1)(int x); void (*pf1)(int x); void (*pf2)(int void (*pf2)(int x,intx,int y); y); pf1=f1; pf1=f1; pf2=f2; pf2=f2; pf1(5); pf1(5); pf2(

66、10,20); pf2(10,20); (*pf1)(50); (*pf1)(50); (*pf2)(100,200); (*pf2)(100,200); 8/2/202458华中科技大学计算机学院自学部分:自学部分:* *9.7.2 9.7.2 函数指针的应用函数指针的应用例例9.30 9.30 读取从键盘输入正文,再将正文以行读取从键盘输入正文,再将正文以行为单位排序后输出。通过命令行参数为单位排序后输出。通过命令行参数-n-n决定决定排序方法。如果有命令行参数排序方法。如果有命令行参数-n-n,则将输入,则将输入行按照数值大小进行排序;否则将按照字典行按照数值大小进行排序;否则将按照字典

67、顺序排序。顺序排序。 *9.7.3 9.7.3 利用函数指针求开普勒方程的近似根利用函数指针求开普勒方程的近似根 8/2/202459华中科技大学计算机学院9.8 9.8 指针函数指针函数n在在C C语言中,函数返回的只能是值。这个值可以是一般的语言中,函数返回的只能是值。这个值可以是一般的数值,也可以是某种类型的指针值。数值,也可以是某种类型的指针值。n如果函数的返回值是指针类型的值,该函数称为指针函数。如果函数的返回值是指针类型的值,该函数称为指针函数。n如果函数的返回值是如果函数的返回值是T *T *类型的指针值,该函数称为类型的指针值,该函数称为T T类型类型的指针函数。的指针函数。

68、9.8.1 9.8.1 指针函数的声明与定义指针函数的声明与定义n声明指针函数原型的一般形式是:声明指针函数原型的一般形式是: 类型类型 * *函数名(形参表);函数名(形参表);n如:如:char * char * strcpy(charstrcpy(char * *t,chart,char *s); *s); 声明函数声明函数strcpystrcpy是一个字符指针函数。即:该函数的返回是一个字符指针函数。即:该函数的返回值是字符指针。值是字符指针。8/2/202460华中科技大学计算机学院 9.8.2 9.8.2 指针函数的使用指针函数的使用 利用指针函数返回的指针,可以对返回的指针利用指

69、针函数返回的指针,可以对返回的指针所指向的对象进行进一步的操作。如果该指针指向所指向的对象进行进一步的操作。如果该指针指向一个数组,实际就间接解决了函数返回多值的问题。一个数组,实际就间接解决了函数返回多值的问题。例例9.32 9.32 查找子串的指针函数应用举例。查找子串的指针函数应用举例。#include #include stdio.hstdio.h char *char *strstr(charstrstr(char *,char *t) *,char *t);void void main(voidmain(void) ) char s1=abcdefghijk,s2= char s1

70、=abcdefghijk,s2=fghfgh,*p;,*p; p=strstr(s1,s2); p=strstr(s1,s2); printf(%pt%sn,&s10,s1); printf(%pt%sn,&s10,s1); printf(%pt%sn,p,pprintf(%pt%sn,p,p);); 8/2/202461华中科技大学计算机学院char *char *strstr(charstrstr(char * *s,chars,char *t) *t) char * char *psps=s,*pt,*pc;=s,*pt,*pc; while(* while(*psps!=0)!=0)

71、for(ptfor(pt= =t,pct,pc= =psps;*pt!=0&;*pt!=0& *pt=* *pt=*pc;pt+,pcpc;pt+,pc+);+); if(*pt=0) return if(*pt=0) return psps; ; psps+;+; return 0; return 0; 8/2/202462华中科技大学计算机学院* *9.9 9.9 指向数组的指针指向数组的指针9.9.1 9.9.1 指向数组的指针的声明与定义指向数组的指针的声明与定义 n指向数组的指针又称为数组的指针。数组的指指向数组的指针又称为数组的指针。数组的指针是指:指针指向的是一个数组,而非指向数

72、针是指:指针指向的是一个数组,而非指向数组中的基本元素。组中的基本元素。n对于常用的整型二维数组和指针对于常用的整型二维数组和指针p p和和p1p1,有声明:,有声明:intint u23,*p=&u00,(*p1)3=u u23,*p=&u00,(*p1)3=u; 此时,此时,p p是指向二维数组中的基本元素是指向二维数组中的基本元素u00u00的指针。的指针。p+ p+ 之后,之后,p p将指向二维数组中的基本将指向二维数组中的基本元素元素u01u01。指针。指针p p加加1 1操作引起的地址增量是操作引起的地址增量是sizeof(intsizeof(int) )。(p1(p1的解释接下页

73、的解释接下页) )8/2/202463华中科技大学计算机学院 p1p1是指向有是指向有3 3个元素的一个元素的一维整型数组的指针。维整型数组的指针。p1p1的值的值为第为第0 0行(行标为行(行标为0 0)的起始)的起始地址;地址;p1+p1+后,后,p1p1的值为第的值为第1 1行(行标为行(行标为1 1)的起始地址。)的起始地址。指针指针p1p1加加1 1操作引起的地址增操作引起的地址增量是量是3 3 sizeof(int)sizeof(int)。 u0u000u0u011u0u022u1u100u1u111u1u122p p和和p1p1p1+1p1+1p+1p+18/2/202464华中

74、科技大学计算机学院 一般的,设一般的,设I I,J J,K K,N N都是通过都是通过#define#define定义过的定义过的n n个符号常量,则指向基本元个符号常量,则指向基本元素类型为素类型为T T的的n-1n-1维数组的指针维数组的指针p p的说明是:的说明是:T (*T (*p)JKp)JK NN; 使使p p指向类型为指向类型为T T的的n n维数组维数组u u的一般形式是:的一般形式是:T uIJKT uIJKN,(*p)JKN,(*p)JKN=uN=u;例如,对于三维整型数组有:例如,对于三维整型数组有:intint v234,(*p2)34=v v234,(*p2)34=v

75、; 8/2/202465华中科技大学计算机学院 建立了上面的指向关系之后,凡是可以建立了上面的指向关系之后,凡是可以用数组名用数组名u u的场合,都可以用指针的场合,都可以用指针p1p1代替;同代替;同理,凡是可以用数组名理,凡是可以用数组名v v的场合,都可以用指的场合,都可以用指针针p2p2代替。代替。 当当0 0 i i 1, 01, 0 j j 2 2,0 0 k k 3 3时,时,uijuij 和和uiui 分别可以用分别可以用p1ijp1ij和和 p1ip1i表示;表示; vijkvijk ,vijvij ,vivi 分别可分别可以用以用p2ijkp2ijk,p2ijp2ij,p2

76、ip2i表示。表示。此时,数组名和指针名可以互换使用此时,数组名和指针名可以互换使用. .8/2/202466华中科技大学计算机学院 9.9.2 9.9.2 用数组名间访多维数组的元素用数组名间访多维数组的元素( (可不讲可不讲) ) 在在C C语言中,数组在实现方法上只有一维语言中,数组在实现方法上只有一维的概念。一个的概念。一个n n维数组被看成以它的下一级维数组被看成以它的下一级n-1n-1维数组为元素的一维数组。设维数组为元素的一维数组。设I I,J J,K K,N N都是通过都是通过#define#define定义过的定义过的n n个符号常量,则个符号常量,则 intint AIJK

77、 AIJKNN; 说明的说明的I I J J K K N N的的n n维整型数组,其维整型数组,其数组数组A A被看成以被看成以I I个个J J K K N N的的n-1n-1维整型数维整型数组为元素的一维数组。组为元素的一维数组。8/2/202467华中科技大学计算机学院 A A是一个指向是一个指向n-1n-1维整型数组的常量指针维整型数组的常量指针(即不能做左值),(即不能做左值),* *A A则表示则表示A A所指向所指向n-1n-1维维整型数组。因此,以整型数组。因此,以n-1n-1维数组为元素的一维数组为元素的一维数组就是维数组就是n n维数组。这种方法可以递归的维数组。这种方法可以

78、递归的理解。即:以理解。即:以n-2n-2维数组为元素的一维数组维数组为元素的一维数组就是就是n-1n-1维数组,维数组,, , 以一维数组为元素的以一维数组为元素的一维数组就是二维数组,直到以基本类型的一维数组就是二维数组,直到以基本类型的变量为元素而组成的一维数组。变量为元素而组成的一维数组。8/2/202468华中科技大学计算机学院 n n维数组可以逐级的分解为以维数组可以逐级的分解为以n-1n-1维数组维数组为元素的一维数组。为元素的一维数组。 n n维数组的数组名是一个指向维数组的数组名是一个指向n-1n-1维数维数组的常量指针,其值为组的常量指针,其值为n n维数组的首地址,维数组

79、的首地址,类型为类型为n-1n-1维数组类型的指针。维数组类型的指针。 虽然虽然n n维数组可以看成以维数组可以看成以n-1n-1维数组为元维数组为元素的一维数组。但在实现上这个一维数组的素的一维数组。但在实现上这个一维数组的每个元素都是指向每个元素都是指向n-2n-2维数组的指针。即维数组的指针。即A0A0,A1A1,AI-1AI-1都是指向都是指向K K N N的的n-2n-2维数组的指针,其值表示维数组的指针,其值表示n-1n-1维数组的维数组的首地址,其类型是首地址,其类型是intint (*)K (*)KNN。8/2/202469华中科技大学计算机学院自学部分:自学部分: * *9.

80、9.3 9.9.3 用指向数组的指针表示多维数组用指向数组的指针表示多维数组 多维数组的指针表示是讨论如何用间访多维数组的指针表示是讨论如何用间访操作符操作符* *来访问数组元素。由于来访问数组元素。由于n n维数组去掉维数组去掉最右边一维,最右边二维,最右边一维,最右边二维,, ,直至数组名直至数组名分别都是指向基本元素,指向一维数组,分别都是指向基本元素,指向一维数组,直至指向,直至指向n-1n-1数组的非左值常量指针;同数组的非左值常量指针;同时,还可以定义指向基本元素,指向一维数时,还可以定义指向基本元素,指向一维数组,组,直至指向,直至指向n-1n-1数组的指针变量;从数组的指针变量

81、;从而使得而使得C C语言中关于数组的指针表示内容丰语言中关于数组的指针表示内容丰富多彩,形式多种多样。富多彩,形式多种多样。 8/2/202470华中科技大学计算机学院 9.9.4 9.9.4 多维数组参数的指针表示多维数组参数的指针表示n多维数组作为函数参数时,是将实参数组的多维数组作为函数参数时,是将实参数组的地址(一般是起始地址)传递给形参。形参地址(一般是起始地址)传递给形参。形参一般说明为指向数组元素的指针,或说明为一般说明为指向数组元素的指针,或说明为指向下一级数组的指针。指向下一级数组的指针。n但从原理上讲,形参声明为指向下二级数组但从原理上讲,形参声明为指向下二级数组的指针,

82、指向下三级数组的指针等都可以,的指针,指向下三级数组的指针等都可以,只是实参的类型必须与形参的类型一致。只是实参的类型必须与形参的类型一致。 8/2/202471华中科技大学计算机学院 1.1.形参为指向数组元素的指针形参为指向数组元素的指针 形参说明为指向数组元素的指针时,实参应形参说明为指向数组元素的指针时,实参应为数组元素的地址,或为指向数组元素的指针变为数组元素的地址,或为指向数组元素的指针变量。量。void void fun(intfun(int * *p,intp,int n); /* n); /* 函数说明,函数说明,形参说明为指向数组元素的指针形参说明为指向数组元素的指针* *

83、/ / 以实参为数组元素的地址调用以实参为数组元素的地址调用funfun函数:函数: intint u23,v234; u23,v234;fun(u0,2*3); /*u0fun(u0,2*3); /*u0是是u00u00的地址的地址 * */ /fun(v00,2*3*4);fun(v00,2*3*4); /*v00 /*v00是元素是元素v000v000的地址的地址 * */ / 8/2/202472华中科技大学计算机学院以实参为指向数组元素的指针变量调用以实参为指向数组元素的指针变量调用funfun函数:函数: intint u23,v234,*p; u23,v234,*p; p=&u0

84、0; /* p=&u00; /* 也可以也可以p=u0 */p=u0 */ fun(p,2*3); /* fun(p,2*3); /* 函数调用,函数调用,p p指向元素指向元素u00 */u00 */ p=&v000; /* p=&v000; /* 也可以也可以p=v00 */p=v00 */ fun(p,2*3*4); /* fun(p,2*3*4); /*函数调用,函数调用,p p指向元指向元v000 v000 */*/ 8/2/202473华中科技大学计算机学院2.2.形参为指向下一级数组的指针形参为指向下一级数组的指针 形参为指向下一级数组的指针时,实参应形参为指向下一级数组的指针时

85、,实参应为数组名或指向下一级数组的指针。为数组名或指向下一级数组的指针。例如:例如:void f1(int (*p1)3,int n);void f1(int (*p1)3,int n); /* /* 指向一维数组的指针指向一维数组的指针p1p1为形参为形参 * */ /void f2(int (*p2)34,int n); void f2(int (*p2)34,int n); /* /* 指向二维数组的指针指向二维数组的指针p2p2为形参为形参 * */ /8/2/202474华中科技大学计算机学院以实参为数组名调用以实参为数组名调用f1f1函数和函数和f2f2函数函数: : intint

86、 u23,v234; u23,v234;f1(u,2*3); /* f1(u,2*3); /* 调用函数调用函数f1f1,数组名,数组名u u作为实参作为实参 * */ /f2(v,2*3*4);/* f2(v,2*3*4);/* 调用函数调用函数f2f2,数组名,数组名v v作为实参作为实参 * */ / 以实参为指向下一级数组的指针调用以实参为指向下一级数组的指针调用f1f1函数和函数和f2f2函数函数: : intint u23,v234,(*p1)3,(*p2)34; u23,v234,(*p1)3,(*p2)34; p1=u; f1(p1,2*3); p1=u; f1(p1,2*3)

87、; /* /* 以指向一维数组的指针以指向一维数组的指针p1p1为实参为实参 * */ /p2=v; f2(p2,2*3*4); p2=v; f2(p2,2*3*4); /*/*以指向二维数组的指针以指向二维数组的指针p2p2为实参为实参 * */ / 8/2/202475华中科技大学计算机学院n例例9.36 日期转换问题。输入一个年、月、日日期转换问题。输入一个年、月、日表示的日期,将其转换为该年的第几天。如表示的日期,将其转换为该年的第几天。如果输入某年的第几天,将其转换为该年某月果输入某年的第几天,将其转换为该年某月某日并输出。某日并输出。 此题视情况讲解此题视情况讲解8/2/20247

88、6华中科技大学计算机学院* *9.10 9.10 用指针编写字符串操作函数用指针编写字符串操作函数9.10.1 9.10.1 字符指针与字符串字符指针与字符串n在在C C语言中,字符数组主要用于构造字符串。字符语言中,字符数组主要用于构造字符串。字符串常量在存储方面也完全与字符数组的存储方式相串常量在存储方面也完全与字符数组的存储方式相同。同。n字符串是一维字符数组,可以用指向一维字符数组字符串是一维字符数组,可以用指向一维字符数组的字符指针来访问和操纵字符串的字符指针来访问和操纵字符串. .n用指针访问字符数组元素首先需要声明字符指针变用指针访问字符数组元素首先需要声明字符指针变量,通过初始

89、化或者赋值使字符指针变量指向字符量,通过初始化或者赋值使字符指针变量指向字符串,然后就可以通过字符指针来访问字符串中对应串,然后就可以通过字符指针来访问字符串中对应的字符。的字符。8/2/202477华中科技大学计算机学院n程序中字符串的表示概括起来有下面几种方法。程序中字符串的表示概括起来有下面几种方法。 (1) (1) 声明一个字符数组并对其初始化形成字符串,通过数声明一个字符数组并对其初始化形成字符串,通过数组名和下标引用字符串和字符。组名和下标引用字符串和字符。 例如:例如: char str80=char str80=This is a string.This is a string

90、.; ; 其中,字符数组其中,字符数组strstr占占8080个字节,最多可存储个字节,最多可存储7979个个字符,必须为字符串的终结符字符,必须为字符串的终结符00保留一个字节保留一个字节的存储空间。字符串常量的存储空间。字符串常量This is a string. This is a string. 是初值。是初值。8/2/202478华中科技大学计算机学院 (2) (2) 先声明一个字符数组,调用字符串输入函先声明一个字符数组,调用字符串输入函数对其赋值形成字符串,再通过数组名和下标引数对其赋值形成字符串,再通过数组名和下标引用字符串和字符。用字符串和字符。 例如:例如: char st

91、r80;char str80;gets(strgets(str); /*); /*输入输入This is a string.*/This is a string.*/str0=str0=t t; ; 其中,字符数组其中,字符数组strstr占占8080个字节,最多可存储个字节,最多可存储7979个个字符,必须为字符串的终结符字符,必须为字符串的终结符00保留一个字节保留一个字节的存储空间。的存储空间。8/2/202479华中科技大学计算机学院(3) (3) 声明一个字符指针变量并初始化,通过字符指针声明一个字符指针变量并初始化,通过字符指针变量使用下标或间访操作访问字符串或字符变量使用下标或间

92、访操作访问字符串或字符( (建议建议尽量不用此方法尽量不用此方法) )。如声明:如声明: char *s=char *s=This is a string.This is a string.; ; 先声明字符指针变量先声明字符指针变量s s(简称字符指针),再用字(简称字符指针),再用字符串符串This is a string. This is a string. 的起始地址,即字符的起始地址,即字符TT的地址初始化的地址初始化s s,使,使s s指向字符在内存中连续指向字符在内存中连续存放的存放的This is a string.This is a string.字符串。字符串。 通过通过s

93、2=a;*(s+3)=t;s2=a;*(s+3)=t;则将字符串改则将字符串改为为That is a string.That is a string.。因此,一旦字符指针。因此,一旦字符指针s s指向了字符串,指向了字符串,s s就可以象数组名一样的使用,用就可以象数组名一样的使用,用来访问和操纵它所指向的字符串。来访问和操纵它所指向的字符串。 8/2/202480华中科技大学计算机学院(4) 声明一个字符数组和一个字符指针变量,声明一个字符数组和一个字符指针变量,并并使字使字符指针指向字符数组。符指针指向字符数组。此时既可以通过数组名和下标,也可以通过字符指此时既可以通过数组名和下标,也可以

94、通过字符指针、下标或间访操作符针、下标或间访操作符*来实现对字符串或字符的访来实现对字符串或字符的访问和操纵。如声明:问和操纵。如声明:char str80,*ps=str; 它先说明了有它先说明了有80个字节的字符数组个字节的字符数组str,接着说明一,接着说明一个字符指针变量个字符指针变量ps,并且用字符数组的起始地址,并且用字符数组的起始地址str(数组名就是数组的起始地址)对其进行初始化,(数组名就是数组的起始地址)对其进行初始化,使使ps指向字符数组指向字符数组str。 8/2/202481华中科技大学计算机学院9.10.2 9.10.2 字符串函数的实现字符串函数的实现n下面根据下

95、面根据ISO/IEC 9899:1999(E)中头文件中头文件string.h中关于字符串函数规定来实现常用的字中关于字符串函数规定来实现常用的字符串函数;然后将它们做成为自己的库文件符串函数;然后将它们做成为自己的库文件mystring.lib,使得在其他程序中可以直接使用,使得在其他程序中可以直接使用这些函数。同时,通过这种方法,也可以使自己这些函数。同时,通过这种方法,也可以使自己写的代码供他人使用。写的代码供他人使用。n1.解释解释p303 头文件头文件mystring.hn2.解释解释p304-p306各字符串操作函数各字符串操作函数.(函数函数strtok的编写请自学的编写请自学

96、) 8/2/202482华中科技大学计算机学院* *9.11 9.11 用用typedeftypedef定义类型表达式定义类型表达式 9.11.1 9.11.1 类型表达式类型表达式n总的来看,总的来看,C C语言中的表达式可以分成两类。语言中的表达式可以分成两类。n一类是可求值表达式,可以称为值表达式,它的基一类是可求值表达式,可以称为值表达式,它的基本特征是可以被本特征是可以被CPUCPU处理和计算。处理和计算。n值进一步又可以分为左值和右值,地址是左值的特值进一步又可以分为左值和右值,地址是左值的特征之一,但仅仅是形成左值的必要条件,数组名就征之一,但仅仅是形成左值的必要条件,数组名就是

97、一个典型的例子,它虽然表征数组的首地址,但是一个典型的例子,它虽然表征数组的首地址,但是却不能被赋值。左值的另外一个特征是必须在内是却不能被赋值。左值的另外一个特征是必须在内存中分配有内存单元,这样才能够被赋值。存中分配有内存单元,这样才能够被赋值。8/2/202483华中科技大学计算机学院nC C中另外一类表达式就是类型表达式中另外一类表达式就是类型表达式. .n类型表达式是由类型说明符和数据类型名所组成的类型表达式是由类型说明符和数据类型名所组成的式子。式子。n可用于类型表达式的类型说明符有:可用于类型表达式的类型说明符有:()()、* *。n类型说明符类型说明符()()用于说明函数以及改

98、变解释的优先级;用于说明函数以及改变解释的优先级;类型说明符类型说明符用于说明数组;类型说明符用于说明数组;类型说明符* *用于说用于说明指针。明指针。n数据类型名也可以分为两类,一类是基本数据类型数据类型名也可以分为两类,一类是基本数据类型名,如:名,如:int,char,doubleint,char,double等等。另一类是构造类等等。另一类是构造类型名,如枚举类型,以及第型名,如枚举类型,以及第1010章中介绍的结构类型,章中介绍的结构类型,联合类型等。联合类型等。类型表达式类型表达式8/2/202484华中科技大学计算机学院n在解释复杂声明时,类型说明符和数据类型在解释复杂声明时,类

99、型说明符和数据类型名要按照表名要按照表9.29.2中优先级与结合性所规定的先中优先级与结合性所规定的先后顺序进行解释。后顺序进行解释。级别级别 符号符号优先级优先级结合性结合性1 12 23 3()()、* *数据类型名数据类型名最高最高次之次之最低最低从左至右从左至右8/2/202485华中科技大学计算机学院 9.11.2 9.11.2 用用typedeftypedef定义类型表达式定义类型表达式n类型表达式可以出现在两个地方类型表达式可以出现在两个地方. .n一是出现在声明语句中一是出现在声明语句中; ;n另外是用另外是用typedeftypedef关键字定义的语句中。关键字定义的语句中。

100、1.1.在声明语句中出现的类型表达式在声明语句中出现的类型表达式 在声明语句中,去掉对象标识符,剩余的部在声明语句中,去掉对象标识符,剩余的部分就是一个类型表达式。例如:分就是一个类型表达式。例如:intint *p3 *p3;去掉对象标识符;去掉对象标识符p p就得到:就得到:intint *3 *3; 该式子就是一个类型表达式。该式子就是一个类型表达式。8/2/202486华中科技大学计算机学院n如何解释这个类型表达式呢?根本的法宝就如何解释这个类型表达式呢?根本的法宝就是对类型说明符是对类型说明符 ()()、* *以及类型说明符以及类型说明符按照数据类型名的优先级与结合性的进行解按照数据

101、类型名的优先级与结合性的进行解释。释。n根据优先级与结合性可以得到下面的解释顺根据优先级与结合性可以得到下面的解释顺序:序: 3 3 * * intintn假设该类型表达式作用于一个标识符,则该假设该类型表达式作用于一个标识符,则该标识符首先与优先级最高的类型说明符作用。标识符首先与优先级最高的类型说明符作用。因此,进一步有:因此,进一步有: p p 3 3 * * intint 8/2/202487华中科技大学计算机学院由第由第步得:步得:p p是一个有是一个有3 3个元素的数组;个元素的数组;由第由第步得:步得:p p是一个有是一个有3 3个元素的指针数组;个元素的指针数组; 由第由第步得

102、:步得:p p是一个有是一个有3 3个元素的个元素的intint类型的指类型的指针数组。针数组。即:即:p p数组中的每一个元素的类型都是数组中的每一个元素的类型都是intint * *,可用于指向一个可用于指向一个intint类型的变量。类型的变量。 p p 3 3 * * intint 8/2/202488华中科技大学计算机学院n设有整型变量设有整型变量x,y,zx,y,z。以。以p0=&x ;p1=&y; p0=&x ;p1=&y; p2=&zp2=&z。则相应的存储结构图可由。则相应的存储结构图可由下下图表示图表示。 xyzp0p1p28/2/202489华中科技大学计算机学院ntyp

103、edeftypedef是是C C的一个关键字,可以用一个标识符为的一个关键字,可以用一个标识符为一个类型表达式命名。一个类型表达式命名。n对于简单的已有数据类型,用对于简单的已有数据类型,用typedeftypedef定义类型的定义类型的一般形式是:一般形式是: typedeftypedef 已有数据类型名已有数据类型名 标识符表列;标识符表列;n该语句的功能是将标识符表列中的每个标识符定该语句的功能是将标识符表列中的每个标识符定义为与已有数据类型等价的类型表示。义为与已有数据类型等价的类型表示。n例如:例如: typedeftypedef unsigned unsigned intint U

104、INT,size_tUINT,size_t; ; 将将UINTUINT和和size_tsize_t都定义成为都定义成为unsigned unsigned intint类型,类型,用用UINTUINT和和size_tsize_t说明的对象将都是无符号整型对说明的对象将都是无符号整型对象。象。 2在在typedef定义中出现的类型表达式定义中出现的类型表达式8/2/202490华中科技大学计算机学院n对于复杂的类型表达式,标识符往往出现在类型表达式中间对于复杂的类型表达式,标识符往往出现在类型表达式中间; ;n暂且称这种含标识符和类型表达式的式子为暂且称这种含标识符和类型表达式的式子为类型定义表达

105、式类型定义表达式. .n则用则用typedeftypedef定义类型的一般形式是:定义类型的一般形式是: typedeftypedef 类型定义表达式;类型定义表达式;n该语句的功能是用类型定义表达式中的标识符为类型表达式该语句的功能是用类型定义表达式中的标识符为类型表达式命名。命名。n例如:例如: typedeftypedef char *(* char *(*p_to_fun)(charp_to_fun)(char * ,char *); * ,char *); char *(* char *(*p_to_fun)(charp_to_fun)(char * ,char *) * ,char

106、 *)是类型定义表达式是类型定义表达式. . char *(*)(char * ,char *) char *(*)(char * ,char *)是类型表达式是类型表达式. . p_to_funp_to_fun是该类型表达式的名字是该类型表达式的名字. .复杂的类型表达式复杂的类型表达式8/2/202491华中科技大学计算机学院np_to_fun可以用于说明一个函数指针,且该函数可以用于说明一个函数指针,且该函数指针所指函数是一个有两个字符指针形参的字符指指针所指函数是一个有两个字符指针形参的字符指针函数。例如:针函数。例如:np_to_fun ptof; 则该语句与则该语句与 char *

107、(* ptof)(char *,char *);等价。等价。n由于由于strstr函数的函数原型是函数的函数原型是char *strstr(char *s,char *t);因此可以对;因此可以对ptof作如下赋值:作如下赋值: ptof = strstr; 此时此时,指针指针ptof指向指向strstr函数。函数。n设有设有char s1=University,s2=sit;,则用表达式则用表达式ptof(s1,s2)或)或(*ptof)(s1,s2)就可就可以调用以调用strstr函数。函数。 8/2/202492华中科技大学计算机学院又例如:又例如: typedef int *(*Arr

108、ay10)(int *);n则则Array代表类型表达式代表类型表达式int *(*10)(int *)。n声明语句:声明语句:Array ptof_ary; 与声明与声明int * (*ptof_ary10)(int *);等价。等价。n值得注意的是:值得注意的是: Array是类型表达式是类型表达式int *(*10)(int *)名字,它代名字,它代表数据类型表数据类型int *(*10)(int *),并且可以用来说,并且可以用来说明其他标识符。明其他标识符。 而而ptof_ary则是有则是有10个元素的函数指针数组,即每个元素的函数指针数组,即每个元素都是一个函数指针,所指函数有一个

109、个元素都是一个函数指针,所指函数有一个int *的的形参且返回类型是形参且返回类型是int *。 8/2/202493华中科技大学计算机学院n在类型表达式中,在类型表达式中,* *、和()可以有多、和()可以有多个,也允许嵌套。但要遵守以下规则:个,也允许嵌套。但要遵守以下规则:n(1 1)数组的元素不能是函数,但可以是函)数组的元素不能是函数,但可以是函数的指针。数的指针。n(2 2)函数的返回值不能是数组或函数,但)函数的返回值不能是数组或函数,但可以是指向数组的指针或指向函数的指针。可以是指向数组的指针或指向函数的指针。8/2/202494华中科技大学计算机学院*9.12 9.12 复杂

110、说明的解释复杂说明的解释 先看下面的声明语句:先看下面的声明语句: char *(*(*char *(*(*f(charf(char *(*)(int)2)(); *(*)(int)2)(); 首先根据优先级和结合性可以得到声明语句的解释顺序如首先根据优先级和结合性可以得到声明语句的解释顺序如下:下:f f (char *(*)( (char *(*)(intint)* *22* *( )( )char *char * 第第步步 f f是一个函数;是一个函数;f f函数的形参为一个函数指针,该函数函数的形参为一个函数指针,该函数指针所指函数有一个整型形参且返回值类型为指针所指函数有一个整型形参

111、且返回值类型为char *char *。第第步步 f f函数的返回值是一个指针。函数的返回值是一个指针。第第步步 f f函数的返回值是一个指向有两个元素的数组的指针。函数的返回值是一个指向有两个元素的数组的指针。第第步步 f f函数的返回值是一个有两个元素的函数指针数组;每函数的返回值是一个有两个元素的函数指针数组;每个函数指针元素所指函数的返回值是指针。个函数指针元素所指函数的返回值是指针。8/2/202495华中科技大学计算机学院char *(*(*char *(*(*f(charf(char *(*)(int)2)(); *(*)(int)2)();f f (char *(*)( (ch

112、ar *(*)(intint)* *22* *( )( )char *char * 第第步步 f函数的返回值是一个指向有两个元素的函函数的返回值是一个指向有两个元素的函数指针数组的指针,数组中每个函数指针元素所指数指针数组的指针,数组中每个函数指针元素所指函数是无参函数。函数是无参函数。 第第步步 f函数的返回值是一个指向有两个元素的函数函数的返回值是一个指向有两个元素的函数指针数组的指针,指针数组中每个函数指针元素所指针数组的指针,指针数组中每个函数指针元素所指函数是无参函数且返回值的类型是指函数是无参函数且返回值的类型是char *。 8/2/202496华中科技大学计算机学院 综上所述,

113、综上所述,f是一个函数;是一个函数;f函数的形参函数的形参为一个函数指针,该函数指针所指函数有为一个函数指针,该函数指针所指函数有一个整型形参且返回值类型为一个整型形参且返回值类型为char *;f函函数的返回值是一个指向有两个元素的函数数的返回值是一个指向有两个元素的函数指针数组的指针,指针数组中每个函数指指针数组的指针,指针数组中每个函数指针元素所指函数是无参函数且返回值的类针元素所指函数是无参函数且返回值的类型是型是char *。可见,。可见,f也是一个指针函数。也是一个指针函数。 8/2/202497华中科技大学计算机学院解释解释intint ( *(*(*f2)()2)(); ( *

114、(*(*f2)()2)();n首先根据优先级和结合性可以得到声明语句的解释首先根据优先级和结合性可以得到声明语句的解释顺序如下:顺序如下:nf 2 * () * 2 * () intn n第第步步 f是一个有两个元素的数组。是一个有两个元素的数组。n第第步步 f是一个有两个元素的指针数组。是一个有两个元素的指针数组。n第第步步 f是一个有两个元素的函数指针数组。是一个有两个元素的函数指针数组。n第第步步 f是一个有两个元素的函数指针数组;每个是一个有两个元素的函数指针数组;每个函数指针元素所指函数无参函数指针元素所指函数无参,且返回值是指针。且返回值是指针。 8/2/202498华中科技大学计

115、算机学院 intint ( *(*(*f2)()2)(); ( *(*(*f2)()2)();f f 2 2 * * () () * * 2 2 * * () () intint n第第步步 f是一个有两个元素的函数指针数组;每个函数指针是一个有两个元素的函数指针数组;每个函数指针元素所指函数的返回值是指向有两个元素数组的指针。元素所指函数的返回值是指向有两个元素数组的指针。n第第步步 f是一个有两个元素的函数指针数组;每个函数指针是一个有两个元素的函数指针数组;每个函数指针元素所指函数的返回值是指向有两个元素的指针数组的指针。元素所指函数的返回值是指向有两个元素的指针数组的指针。n第第步步

116、f是一个有两个元素的函数指针数组;每个函数指针是一个有两个元素的函数指针数组;每个函数指针元素所指函数的返回值是指向有两个元素的函数指针数组的元素所指函数的返回值是指向有两个元素的函数指针数组的指针,指针数组的每个指针元素指向的函数无参。指针,指针数组的每个指针元素指向的函数无参。n第第步步 f是一个有两个元素的函数指针数组;每个函数指针是一个有两个元素的函数指针数组;每个函数指针元素所指函数的返回值是指向有两个元素的指针数组的指针,元素所指函数的返回值是指向有两个元素的指针数组的指针,指针数组的每个指针元素指向的函数无参,且返回值的类型指针数组的每个指针元素指向的函数无参,且返回值的类型为整

117、型。为整型。 8/2/202499华中科技大学计算机学院n综上所述,综上所述,f是一个有两个元素的函数指针数是一个有两个元素的函数指针数组;函数指针数组中的每个函数指针元素所组;函数指针数组中的每个函数指针元素所指函数的返回值是指向有两个元素的指针数指函数的返回值是指向有两个元素的指针数组的指针,指针数组的每个指针元素指向一组的指针,指针数组的每个指针元素指向一个无参整型函数。(无参整型函数指函数没个无参整型函数。(无参整型函数指函数没有参数且返回值为整型值)。有参数且返回值为整型值)。n总之,无论声明语句如何复杂,只要严格按总之,无论声明语句如何复杂,只要严格按照优先级和结合性规定的解释顺序

118、进行解释,照优先级和结合性规定的解释顺序进行解释,就可以得到准确的理解和解释。就可以得到准确的理解和解释。8/2/2024100华中科技大学计算机学院*9.13 9.13 复杂说明的应用复杂说明的应用 n理解复杂声明仅仅是应用复杂数据类型的第一步,理解复杂声明仅仅是应用复杂数据类型的第一步,能够应用复杂类型才算真正掌握了复杂类型。能够应用复杂类型才算真正掌握了复杂类型。 n说明说明: : intint (*fpa2)(int); (*fpa2)(int);要从理解要从理解fpafpa的含义,的含义,对对fpafpa数组的元素进行赋值,以及通过数组的元素进行赋值,以及通过fpafpa去调用去调用

119、fpafpa数组元素所指函数三个方面加以把握数组元素所指函数三个方面加以把握. .n赋值赋值: :由于由于fpafpa是一个有两个元素的函数指针数组,是一个有两个元素的函数指针数组,因此构造两个函数因此构造两个函数a1a1和和a2a2,并通过,并通过fpa0=a1;fpa0=a1;和和fpa1=a2;fpa1=a2;使使fpa0fpa0指向指向a1a1,fpa1fpa1指向指向a2a2。n调用调用: fpa1(5);: fpa1(5);或或 (*fpa1)(5); (*fpa1)(5); 详见例详见例9.479.478/2/2024101华中科技大学计算机学院课堂练习课堂练习n根据解释根据解释

120、,写出对应的声明语句写出对应的声明语句:1. fp是一个函数指针是一个函数指针,所指向的函数有所指向的函数有2个字符个字符指针形参指针形参,且返回指向有且返回指向有3个整型元素数组的指个整型元素数组的指针针.2. pa是是2个元素的函数指针数组个元素的函数指针数组;数组每个元素数组每个元素所指向的函数有所指向的函数有1个整型指针形参个整型指针形参,且返回指向且返回指向有有3个元素函数指针数组的指针个元素函数指针数组的指针,该数组每个元该数组每个元素指向的函数无参素指向的函数无参,返回值是字符指针返回值是字符指针.8/2/2024102华中科技大学计算机学院n1. fp是一个函数指针是一个函数指

121、针,所指向的函数有所指向的函数有2个字符指针形参个字符指针形参,且返回指向有且返回指向有3个整型个整型元素数组的指针元素数组的指针.n解解:int (*(*fp)(char *,char *)3;第第1题参考解答题参考解答8/2/2024103华中科技大学计算机学院2. pa是是2个元素的函数指针数组个元素的函数指针数组;数组每个数组每个元素所指向的函数有元素所指向的函数有1个整型指针形参个整型指针形参,且且返回指向有返回指向有3个元素函数指针数组的指针个元素函数指针数组的指针,该数组每个元素指向的函数无参该数组每个元素指向的函数无参,返回值是返回值是字符指针字符指针.n解解:char * (*(*(*pa2)(int *)3)(void); 第第2题参考解答题参考解答8/2/2024104华中科技大学计算机学院本章习题本章习题n9.1, 9.2, 9.5, 9.6, 9.7, 9.10, n9.12, 9.15, 9.16, 9.17, 9.18, 9.208/2/2024105华中科技大学计算机学院

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑/环境 > 施工组织

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号