C语言程序设计善于利用指针.ppt
1第第8 8章章 善于利用指针善于利用指针C C 语言程序设计语言程序设计北京航空航天大学北京航空航天大学 交通科学与工程学院交通科学与工程学院徐国艳徐国艳2/56指针指针的概念的概念指针和指针变量指针和指针变量指针指针与与数组数组指针做函数参数指针做函数参数8.1 8.1 8.2 8.2 8.38.38.4 8.4 章节章节内容内容3/56访问内存的两种方式:访问内存的两种方式:l l直接访问:按地址直接存取直接访问:按地址直接存取&a al l间接访问:通过指针间接访问:通过指针i间接存取间接存取8.18.1指针指针的概念的概念什么是指针?什么是指针?如何使用指针?如何使用指针?100010081004102310a bc3.551000i对于对于int a=10,c=5;int a=10,c=5;float b=3.5;float b=3.5;内存分配内存分配例例a的地址的地址a的内容的内容指针指针a的地址的地址a a是整型变量,存放内容是整型变量,存放内容i i是指针变量,存放地址是指针变量,存放地址a的地址a的指针指向指向a a4/56用指针i访问:用i+可以指向字符串中的每个地址!8.18.1指针指针的概念的概念1000ichar c=char c=“GOOD!GOOD!”;例例Gc0 OO内存分配内存分配D!0c1 c2 c5 1000100210011023为什么要使用指针?为什么要使用指针?5/568.2 8.2 指针和指针变量指针和指针变量一、指针、指针变量与指向一、指针、指针变量与指向例:例:int a=10,*i,x;int a=10,*i,x;float b=3.5,float b=3.5,*p1*p1;char c,char c,*p2=&c*p2=&c;i=&a;p1=&b;i=&a;p1=&b;x=*i;x=*i;1010i i*i ia a10001000l l指针地址指针地址l l指针变量:指针变量:存放地址的变量存放地址的变量l l指针变量是一种新的数据类型指针变量是一种新的数据类型l l10001000是是a a 的指针的指针l li i是指针变量是指针变量*i=ai=a二、指针变量的定义与赋值二、指针变量的定义与赋值数据类型数据类型*指针变量名指针变量名 10001000l l*i i是是i i指向的变量指向的变量a a指针运算指针运算*i i*i i定义指针变量定义指针变量指针初始化指针初始化指针赋值指针赋值6/56三、指针变量的赋值与操作三、指针变量的赋值与操作*-*-指针运算符指针运算符&-&-取地址运算符取地址运算符同级,右结合同级,右结合l l指针变量的赋值int a=3,*p,*p1,*p2,*p3,p4;int a=3,*p,*p1,*p2,*p3,p4;p=&a;p=&a;/*/*取取a a地址运算地址运算*/p1=p;p1=p;/*/*直接赋值直接赋值*/p2=NULL;p2=NULL;/*/*赋空值,不指向任何变量赋空值,不指向任何变量*/*/p3=0;p3=0;l l指针变量的操作 int a=3,*p,*p1,k;int a=3,*p,*p1,k;p=&a;p=&a;/*a/*a地址地址P P*/*/k=*P;k=*P;/*3/*3k k*/*/*p=20;*p=20;/*20/*20a a*/*/*&a&a=30;=30;/*/*先取先取a a的地址,再按地址赋值的地址,再按地址赋值3 30 0a a*/*/p1=&*p;p1=&*p;/*/*因为因为&*&*p=&ap=&a,操作结果使操作结果使p1p1指向指向a a*/*/7/56四、四、指针的引用指针的引用例例8.18.1:指针的赋值与输出指针的赋值与输出void main()void main()int a=10,b,c,*p;int a=10,b,c,*p;p=&a;b=*pp=&a;b=*p;c=a;c=a;printf(%d,%d,%dn,a,b,c);printf(%d,%d,%dn,a,b,c);printf(%d,%d,%dn printf(%d,%d,%dn,*p,p,&a,*p,p,&a););输出结果:输出结果:10,10,1010,10,1010,1739919326,173991932610,1739919326,1739919326printf(“%d,%dn,*&a,&*p);printf(“%d,%dn,*&a,&*p);第三行输出结果:第三行输出结果:10,173991932610,1739919326指针赋值指针赋值指针运算指针运算指针输出指针输出8/56方法方法方法方法1 1 1 1:目标变量值不变,改变指针变量的:目标变量值不变,改变指针变量的:目标变量值不变,改变指针变量的:目标变量值不变,改变指针变量的指向求解。指向求解。指向求解。指向求解。void main()void main()void main()void main()int a,b,int a,b,int a,b,int a,b,*p1p1p1p1,*p2p2p2p2,*p p p p;p1p1p1p1=&a;a;a;a;p2p2p2p2=&b;b;b;b;scanf(scanf(scanf(scanf(%d%d%d%d%d%d%d%d,p1p1p1p1,p2p2p2p2););););if(if(if(if(*p1p1p1p1 *p2p2p2p2)p p p p=p1p1p1p1;p1p1p1p1=p2p2p2p2;p2p2p2p2=p p p p;printf(printf(printf(printf(a=%d,b=%dna=%d,b=%dna=%d,b=%dna=%d,b=%dn,a,b);,a,b);,a,b);,a,b);printf(printf(printf(printf(max=%d,min=%dnmax=%d,min=%dnmax=%d,min=%dnmax=%d,min=%dn,*p1p1p1p1,*p2p2p2p2););););a ab bp1p1p2p2p p6 68 8a=6,b=8a=6,b=8max=8,min=6max=8,min=68.2 指针和指针变量指针和指针变量【例【例8.2】输入输入a、b两个整数,两个整数,使用指针变量按大小顺序输出使用指针变量按大小顺序输出这两个整数。这两个整数。9/56方法方法方法方法2 2 2 2:利用指针变量直接改变目标变量的值:利用指针变量直接改变目标变量的值:利用指针变量直接改变目标变量的值:利用指针变量直接改变目标变量的值求解。求解。求解。求解。void main()void main()void main()void main()int a,b,t,int a,b,t,int a,b,t,int a,b,t,*p1p1p1p1,*p2p2p2p2;p1p1p1p1=&a;a;a;a;p2p2p2p2=&b;b;b;b;scanf(scanf(scanf(scanf(%d%d%d%d%d%d%d%d,p1p1p1p1,p2p2p2p2););););if(if(if(if(*p1p1p1p1 p1、p2=p1。指针与一个整型数据进行比较是没有意指针与一个整型数据进行比较是没有意义的义的。不同类型指针变量之间比较是非法的不同类型指针变量之间比较是非法的。NULL可以与任何类型指针进行可以与任何类型指针进行=、!=的关系运算,用于判断指针是否为空指针的关系运算,用于判断指针是否为空指针。404404404404404040408 8 8 841241241241241641641641642042042042012/56判断判断指针变量只指针变量只存放地址存放地址!一个指针变量不能一个指针变量不能指向与其类型不同指向与其类型不同的变量的变量!我是真的,我是真的,你对了吗?你对了吗?应在类型相同应在类型相同的指针变量之的指针变量之间赋值间赋值13/56 数组名是该数组的指针数组名是该数组的指针数组名是该数组的指针数组名是该数组的指针 a a a a是是是是数组的首地址(即数组的首地址(即数组的首地址(即数组的首地址(即a0a0a0a0的地址),是一的地址),是一的地址),是一的地址),是一个指针常量。个指针常量。个指针常量。个指针常量。a=&a0,a+1=&a1,a=&a0,a+1=&a1,a=&a0,a+1=&a1,a=&a0,a+1=&a1,a+9=&a9,a+9=&a9,a+9=&a9,a+9=&a9 数组元素的下标表示法:数组元素的下标表示法:数组元素的下标表示法:数组元素的下标表示法:a a a a 0 0 0 0 ,a,a,a,a 1 1 1 1 ,a,a,a,a i i i i ,a,a,a,a 9 9 9 9 数组元素的指针表示法:数组元素的指针表示法:数组元素的指针表示法:数组元素的指针表示法:*(a+0),(a+0),(a+0),(a+0),*(a+1),(a+1),(a+1),(a+1),*(a+i),(a+i),(a+i),(a+i),*(a+9)(a+9)(a+9)(a+9)8.3 指针与数组指针与数组8 8.3.1 3.1 指向数组的指针指向数组的指针指向数组的指针指向数组的指针1.1.一维数组的指针一维数组的指针一维数组的指针一维数组的指针 例如:例如:例如:例如:int a10,*p;int a10,*p;int a10,*p;int a10,*p;a0a0a9a9p p p pa a14/56 当当当当p p p p指向指向指向指向a0a0a0a0时,用时,用时,用时,用p p p p表示数组元素表示数组元素表示数组元素表示数组元素 下标法:下标法:下标法:下标法:p0,p1,p0,p1,p0,p1,p0,p1,pi,pi,pi,pi,p9,p9,p9,p9 指针法:指针法:指针法:指针法:*(p+0),(p+0),(p+0),(p+0),*(p+1),(p+1),(p+1),(p+1),*(p+i),(p+i),(p+i),(p+i),*(p+9)(p+9)(p+9)(p+9)a0a0a9a9p p p p8.3 指针与数组指针与数组8 8.3.1 3.1 指向数组的指针指向数组的指针指向数组的指针指向数组的指针1.1.一维数组的指针一维数组的指针一维数组的指针一维数组的指针 指向一维数组元素的指针变量指向一维数组元素的指针变量指向一维数组元素的指针变量指向一维数组元素的指针变量 由于数组元素也是一个内存变量,所以由于数组元素也是一个内存变量,所以由于数组元素也是一个内存变量,所以由于数组元素也是一个内存变量,所以此类指针变量的定义和使用与指向基本变量此类指针变量的定义和使用与指向基本变量此类指针变量的定义和使用与指向基本变量此类指针变量的定义和使用与指向基本变量的指针变量相同。例如:的指针变量相同。例如:的指针变量相同。例如:的指针变量相同。例如:int a10,*p;int a10,*p;int a10,*p;int a10,*p;p=a;p=a;p=a;p=a;(或或或或 p=&a0;p=&a0;p=&a0;p=&a0;)a a15/56a a00a a99p p p pa a【例【例【例【例8 8.3.3.1.1】用指用指用指用指针输针输针输针输出数出数出数出数组组组组元素。元素。元素。元素。#include stdio.h#include stdio.hvoid main()void main()int a10,i,*p;int a10,i,*p;for(i=0;i10;i+)for(i=0;i10;i+)scanf(%d,a+i);scanf(%d,a+i);for(i=0;i10;i+)for(i=0;i10;i+)printf(%4d,*(a+i);printf(%4d,*(a+i);printf(n);printf(n);for(p=a,i=0;i10;i+)for(p=a,i=0;i10;i+)printf(%4d,*(p+i);printf(%4d,*(p+i);printf(n);printf(n);8.3 指针与数组指针与数组8 8.3.1 3.1 指向数组的指针指向数组的指针指向数组的指针指向数组的指针1.1.一维数组的指针一维数组的指针一维数组的指针一维数组的指针 12345678910 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 1016/56a a00a a99p p p pa a【例【例【例【例8 8.3.3.2.2】用指用指用指用指针针针针法法法法输输输输入入入入输输输输出数出数出数出数组组组组元素。元素。元素。元素。main()main()int a10,i,*p;int a10,i,*p;for(p=a;pa+10;p+)for(p=a;pa+10;p+)scanf(%d,p);scanf(%d,p);for(p=a;pa+10;p+)for(p=a;pa+10;p+)printf(%d,*p);printf(%d,*p);printf(n);printf(n);8.3 指针与数组指针与数组8 8.3.1 3.1 指向数组的指针指向数组的指针指向数组的指针指向数组的指针1.1.一维数组的指针一维数组的指针一维数组的指针一维数组的指针 1017/56a0a0a9a9p p p pa1a1 .1 12 23 34 45 56 67 78 89 91010a a a a 数组名数组名数组名数组名是地址,指向数组的是地址,指向数组的是地址,指向数组的是地址,指向数组的指针变量指针变量指针变量指针变量存放的也是地址。存放的也是地址。存放的也是地址。存放的也是地址。通过指针变量也可以引用数组元素。通过指针变量也可以引用数组元素。通过指针变量也可以引用数组元素。通过指针变量也可以引用数组元素。p p p p =&a0&a0&a0&a0 等效于等效于等效于等效于 p p p p =a a a a。数组名数组名数组名数组名和指向数组的和指向数组的和指向数组的和指向数组的指针变量指针变量指针变量指针变量的区别:的区别:的区别:的区别:指针变量指针变量指针变量指针变量p p p p是是是是变量变量变量变量可以赋值可以赋值可以赋值可以赋值,数组名数组名数组名数组名a a a a是地址是地址是地址是地址常量常量常量常量不能赋值。不能赋值。不能赋值。不能赋值。8.3 指针与数组指针与数组8 8.3.1 3.1 指向数组的指针指向数组的指针指向数组的指针指向数组的指针用指针变量引用数组元素,用指针变量引用数组元素,用指针变量引用数组元素,用指针变量引用数组元素,必须关注其当前值。例如:必须关注其当前值。例如:必须关注其当前值。例如:必须关注其当前值。例如:p p p p=p p p p+3+3+3+3*(p-1)*(p-1)*(p-1)*(p-1)、p-1p-1p-1p-1等价于等价于等价于等价于a2a2a2a218/56 输入输入a数组数组 for(p=a;pa+4;p+)pp=p for(q=p+1;q*q F pp=q T pp!=p F *pp*p 输出输出a数组数组选择法排序选择法排序N-S图图【例例例例8.8.4 4】输输输输入五个整数,使用指入五个整数,使用指入五个整数,使用指入五个整数,使用指针变针变针变针变量将量将量将量将这这这这五个五个五个五个数数数数 按从小到大排序后按从小到大排序后按从小到大排序后按从小到大排序后输输输输出。出。出。出。8.3 指针与数组指针与数组#include“stdio.h”#include“stdio.h”void main()void main()int a5,*pp,*p,*q,t;int a5,*pp,*p,*q,t;for(p=a;pa+5;p+)for(p=a;pa+5;p+)scanf(%d,p);scanf(%d,p);for(p=a;pa+4;p+)for(p=a;pa+4;p+)pp=p;pp=p;for(q=p+1;qa+5;q+)for(q=p+1;q*q)pp=q;if(*pp*q)pp=q;if(pp!=p)if(pp!=p)t=*p;*p=*pp;*pp=t;t=*p;*p=*pp;*pp=t;for(p=a;pa+5;p+)for(p=a;pa+5;p+)printf(%d,*p);printf(%d,*p);printf(n);printf(n);19/56【例【例【例【例8 8.7.7】通过初始化使指针指向一个字符串。】通过初始化使指针指向一个字符串。】通过初始化使指针指向一个字符串。】通过初始化使指针指向一个字符串。void main()void main()char str1=Good morning!;char str1=Good morning!;char*str2=Good night!;char*str2=Good night!;printf(%sn,str1);printf(%sn,str1);printf(%sn,str2);printf(%sn,str2);8.3 指针与数组指针与数组 8 8.3.2 3.2 指向字符串的指针变量指向字符串的指针变量指向字符串的指针变量指向字符串的指针变量1.1.指向字符串的指针变量指向字符串的指针变量指向字符串的指针变量指向字符串的指针变量的定义及初始化的定义及初始化的定义及初始化的定义及初始化 字符串的两种表示方式:字符串的两种表示方式:字符数组表示方式,字符串存放在一维数组中,字符数组表示方式,字符串存放在一维数组中,引用时用数组名。引用时用数组名。字符指针变量表示方式,字符指针变量存放字符字符指针变量表示方式,字符指针变量存放字符串的首地址,引用时用指针变量名。串的首地址,引用时用指针变量名。Good morning!Good night!C语言对字符串常量是按字符数组处理的,在内存中开辟一个语言对字符串常量是按字符数组处理的,在内存中开辟一个字符数组用来存放字符串常量,但是这个字符数组没有名字。字符数组用来存放字符串常量,但是这个字符数组没有名字。20/56【例例例例8 8.8.8】通通通通过过过过赋赋赋赋值值值值运运运运算算算算使使使使字字字字符符符符指指指指针针针针变变变变量量量量指指指指向向向向一一一一个字符串。个字符串。个字符串。个字符串。#includeinclude main()main()char c80,*str;char c80,*str;strcpy(c,How are you?);strcpy(c,How are you?);str=Fine,thanks.;str=Fine,thanks.;printf(%sn%sn,c,str);printf(%sn%sn,c,str);8.3 指针与数组指针与数组 8 8.3.2 3.2 指向字符串的指针变量指向字符串的指针变量指向字符串的指针变量指向字符串的指针变量2.2.字符串的赋值运算字符串的赋值运算字符串的赋值运算字符串的赋值运算 将一个字符串赋给一个字符数组只能使用将一个字符串赋给一个字符数组只能使用strcpy函数函数 将字符串常量的首地址赋给指针变量,可使用赋值运将字符串常量的首地址赋给指针变量,可使用赋值运算符算符“=”How are you?Fine,thanks.21/56【例【例【例【例8 8.9.9】利用指针变量输入输出字符串。】利用指针变量输入输出字符串。】利用指针变量输入输出字符串。】利用指针变量输入输出字符串。#includeinclude void main()void main()char c80,*str;char c80,*str;str=c;str=c;gets(str);gets(str);puts(str);puts(str);8.3 指针与数组指针与数组 8 8.3.2 3.2 指向字符串的指针变量指向字符串的指针变量指向字符串的指针变量指向字符串的指针变量3.3.字符串的输入输出字符串的输入输出字符串的输入输出字符串的输入输出 使用字符串输入输出函数使用字符串输入输出函数gets()和和puts();在在scanf和和printf函数中使用函数中使用%s格式实现。格式实现。输入字符串时,函数参数:数组名、存有数组名输入字符串时,函数参数:数组名、存有数组名的指针变量;的指针变量;输出字符串时,函数参数:数组名、存有字符串输出字符串时,函数参数:数组名、存有字符串首地址的指针变量。首地址的指针变量。I love China!I love China!22/56 【例例例例8 8.11.11】已知字符串】已知字符串】已知字符串】已知字符串strstr,从中截取一子串。要求从中截取一子串。要求从中截取一子串。要求从中截取一子串。要求该该该该子串是从子串是从子串是从子串是从strstr的第的第的第的第mm个字符开始,由个字符开始,由个字符开始,由个字符开始,由n n个字符个字符个字符个字符组组组组成。成。成。成。思路:思路:思路:思路:定定定定义义义义字符数字符数字符数字符数组组组组c c 存放子串,字符指存放子串,字符指存放子串,字符指存放子串,字符指针变针变针变针变量量量量p p 用于复制用于复制用于复制用于复制子串,利用循子串,利用循子串,利用循子串,利用循环语环语环语环语句从字符串句从字符串句从字符串句从字符串strstr截取截取截取截取n n个字符。个字符。个字符。个字符。考考考考虑虑虑虑到几种特殊情况:到几种特殊情况:到几种特殊情况:到几种特殊情况:mm位置后的字符数有可能不足位置后的字符数有可能不足位置后的字符数有可能不足位置后的字符数有可能不足n n个,所以在循个,所以在循个,所以在循个,所以在循环读环读环读环读取字符取字符取字符取字符时时时时,若若若若读读读读到到到到 0 0 停止截取,利用停止截取,利用停止截取,利用停止截取,利用breakbreak语语语语句跳出循句跳出循句跳出循句跳出循环环环环。输输输输入的截取位置入的截取位置入的截取位置入的截取位置mm大于字符串的大于字符串的大于字符串的大于字符串的长长长长度,度,度,度,则则则则子串子串子串子串为为为为空。空。空。空。要求要求要求要求输输输输入的截取位置和字符个数均大于入的截取位置和字符个数均大于入的截取位置和字符个数均大于入的截取位置和字符个数均大于0 0,否,否,否,否则则则则子串子串子串子串为为为为空。空。空。空。8.3 指针与数组指针与数组 8 8.3.2 3.2 指向字符串的指针变量指向字符串的指针变量指向字符串的指针变量指向字符串的指针变量23/56#includeincludevoid main()void main()char c80,*p,*str=This is a string.;char c80,*p,*str=This is a string.;int i,m,n;int i,m,n;printf(m,n=);printf(m,n=);scanf(%d,%d,&m,&n);scanf(%d,%d,&m,&n);if(mstrlen(str)|n=0|mstrlen(str)|n=0|m=0)printf(NULLn);printf(NULLn);else else for(p=str+m-1,i=0;in;i+)for(p=str+m-1,i=0;in;i+)if(*p)ci=*p+;if(*p)ci=*p+;else break;/*else break;/*如如如如读读读读取到取到取到取到 0 0 则则则则停止循停止循停止循停止循环环环环*/*/ci=0;/*ci=0;/*在在在在c c数数数数组组组组中加上子串中加上子串中加上子串中加上子串结结结结束束束束标标标标志志志志*/*/printf(%sn,c);printf(%sn,c);8.3 指针与数组指针与数组 从从从从mm位置读取位置读取位置读取位置读取n n个字符送到个字符送到个字符送到个字符送到c c数组数组数组数组 要求位置要求位置要求位置要求位置m m m m和长度和长度和长度和长度n n n n大于大于大于大于0 0 24/56指针数组定义的一般形式:指针数组定义的一般形式:指针数组定义的一般形式:指针数组定义的一般形式:数据类型标识符数据类型标识符数据类型标识符数据类型标识符 *数组名数组名数组名数组名元素个数元素个数元素个数元素个数;在在在在这这这这个个个个定定定定义义义义中中中中由由由由于于于于“”比比比比“*”的的的的优优优优先先先先级级级级高高高高,所所所所以以以以数数数数组组组组名名名名先先先先与与与与“元元元元素素素素个个个个数数数数”结结结结合合合合,形形形形成成成成数数数数组组组组的的的的定定定定义义义义形形形形式式式式,“*”表表表表示示示示数数数数组组组组中中中中每每每每个个个个元元元元素素素素是是是是指指指指针针针针类类类类型型型型,“数数数数据据据据类类类类型标识符型标识符型标识符型标识符”说明指针的目标变量的数据类型。例如:说明指针的目标变量的数据类型。例如:说明指针的目标变量的数据类型。例如:说明指针的目标变量的数据类型。例如:int int*ipip 1010;char char*cpcp 5 5;8.3 指针与数组指针与数组 8 8.3.3 3.3 指针数组指针数组指针数组指针数组1.1.指针数组的定义指针数组的定义指针数组的定义指针数组的定义 指针数组就是数组中的每个元素均为指针类型指针数组就是数组中的每个元素均为指针类型 25/56例如:例如:例如:例如:char char c48=Fortran,COBOL,BASIC,Pascal;c48=Fortran,COBOL,BASIC,Pascal;char*cp4=c0,c1,c2,c3;char*cp4=c0,c1,c2,c3;8.3 指针与数组指针与数组 8 8.3.3 3.3 指针数组指针数组指针数组指针数组2.2.指针数组初始化指针数组初始化指针数组初始化指针数组初始化 cpcpC C 数数数数 组组组组cp0cp0F Fo or rt tr ra an n00cp1cp1C C OO B B OO L L00cp2cp2B B A A S SI IC C 00cp3cp3P Pa as sc ca al l 0 026/56char*str5=int,long,char,float,double;char*str5=int,long,char,float,double;str0str0i in nt t00str1str1l lo on ng g00str2str2c ch ha ar r00str3str3f fl lo oa at t00str4str4d do ou ub bl le e0027/56【例例例例8 8.13.13】用用用用0 06 6分分分分别别别别代代代代表表表表星星星星期期期期日日日日至至至至星星星星期期期期六六六六,当当当当输输输输入入入入其其其其中中中中任任任任意意意意一个数字时,输出相应英文单词。一个数字时,输出相应英文单词。一个数字时,输出相应英文单词。一个数字时,输出相应英文单词。#includeinclude void main()void main()char*weekname7=Sunday,Monday,Tuesday,char*weekname7=Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday;Wednesday,Thursday,Friday,Saturday;int week;int week;printf(Enter week No.:);printf(Enter week No.:);scanf(%d,&week);scanf(%d,&week);if(week=0&week=0&weekb)swap(&a,&b);if(ab)swap(&a,&b);if(ac)swap(&a,&c);if(ac)swap(&a,&c);if(bc)swap(&b,&c);if(bc)swap(&b,&c);printf(%d,%d,%dn,a,b,c);printf(%d,%d,%dn,a,b,c);7 5 97 5 95 5,7,9,7,97a a5b b9c c&a ax1x1&b bx2x27t t79 975 75通过指针形参指向域扩展到主调函通过指针形参指向域扩展到主调函通过指针形参指向域扩展到主调函通过指针形参指向域扩展到主调函数,达到主调函数与被调函数间交数,达到主调函数与被调函数间交数,达到主调函数与被调函数间交数,达到主调函数与被调函数间交换多个数据的目的换多个数据的目的换多个数据的目的换多个数据的目的:形参形参形参形参x1x1x1x1和和和和x2x2x2x2得到得到得到得到mainmainmainmain函数中函数中函数中函数中a a a a和和和和b b b b的地址,这样的地址,这样的地址,这样的地址,这样x1x1x1x1和和和和x2x2x2x2的目标变量的目标变量的目标变量的目标变量就是就是就是就是mainmainmainmain函数的变量函数的变量函数的变量函数的变量a a a a和和和和b b b b。在在在在swapswapswapswap函数中交换函数中交换函数中交换函数中交换 *x1x1x1x1和和和和 *x2x2x2x2的内容,就是交换的内容,就是交换的内容,就是交换的内容,就是交换a a a a和和和和b b b b的内容,的内容,的内容,的内容,所以当函数调用结束后,尽管所以当函数调用结束后,尽管所以当函数调用结束后,尽管所以当函数调用结束后,尽管x1x1x1x1和和和和x2x2x2x2已经释放,但操作结果仍保已经释放,但操作结果仍保已经释放,但操作结果仍保已经释放,但操作结果仍保留在留在留在留在mainmainmainmain函数的变量函数的变量函数的变量函数的变量a a a a和和和和b b b b中中中中.30/568.4 指针变量作函数参数指针变量作函数参数2.2.数组的指针作函数参数数组的指针作函数参数数组的指针作函数参数数组的指针作函数参数 一一一一维维维维数数数数组组组组的指的指的指的指针针针针作函数参数作函数参数作函数参数作函数参数 例如被调函数例如被调函数例如被调函数例如被调函数abcabc的定义形式有以下三种:的定义形式有以下三种:的定义形式有以下三种:的定义形式有以下三种:void abc(int b10)void abc(int b10)void abc(int b)void abc(int b)void abc(int*b)void abc(int*b)在主调函数有如下定义:在主调函数有如下定义:在主调函数有如下定义:在主调函数有如下定义:int a10,*p=a;int a10,*p=a;则调用则调用则调用则调用abcabc函数时可用函数时可用函数时可用函数时可用:abc(a)abc(a)或或或或 abc(p)abc(p)当函数之间需要传递数组时,可以通过传递数当函数之间需要传递数组时,可以通过传递数当函数之间需要传递数组时,可以通过传递数当函数之间需要传递数组时,可以通过传递数组的首地址(即通过指针参数指向域的扩展),组的首地址(即通过指针参数指向域的扩展),组的首地址(即通过指针参数指向域的扩展),组的首地址(即通过指针参数指向域的扩展),完成存取主调函数中数组元素的操作。完成存取主调函数中数组元素的操作。完成存取主调函数中数组元素的操作。完成存取主调函数中数组元素的操作。31/568.4 指针变量作函数参数指针变量作函数参数2.2.数组的指针作函数参数数组的指针作函数参数数组的指针作函数参数数组的指针作函数参数 【例【例【例【例8 8.20.20】字符串复制函数。】字符串复制函数。】字符串复制函数。】字符串复制函数。void copystr(char void copystr(char*t t,char,char*s s)/*/*字符指针变量字符指针变量字符指针变量字符指针变量t t和和和和s s作形参作形参作形参作形参*/*/while(while(*t t+=+=*s s+)!=0);+)!=0);void main()void main()char char c c80,80,*p p=I am a student.;=I am a student.;copystr(copystr(c c,p p););/*/*数组名数组名数组名数组名c c和字符指针变量和字符指针变量和字符指针变量和字符指针变量p p作实参作实参作实参作实参*/*/printf(%sn,c);printf(%sn,c);32/56作业作业l lP291(要求用指针完成)(要求用指针完成)1 3 4 17 18