c语言指针课件实用教案

上传人:pu****.1 文档编号:568224673 上传时间:2024-07-23 格式:PPT 页数:82 大小:4.28MB
返回 下载 相关 举报
c语言指针课件实用教案_第1页
第1页 / 共82页
c语言指针课件实用教案_第2页
第2页 / 共82页
c语言指针课件实用教案_第3页
第3页 / 共82页
c语言指针课件实用教案_第4页
第4页 / 共82页
c语言指针课件实用教案_第5页
第5页 / 共82页
点击查看更多>>
资源描述

《c语言指针课件实用教案》由会员分享,可在线阅读,更多相关《c语言指针课件实用教案(82页珍藏版)》请在金锄头文库上搜索。

1、特特 点点能直接能直接(zhji)(zhji)对内存地址操作对内存地址操作, , 使用灵活使用灵活实现实现(shxin)(shxin)动态存储管理动态存储管理可以使程序简洁可以使程序简洁(jinji)(jinji)、紧凑、高效、紧凑、高效用间接访问的方式改变数据的逻辑顺序用间接访问的方式改变数据的逻辑顺序调用函数时可实现变量的引用传递调用函数时可实现变量的引用传递第1页/共81页第一页,共82页。地址地址(dzh)和指针的概念和指针的概念变量变量(binling)的地址和变量的地址和变量(binling)的值的值int i=3;float j=6;double k=9;36.09.0变量变量(

2、binling)i变量变量j变量变量k2200220622022214 程序中定义的变量程序中定义的变量, 系统根据它的系统根据它的类型给它分配一定长度的内存单元类型给它分配一定长度的内存单元, 该该内存单元的起始地址即为变量的地址。内存单元的起始地址即为变量的地址。该该内存单元的内容就是变量的值。内存单元的内容就是变量的值。第2页/共81页第二页,共82页。直接访问直接访问(fngwn)和间接访问和间接访问(fngwn)直接直接(zhji)访问:访问:用变量名直接用变量名直接(zhji)从它对应的地址存取内容。从它对应的地址存取内容。如如: int x=5,y=8,z=0; z =x+y;

3、580变量变量x变量变量y变量变量z22002202220413直接从直接从 x 和和 y 对应的地址对应的地址2200和和2202取出内容取出内容5和和8然后相加将结果然后相加将结果13存入存入变量变量 z 对应的地址对应的地址2204的单元中。的单元中。第3页/共81页第三页,共82页。间接间接(jin ji)访问访问定义定义(dngy)一个存放地址的变量一个存放地址的变量p (p的地址的地址1500), 将将x的地址的地址2200存放在变量存放在变量 p 中。通过中。通过变量变量p取出地址取出地址2200, 再按此再按此地址存取其中的内容地址存取其中的内容, 就间接就间接的完成了对的完成

4、了对x的存取。的存取。当当p的内容改为的内容改为2202时时, 通过通过(tnggu)变量变量p取出地址取出地址2202, 再按此再按此地址地址, 存取的就是变量存取的就是变量y的内的内容。容。p就是指针变量就是指针变量580变量x变量y变量z22002202220422001500变量p2202第4页/共81页第四页,共82页。指针指针(zhzhn)变量的定义变量的定义一般一般(ybn)形式形式:基类型基类型(lixng)名名 *指针变量名指针变量名说明说明:基类型名基类型名: 指针变量所指向的变量的类型名称指针变量所指向的变量的类型名称指针变量名指针变量名: 所定义的指针变量的名称所定义的

5、指针变量的名称*: 表示它后面的变量名是指针类型表示它后面的变量名是指针类型功能功能:(1)定义该指针变量名为指向基类型的指针变量定义该指针变量名为指向基类型的指针变量,为为该变量分配存储单元该变量分配存储单元, 其长度等于存储地址的字节数。其长度等于存储地址的字节数。(2) 基类型确定用指针变量基类型确定用指针变量“间接间接”存取数据的存储单存取数据的存储单元个数和存储形式。该变量只能指向基类型数据。元个数和存储形式。该变量只能指向基类型数据。第5页/共81页第五页,共82页。指针指针(zhzhn)变量的初始化变量的初始化用用 =&变量名变量名 来给指针变量赋初值。选项中的变量名必须来给指针

6、变量赋初值。选项中的变量名必须(bx)是已定义过的是已定义过的,其类型必须其类型必须(bx)与基类型一致。表示将它对应的地与基类型一致。表示将它对应的地址值赋给所定义的指针变量。址值赋给所定义的指针变量。例如例如(lr): int x,p=&x;int x,*p=&x;int x; float *p=&x; 可以用赋值语句给指针变量赋值:可以用赋值语句给指针变量赋值:float y, *py; py=&y;第6页/共81页第六页,共82页。指针指针(zhzhn)变量的引用变量的引用引用指针变量的指针值与引用其它引用指针变量的指针值与引用其它类型类型(lixng)的变量一样直接用它的变量名的变量

7、一样直接用它的变量名引用指针变量引用指针变量(binling)所指向的变量所指向的变量(binling)时时, 用用“*指针变量指针变量(binling)名名”注意:注意:指针变量的值与它所指向变量的值指针变量的值与它所指向变量的值之间的差别之间的差别指针变量只有正确赋值后才能通过它访问指向的变量。指针变量只有正确赋值后才能通过它访问指向的变量。xint x;pp=&x;&xint *p;*p*p=5;5第7页/共81页第七页,共82页。指针变量指针变量(binling)的运算的运算1. &: 取地址取地址(dzh)运算符运算符, 取右边变量的地址取右边变量的地址(dzh)2. * : 指向运

