c语言课件 第九章

上传人:m**** 文档编号:579550534 上传时间:2024-08-26 格式:PPT 页数:90 大小:861.03KB
返回 下载 相关 举报
c语言课件 第九章_第1页
第1页 / 共90页
c语言课件 第九章_第2页
第2页 / 共90页
c语言课件 第九章_第3页
第3页 / 共90页
c语言课件 第九章_第4页
第4页 / 共90页
c语言课件 第九章_第5页
第5页 / 共90页
点击查看更多>>
资源描述

《c语言课件 第九章》由会员分享,可在线阅读,更多相关《c语言课件 第九章(90页珍藏版)》请在金锄头文库上搜索。

1、第第九九章章 指指 针针C C语言程序设计语言程序设计1本 章 要 点1. 理解指针与地址的概念;理解指针与地址的概念;2. 掌握指针的定义和运算;掌握指针的定义和运算;3. 掌握指向基本类型、数组、字符串的指掌握指向基本类型、数组、字符串的指针的使用针的使用;4.充分理解指针和数组的等价性充分理解指针和数组的等价性; ;5.掌握指针函数和函数指针的使用;掌握指针函数和函数指针的使用;6.了解指向指针的指针的概念及其使用。了解指向指针的指针的概念及其使用。2预 备 知 识内存:内存:就是内部存储器,是由存储单元组成就是内部存储器,是由存储单元组成 的。它的特点是存储单元是线性连续的。它的特点是

2、存储单元是线性连续 的。存储单元的最小单位是的。存储单元的最小单位是字节字节。 1. 内存的概念内存的概念3地址:地址:为了访问内存中的某个存储单元,我们为了访问内存中的某个存储单元,我们 要为它编号,这种编号称为要为它编号,这种编号称为内存地址内存地址。 通过地址我们就能够访问该地址所标通过地址我们就能够访问该地址所标 识的存储单元。识的存储单元。2. 地址的概念地址的概念4变变量量的的地地址址:变变量量的的地地址址是是变变量量在在内内存存中中占占用用连连续续字节的首地址。字节的首地址。20072007存储单元5以往对变量的访问以往对变量的访问: :定义变量定义变量: : intint k;

3、 k;编译系统根据类型为编译系统根据类型为k k分配内存。分配内存。输入变量的值输入变量的值: :scanf(“%d”,&kscanf(“%d”,&k);); &k &k就代表了变量就代表了变量k k在内存中的地址。在内存中的地址。通过变量名访问变量通过变量名访问变量, ,这种操作称为这种操作称为直接访问直接访问; ;通过指针间接访问通过指针间接访问: :C C提供了另一种方式,将变量提供了另一种方式,将变量 k k的地址存放在另一个的地址存放在另一个变量处变量处( (假定为假定为pkpk) ),通过通过访问访问 pkpk,就可以间接地访就可以间接地访问变量问变量 k k,这种方式称为这种方式

4、称为间接访问间接访问。变量的存取方法:变量的存取方法:直接存取和间接存取。直接存取和间接存取。 6引入指针程序设计的优点引入指针程序设计的优点1.有效表示复杂的数据结构。有效表示复杂的数据结构。2.方便使用字符串、数组。方便使用字符串、数组。3.可以得到多个返回值。可以得到多个返回值。4.可以进行动态分配内存。可以进行动态分配内存。5.程序简洁、紧凑程序简洁、紧凑, 执行效率高。执行效率高。7 9.1.1 9.1.1 指针的基本概念指针的基本概念u指针指针:一个变量的地址称为该变量的指针。:一个变量的地址称为该变量的指针。u指针变量:指针变量:若一个变量专用于若一个变量专用于存放另一个变量存放

5、另一个变量的地址(指针),的地址(指针),则称此变量为指针变量。则称此变量为指针变量。 若指针变量若指针变量p的值等于变量的值等于变量x的地址的地址, 则说指针变则说指针变量量p指向变量指向变量x。1000351000pxx的值p的值X的内存地址9.1 9.1 指针的基本概念及指针变量的定义指针的基本概念及指针变量的定义8指针的对象:指针的对象:当把变量的地址存入指针变量后,当把变量的地址存入指针变量后,就可以说就可以说这个指针指向了该变量这个指针指向了该变量。 99.1.2 9.1.2 指针变量的定义指针变量的定义指针变量定义的一般形式:指针变量定义的一般形式: 类型标识符类型标识符 * *

6、标识符标识符例例:float *p1;int *p2;作用:作用:定义变量为指针类型,使之专门用于存放定义变量为指针类型,使之专门用于存放地址地址。指针所指的指针所指的变量的类型变量的类型指针变量名指针变量名10说明:说明:说明:说明:(1 1)* *用于定义指针变量,但指针变量名不带用于定义指针变量,但指针变量名不带* *。 如如 int *p1;int *p1; float *p2;float *p2; 定义的指针变量为定义的指针变量为p1,p2 p1,p2 (2 2)一个指针变量只能指向同一类型的变量。一个指针变量只能指向同一类型的变量。 如如 p1 p1 只能用于指向只能用于指向整型变

