《C程序设计第6章.ppt》由会员分享,可在线阅读,更多相关《C程序设计第6章.ppt(68页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第第6章章 指针指针第第1章章 C语言概述语言概述第第2章章 基本数据类型和运算基本数据类型和运算第第3章章 结构化程序设计结构化程序设计第第5章章 函数函数第第6章章 指针指针第第7章章 复合结构类型复合结构类型第第8章章 编译预处理编译预处理第第4章章 数组及字符串数组及字符串 课程概述课程概述 附录附录6.1 指针的基本概念指针的基本概念6.2 指针变量的运算指针变量的运算6.3 指向数组元素的指针指向数组元素的指针6.4 指向多维数组的指针变量指向多维数组的指针变量6.5 指向字符串的指针变量指向字符串的指针变量6.6指针型函数指针型函数6.7指针数组指针数组6.8二级指针二级指针6.
2、9程序举例程序举例6.10用指针进行内存动态分配用指针进行内存动态分配6.11指针数据类型的总结指针数据类型的总结 第第9章章 位运算位运算第第10章章 文件文件指针指针第第6章章教学目标教学目标掌握指针的概念和运算规则掌握指针的概念和运算规则掌握用指针访问变量、一维数组和二维数组掌握用指针访问变量、一维数组和二维数组用指针处理字符串的方法用指针处理字符串的方法6.1.1 指针和指针变量指针和指针变量6.1 指针的基本概念指针的基本概念1.指针的概念指针的概念 2.指针变量指针变量内内存存单单元元的的编编号号叫叫做做地地址址,通通常常也也把把这这个个地地址址称称为为“指指针针”。6.1.1 指
3、针和指针变量指针和指针变量6.1 指针的基本概念指针的基本概念1.指针的概念指针的概念 2.指针变量指针变量在在语语言言中中,允允许许用用一一个个变变量量来来存存放放指指针针,这这种种变变量量称称为为“指针变量指针变量”。6.1.2 指针变量的定义指针变量的定义1.定义的一般格式定义的一般格式 2.举例说明举例说明6.1 指针的基本概念指针的基本概念存储类型存储类型 类型说明符类型说明符*变量名变量名;其中,其中,“*”表示这是一个指针变表示这是一个指针变量,变量名即为定义的指针变量名,量,变量名即为定义的指针变量名,类型说明符表示本指针变量所指向类型说明符表示本指针变量所指向的变量的数据类型
4、。的变量的数据类型。一个指针变量只能指向同一种类一个指针变量只能指向同一种类型的变量,也就是说,不能定义一型的变量,也就是说,不能定义一个既指向一个整型变量又指向一个个既指向一个整型变量又指向一个双精度型变量的指针变量。双精度型变量的指针变量。6.1.2 指针变量的定义指针变量的定义1.定义的一般格式定义的一般格式 2.举例说明举例说明6.1 指针的基本概念指针的基本概念例如:例如:int*m1;表示表示m1是一个指针变量,它的值是是一个指针变量,它的值是某个整型变量的地址;或者说某个整型变量的地址;或者说m1指指向一个整型变量。至于向一个整型变量。至于m1究竟指向究竟指向哪一个整型变量,应该
5、由指向哪一个整型变量,应该由指向m1赋赋予的地址来决定。予的地址来决定。再例如:再例如:static int*m2;/*m2是指向静态是指向静态整型变量的指针变量整型变量的指针变量*/float*m3;/*m3是指向浮点型变是指向浮点型变量的指针变量量的指针变量*/char*m4;/*m4是指向字符型变是指向字符型变量的指针变量量的指针变量*/6.1.3 指针变量赋值指针变量赋值1.变量地址表示方法变量地址表示方法 2.给指针变量赋给指针变量赋地址的方法地址的方法语言提供了地址运算符语言提供了地址运算符“&”,表示变量地址的一般,表示变量地址的一般形式为:形式为:&变量名变量名;如:如:&a表
6、示变量表示变量a的地址,的地址,&b表示变量表示变量b的地址。的地址。6.1 指针的基本概念指针的基本概念3.例例6.16.1.3 指针变量赋值指针变量赋值1.变量地址表示方法变量地址表示方法(1)指针变量初始化的方法。)指针变量初始化的方法。int a;/*定义整型变量定义整型变量a*/int*p=&a;/*定义指针定义指针p,并将变量并将变量a的地址赋给指针的地址赋给指针p*/(2)赋值语句的方法。)赋值语句的方法。int a;/*定义整型变量定义整型变量a*/int*p;/*定义指针定义指针p*/p=&a;/*将变量将变量a的地址的地址赋给指针赋给指针p*/6.1 指针的基本概念指针的基
7、本概念2.给指针变量赋给指针变量赋地址的方法地址的方法3.例例6.16.1.3 指针变量赋值指针变量赋值1.变量地址表示方法变量地址表示方法【例例6.1】用指针变量访问变量中的数用指针变量访问变量中的数据。据。#includemain()int a,*p;/*定义整型变量定义整型变量a和整和整型变量指针型变量指针p*/p=&a;/*指针指针p指向变量指向变量a*/printf(please enter a number:n,*p);scanf(%d,p);/*为指针为指针p所指所指的存储单元输入数值的存储单元输入数值*/printf(%dn,*p);/*输出指针输出指针p所指的存储单元的内容所
8、指的存储单元的内容*/6.1 指针的基本概念指针的基本概念2.给指针变量赋给指针变量赋地址的方法地址的方法3.例例6.11501000ap10001001200020012.取内容运算符取内容运算符*3.注意事项注意事项取地址运算符取地址运算符“&”是单目运算符,是单目运算符,其结合性为自右至左,功能是取变其结合性为自右至左,功能是取变量的地址。量的地址。在在scanf函数中,我们已经认识并使函数中,我们已经认识并使用了用了&运算符。运算符。1.取地址运算符取地址运算符&6.2.1 指针运算符指针运算符6.2 指针变量的运算指针变量的运算2.取内容运算符取内容运算符*3.注意事项注意事项取内容
9、运算符取内容运算符“*”是单目运算符,其结是单目运算符,其结合性为自右至左,通过合性为自右至左,通过“*”可以存取指可以存取指针所指的存储单元的内容。针所指的存储单元的内容。在在“*”运算符之后跟的变量必须是指针运算符之后跟的变量必须是指针变量。变量。需要注意的是指针运算符需要注意的是指针运算符“*”和指针变和指针变量说明中的指针说明符量说明中的指针说明符“*”不是一回事。不是一回事。在指针变量说明中,在指针变量说明中,“*”是类型说明符,是类型说明符,表示其后的变量是指针类型。而表达式中表示其后的变量是指针类型。而表达式中出现的出现的“*”则是一个运算符,用以表示则是一个运算符,用以表示指针
10、变量所指的内容。指针变量所指的内容。1.取地址运算符取地址运算符&6.2.1 指针运算符指针运算符6.2 指针变量的运算指针变量的运算2.取内容运算符取内容运算符*3.注意事项注意事项【例例6.2】分析下面程序的运行结果。分析下面程序的运行结果。#includemain()int d,x,*p;/*定义整型变量定义整型变量d、x和和整型指针整型指针p*/d=10;x=19;p=&x;/*将变量将变量x的地址赋给指针的地址赋给指针p*/printf(d=%dn,*p);1.取地址运算符取地址运算符&6.2.1 指针运算符指针运算符6.2 指针变量的运算指针变量的运算程序的运行结果如下:程序的运行
11、结果如下:d=192.取内容运算符取内容运算符*3.注意事项注意事项(1)取地址运算符)取地址运算符&表示变量的地址;而表示变量的地址;而取内容运算符取内容运算符*表示指针所指的内容。表示指针所指的内容。(2)运算符)运算符&只能用于变量和数组元素。只能用于变量和数组元素。(3)*和和&都是单目运算符,两者的优先级都是单目运算符,两者的优先级相同,结合性均是从右到左相同,结合性均是从右到左。(4)&x不能出现在赋值号的左边。不能出现在赋值号的左边。(5),因此不能用),因此不能用&取寄存器变量的地址。取寄存器变量的地址。(6)被赋值的指针变量前不能再加)被赋值的指针变量前不能再加“*”说明说明
12、符,如写为符,如写为*p=&a 也是错误的。也是错误的。1.取地址运算符取地址运算符&6.2.1 指针运算符指针运算符6.2 指针变量的运算指针变量的运算2.取内容运算符取内容运算符*3.注意事项注意事项【例例6.3】通过指针变量访问字符型变量。通过指针变量访问字符型变量。#includemain()char ch1,ch2;/*定义字符型变量定义字符型变量ch1和和ch2*/char*p1,*p2;/*定义字符型指针定义字符型指针p1和和p2*/ch1=A;ch2=B;p1=&ch1;/*指针指针p1指向变量指向变量ch1*/p2=&ch2;/*指针指针p2指向变量指向变量ch2*/prin
13、tf(%c,%cn,ch1,ch2);/*输出变量输出变量ch1和变量和变量ch2的内容的内容*/printf(%c,%c,*p1,*p2);/*输出指针输出指针p1和和p2所指的存储单元的内容所指的存储单元的内容*/1.取地址运算符取地址运算符&6.2.1 指针运算符指针运算符6.2 指针变量的运算指针变量的运算程序的运行结果为:程序的运行结果为:A,BA,B&ch1&ch2P1P2ch1ch2(a)p1与与ch1之间的关系之间的关系(b)p2与与ch2之间的关系之间的关系2.指针中加减运算指针中加减运算3.指针变量的关系运算指针变量的关系运算(1)指针变量初始化赋值时,不要)指针变量初始化
14、赋值时,不要将一个内存地址常量赋给一指针变量。将一个内存地址常量赋给一指针变量。例如:例如:int i=100,x;int*m;:m=&i;1.赋值运算赋值运算6.2.2 指针变量的运算指针变量的运算6.2 指针变量的运算指针变量的运算4.两指针变量相减两指针变量相减2.指针中加减运算指针中加减运算3.指针变量的关系运算指针变量的关系运算(2)指针变量和一般变量一样,存放在)指针变量和一般变量一样,存放在其中的值是可以改变的,也就是说可以改其中的值是可以改变的,也就是说可以改变指针变量的指向,例如:变指针变量的指向,例如:int i,j;int*p1;int*p2;i=c;j=d;p1=&i;
15、p2=&j;上面的程序语句也可以用下面的图来说明。上面的程序语句也可以用下面的图来说明。1.赋值运算赋值运算6.2.2 指针变量的运算指针变量的运算6.2 指针变量的运算指针变量的运算赋值运算结果赋值运算结果4.两指针变量相减两指针变量相减2.指针中加减运算指针中加减运算3.指针变量的关系运算指针变量的关系运算如果此时有如下的赋值表达式:如果此时有如下的赋值表达式:p2=p1;则指针变量则指针变量p2与与p1就指向了同一个对象就指向了同一个对象i,此时的,此时的*p2就等价于就等价于i,而不再是,而不再是j了,这了,这种情况可以用如下的图来说明。种情况可以用如下的图来说明。1.赋值运算赋值运算
16、6.2.2 指针变量的运算指针变量的运算6.2 指针变量的运算指针变量的运算p2=p1时的情形时的情形P1P24.两指针变量相减两指针变量相减2.指针中加减运算指针中加减运算3.指针变量的关系运算指针变量的关系运算再例如,如果执行如下的表达式:再例如,如果执行如下的表达式:*p2=*p1;则此时表示把则此时表示把p1指向的内容赋给指向的内容赋给p2所指的所指的区域,此时可用下图来表示情形。区域,此时可用下图来表示情形。1.赋值运算赋值运算6.2.2 指针变量的运算指针变量的运算6.2 指针变量的运算指针变量的运算*p2=*p1时的情形时的情形P1P24.两指针变量相减两指针变量相减2.指针中加
17、减运算指针中加减运算3.指针变量的关系运算指针变量的关系运算(3)如果需要,也可以把数组的首地址)如果需要,也可以把数组的首地址赋予指向数组的指针变量。赋予指向数组的指针变量。例如:例如:int a8,*pa;pa=a;也可写为:也可写为:pa=&a0;也可采取如下初始化赋值的方法:也可采取如下初始化赋值的方法:int a8,*pa=a;1.赋值运算赋值运算6.2.2 指针变量的运算指针变量的运算6.2 指针变量的运算指针变量的运算4.两指针变量相减两指针变量相减2.指针中加减运算指针中加减运算3.指针变量的关系运算指针变量的关系运算(4)可以把字符串的首地址赋给指向字)可以把字符串的首地址赋
18、给指向字符类型的指针变量。符类型的指针变量。例如,把字符串例如,把字符串“Hello human”赋给指针赋给指针变量变量p,方法如下:,方法如下:char*p;p=Hello human;或用初始化赋值的方法写为:或用初始化赋值的方法写为:char*p=Hello human;1.赋值运算赋值运算6.2.2 指针变量的运算指针变量的运算6.2 指针变量的运算指针变量的运算4.两指针变量相减两指针变量相减2.指针中加减运算指针中加减运算3.指针变量的关系运算指针变量的关系运算对于指向数组的指针变量,可以给其加对于指向数组的指针变量,可以给其加上或减去一个整数上或减去一个整数n。例如,设例如,设
19、p是指向数组是指向数组m的指针变量,则的指针变量,则p+n,p-n,p+,+p,p-,-p都是合法都是合法的运算表达式。的运算表达式。给指针变量加上或减去一个整数给指针变量加上或减去一个整数n表示表示把指针指向的当前位置(指向某数组元素)把指针指向的当前位置(指向某数组元素)向前或向后移动向前或向后移动n个位置。个位置。1.赋值运算赋值运算6.2.2 指针变量的运算指针变量的运算6.2 指针变量的运算指针变量的运算4.两指针变量相减两指针变量相减2.指针中加减运算指针中加减运算3.指针变量的关系运算指针变量的关系运算指向同一数组的两个指针变量进行关系指向同一数组的两个指针变量进行关系运算可表示
20、它们所指数组元素之间的关系。运算可表示它们所指数组元素之间的关系。例如:例如:p1=p2;/*表示表示p1和和p2指向同一数组元指向同一数组元素素*/p1p2;/*表示表示p1处于高地址位置处于高地址位置*/p1y)/*三个数进行大小比较三个数进行大小比较*/max=&x;min=&y;elsemax=&y;min=&x;if(z*max)max=&z;if(z*min)min=&z;printf(the max is:%dnthe min is:%dn,*max,*min);1.赋值运算赋值运算6.2.2 指针变量的运算指针变量的运算6.2 指针变量的运算指针变量的运算该程序的运行结果如下:
21、该程序的运行结果如下:please input three numbers:23 34 65 the max is:65the min is:232.指针中加减运算指针中加减运算4.两指针变量相减两指针变量相减两指针变量也可以进行相减运算,其所两指针变量也可以进行相减运算,其所得之差是:两个指针所指的数组元素之间得之差是:两个指针所指的数组元素之间相差的元素个数,实际上是两个指针值相差的元素个数,实际上是两个指针值(地址)相减之差再除以该数组元素的长(地址)相减之差再除以该数组元素的长度(字节数度(字节数)。)。例如:例如:p1和和p2 是指向同一整型数组的是指向同一整型数组的两个指针变量,设
22、两个指针变量,设p1的值为的值为1100H,p2的的值为值为1050H,由于整型数组每个元素占,由于整型数组每个元素占2个个字节,所以字节,所以p1-p2的结果为的结果为(1100H-1050H)/2=25,因此,因此“p1-p2”表示表示p1和和 p2之之间相差间相差25个元素。个元素。但是,但是,p1和和p2不能进行加法运算,因为不能进行加法运算,因为指针变量相加是毫无意义的。指针变量相加是毫无意义的。1.赋值运算赋值运算6.2.2 指针变量的运算指针变量的运算6.2 指针变量的运算指针变量的运算3.指针变量的关系运算指针变量的关系运算2.数组指针变数组指针变量的说明量的说明3.数组名和数
23、组指数组名和数组指针变量作函数参数针变量作函数参数第一,一个数组是由连续的一块内存单元组成的。第一,一个数组是由连续的一块内存单元组成的。其中的数组名就是这块连续内存单元的首地址。其中的数组名就是这块连续内存单元的首地址。第二,一个数组也是由各个数组元素组成的。第二,一个数组也是由各个数组元素组成的。第三,数组元素的首地址也是指它所占有的几个第三,数组元素的首地址也是指它所占有的几个内存单元的首地址。内存单元的首地址。1.几个数组指几个数组指针变量的关系针变量的关系6.3 指向数组元素的指针指向数组元素的指针2.数组指针变数组指针变量的说明量的说明3.数组名和数组指数组名和数组指针变量作函数参
24、数针变量作函数参数数组指针变量说明的一般形式为:数组指针变量说明的一般形式为:类型说明符类型说明符*指针变量名指针变量名;其中,其中,“类型说明符类型说明符”表示指针变量所指表示指针变量所指数组的类型;数组的类型;“*”表示其后的变量是指针表示其后的变量是指针变量。变量。用数组指针变量访问数组元素有两种方法:用数组指针变量访问数组元素有两种方法:第一种方法为下标法,即用第一种方法为下标法,即用mi形式访问数形式访问数组元素。组元素。第二种方法为指针法,即采用第二种方法为指针法,即采用*(pm+i)形式,形式,该方法是用间接访问的方法来访问数组元该方法是用间接访问的方法来访问数组元素。素。1.几
25、个数组指几个数组指针变量的关系针变量的关系6.3 指向数组元素的指针指向数组元素的指针2.数组指针变数组指针变量的说明量的说明3.数组名和数组指数组名和数组指针变量作函数参数针变量作函数参数【例例6.6】采用指针法访问数组元素。采用指针法访问数组元素。#includemain()int m5,i,*pm;pm=m;for(i=0;i5;i+)*pm=i;pm+;pm=m;for(i=0;i5;i+)printf(m%d=%dn,i,*pm);pm+;1.几个数组指几个数组指针变量的关系针变量的关系6.3 指向数组元素的指针指向数组元素的指针该程序的运行结果如下:该程序的运行结果如下:m0=0m
26、1=1m2=2m3=3m4=42.数组指针变数组指针变量的说明量的说明3.数组名和数组指数组名和数组指针变量作函数参数针变量作函数参数【例【例6.7】与例】与例6.6的本意相同,但是其实现的本意相同,但是其实现方式不同。方式不同。#includemain()int m5,i,*pm=m;for(i=0;i5;)*pm=i;printf(m%d=%dn,i+,*pm+);1.几个数组指几个数组指针变量的关系针变量的关系6.3 指向数组元素的指针指向数组元素的指针该程序的运行结果如下:该程序的运行结果如下:m0=0m1=1m2=2m3=3m4=42.数组指针变数组指针变量的说明量的说明3.数组名和
27、数组指数组名和数组指针变量作函数参数针变量作函数参数数组名是数组的首地址,实参向形参传送数组名是数组的首地址,实参向形参传送数组名实际上就是传送数组的地址,形参数组名实际上就是传送数组的地址,形参得到该地址后也指向同一数组得到该地址后也指向同一数组。指针变量的值也是地址,数组指针变量的指针变量的值也是地址,数组指针变量的值即为数组的首地址,也可作为函数的参值即为数组的首地址,也可作为函数的参数使用数使用。1.几个数组指几个数组指针变量的关系针变量的关系6.3 指向数组元素的指针指向数组元素的指针2.数组指针变数组指针变量的说明量的说明3.数组名和数组指数组名和数组指针变量作函数参数针变量作函数
28、参数【例例6.8】编写求五门课程平均成绩的函编写求五门课程平均成绩的函数,并编写主函数调用该函数。数,并编写主函数调用该函数。下图所示为对应的下图所示为对应的N-S流程图。流程图。1.几个数组指几个数组指针变量的关系针变量的关系6.3 指向数组元素的指针指向数组元素的指针定义浮点型的数组sco5、变量 av 和指针*spsp=scofor(i=0;i5;i+)将5门课程的成绩依次输入到scoi中av=aver(sp)输出平均分av的值main函数的函数的N-S流程图流程图定义浮点型变量 av和 s for(i=0;i5;i+)s=s+*pm+av=s/5返回av的值aver函数的函数的N-S流
29、程图流程图2.数组指针变数组指针变量的说明量的说明3.数组名和数组指数组名和数组指针变量作函数参数针变量作函数参数程序代码如下:程序代码如下:#includefloat aver(float*pm);main()float sco5,av,*sp;int i;sp=sco;printf(n please input 5 scores:n);for(i=0;i5;i+)scanf(%f,&scoi);av=aver(sp);printf(average score is%5.2f,av);float aver(float*pm)/*函数函数aver*/int i;float av,s=0;for
30、(i=0;i5;i+)s=s+*pm+;av=s/5;return av;1.几个数组指几个数组指针变量的关系针变量的关系6.3 指向数组元素的指针指向数组元素的指针程序的运行结果如下:程序的运行结果如下:please input 5 scores:90 45 56 80 100 average score is 74.206.4 指向二维数组的指针变量指向二维数组的指针变量1.二维数组地址二维数组地址的表示方法的表示方法 2.二维数组的指二维数组的指针变量针变量语言允许把一个二维数组分解为多个语言允许把一个二维数组分解为多个一维数组来处理。因此二维数组一维数组来处理。因此二维数组m可分解可分
31、解为三个一维数组,即为三个一维数组,即m0、m1、m2。每个一维数组又含有四个元素。每个一维数组又含有四个元素。例如例如m0数组,含有数组,含有m00、m01、m02、m03四个元素。四个元素。6.4 指向二维数组的指针变量指向二维数组的指针变量1.二维数组地址二维数组地址的表示方法的表示方法 2.二维数组的指二维数组的指针变量针变量【例例6.9】用不同的方式输出同一数组元素的用不同的方式输出同一数组元素的数据值的应用举例。数据值的应用举例。#includemain()int m34=0,1,2,3,4,5,6,7,8,9,10,11;printf(%d,%d,%d,%d,%d,n,m,*m,
32、m0,&m0,&m00);printf(%d,%d,%d,%d,%d,n,m+1,*(m+1),m1,&m1,&m10);printf(%d,%d,%d,%d,%d,n,m+2,*(m+2),m2,&m2,&m20);printf(%d,%dn,m1+1,*(m+1)+1);printf(%d,%dn,*(m1+1),*(*(m+1)+1);其运行结果如下:其运行结果如下:404,404,404,404,404412,412,412,412,412420,420,420,420,420414,4145,56.4 指向二维数组的指针变量指向二维数组的指针变量1.二维数组地址二维数组地址的表示方法
33、的表示方法 2.二维数组的指二维数组的指针变量针变量二维数组指针变量说明的一般形式为二维数组指针变量说明的一般形式为:类型说明符类型说明符(*指针变量名指针变量名)长度长度;其中其中“类型说明符类型说明符”为所指数组的数据类型。为所指数组的数据类型。“*”表示其后的变量是指针类型。表示其后的变量是指针类型。“长度长度”表示二维数组分解为多个一维数组时,一维数表示二维数组分解为多个一维数组时,一维数组的长度,也就是二维数组的列数。组的长度,也就是二维数组的列数。“*(p+i)+j”是二维数组是二维数组i行行j 列的元素的地址,列的元素的地址,而而“*(*(p+i)+j)”则是则是i行行j列元素的
34、值。列元素的值。6.4 指向二维数组的指针变量指向二维数组的指针变量1.二维数组地址二维数组地址的表示方法的表示方法 2.二维数组的指二维数组的指针变量针变量【例例6.10】二维数组指针变量的应用举例。二维数组指针变量的应用举例。main()static int m34=0,1,2,3,4,5,6,7,8,9,10,11;int(*p)4;int i,j;p=m;for(i=0;i3;Ifor(j=0;j4;j+)printf(%3d,*(*(p+i)+j);该程序的运行结果为:该程序的运行结果为:0 1 2 3 4 5 6 7 8 9 10 116.5 指向字符串的指针变量指向字符串的指针变
35、量1.字符串的表字符串的表示形式示形式2.字符串指针变量字符串指针变量与字符数组的区别与字符数组的区别在在C语言中,可以用两种方法访语言中,可以用两种方法访问一个字符串。问一个字符串。(1)第一种:用字符串指针指向)第一种:用字符串指针指向一个字符串。一个字符串。(2)第二种:用字符数组存放一)第二种:用字符数组存放一个字符串,然后输出该字符串。个字符串,然后输出该字符串。6.5 指向字符串的指针变量指向字符串的指针变量1.字符串的表字符串的表示形式示形式2.字符串指针变量字符串指针变量与字符数组的区别与字符数组的区别【例例6.11】编程实现:把一个字符串的内容编程实现:把一个字符串的内容复制
36、到另一个字符串中,要求不能使用复制到另一个字符串中,要求不能使用strcpy函数。函数函数。函数cprstr的形参为两个字符的形参为两个字符指针变量指针变量pm和和pn。其中,。其中,pm指向源字符串,指向源字符串,pn指向目标字符串。这里要注意表达式指向目标字符串。这里要注意表达式“(*pn=*pm)!=0”的用法。的用法。程序代码如下:程序代码如下:#includecprstr(char*pm,char*pn)/*定义字符串复定义字符串复制函数制函数cpystr*/while(*pn=*pm)!=0)pn+;pm+;6.5 指向字符串的指针变量指向字符串的指针变量1.字符串的表字符串的表示
37、形式示形式2.字符串指针变量字符串指针变量与字符数组的区别与字符数组的区别main()char*pa=Human,b10,*pb;pb=b;cprstr(pa,pb);/*调用字符串复制函调用字符串复制函数数cpystr*/printf(string_a=%snstring_b=%sn,pa,pb);程序的输出结果为:程序的输出结果为:string_a=Humanstring_b=Human6.5 指向字符串的指针变量指向字符串的指针变量1.字符串的表字符串的表示形式示形式2.字符串指针变量字符串指针变量与字符数组的区别与字符数组的区别简化后的程序如下所示:简化后的程序如下所示:#includ
38、ecprstr(char*pm,char*pn)while(*pn+=*pm+)!=0);main()char*pa=Human,b10,*pb;pb=b;cprstr(pa,pb);printf(string_a=%snstring_b=%sn,pa,pb);程序的输出结果为:程序的输出结果为:string_a=Humanstring_b=Human6.5 指向字符串的指针变量指向字符串的指针变量1.字符串的表字符串的表示形式示形式2.字符串指针变量字符串指针变量与字符数组的区别与字符数组的区别(1)在对字符数组作初始化赋值时,必须)在对字符数组作初始化赋值时,必须采用外部类型或静态类型采用
39、外部类型或静态类型。(2)字符串指针变量本身是一个变量,用)字符串指针变量本身是一个变量,用于存放字符串的首地址。而字符串本身是存于存放字符串的首地址。而字符串本身是存放在以该首地址为首的一块连续的内存空间放在以该首地址为首的一块连续的内存空间中,并以中,并以0作为串的结束。作为串的结束。(3)字符串指针方式可以根据需要灵活使)字符串指针方式可以根据需要灵活使用。例如,对字符串指针方式:用。例如,对字符串指针方式:char*m=Hello Human;可以改写为另一种方式:可以改写为另一种方式:char*m;m=Hello Human;6.6.1 指针型函数的定义方法指针型函数的定义方法1.定
40、义的一般形式定义的一般形式 2.例例6.12 6.6 指针型函数指针型函数类型说明符类型说明符*函数名函数名(形参表形参表)函数体函数体其中函数名之前加了其中函数名之前加了“*”号表明号表明这是一个指针型函数,即返回值这是一个指针型函数,即返回值将是一个指针将是一个指针。类型说明符表示了返回的指针值类型说明符表示了返回的指针值所指向的数据类型所指向的数据类型。6.6.1 指针型函数的定义方法指针型函数的定义方法1.定义的一般形式定义的一般形式 2.例例6.12 6.6 指针型函数指针型函数【例例6.12】使用指针函数编写程序,实使用指针函数编写程序,实现求两个数中的较大者。现求两个数中的较大者
41、。#includeint*max(int a,int b)int*p;if(ab)p=&a;elsep=&b;return p;main()printf(max=%d,*(max(12,56);6.6.2 函数指针变量函数指针变量1.一般形式一般形式 2.例例6.13 6.6 指针型函数指针型函数类型说明符类型说明符(*指针变量名指针变量名)();上面就是函数指针变量定义的上面就是函数指针变量定义的一般形式,其中一般形式,其中“类型说明符类型说明符”表表示被指函数的返回值的类型示被指函数的返回值的类型。“(*指针变量名指针变量名)”表示表示“*”后面后面的变量是定义的指针变量。最后的变量是定义
42、的指针变量。最后的空括号表示指针变量所指的是的空括号表示指针变量所指的是一个函数。例如一个函数。例如:int(*f1)();表示表示f1是一个指向函数入口的是一个指向函数入口的指针变量,该函数的返回值是整指针变量,该函数的返回值是整型。型。3.几点注意事项几点注意事项 6.6.2 函数指针变量函数指针变量1.一般形式一般形式 2.例例6.13 6.6 指针型函数指针型函数【例例6.13】编程实现:求两个整数中的编程实现:求两个整数中的较小者,在程序中使用指针形式实现较小者,在程序中使用指针形式实现对函数的调用。对函数的调用。#includeint min(int a,int b)if(ab)r
43、eturn a;else return b;main()int min(int a,int b);int(*pmin)();int x,y,z;pmin=min;printf(please input two numbers:n);scanf(%d%d,&x,&y);z=(*pmin)(x,y);printf(min_number=%d,z);程序的运行情况为:程序的运行情况为:please input two numbers:35 23 min_number=233.几点注意事项几点注意事项 6.6.2 函数指针变量函数指针变量1.一般形式一般形式 2.例例6.13 6.6 指针型函数指针型
44、函数(1)函数调用中)函数调用中“(*指针变量名指针变量名)”两边两边的括号不可少,其中的的括号不可少,其中的“*”不应该理解不应该理解为求值运算,在此处它只是一种表示符为求值运算,在此处它只是一种表示符号。号。(2)不能让函数指针变量参与算术运)不能让函数指针变量参与算术运算,这是与数组指针变量不同的。算,这是与数组指针变量不同的。应该特别注意的是:应该特别注意的是:函数指针变量和指函数指针变量和指针型函数这两者在写法和意义上是有区针型函数这两者在写法和意义上是有区别的。例如,别的。例如,float(*p)()和和float*p()是两是两个完全不同的概念,个完全不同的概念,3.几点注意事项
45、几点注意事项 6.7 指针数组指针数组1.指针数组的定义指针数组的定义2.指针数组中的字指针数组中的字符串符串指针数组定义的一般形式为:指针数组定义的一般形式为:类型说明符类型说明符 *数组名数组名数组长度说明数组长度说明 例如:例如:int*p3;定义了一个有三个元素定义了一个有三个元素的指针数组,每个数组元素(指针变量)的指针数组,每个数组元素(指针变量)都可以指向一个整型变量。都可以指向一个整型变量。6.7 指针数组指针数组1.指针数组的定义指针数组的定义2.指针数组中的字指针数组中的字符串符串【例例6.14】指针数组应用举例。指针数组应用举例。int m33=1,2,3,4,5,6,7
46、,8,9;int*pm3=m0,m1,m2;int*p=m0;main()int i;for(i=0;i3;i+)printf(%d,%d,%dn,mi2-i,*mi,*(*(m+i)+i);for(i=0;i3;i+)printf(%d,%d,%dn,*pmi,pi,*(p+i);该程序的运行结该程序的运行结果如下:果如下:3,1,15,4,57,7,91,1,14,2,27,3,36.7 指针数组指针数组1.指针数组的定义指针数组的定义2.指针数组中的字指针数组中的字符串符串指针数组也常用来表示一组字符串,指针数组也常用来表示一组字符串,这时指针数组的每个元素被赋予一个这时指针数组的每个元
47、素被赋予一个字符串的首地址。指向字符串的指针字符串的首地址。指向字符串的指针数组的初始化更为简单数组的初始化更为简单。例如,采用指针数组来表示一组字符例如,采用指针数组来表示一组字符串,其初始化赋值如下串,其初始化赋值如下:char*p=Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday;完成这个初始化赋值之后,完成这个初始化赋值之后,p0即指即指向字符串向字符串“Monday”,p6指向指向“Sunday”。6.8.1 一级指针和二级指针的概念一级指针和二级指针的概念6.8 二级指针二级指针一级指针是直接指向数据对象的指针,即其中
48、存放的一级指针是直接指向数据对象的指针,即其中存放的是数据对象,如变量或数组元素的地址是数据对象,如变量或数组元素的地址。二级指针是指向指针的指针,二级指针并不直接指向二级指针是指向指针的指针,二级指针并不直接指向数据对象,而是指向一级指针的指针,也就是说,二级数据对象,而是指向一级指针的指针,也就是说,二级指针中存放的是一级指针的地址指针中存放的是一级指针的地址。下图下图所示是一级指针和二级指针的示意图所示是一级指针和二级指针的示意图。地址值指针变量(a)一级指针)一级指针值地址地址二级指针一级指针变量(b)二级指针)二级指针一级指针和二级指针的示意图一级指针和二级指针的示意图6.8.2 二
49、级指针的定义二级指针的定义6.8 二级指针二级指针二级指针的定义格式为二级指针的定义格式为:存储类型存储类型 数据类型数据类型 *指针名指针名;其中,指针名前面有两个其中,指针名前面有两个*,表示是一个二级指针。表示是一个二级指针。例如,有以下定义例如,有以下定义:int a,*pa,*pb;pa=&a;pb=&pa;则指针则指针pa存放变量存放变量a的地址,即指向了变量的地址,即指向了变量a,指针,指针pb存放一级指针存放一级指针pa的地址,即指向了的地址,即指向了pa。因此,因此,pa是一级指针,是一级指针,pb是二级指针是二级指针。6.8.3 二级指针的使用二级指针的使用6.8 二级指针
50、二级指针一般情况下,二级指针必须与一级指针联合使用才有一般情况下,二级指针必须与一级指针联合使用才有意义,不能将二级指针直接指向数据对象。意义,不能将二级指针直接指向数据对象。【例【例6.15】用二级指针访问二维数组。】用二级指针访问二维数组。如果有如下定义:如果有如下定义:int a34;int*p3,*pp;p0=a0;p1=a1;p2=a2;pp=p;6.8 二级指针二级指针可以编制用二级指针访问二维数组的程序如下:可以编制用二级指针访问二维数组的程序如下:#include main()static int a34;static int*p3,*pp;int i,j;p0=a0;p1=a