8、算符指向运算符(间接访问运算符间接访问运算符), 访问指针访问指针(zhzhn)变量右边所指向的变量。变量右边所指向的变量。&a是变量是变量a的地址的地址*p 是指针变量是指针变量p指向的变量。指向的变量。说明: “&”和“*”都是单目运算符, 它们的优先级 相同, 按自右而左方向结合。第8页/共81页第八页,共82页。如果(rgu)已定义 float a, *p=&a ; 则则 *p是变量是变量(binling) a&*p是变量是变量(binling)a的地址的地址 p&*p等价于等价于 p而而 &a是变量是变量a的地址的地址 p*&a是是p所指向的变量所指向的变量 a*&a等价于等价于a第

9、9页/共81页第九页,共82页。注意注意(zh y)(1). 指针指针(zhzhn)变量定义和引用指向变量的变量定义和引用指向变量的“*”含义有差别。含义有差别。(2).不能引用没有赋值的指针变量不能引用没有赋值的指针变量,不要误认为不要误认为p定义后定义后 变量变量*p就已存在就已存在(cnzi),必须给必须给p正确赋值后正确赋值后,变量变量*p才存在才存在(cnzi)。 (3).p=&a;是给指针变量是给指针变量p 赋值赋值, *p=3; 是给是给p指向的变量指向的变量 赋值。两者含义完全不同。赋值。两者含义完全不同。(4).给指针变量赋值必须用同类型的指针。给指针变量赋值必须用同类型的指

10、针。(5).指针变量只存放地址指针变量只存放地址, 地址值是无符号整数地址值是无符号整数, 但不能直但不能直 接用整型量接用整型量(或其它非地址量或其它非地址量)赋值给指针变量。赋值给指针变量。int *p1=2200;第10页/共81页第十页,共82页。给变量给变量(binling)赋值的两种方法赋值的两种方法1. 直接直接(zhji)访问用变量名访问用变量名如如: int i; i=5;2. 间接访问间接访问(fngwn)通过指向变量通过指向变量i的地址的指针变量的地址的指针变量 p 赋值赋值如:如:int i, *p; p=&i; *p=5;第11页/共81页第十一页,共82页。取地址取

11、地址(dzh)运算符运算符&和指向运算符和指向运算符*的应用的应用main( ) int m, n; int *p=&m,*q=&n; printf(Input m,n:); scanf(%d %d,p,&n); printf(m=%d &m=%Xn,m,&m); printf(*p=%d p=%Xn,*p,p); printf(n=%d &n=%Xn,n,&n); printf(*q=%d q=%Xn,*q,q);运行(ynxng)结果:Input m,n: 123 456 m=123 &m=FFD6*p=123 p=FFD6n=456 &n=FFD8*q=456 q= FFD8第12页/共

12、81页第十二页,共82页。 int x,y;xyp1pp2 int *p, *p1, *p2; p1=&x; p2=&y;&x&y86 x=8; y=6; printf(min=%d, max=%dn,*p1,*p2); p1=p2; &y if ( xy ) p=p1;&x p2=p; &xmain( )运行运行(ynxng)(ynxng)结果结果: min=6, max=8: min=6, max=8例:通过交换指针变量值按大小顺序例:通过交换指针变量值按大小顺序(shnx)输出输出第13页/共81页第十三页,共82页。指针变量作为指针变量作为(zuwi)函数的函数的参数参数以指针类型为函

13、数的参数以指针类型为函数的参数,作用是将变量的地址作用是将变量的地址(dzh)传入函数。传入函数。第14页/共81页第十四页,共82页。int x,y;int *pt1;*pt2;x=8;y=6;pt1=&x;pt2=&y;if (xy) swap(pt1,pt2);printf(x=%d, y=%dn,x,y);swap(int *p1,int *p2)p=*p1;*p1=*p2;*p2=p; int p;p8pt1pt2xy main() &x&yp1p2&x&y8668运行(ynxng)结果: x=6, y=8int x,y;int *pt1;*pt2;x=8;y=6;pt1=&x;pt

14、2=&y;if (xy) swap(pt1,pt2);swap(int *p1,int *p2)p=*p1;*p1=*p2;*p2=p; int p;printf(x=%d, y=%dn,x,y);第15页/共81页第十五页,共82页。指针指针(zhzhn)与数与数组组C语言中规定数组名是指针语言中规定数组名是指针(zhzhn)类型的符号常量类型的符号常量, 该符号常量值等于数组首元素的地址该符号常量值等于数组首元素的地址 ( 简称数简称数组首地址组首地址) ,它的类型是指向数组元素的指针它的类型是指向数组元素的指针(zhzhn)类型。类型。即数组名是指向该数组首元素的指针即数组名是指向该数组

15、首元素的指针(zhzhn)常量。常量。第16页/共81页第十六页,共82页。指向数组元素指向数组元素(yun s)的的指针指针1.定义定义(dngy)指向数组元素的指针变量指向数组元素的指针变量定义指向数组元素的指针定义指向数组元素的指针(zhzhn)变量与定义指向变量的指针变量与定义指向变量的指针(zhzhn)变量的变量的方法相同方法相同.如如:int a10;int *p; p=&a0; 由于数组名是指向由于数组名是指向0号元素的指针类型符号常量号元素的指针类型符号常量, 所以所以a与与&a0相等相等。p=&a0; p=a; 两句等价两句等价p=a不是把不是把a的各元素赋给的各元素赋给p注