7、量整型变量 p2 p2 只能用于指向只能用于指向实型变量实型变量(3 3)无论指针变量指向何种类型,指针变量本身都)无论指针变量指向何种类型,指针变量本身都是是整型整型的,指针变量本身也有自己的地址,占的,指针变量本身也有自己的地址,占两个两个字节字节的存储空间。的存储空间。 111.取地址运算取地址运算 & 格式格式: & 变量变量 设有变量说明设有变量说明 int a, b, *p, *q; p=&a; 把把a的地址赋给的地址赋给p,使,使p指向指向a q=p; 让让q也指向也指向a,使,使p、q都指向都指向a p=&b; 让让p指向指向b,使,使q指向指向a,p指向指向b 9.2 9.2

8、 指针变量的引用和运算指针变量的引用和运算C C语言提供两种与指针有关的运算符:语言提供两种与指针有关的运算符:& *& *12 2. 取内容运算取内容运算 *格式:格式: * * 指针表达式指针表达式设设p p是一个指针表达式,则:是一个指针表达式,则:(1 1)若)若* *p p出现在赋值号左边,表示给出现在赋值号左边,表示给p p所指变量赋值所指变量赋值(2 2)若)若* *p p不出现在赋值号左边,表示不出现在赋值号左边,表示p p所指变量的值所指变量的值 若有变量说明:若有变量说明:intint a, *p ; a, *p ; p=&a; p=&a; 让让p p指向变量指向变量a a

9、 *p=10; *p=10; 等价于等价于 a=10a=10 printf(printf(“%d%d”, *p); , *p); 打印打印p p所指变量的值所指变量的值 scanf(scanf(“%d%d”, &a); , &a); 给变量给变量a a输入值输入值 scanf(scanf(“%d%d”, p); , p); 给变量给变量a a输入值输入值 * *p+25 p+25 等价于等价于a+25a+25133. 为指针变量赋初值为指针变量赋初值 指针变量使用前必须有值指针变量使用前必须有值 指针变量的初值必须是地址值指针变量的初值必须是地址值(不能是整数不能是整数) 方法方法 :(1)在