16、意数组名与指针变量的区别注意数组名与指针变量的区别第17页/共81页第十七页,共82页。指针指针(zhzhn)运算运算 指针变量可以加减一个整数指针变量可以加减一个整数,两个同类型指针可以两个同类型指针可以 相减相减得到得到(d do)一个整数。指针变量每增减一个整数。指针变量每增减1, 地址值增减量等于所指向地址值增减量等于所指向的变量类型的字节数的变量类型的字节数sizeof(type), 将它称作地址步进单位将它称作地址步进单位d。当指针变量指向数组元素时当指针变量指向数组元素时, 指针变量每加减指针变量每加减1,表示指针前表示指针前后移动后移动1个元素个元素, 地址值增减地址值增减d。

17、如如: int a10,*p; p=a; p+; p+=3; 第18页/共81页第十八页,共82页。注意(zh y): 指针变量的运算顺序。+*p,*p+,*(+p),(*p)+ 四者之间的差别四者之间的差别(chbi):+*p先给先给p指向的变量指向的变量(binling)加加1,然后取然后取其值其值(*p)+先取先取p指向的变量值指向的变量值, 然后该变量值加然后该变量值加1*p+取取p所指向变量的值所指向变量的值, 然后然后p增增1*+pP先增先增1, 然后取然后取p所指向变量的值所指向变量的值第19页/共81页第十九页,共82页。main()main()int a4=1,2,3,4,b

18、,c,d,e;int a4=1,2,3,4,b,c,d,e; int *p=a; int *p=a; b=*p+; b=*p+; printf( printf(“n%d,%d,n%d,%d,”,b,*p);,b,*p); c=*+p; c=*+p; d=+*p; d=+*p; printf( printf(“%d,%d%d,%d”,c,d);,c,d); 运行运行(ynxng)(ynxng)结结果果1,2,3,41,2,3,4第20页/共81页第二十页,共82页。通过指针通过指针(zhzhn)引用数组引用数组元素元素在在 int a10,*p=a; 定义定义(dngy)的情况下的情况下:(1)

19、 p+i或或a+i就是就是ai的地址。都要进行的地址。都要进行(jnxng)a+id的运的运算。算。(2) *(p+i)或或*(a+i)就是就是p+i或或a+i所指向的数组元素所指向的数组元素ai。 数组元素中的数组元素中的 “ ” 是变址运算符是变址运算符, 相当于相当于*( + ) , ai 相当于相当于*(a+i)。(3) 指向数组元素的指针变量也可带下标指向数组元素的指针变量也可带下标, 如如 pi与与*(p+i)等价。等价。 所以所以, ai,*(a+i) ,pi,*(p+i) 四种表示法全部等价。四种表示法全部等价。(4) 注意注意p与与a的差别的差别,p是变量是变量a是符号常量是

20、符号常量,不能给不能给a赋值赋值, 语句语句a=p; a+; 都是错的。都是错的。第21页/共81页第二十一页,共82页。p &a0a9a1a2aia0p+1,a+1p+2,a+2 p+i,a+ip+9,a+9a引用引用(ynyng)(ynyng)数组元素数组元素可用可用: :1)1)下标法下标法, ,如如ai,piai,pi。2) 2) 指针法指针法, ,如如*(p+i)*(p+i)或或*(a+i),*(a+i),其中其中p p是指向数组是指向数组a a的元素的指针变量。的元素的指针变量。第22页/共81页第二十二页,共82页。main( ) int a10; int *p,i; for(p

21、=a;p(a+10);p+) scanf(%d, p); printf(n); for(i=0;i10;i+) printf(%d, ai); for(i=0;i10;i+) for(i=0;i10;i+) printf(%d, printf(%d, *(a+i);*(a+i); p=a; /* p=a; /*不能省略不能省略(shngl)*/(shngl)*/ for(i=0;i10;i+,p+) for(i=0;i10;i+,p+) printf(%d, *p); printf(%d, *p); for(p=a;p(a+10);p+) for(p=a;p(a+10);p+) printf(

22、%d,*p); printf(%d,*p); 例例. .输入输入(shr)/(shr)/输出数组全部元输出数组全部元素素第23页/共81页第二十三页,共82页。用字符型指针用字符型指针(zhzhn)访问字符数组和字符串访问字符数组和字符串【例【例9.59.5】用字符型数组名和字符指针变量】用字符型数组名和字符指针变量 两种方法两种方法(fngf)(fngf)整体输入整体输入/ /输出字符串。输出字符串。 main() char s81=Hello!,*p=s; char *ps=Welcome to you!; printf(%sn,s); printf(%sn,ps); gets(s); p

23、rintf(%sn,s); gets(p); printf(%sn,s); 第24页/共81页第二十四页,共82页。字符指针变量字符指针变量(binling)和字符数组的区别和字符数组的区别(1) 存储的内容存储的内容(nirng)不同不同:字符数组存储着字符串的内容字符数组存储着字符串的内容, 而字符指针变量而字符指针变量存放的是字符串首元素的地址存放的是字符串首元素的地址(dzh),不是它的内容。不是它的内容。(2) 分配的内存单元不同分配的内存单元不同:字符数组分配一段有确定地址的内存。而指针变字符数组分配一段有确定地址的内存。而指针变量只分配存放地址的内存单元量只分配存放地址的内存单元

24、,该指针变量可以该指针变量可以指向一个字符型数据指向一个字符型数据,但若未赋初值但若未赋初值,则它并未指向则它并未指向一个明确的地址。此时它指向的变量并不存在。一个明确的地址。此时它指向的变量并不存在。第25页/共81页第二十五页,共82页。(3) 赋值方法赋值方法(fngf)不同不同:对字符数组只能在定义对字符数组只能在定义(dngy)时整体赋初值时整体赋初值, 不能用赋值语句不能用赋值语句整体赋值。赋值语句只能对各个元素分开赋值。整体赋值。赋值语句只能对各个元素分开赋值。如如: char s16; s=I am a student.;char s16=I am a student.;对字符

25、指针变量对字符指针变量(binling), 可以采用下面方法赋值可以采用下面方法赋值: char *p; p=I am a student.;(4) 指针变量的值是可以改变的指针变量的值是可以改变的, 字符数组名是地址常量其值是不能改变的。字符数组名是地址常量其值是不能改变的。第26页/共81页第二十六页,共82页。数组或指针(zhzhn)变量作函数参数如如:main( ) f(int a , int n) int array10; . . . . . . f(array,10) . . .第27页/共81页第二十七页,共82页。由于数组名代表首地址由于数组名代表首地址(dzh),能接收并存放

26、地址能接收并存放地址(dzh)值的只能值的只能是指针变量。故编译系统将形参数组名作为指针变量是指针变量。故编译系统将形参数组名作为指针变量来处理。例中函数首部来处理。例中函数首部 f(int a , int n)可写成可写成 f(int *a, int n) 两种完全等价。两种完全等价。第28页/共81页第二十八页,共82页。 归纳起来归纳起来, ,如果有一个如果有一个(y )(y )数组数组, ,想在被调用的函数中想在被调用的函数中改变其元素的值改变其元素的值, ,实参与形参的对应关系有以下四种实参与形参的对应关系有以下四种: :(1).实参和形参都用数组名。实参和形参都用数组名。(2).实

27、参用数组名实参用数组名, 形参用指针形参用指针(zhzhn)变量。变量。(3).实参用指针实参用指针(zhzhn)变量变量, 形参用数组名。形参用数组名。(4).实参和形参都用指针实参和形参都用指针(zhzhn)变量。变量。实质都是地址实质都是地址(dzh)值的传递值的传递第29页/共81页第二十九页,共82页。【例【例9.7】通过调用函数】通过调用函数, 将整型数组的所有元素将整型数组的所有元素(yun s)加加10。参数传递用四种方法实现。参数传递用四种方法实现。void add(int b , int n) int i; for(i=0; in; i+) bi+=10;main( ) i

28、nt i, a10= 1,2,3,4,5,6,7,8,9,10; add(a,10); for(i=0; i10; i+) printf(%4d,ai);void add(int *p, int n) int *pend=p+n; for(; ppend; p+) *p+=10;main( ) int i, a10= 1,2,3,4,5,6,7,8,9,10; add(a,10); for(i=0; i10; i+) printf(%4d,ai);void add(int b , int n) int i; for(i=0; in; i+) bi+=10;main( ) int i, a10=

29、 1,2,3,4,5,6,7,8,9,10; int *q=a; add(q,10); for(i=0; i10; i+) printf(%4d,ai);void add(int *p, int n) int *pend=p+n; for(; ppend; p+) *p+=10;main( ) int i, a10= 1,2,3,4,5,6,7,8,9,10; int *q=a; add(q,10); for(i=0; i10; i+) printf(%4d,ai);第30页/共81页第三十页,共82页。用字符数组或指针用字符数组或指针(zhzhn)做函数参数传递字符串做函数参数传递字符串将字

30、符串从一个函数传递到另一个函数将字符串从一个函数传递到另一个函数, 可以可以(ky)用地址传递的方法用地址传递的方法, 即用字符数组名即用字符数组名或用字符指针变量作参数。在被调用的函或用字符指针变量作参数。在被调用的函数中可以数中可以(ky)改变字符串中的内容改变字符串中的内容, 在主调函数在主调函数中可以中可以(ky)得到改变了的字符串。得到改变了的字符串。第31页/共81页第三十一页,共82页。【例【例9.89.8】 字符串复制字符串复制(fzh)(fzh)函数主要功能的函数主要功能的实现。实现。 (1)用字符用字符(z f)数组作参数数组作参数void strcpy(char s1 ,

31、char s2 ) int i=0; while(s2i!=0) s1i=s2i; i+; s2i=0; main( ) char a20=I am a teacher.; char b =you are a srudent.; printf(string a=%sn string b=%sn,a,b); strcpy (a,b); printf(n string a=%sn string b=%sn,a,b); 第32页/共81页第三十二页,共82页。(2)形参用字符指针)形参用字符指针(zhzhn)变量。变量。程序(chngx)如下:void strcpy(char *s1, char *

32、s2) for( ; *s2!=0; s2+, s1+) *s1=*s2; *s1=0;main( ) char a20=I am a teacher.; char *b=you are a srudent.; printf(string a=%sn string b=%sn,a,b); strcpy(a,b); printf(n string a=%sn string b=%sn,a,b); while( *s1=*s2)!=0 ) s1+; s2+; *s1=0; while( *s2!=0 ) *s1+=*s2+; *s1=0; while( *s2 ) *s1+=*s2+; *s1=0

33、; while( *s1+=*s2+)!=0 ) while( *s1+=*s2+ ) 第33页/共81页第三十三页,共82页。多维数组和指向多维数组和指向(zh xin)分数组的指针分数组的指针多维数组的地址多维数组的地址(dzh)以二维数组为例以二维数组为例,设二维数组设二维数组a有有3行行4列。列。 int a34=1,2,3,4,5,6,7,8,9,10,11,12a是数组名是数组名, a数组有数组有3行行, 即即3个分数组个分数组:a0,a1,a2。每个分数组又是含每个分数组又是含4个列元素个列元素(yun s)的一维数组的一维数组 。第34页/共81页第三十四页,共82页。a22a