10、说明指针变量时同时初始化在说明指针变量时同时初始化(2) int a , *p = &a;(3)(2) 使用赋值语句赋值使用赋值语句赋值(4) int a,*p;(5) p =&a ; 可以为指针赋空值可以为指针赋空值(NULL),此时指针不指向任何此时指针不指向任何 变量变量, 如如 p=NULL或或 p=0;p=0; ( p为空指针为空指针)14对对对对* * * *及及及及& & & &的说明:(的说明:(的说明:(的说明:(同级运算,由右向左同级运算,由右向左同级运算,由右向左同级运算,由右向左)若若pa=&a pa=&a (将(将 a a 的地址送指针变量的地址送指针变量papa),

11、 , 则则&*pa&*pa &(*pa) &(*pa) &(a) &(a) &a &a*&a *&a *(&a) *(&a) *pa *pa a a (*pa)+ (*pa)+ a+ a+*pa+ *pa+ *(pa+) ( *(pa+) (先取先取* *papa值,然后使值,然后使papa加加1 1)* *+pa +pa *(*(+pa+pa) ) (先使(先使papa加加1 1 ,再取,再取* *papa值)值)注意:此时pa不再指向a15 例例 9-1 9-1 输出变量的值。输出变量的值。 main( )main( ) int a,b; int a,b; int *pa, *pb; in

12、t *pa, *pb; a=100; b=10; a=100; b=10; pa=&a; pa=&a; pb=&b; pb=&b; printf(“%d,%dn”,a,b); printf(“%d,%dn”,a,b); printf(“%d,%dn”,*pa,*pb); printf(“%d,%dn”,*pa,*pb); 定义指针变量pa,pb将a的地址送pa将b的地址送pb输出所指向的变量运行结果为100,10100,1016 例例例例9-29-29-29-2将两个整型数将两个整型数将两个整型数将两个整型数a,ba,ba,ba,b按由大到小次序输出。按由大到小次序输出。按由大到小次序输出。按

13、由大到小次序输出。main( ) int *p1 ,*p2 ,*p ,a ,b; scanf(“%d,%d”,&a,&b); p1=&a;p2=&b; if(a、=、 q pq p指针所指元素位于指针所指元素位于q q所指元素所指元素之后之后时为时为1 1,反之为,反之为0 0。 p p=q pq p指针所指元素位于指针所指元素位于q q所指元素所指元素之后之后(或两指针指向(或两指针指向同同一元素一元素)时为)时为1 1,反之为,反之为0 0。=和和!=!=运算符,比较的是两个指针表达式是否指向运算符,比较的是两个指针表达式是否指向同一个内同一个内存单元存单元; ; 、= 、=,比较的是两个

14、指针所指内存区域的比较的是两个指针所指内存区域的先后次序先后次序语法格式语法格式: 指针表达式指针表达式 关系运算符关系运算符 指针表达式指针表达式例:例:intint a10; a10; intint *p=a, *q=a+3; *p=a, *q=a+3;判断以下表达式的值判断以下表达式的值p=&a0 p=&a1 p=q p+4=q+2 pa+2 p=&a0 p=&a1 p=q p+4=q+2 pa+2 pq pq 265. 5. 同类指针相减同类指针相减 同类指针相减时,两个指针应该指向连续存放同类指针相减时,两个指针应该指向连续存放的同类数据区域。的同类数据区域。 语法语法 :p-qp-

15、q 说明:说明: p-qp-q 的值,等于的值,等于(p(p的值的值-q-q的值的值) )/ /所指类型长度所指类型长度, 即即p,qp,q两个指针之间数据元素的个数。两个指针之间数据元素的个数。 例如:若有例如:若有 intint a10 , *p, *q; a10 , *p, *q; p=a; p=a; q=&a5; q=&a5; 则则p-qp-q=5 =5 表示表示p,qp,q之间数据元素的个数是之间数据元素的个数是5 5。 27格式格式: (类型名类型名 * ) 指针表达式指针表达式功能:将指针表达式的值转换成指定类型的指针。功能:将指针表达式的值转换成指定类型的指针。 例如例如: i

16、nt *p; double d, *q=&d; p=(int * )q;6. 强制类型转换运算强制类型转换运算28 9.3.3 通过指针引用数组元素通过指针引用数组元素引用数组中的元素可以用以下方法:引用数组中的元素可以用以下方法: 下标法下标法 : 如如 a3,ai 指针法指针法: 即通过指向数组元素的指针找到所需的元素即通过指向数组元素的指针找到所需的元素. 这种方法占内存少这种方法占内存少, 运行速度快运行速度快,程序代码质量高。程序代码质量高。 假设假设p已定义为指针变量已定义为指针变量,并已赋了一个地址并已赋了一个地址,它指向某一它指向某一个数组元素个数组元素. 且有赋值语句且有赋值

17、语句p= &a0; 则:则: p+1 表示数组中的表示数组中的下一个元素下一个元素, a+i和和p+i都是都是ai 的地址,或者说它们指向的地址,或者说它们指向ai. *(a+i) 或或 *(p+i)是是a+i或或p+i所指向的数组元素。所指向的数组元素。 指向数组的指针变量也可带有下标,如指向数组的指针变量也可带有下标,如pi与与*(p+i)等等价。价。v对下标为对下标为i i的元素访问:的元素访问: ai,*(a+i),*(ai,*(a+i),*(p+i),pip+i),pi v对对aiai的地址表示:的地址表示: & &ai,a+i,p+i,&piai,a+i,p+i,&pi 29例例:

18、 用三种方法输出数组全部元素。用三种方法输出数组全部元素。u下标法下标法:main( ) int a10, i; for(i=0;i10;i+) scanf(“%d”,&ai); printf(“n”); for(i=0;i10;i+) printf(“%5d”,ai); u地址法地址法(通过数组名计算数组元素地(通过数组名计算数组元素地址)址)for(i=0;i10;i+)printf(“%5d”,*(a+i);u指针法指针法for(p=a;p(a+10);p+)printf(“%5d”,*p );30 例例例例9-3 9-3 9-3 9-3 用指针访问数组元素。用指针访问数组元素。用指针访

19、问数组元素。用指针访问数组元素。main( )main( ) intint a10,*pa, i; a10,*pa, i; for (i=0;i10;i+) for (i=0;i10;i+) ai=i+1; ai=i+1; pa=a; pa=a; for(i=0;i10;i+,pa+) for(i=0;i10;i+,pa+) printf(“%dprintf(“%d”,*pa);”,*pa); printf(“nprintf(“n”);”); 不要忘记赋初值不要忘记赋初值如何修改程序可如何修改程序可以完成功能以完成功能? ?31 例例例例9-4 9-4 9-4 9-4 给定给定给定给定1010

20、1010个整数,求最大值。个整数,求最大值。个整数,求最大值。个整数,求最大值。main( )main( ) intint a10=5,7,3,6,2,1,8,9,4,0; a10=5,7,3,6,2,1,8,9,4,0; int i, * int i, *p,maxp,max; ; p=a; p=a; max=*p+; max=*p+; for(ifor(i=1; i10; i+, p+ )=1; imax ) max=*p ; if (*pmax ) max=*p ; printf ( “max=% printf ( “max=%dndn”, max); ”, max); 问题问题: :如

21、果修改语句如果修改语句for(ifor(i=1;i10; i+ =1;imax) if (*pmax) max=*p+ ; max=*p+ ;能实现程序功能吗能实现程序功能吗? ?问题问题: :如果修改语句如果修改语句for(;pfor(;pa+10; p+ ) max) if (*pmax) max=*p ; max=*p ;能实现程序功能吗能实现程序功能吗? ?329.3.4 字符串指针与字符串字符串指针与字符串1.字符串的表示形式字符串的表示形式u 用用字符数组字符数组表示,如:表示,如:main( ) char string =“I love China!”; printf(“%sn”

22、,string);数组名数组名u 用用字符指针字符指针实现,如:实现,如:mian( ) char * string =“I love China!”; printf(“%sn”,string);把“I love China!”的首地首地址赋址赋给指针变量string特点特点: :字符串的长度不受字符串的长度不受限制限制; ;字符指针指向别处字符指针指向别处, ,字符串将失踪字符串将失踪. .332.字符指针变量与字符数组的比较字符指针变量与字符数组的比较u字符数组由若干个元素组成,每个元素中放一个字符,字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是字符串的首地址。而

23、字符指针变量中存放的是字符串的首地址。 赋值方式:赋值方式: char str =“I am a boy!” 或或: char str20; scanf(“%s”,str);u字符指针变量指向字符串首地址。字符指针变量指向字符串首地址。赋值方法三种:赋值方法三种: (1) char *pa=“I am a boy!” (2) char *pa; pa=“I am a boy!” (3) char *pa, str20; pa=str; scanf(“%s”,pa);34 例例9-5 9-5 已知下面程序的输出结果已知下面程序的输出结果:ABCDCD,:ABCDCD,请完善请完善程序程序: :

24、main() main() char * char *chpchp=“ABCD”;=“ABCD”; for( ; _A_; for( ; _A_; chpchp=chp+2)=chp+2) printf(“%sprintf(“%s”, _B_);”, _B_); printf(“nprintf(“n”);”); A. *chp!=0B. chp35作用:作用: 函数的参数不仅可以是整型、实型、字符函数的参数不仅可以是整型、实型、字符型,还可以是指针型,型,还可以是指针型,它的作用是将一个变量它的作用是将一个变量的地址传送到另的地址传送到另外外一个函数中。一个函数中。9. 4 指针与函数指针与函

25、数9.4.1 9.4.1 指针变量作函数参数指针变量作函数参数36例:交换两个变量的值。注意函数调用形实结合方式例:交换两个变量的值。注意函数调用形实结合方式例:交换两个变量的值。注意函数调用形实结合方式例:交换两个变量的值。注意函数调用形实结合方式. . . .swap(x,y)int x,y; int t; t=x; x=y; y=t;main( ) int a,b; scanf(“%d,%d”,&a,&b); if(ab) swap(a,b); printf(“%d,%dn”,a,b); 单向值传递!单向值传递!单向值传递!单向值传递!调用函数时调用函数时a的值传送给的值传送给x,b值值

26、传送给传送给y,可是执行完函数后可是执行完函数后,x和和y的值是互换了的值是互换了,但但a,b的值并的值并未互换。未互换。37swap(int *p1,int *p2) int p; p=*p1; *p1=*p2; *p2=p;main( )int a,b; int *pa, *pb; scanf(“%d,%d”,&a,&b); pa=&a; pb=&b; if(ab) swap(pa,pb); pintf(“%d,%dn”,a,b); 运行情况:运行情况:5,9 9,5交换指针所指交换指针所指向的向的变量的值变量的值分析观察使用指针做形参和实参的结果分析观察使用指针做形参和实参的结果分析观察

27、使用指针做形参和实参的结果分析观察使用指针做形参和实参的结果例:将两个数按从大到小顺序输出例:将两个数按从大到小顺序输出(交换两个变量的值)。交换两个变量的值)。结论:被调用函数不能改变实参指针变结论:被调用函数不能改变实参指针变量的值,但可以改变实参指针变量所指量的值,但可以改变实参指针变量所指向的变量的值。向的变量的值。38函数调用过程如下图所示函数调用过程如下图所示:调用swap函数之前:pa &a 5 a &b pb 9 b39 &ap1 &bp2 5 &apa a 9 &bpb b &a 9 &apap1 a 5 &b &bpbp2 b执行函数语句,执行函数语句,p1、p2所指所指向

28、的变量的值相互交换向的变量的值相互交换*p1*p240pa &a 9 a &b 5 pb b函数调用结束后,函数调用结束后,p1、p2所占所占用的内存单元被释放,用的内存单元被释放,41swap(int *p1,int *p2) int *p; p=p1; p1=p2; p2=p; main( )int a,b;int *pa, *pb; scanf(“%d,%d”,&a,&b); pa=&a; pb=&b; if(ab) swap(pa, pb);printf(“%d,%dn”,*pa,*pb);C语言中,实参和形参间的数据是单向值传递方式。语言中,实参和形参间的数据是单向值传递方式。指针做

29、函数参数也遵循该原则指针做函数参数也遵循该原则.改变指针形参的值,也不改变指针形参的值,也不能改变指针实参的值能改变指针实参的值. .结果为结果为:?:?交换了两个指针中的内容。42 9.4.2 数组名作函数参数数组名作函数参数 当用数组名作为参数时,如果形参数组中元素当用数组名作为参数时,如果形参数组中元素的值发生变化,实参数组元素的值也随之变化,的值发生变化,实参数组元素的值也随之变化,为为什么?什么? 若有一个实参数组,想在函数中改变此数组的若有一个实参数组,想在函数中改变此数组的元素的值,实参与形参的对应关系有以下元素的值,实参与形参的对应关系有以下4 4种情况:种情况: 形参与实参都

30、用数组名形参与实参都用数组名 实参用数组名,形参用指针变量实参用数组名,形参用指针变量 实参形参均用指针变量实参形参均用指针变量 实参为指针变量,形参为数组名实参为指针变量,形参为数组名都是地址传递,只是形式不同!都是地址传递,只是形式不同!43指针作函数参数应注意的问题指针作函数参数应注意的问题指针作函数参数应注意的问题指针作函数参数应注意的问题u指针变量在作实参时,必须有确定的值,即指向一个指针变量在作实参时,必须有确定的值,即指向一个已定义的单元。已定义的单元。 如:如:main()main() intint *p; *p; f(p,10); f(p,10); intint f(intf

31、(int x , x ,intint n n) 错误!如何修改?如何修改?44例例9-6:用选择法对:用选择法对10个整数由小到大排序。个整数由小到大排序。方法方法1:形参和实参都用数组名:形参和实参都用数组名(在函数中介绍的在函数中介绍的)main( ) int i, a10;void sort( );for(i=0;i10;i+) scanf(%d”,&ai);sort(a,10);for(i=0; i10 ;i+) printf(%d, ai); void sort( int x , int n) int i,j, t; for(i=0;in-1;i+) for(j=i+1;jxj) t

32、=xi; xi=xj; xj=t; 形参是形参是数组名数组名实参也是数组名实参也是数组名45方法方法2:形参是数组名,实参是指针变量。:形参是数组名,实参是指针变量。main( ) int *p, i, a10;void sort( );p=a;for(i=0;i10;i+) scanf(%d,p+);sort(p,10);for(p=a, i=0; i10 ;i+) printf(%d, *p+); void sort( int x, int n) int i,j, t; for(i=0;in-1;i+) for(j=i+1;jxj) t=xi; xi=xj; xj=t; p=a;形参是形参

33、是数组名数组名实参是指针实参是指针当用当用数组名作函数参数时,由于数组名作函数参数时,由于数组名代表的是数组首元素地址,数组名代表的是数组首元素地址,因此传递的是地址,所以要求实因此传递的是地址,所以要求实参为指针变量。参为指针变量。46方法方法3:实参是数组名,形参是指针变量。:实参是数组名,形参是指针变量。void sort( int *x, int n) int i,j, t; for(i=0;in-1;i+) for(j=i+1;j*(x+j) t=*(x+i); *(x+i)=*(x+j); *(x+j)=t; 实参是指针实参是指针main( ) int i, a10;void so

34、rt( );for(i=0;i10;i+) scanf(%d”,&ai);sort(a,10);for(i=0; i10 ;i+) printf(%d , ai); 形参形参是指针是指针实参是数组名实参是数组名47方法方法4:实参和形参都是指针变量。:实参和形参都是指针变量。void sort( int*x, int n) int i,j, t; for(i=0;in-1;i+) for(j=i+1;j*(x+j) t=*(x+i); *(x+i)=*(x+j); *(x+j)=t; 实参是指针实参是指针main( ) int *p, i, a10;void sort( );p=a;for(i

35、=0;i10;i+) scanf(%d,p+);p=a;sort(p,10);for(p=a, i=0; iy) z=x; else z=y; return (z);指向函数的指针指向max函数58在一个程序中,一个指针变量可以先后指向不同在一个程序中,一个指针变量可以先后指向不同的函数;的函数; 例如:例如: intint (*p)( ); (*p)( ); intint max( ); max( ); intint min( ); min( ); p=max; c=(*p)(a , b); p=max; c=(*p)(a , b); p=min; c=(*p)(a , b); p=min;

36、 c=(*p)(a , b);P先于先于*结合,是指针变量,结合,是指针变量,然后再与()结合,表示此然后再与()结合,表示此指针变量指向函数。指针变量指向函数。59实参函数名实参函数名f1 f2 sub( x1, x2)int(*x1)( ),(*x2)( );int a,b,i,j;a=(*x1)(i);b=(*x2)(i,j);定义x1,x2为函数指针变量调用f1函数调用f2函数指向函数的指针变量作函数参数指向函数的指针变量作函数参数: :609.5 指针与二维数组指针与二维数组9.5.1 二维数组的结构二维数组的结构 数数组组的的名名代代表表该该数数组组的的首首地地址址,并并可可看看成

37、成是是地地址址常量,这一规定对二维数组或更高维数组同样适用。常量,这一规定对二维数组或更高维数组同样适用。若有定义:若有定义: float *p, d35; d0,d1,d2 分分别别是是一一维维数数组组名名,表表示示一一维维数数组组的的首首地址,地址,p=d0是正确的。是正确的。d00d00d01d01 d02d02d03d03 d04d04d10d10d11d11 d12d12d13d13 d14d14d20d20d21d21 d22d22d23d23 d24d24d0d0d1d1d2d2d可以把可以把d看成是由看成是由3个一维数组个一维数组组成,即组成,即d0,d1,d261a a代表整

38、个二维数组的首地址,即代表整个二维数组的首地址,即第第0 0行的首地址行的首地址a+1a+1是数组是数组a a第第1 1行首地址行首地址(208)(208)a0,a1,a2a0,a1,a2是二维数组中三个是二维数组中三个一维数组的名字(地址),是第一维数组的名字(地址),是第0 0行,第行,第1 1行,第行,第2 2行的首地址,即:行的首地址,即:a0=a+0a0=a+0、a1=a+1a1=a+1、a2=a+2a2=a+2ai+jai+j是第是第i i行行j j列的地址列的地址* *(ai+j)(ai+j)是该地址存储的值,是该地址存储的值, 即即aijaij考虑考虑 * *(a2+3)=?(

39、a2+3)=?a0a1a2a数组数组a (200)a+1a+2(216)假设数组名为假设数组名为a,起始地址设为起始地址设为200,按行优先存放按行优先存放, int a34=1,3,5,7,9,11,13,15,17,19,21,23;则:则:9.5.2 二维数组元素及其地址二维数组元素及其地址62注意:注意:aiai和和* *(a+i)(a+i)无条件等价无条件等价a+ia+i、aiai、* *(a+i)(a+i)、&ai0&ai0均表示第均表示第i i行首行首地址;地址;&aij&aij、 ai+jai+j、* *(a+i)+j(a+i)+j都是第都是第i i行行j j列元列元素的素的地

40、址地址;aijaij、 * *( (ai+jai+j) )、* *(*(a+i)+j(*(a+i)+j) )都是第都是第i i行行j j列元素的列元素的值值;63int i,j;main( ) int *p, a34, b34, c34; printf(The value of a:n); for(i=0; i3; i+) for(j=0; j4; j+) scanf(%d,ai+j); printf(The value of b:n); for(i=0; i3; i+) for(j=0; j4; j+) scanf(%d, *(b+i)+j);例例9-11: 将将a矩阵与矩阵与b矩阵相加矩阵

41、相加,计算结果存入计算结果存入c矩阵。矩阵。表示表示a数组第数组第i行第行第j列元素的列元素的地址地址表示表示b数组第数组第i行第行第j列元素的列元素的地址地址64 matrix(*a, b0, &c00); printf(The value of c:); for(i=0, p=c0; pc0+12; p+,i+) if (i%4=0) printf(n); printf(%-4d,*p); matrix(int *x, int *y, int *z) for(i=0; i3; i+) for(j=0; j4; j+) *(z+i*4+j)=*(x+i*4+j)+ *(y+i*4+j); 数

42、组元素在内存中按数组元素在内存中按“行优先行优先”的顺序存放,因此可用的顺序存放,因此可用x+i*4+j表示二维数组各元素的表示二维数组各元素的地址,相当于地址,相当于&xij ,*(x+i*4+j)就是取该元素的值。就是取该元素的值。*a相当于相当于*(a+0),即即a0表示表示a数组第数组第0行第行第0列元素的地址。列元素的地址。b0表示表示 b数组第数组第0行第行第0列元素的地址。列元素的地址。&c00表示表示 c数组第数组第0行第行第0列元素的地址。列元素的地址。计算计算aij在数组中相对位置的在数组中相对位置的计算公式为:计算公式为:i*m+jm为二维数组的列数为二维数组的列数65

43、例例9-12 将矩阵将矩阵A转置后存放到矩阵转置后存放到矩阵B中,中, 即:即:bji=aij (下标法下标法)main()int a34,b43,i,j;for(i=0;i3;i+) for(j=0;j4;j+) scanf(%d,&aij);for(i=0;i3;i+) for(j=0;j4;j+) bji=aij;for(i=0;i4;i+) for(j=0;j3;j+) printf(%5d,bij); printf(n); 66指针法(方法指针法(方法1) main()int a34,b43,i,j,*p,*q;p=&a00;q=&b00;for(i=0;i3;i+) for(j=0

44、;j4;j+) scanf(%d,p+i*4+j);for(i=0;i3;i+) for(j=0;j4;j+) bji=aij;for(i=0;i4;i+) for(j=0;j3;j+) printf(%5d,*(q+i*3+j); printf(n); 将将指针变量指针变量p,q指向指向两数组的开始位置两数组的开始位置利用指针利用指针p为数组为数组a输入数据输入数据利用指针利用指针q输出数组输出数组b这里的指针变量这里的指针变量p和和q都是用都是用int *p,*q定义的定义的是指向整型数据的,是指向整型数据的,p+1是指向是指向p所指向的下所指向的下一个元素。能否使一个元素。能否使p不是指

45、向整型变量,而不是指向整型变量,而是指向一个包含是指向一个包含m个元数的一维数组呢?个元数的一维数组呢?679.5.3 9.5.3 指向数组的指针变量指向数组的指针变量1. 1. 定义格式定义格式 类型说明符类型说明符 (* *变量名)变量名) 正整型常量表达式正整型常量表达式 2. 2. 功能功能 定义一个名为定义一个名为“变量名变量名”的指针变量,这个指针的指针变量,这个指针变量所指的对象是一个变量所指的对象是一个有有“正整型正整型常量表达式常量表达式”个元素的一维数组。个元素的一维数组。例如:例如:intint a34,(*p)4=a; a34,(*p)4=a;定义定义p p是一个指针变

46、量,它指向包含是一个指针变量,它指向包含4 4个整型元素的个整型元素的一维数组。一维数组。 p p的值就是该一维数组的起始地址。的值就是该一维数组的起始地址。a0a1a2p,ap+1p+268例例9-139-13:输出二维数组任一行任一列元素的值:输出二维数组任一行任一列元素的值main( )main( ) intint a34=1,3,5,7,9,11,13,15,17,19,21,23;a34=1,3,5,7,9,11,13,15,17,19,21,23; intint * *p p,i,j,i,j ; ; p=a; p=a; scanf(“%d,%d”,&i,&jscanf(“%d,%d

47、”,&i,&j);); printf(“a%d%dprintf(“a%d%d=%dn”, i , j,=%dn”, i , j,*(*(p+ip+i*4+j)*4+j);); 输入输入1,21,2运行结果:运行结果:a12=13a12=13这里的指针变量这里的指针变量p是定义为指向整型数据的是定义为指向整型数据的aij在数组中在数组中的位置用相对于的位置用相对于数组起始位置的数组起始位置的相对移位量计算相对移位量计算69 例例例例9-14 9-14 9-14 9-14 输出二维数组任一行任一列元素的值输出二维数组任一行任一列元素的值输出二维数组任一行任一列元素的值输出二维数组任一行任一列元素的

48、值main( )main( ) intint a34=1,3,5,7,9,11,13,15,17,19,21,23;a34=1,3,5,7,9,11,13,15,17,19,21,23; intint (*p)4,i,j ; (*p)4,i,j ; p=a; p=a; scanf(“%d%d”,&i,&jscanf(“%d%d”,&i,&j);); printf(“a%d%dprintf(“a%d%d=%=%dn”,i,jdn”,i,j,*(*(p+i)+j);,*(*(p+i)+j); 输入输入1,21,2运行结果:运行结果:a12=13a12=13 1 3 5 7 9 11 13 1517

49、 19 21 23p,ap+1p+2a0a1a2=第第i行行j列元素的地址列元素的地址为:为:*(p+i)+j第第i行行j列元素的值为:列元素的值为:*(*(p+i)+j)这里的指针变量这里的指针变量p不是指不是指向整型变量,而是指向一向整型变量,而是指向一个包含个包含4个整型元素的一维个整型元素的一维数组。数组。70例例9-15 阅读下面程序。阅读下面程序。 main( )int i;int *q,(*p)4,a34=2,4,6,8,10,12,14,16,18,20,22,24; q=a0; for(i=1;i=0;i-) printf(%dt, *(pi+i); printf(n);程序

50、运行结果:程序运行结果: 2 6 10 14 22 12 2 第第i行行j列元素的地址列元素的地址为:为:pi+j第第i行行j列元素的值为:列元素的值为:*(pi+j)q q是定义为指向整型数据的是定义为指向整型数据的P P指指向一个包含向一个包含4 4个整型元素的个整型元素的一维数组。一维数组。71定义一个由定义一个由 6 6个个指针变量构成的指针变量构成的指针数组指针数组,数组中,数组中的每个数组元素都是一个指向一个整数的指针变量。的每个数组元素都是一个指向一个整数的指针变量。整数整数整数整数整数整数整数整数整数整数整数整数pa0pa1pa2pa3pa4pa5指针数组指针数组pa指针数组指

51、针数组: :数组中的数组中的元素元素均为均为指针类型指针类型。适合用来指向字符串。适合用来指向字符串1.1.定义形式:定义形式:数据类型数据类型 * * 数组名数组名 常量表达式常量表达式 例如:例如: intint *pa6; *pa6;2.2.功能:功能:9.6 9.6 指针数组指针数组723.3.3.3.指针数组的初始化指针数组的初始化指针数组的初始化指针数组的初始化 必须用地址值为指针数组初始化必须用地址值为指针数组初始化 intint a33 = 1,2,3,4,5,6,7,8,9,*pa3; a33 = 1,2,3,4,5,6,7,8,9,*pa3; pa0=a0;pa1=a1;p

52、a2=a2; pa0=a0;pa1=a1;pa2=a2; 1 2 34 5 67 8 9a0a1a2*pa0*pa1*pa2指针数组指针数组*pa3 相当于有三个指针,相当于有三个指针,*pa0,*pa1,*pa2 初始化的结果初始化的结果:73对指针数组中的任意一个对指针数组中的任意一个pai,移动移动j个元素,有:个元素,有: pai+j = ai+j = &aij;*(pai+j) = *(ai+j) = aij;指针与数组的等价性:指针与数组的等价性:*(a+i )=*(pa+i )=a i ;*(pa i +j)=*(a i +j )=*(*(a+i )+j ) =a i j 指针数

53、组与二维数组是等价的,通过指针数组指针数组与二维数组是等价的,通过指针数组可以引用二维数组中的元素。可以引用二维数组中的元素。注意:注意: intint *p5 *p5 与与 intint (*p)5 (*p)5 不同不同74 字符串数组:字符串数组:数组中的每个元素都是存放字符的数组。数组中的每个元素都是存放字符的数组。 字符串数组的每一行可存放一个字符串。字符串数组的每一行可存放一个字符串。 用赋初值的方式给字符串数组赋值:用赋初值的方式给字符串数组赋值:直接给字符串数组赋初值直接给字符串数组赋初值若有定义:若有定义:char b48= Turbo C, FORTRAN, BASIC, F

54、oxpro;此定义还可以写成:此定义还可以写成:char b8= Turbo C, FORTRAN, BASIC, Foxpro;由于字符串长短不一,定义时应考虑最长的串和结束标志的位置。由于字符串长短不一,定义时应考虑最长的串和结束标志的位置。9.7 9.7 指针与字符串数组指针与字符串数组75用给字符型指针数组赋初值的方式构成字符串数组用给字符型指针数组赋初值的方式构成字符串数组若有定义:若有定义:char *f4= Turbo C, FORTRAN, BASIC, Foxpro;此定义还可以写成:此定义还可以写成:char *f= Turbo C, FORTRAN, BASIC, Fox

55、pro;则则数数组组f中中的的每每个个元元素素都都存存放放着着对对应应的的一一个个字字符符串串的的首首地地址址,各字符串依次存入各相应的首地址开始的连续存储单元中。各字符串依次存入各相应的首地址开始的连续存储单元中。 F O R T R A N 0 B A S I C 0F o x p r o 0f0f1f2f3 T u r b o C 0节省内存空间!76例9-16#include “stdio.h”main( )char *s4=“dog”,“cat” , “pig”, “all animals”; int i; for (i=0; i 1)while (argc1) +argv; +ar

56、gv; printf(“%snprintf(“%sn”,*argv );”,*argv ); -argc ; -argc ; 若输入的命令行参数为若输入的命令行参数为F ABC DEF则执行结果为则执行结果为ABCDEF86有关指针数据类型的小结有关指针数据类型的小结定义:定义:intint *p;.p *p;.p为指向整型数据的指针变量;为指向整型数据的指针变量;intint *pn;. *pn;.定义定义指针数组指针数组p p,它由它由n n个指向整型数据指针元素组个指向整型数据指针元素组成;成;int (*p)n;int (*p)n;定义指向含定义指向含n n个元素的一维数组的个元素的一

57、维数组的指针变量指针变量p p;int f( );fint f( );f为带回整型函数值的函数;为带回整型函数值的函数;int *p( );int *p( );p p为带回一个指针的为带回一个指针的函数函数,该指针指向整型数据;,该指针指向整型数据;int (*p)( );.pint (*p)( );.p为为指向函数的指针指向函数的指针,该函数返回一个整型值;,该函数返回一个整型值;int *p;.pint *p;.p是一个是一个指针变量指针变量,它指向一个指向整型数据的指针,它指向一个指向整型数据的指针变量。二级指针。变量。二级指针。指针在使用前一定要赋值指针在使用前一定要赋值, ,指针可以

58、指向任何数据类型指针可以指向任何数据类型, ,指向谁指向谁, ,就就存谁的地址存谁的地址必须用地址值为指针变量初始化必须用地址值为指针变量初始化(&(&变量名变量名,&a,&a,或数组名或数组名),),不允许用不允许用整数整数相同类型的指针可以相互赋值相同类型的指针可以相互赋值优缺点:优缺点:快速灵活、可实现动态存储分配;易出大错。快速灵活、可实现动态存储分配;易出大错。87P173-1:P173-1:使用指针编写程序,删除字符串的所有尾部空格。使用指针编写程序,删除字符串的所有尾部空格。#include “#include “stdio.hstdio.h”main()main()char *

59、p,s20;char *p,s20; intint i, j; i, j; p=s; p=s; gets(pgets(p);); for(; *p!=0; p+); for(; *p!=0; p+); for(pfor(p-; *p= ;p-);-; *p= ;p-); p+; p+; *p=0; *p=0; printf(“%sn”,sprintf(“%sn”,s);); 88P173-1.P173-1.使用指针编写程序,删除字符串的所有尾部使用指针编写程序,删除字符串的所有尾部空格。空格。#include “#include “stdio.hstdio.h”del(chardel(char

60、 *p) *p) for(; *p!=0; p+); for(; *p!=0; p+); for(pfor(p-; *p= ;p-);-; *p= ;p-); *+p=0; *+p=0; main()main()char s20;char s20; gets(sgets(s);); del(sdel(s);); printf(“%sn”,sprintf(“%sn”,s);); 删除空格函数89P173-2: P173-2: 使用指针编写程序,对具有使用指针编写程序,对具有1010个元素的个元素的charchar类型的数组,从下标为类型的数组,从下标为6 6的元素开始全部设置的元素开始全部设置#号,保持前号,保持前6 6个元素中的内容不变。个元素中的内容不变。main()main()char *p=char *p=abcdefghijabcdefghij ; ; intint j; j; for(jfor(j=0;*p!=0; =0;*p!=0; p+,jp+,j+)+) if(jif(j=6) *p=#;=6) *p=#; printf(“%sn”,pprintf(“%sn”,p);); 运行结果正确吗?如何修改?运行结果正确吗?如何修改?90

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

最新文档


当前位置:首页 > 办公文档 > 工作计划

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