34、12a02a23a21a20a13a11a10a03a01a00a0a1a22000a00a01a02a03a10a11a12a13a20a21a22a23a2000Ha+12008a+22010a0+1*(a+0)+1a1+1*(a+1)+1a2+1*(a+2)+1200A20122002基类型(lixng)行指针(zhzhn)与列指针(zhzhn)a23*(a2+3)*(*(a+2)+3) +3 +2 +1 +0a0 a0a0a0*(a+0)*(a+0)*(a+0)*(a+0) +3 +2 +1 +0a1 a1a1a1*(a+1)*(a+1)*(a+1)*(a+1)第35页/共81页第三十

35、五页,共82页。注意注意(zh y) a+1与a0+1不同(b tn)a+1是a第1行分数组地址*(a+1)是第1行数组名*(a+1)是元素a10 a0是第0行分数组名a0+1是元素a01 地址*(a0+1)是元素a01第36页/共81页第三十六页,共82页。 形式形式 含义含义 内容内容a ,&a0 二维数组名二维数组名,0行分数组地址行分数组地址 1000a0,*(a+0),*a ,&a00 0行一维数组名行一维数组名,0行行0列元素列元素(yun s)地址地址 1000a0+1,*a+1,&a01 0行行1列元素列元素(yun s)地址地址 1002a+1,&a1 1行一维数组首地址行一

36、维数组首地址 1008a1,*(a+1) ,&a10 1行一维数组名行一维数组名,1行行0列元素列元素(yun s)地址地址 1008a1+3,*(a+1)+3,&a13 1行行3列元素列元素(yun s)地址地址 1014*(a2+3),*(*(a+2)+3),a23 2行行3列元素列元素(yun s) 12注意注意: a和和a0的地址均为的地址均为1000但不等价但不等价,a+1和和a0+1不等。不等。第37页/共81页第三十七页,共82页。指向指向(zh xin)多维数组多维数组的指针的指针1.指向多维数组元素指向多维数组元素(yun s)的指针的指针例:用指针变量例:用指针变量(bin

37、ling)输出数组元素的值。输出数组元素的值。main( ) int a34=1,2,3,4,5,6,7,8,9,10,11,12; int *p; for (p=a0;pa0+15;p+) if(p-a0)%5=0) printf(n); printf(%4d,*p); 第38页/共81页第三十八页,共82页。定义形式(xngsh): 数据类型 (*指针名)一维数组维数;一维数组指针变量(binling)维数和二维数组列数必须相同。例:int a34, (*p)4=a;2.指向指向(zh xin)分数组的指针分数组的指针第39页/共81页第三十九页,共82页。a22a12a02a23a21a

38、20a13a11a10a03a01a00a00a01a02a03a10a11a12a13a20a21a22a23a2000a+12008a+22010p0+1p或*p+1p1+2p+1或*(p+1)+2p+2int a34;int (*p)4=a;第40页/共81页第四十页,共82页。例:用指向例:用指向(zh xin)二维数组的分数组的指针变量,按行二维数组的分数组的指针变量,按行输出。输出。main( ) int a34=1,2,3,4,5,6,7,8,9,10,11,12; int *q,(*p)4; for(p=a;pa+3;p+) for(q=*p;q*p+4;q+) printf(

39、%5d,*q); printf(n); 注意注意: int (*p)5; 表示表示p是一个是一个(y )指针变量指针变量,可以指向可以指向含有含有5个元素的一维数组,其中每个元素都是整型的。个元素的一维数组,其中每个元素都是整型的。 如如果定义为果定义为 int *p5; 由于由于 “ ” 优先级高优先级高, 则表示则表示p首先首先是数组是数组,它有它有5个元素个元素, 每个元素为指向整型变量的指针。每个元素为指向整型变量的指针。 1 2 3 4 1 2 3 4 5 6 7 8 5 6 7 8 9 9 10 11 12 10 11 12q q+2pp+2第41页/共81页第四十一页,共82页。

40、用多维数组名和指针用多维数组名和指针(zhzhn)变量作函变量作函数参数数参数(1)用多维数组名作实参或形参。用多维数组名作实参或形参。如如: f(int a 4, int n);(2)用指向用指向(zh xin)元素的指针变量作实参或元素的指针变量作实参或形参。形参。如如: f1(int *p);(3)用指向分数组的指针用指向分数组的指针(zhzhn)变量作函数变量作函数参数。参数。如如:f2(int (*q)4, int m);第42页/共81页第四十二页,共82页。【例【例9.169.16】 用两个二维数组存储矩阵,调用函数求两个用两个二维数组存储矩阵,调用函数求两个矩阵之差,差矩阵存放

41、在第一个实参数组中,用指向分数矩阵之差,差矩阵存放在第一个实参数组中,用指向分数组的指针变量组的指针变量(binling)(binling)作形参。矩阵输出也用函数实现。作形参。矩阵输出也用函数实现。 #define N 4sub(int (*p1)N,int (*p2)N,int m) int *q1,*q2,(*u)N; u=p1+m; for(;p1u;p1+,p2+) for(q1=*p1,q2=*p2;q1*p1+N;q1+,q2+) *q1-=*q2;print(int (*p)N,int m) int *q,(*u)N; u=p+m; for(;pu;p+) for(q=*p;q

42、*p+N;q+) printf(%6d,*q); printf(n); printf(n);main() int i,j,a N=1,2,3,4,5,6,7,8 ; int b N=10,20,30,40,50,60,70,80; print(a,2); print(b,2); sub(b,a,2); print(b,2); 第43页/共81页第四十三页,共82页。指针指针(zhzhn)(zhzhn)数组数组 如果每个数组元素均为指针类型如果每个数组元素均为指针类型(lixng)(lixng)的变量,即数组元的变量,即数组元素的类型素的类型(lixng)(lixng)是指针类型是指针类型(li

43、xng)(lixng),则称这样的数组为指针数组。,则称这样的数组为指针数组。 一维指针数组的定义形式为:一维指针数组的定义形式为:基类型名基类型名 * *数组名数组名 数组长度数组长度(chngd) (chngd) =地址初值列表地址初值列表 例如:例如:int i,j,k,m,n;int *q5=&i,&j,&k,&m,&n; 第44页/共81页第四十四页,共82页。main() char a =Program; char b =Fortran; char c =Basic; char *p4; p0=a; p1=b; p2=c; p3=NULL;p0p1p2p3char *p4Basic

44、0P r o g r a m0Fortra n00或或:main() char *p4; p0= Program; p1= Fortran; p2= Basic; p3=NULL;初始化初始化:main() char *p =Program, Fortran, Basic,NULL;第45页/共81页第四十五页,共82页。用指针数组处理(chl)多个字符串例:将5个字符串递增(dzng)排序后输出。#include #include main() char *pccolor =red, blue, yellow, green, purple; int n=5; printf(Before so

45、rting is:n); OutPut(pcolor,n); Sort(pcolor,n); printf(After sorting is:n); OutPut(pcolor,n);第46页/共81页第四十六页,共82页。void Sort(char *a , int n)int i,j,k; char *t;for(i=0;in-1;i+)for(j=i+1;j0)第47页/共81页第四十七页,共82页。void OutPut(char *a ,int n)int i;for(i=0;in;i+)printf(%sn,ai);第48页/共81页第四十八页,共82页。0der0neerg0e

46、ulb0wolley0elpruppcolor4pcolor3pcolor2pcolor1pcolor00der0neerg0eulb0wolley0elpruppcolor4pcolor3pcolor2pcolor1pcolor0排排序序前前排排序序后后第49页/共81页第四十九页,共82页。指向指向(zh xin)指针的指指针的指针针(二级指针二级指针)指针指针(zhzhn)变量中存放一级指针变量中存放一级指针(zhzhn)变量的地址变量的地址例例 int *p1; int *p2; int i=3; p2=&i; p1=&p2; *p1=5;p1P2(指针变量指针变量) i(整型变量整型

47、变量)二级指针(zhzhn)一级指针目标变量二级间接寻址&p2&i53第50页/共81页第五十页,共82页。用指向用指向(zh xin)(zh xin)指针的指针访问指针数组指针的指针访问指针数组 通过指针变量来访问通过指针变量来访问(fngwn)(fngwn)指针数组的元素,就必须定义指针数组的元素,就必须定义指向指针的指针变量。用所定义的指向指针的指针指向指针的指针变量。用所定义的指向指针的指针变量来指向指针数组的各元素,进行间接访问变量来指向指针数组的各元素,进行间接访问(fngwn)(fngwn)。若。若要通过该指针变量来访问要通过该指针变量来访问(fngwn)(fngwn)指针数组元

48、素所指向的变指针数组元素所指向的变量的内容,则需要进行两次间接访问量的内容,则需要进行两次间接访问(fngwn)(fngwn)。 第51页/共81页第五十一页,共82页。【例【例9.109.10】 指针数组的各元素指针数组的各元素(yun s)(yun s)指向整型数据的简单实例指向整型数据的简单实例 main() static int s5=10,20,30,40,50; int *q5=&s0,&s1,&s2,&s3,&s4; int *p; for(p=q;pq+5;p+) printf(%dt,*p); 第52页/共81页第五十二页,共82页。指针指针(zhzhn)数组作数组作main

49、( )函数的形参函数的形参 C C语言规定,语言规定,main() main() 函数形参是固定的,第一个形参为函数形参是固定的,第一个形参为整型,它接收整型,它接收(jishu)(jishu)实参的个数,第二个形参为字符指针数组,实参的个数,第二个形参为字符指针数组,它的各元素分别接收它的各元素分别接收(jishu)(jishu)命令行输入的各字符串的首地址。命令行输入的各字符串的首地址。 例如例如(lr):main(int argc,char *argv ) 形参形参argcargc接收实参的个数,接收实参的个数,字符指针数组字符指针数组argvargv接收各字符串的首地址。接收各字符串的

50、首地址。 它的一般形式为它的一般形式为:命令名命令名 参数参数1 1 参数参数2 2 参数参数n-1n-1第53页/共81页第五十三页,共82页。【例【例9.119.11】编写】编写(binxi)(binxi)源程序源程序show.cshow.c,在命令行输入,在命令行输入showshow和和 若干个字符串后,顺序分行显示这些字符串。若干个字符串后,顺序分行显示这些字符串。 show.c 的程序的程序(chngx)如下:如下:main(int argc,char *argv) int i; for(i=1;i0) printf(%sn,*+argv); 第54页/共81页第五十四页,共82页。

51、【例【例9.12】 编写程序编写程序echo.c,实现操作系统中的,实现操作系统中的echo命令,命令,echo命令是将后面所带的参数命令是将后面所带的参数(cnsh)原样显示出来。它与上例相似原样显示出来。它与上例相似但不分行,所带的参数但不分行,所带的参数(cnsh)都显示在同一行。都显示在同一行。 main(int argc,char *argv) while(-argc0) printf(%s%c,*+argv,(argc1)? :n); 在操作系统命令行状态在操作系统命令行状态(zhungti)下输入:下输入: echo Welcome to you ! 执行后输出以下执行后输出以下

52、(yxi)信息:信息: Welcome to you ! 第55页/共81页第五十五页,共82页。【例【例9.189.18】实现】实现(shxin)(shxin)系统提供的字符串复制函数系统提供的字符串复制函数strcpy()strcpy()的全部功能。的全部功能。 char *strcpy(char *s1,char *s2) char *p=s1; while(*s1+=*s2+); return(p); main() char s20; printf(%sn,strcpy(s,Welcome to you!); 第56页/共81页第五十六页,共82页。结构结构(jigu)体体与指针与指针

53、指向指向(zh xin)结构体变量的指针结构体变量的指针结构(jigu)体指针变量的定义:struct 结构(jigu)体名 * 指针变量名;例如:struct student *pt=&stu;struct student int num; char name20; char sex; int age;stu;第57页/共81页第五十七页,共82页。使用结构体指针变量引用(ynyng)成员形式(*结构结构(jigu)体指针名体指针名).成员名成员名结构结构(jigu)体指针名体指针名-成员名成员名结构体变量名结构体变量名.成员名成员名struct student int num; char

54、name20; char sex; int age;stu;struct student *p=&stu;(*p).nump-numstu.numagesexnamenumstupp=&stu.num第58页/共81页第五十八页,共82页。例:结构(jigu)体指针的使用#include #include struct student int num; char name20; char sex; int age;main() struct student stu, *p; p=&stu; stu.num=10011; strcpy(stu.name, Kobe Bryant ); p-sex

55、=M; p-age=33; printf(nNo:%dnname:%snsex:%cnscore:%dn, (*p).num, p-name, stu.sex, p-age);第59页/共81页第五十九页,共82页。例:结构(jigu)体数组指针的使用struct student int num; char name20; char sex; int age;stu3= 10101, Li Lin,M,18, 10102,Zhang Fun,M,19, 10103,Wang Min,F,20;main() struct student *p; for(p=stu;pnum,p-name, p-

56、sex,p-age);10101Li LinM18stu0pstu1stu2p+1p+210102Zhang FunM1910103Wang MinF20第60页/共81页第六十页,共82页。结构结构(jigu)(jigu)体指针作函数参数体指针作函数参数 用结构体变量(binling)的成员作参数-单值传递 用结构体变量(binling)作参数-多值传递用指向结构体变量(binling)或数组的指针作参数 -地址传递。第61页/共81页第六十一页,共82页。【例【例9.179.17】 采用采用(ciyng)“(ciyng)“引用传递引用传递”的方式,用指向结构体的方式,用指向结构体的指针变量

57、作参数,在的指针变量作参数,在inputinput函数中输入并计算平均成函数中输入并计算平均成绩,在绩,在mainmain函数输出。函数输出。 #define N 4#include#define FMT %5d %-11s%5d%8d%8d%10.1fnstruct st int num; char name11; int s3; float aver;void input(struct st *p)scanf(%d%s%d%d%d,&p-num,p-name,&p-s0,&p-s1,&p-s2); p-aver=(p-s0+p-s1+p-s2)/3.0;main() struct st a

58、N,*p=a; printf(Input student:number name score1 score2 score3n); while(pa+N) input(p+); printf(number name score1 score2 score3 averagen); for(p=a;pnum,p-name,p-s0,p-s1,p-s2,p-aver); 第62页/共81页第六十二页,共82页。指针指针(zhzhn)与与链表链表链表可以链表可以(ky)动态的进行存储分配动态的进行存储分配1249head1249A13561356B14751475C10211021DNULLhead:

59、头指针头指针,存放存放(cnfng)一个地址一个地址,指向链表中的第一个元素指向链表中的第一个元素.每一个元素称为一个每一个元素称为一个“结点结点”,每个结点都包括两部分每个结点都包括两部分:1.用户需要的实际数据用户需要的实际数据;2.下一个结点的地址下一个结点的地址.表尾表尾: 它的地址部分放一个它的地址部分放一个“NULL”,链表到此结束链表到此结束.第63页/共81页第六十三页,共82页。可用结构体类型可用结构体类型(lixng)的变量来存储链表中的结点元素的变量来存储链表中的结点元素.1249head1249A13561356B14751475C10211021DNULL每一个结点中

60、存放地址每一个结点中存放地址(dzh)的部分可用指针来实现的部分可用指针来实现.例例: struct student int num; float score; struct student *next; ;第64页/共81页第六十四页,共82页。简单简单(jindn)静态链表静态链表# define NULL 0struct student long num; float score; struct student *next; ;main( ) struct student a,b,c,*head,*p; a.num=9901; a.score=89.5; b.num=9903; b.sc

61、ore=90; c.num=9905; c.score=85; head=&a; a.next=&b; b.next=&c; c.next=NULL; p=head; do printf(“%ld %5.2f n”,p-num,p-score); p=p-next; while(p!=NULL);anumscorenextbchead p990189.5990390990585&a&b&cNULL&a&b&cNULL第65页/共81页第六十五页,共82页。动态动态(dngti)链表链表处理动态处理动态(dngti)链表所需的链表所需的函数函数1. malloc 函数函数(hnsh)void *

62、malloc (unsigned int size);作用是作用是: 在内存的动态存储区分配一个长度为在内存的动态存储区分配一个长度为size的连续空间的连续空间原型说明在“stdlib.h”头文件和“alloc.h”头文件中第66页/共81页第六十六页,共82页。2.calloc函数函数(hnsh) void *calloc(unsigned n,unsigned size);作用是作用是: 在内存的动态区分配在内存的动态区分配n个长度个长度(chngd)为为size的连续空间的连续空间.3. free函数函数(hnsh)void free(void *p);作用是作用是: 释放由释放由p指

63、向的内存区指向的内存区.第67页/共81页第六十七页,共82页。typedef struct Node int data; struct Node *next;Node;链表的插入链表的插入(ch r)操作操作ses-next=pre-next;pre-next=s;顺序可以(ky)颠倒吗?a1a2ai-1aianpreh void InsList(Node *L,int i,int e) Node *pre,*s; int k=0; pre=L; while(pre!=NULL&knext; k=k+1; if(k!=i-1) printf(“插入插入(ch r)位置不合理!位置不合理!”)

64、; return; s=(Node*)malloc(sizeof(Node); s-data=e; s-next=pre-next; pre-next=s; 第68页/共81页第六十八页,共82页。链表的删除链表的删除(shnch)操作操作pre-next=pre-next-next;a1a2ai-1aianpreai+1rL free(r); void DelList(Node *L,int i) Node *pre,*r; pre=L; int k =0; while(pre-next!=NULL&knext; k=k+1; if(k!=i-1) printf(“删除删除(shnch)结点

65、的位置结点的位置i不合理!不合理!”); return ERROR; r=pre-next; pre-next=pre-next-next; free(r); return OK; 第69页/共81页第六十九页,共82页。建立建立(jinl)动动态链表态链表头插法建表头插法建表尾插法建表尾插法建表头插法建表头插法建表sAs指向新申请指向新申请(shnqng)的结点的结点s-data=A;HsA插入插入(ch r)第一个结第一个结点:点:插入某一个结点:插入某一个结点:HAsB从一个空表开始,重复读入数据,生成新结点,从一个空表开始,重复读入数据,生成新结点,将读入数据存放到新结点的数据域中,然

66、后将新结点插入将读入数据存放到新结点的数据域中,然后将新结点插入到当前链表的表头结点之后,直至读入结束标志为止。到当前链表的表头结点之后,直至读入结束标志为止。s-next=H-next;H-next=s;顺序可以颠倒吗?H初始化空表初始化空表第70页/共81页第七十页,共82页。 Linklist CreateFromHead( ) Node *s,*L; char c; int flag=1; L=(Node*)malloc(sizeof(Node); L-next=NULL; while(flag) c=getchar(); if(c!=$) s=(Node*)malloc(sizeof

67、(Node); s-data=c; s-next=L-next; L-next=s; else flag=0; 第71页/共81页第七十一页,共82页。尾插法建表尾插法建表sAs指向新申请指向新申请(shnqng)的结点的结点s-data=A;HsA插入插入(ch r)第一个结第一个结点:点:插入某一个插入某一个(y )结结点:点:sB将新结点插到当前单链表的表尾上。将新结点插到当前单链表的表尾上。增加一个增加一个尾指针尾指针r,使之,使之指向当前单链表的表尾指向当前单链表的表尾。r-next=s;r=s;顺序可以颠倒吗?H初始化空表初始化空表rrHArr第72页/共81页第七十二页,共82页

68、。 Linklist CreateFromTail() Node *L,*r, *s; int flag =1; L=(Node * )malloc(sizeof(Node); L-next=NULL; r=L; while(flag) c=getchar(); if(c!=$) s=(Node*)malloc(sizeof(Node); s-data=c; r-next=s; r=s; else flag=0; r-next=NULL; 第73页/共81页第七十三页,共82页。指针指针(zhzhn)与函数与函数返回值为指针类型返回值为指针类型(lixng)(lixng)的函数的函数 指针函数

69、的定义格式指针函数的定义格式(g shi)(g shi)如下:如下:类型名类型名 * *函数名函数名( (参数表参数表) )例如:例如:int *f(int x) 第74页/共81页第七十四页,共82页。指向指向(zh xin)函数的指针函数的指针指针变量的另一的重要指针变量的另一的重要(zhngyo)用途是用途是, 它可以指向一个函数它可以指向一个函数(存储函数入口地址存储函数入口地址), 通过它可以调用指向的函数通过它可以调用指向的函数, 改改变它的值就可以动态的调用不同的函数。变它的值就可以动态的调用不同的函数。指向指向(zh xin)(zh xin)函数的指针和函数参数函数的指针和函数

70、参数 第75页/共81页第七十五页,共82页。指向指向(zh xin)函数的指针函数的指针的定义的定义一般一般(ybn)形式形式:数据类型数据类型 (* 指针指针(zhzhn)变量名变量名)( )例如例如: int (*p)( );说明说明:1.在给函数指针变量赋值时在给函数指针变量赋值时,只需给出函数名而不必给参数只需给出函数名而不必给参数;2.用函数指针调用函数时用函数指针调用函数时,只需用只需用*p代替函数名即可代替函数名即可.第76页/共81页第七十六页,共82页。【例【例9.20】 指向指向(zh xin)函数的指针程序举例。函数的指针程序举例。#includeint f(int x

71、) return 3*x*x+5*x-7;void main() int (*p)(); int a; p=f; printf(Input x=); scanf(%d,&a); printf(*p)(a)=%dn,(*p)(a); printf(p(2a)=%dn,p(2*a); 第77页/共81页第七十七页,共82页。作作 业业1.#include main( ) int a23=1,2,3,4,5,6; int m,*p; p=&a00; m=*p*(*(p+2)*(*(p+4); printf(“%dn”,m);第78页/共81页第七十八页,共82页。2.#include main( ) char a =“language”,b =“program”; char *p=a,*q=b; int k; for(k=0;k7;k+) if(*(p+k)=*(q+k) printf(“%c”,*(p+k); 第79页/共81页第七十九页,共82页。3.main( ) char a =“Basic”; char *p; for(p=a;p成员名第八十二页,共82页。

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

最新文档


当前位置:首页 > 高等教育 > 研究生课件

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