版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、void main(void) float s10=90,95,88,70,65,86,74,80,92,84; float aver=ave(s,10); cout“aver=“avern;float ave(float a ,int n) int i; float sum=a0; for (i=1; in; i+) sum=sum+ai; return sum/10;float ave(float *a,int n) int i; float sum=a0; for (i=1; iicini; ; 实际上是按实际上是按将输入将输入放到定义放到定义 i i 单元中。单元中。i2 2、间接访问
2、、间接访问将变量的地址存放在另一个单元将变量的地址存放在另一个单元p p中中,通过,通过 p p 取出取出变量的地址,再针对变量操作。变量的地址,再针对变量操作。i2000H2000H3000Hpp=&i;cin*p;指针的概念指针的概念一个变量的地址称为该变量的指针。一个变量的地址称为该变量的指针。如果在程序中定义了一个变量或数组,那么,这个变如果在程序中定义了一个变量或数组,那么,这个变量或数组的地址(指针)也就确定为一个量或数组的地址(指针)也就确定为一个常量常量。变量的变量的指针指针和指向变量的和指向变量的指针变量指针变量变量的指针就是变量的指针就是变量的地址变量的地址,当变量
3、定义后,其当变量定义后,其指针(地址)是一指针(地址)是一。 int i; &i :2000H 可以可以定义一个变量定义一个变量专门用来专门用来存放存放另一变量的另一变量的地地址址,这种变量称之为,这种变量称之为指针变量指针变量。在编译时同样分配。在编译时同样分配一定字节的存储单元,未赋初值时,该存储单元内的一定字节的存储单元,未赋初值时,该存储单元内的值是值是随机随机的。的。2000Hi7.2.1 指针变量的定义指针变量的定义指针变量定义的一般形式为:指针变量定义的一般形式为:类型标识符类型标识符 * *变量变量名名int *i_point;指针类型指针类型变量名变量名指针指针变量变
4、量同样也可以赋值:同样也可以赋值:int i;int *i_point=&i;3000H i_point2000H i2000H运算符运算符*和指针变量和指针变量一个指针变量只能指向一个指针变量只能指向同一类型同一类型的变量的变量。即整。即整型指针变量只能放整型数据的地址,而不能放型指针变量只能放整型数据的地址,而不能放其它类型数据的地址。其它类型数据的地址。&运算符表示运算符表示“地址地址”。 * * 在在定义语句定义语句中只表示变量的类型是指针,中只表示变量的类型是指针,没有任何其它意义。没有任何其它意义。intint * *p=&ap=&a * * 和指针
5、变量结合表示和指针变量结合表示“指向指向”,表示对指针,表示对指针变量指向的内存单元变量指向的内存单元(变量变量)进行读进行读/写操作写操作。* *p=3 p=3 2000H3000H point*point=5;表示表示指向指向表示表示类型类型i2000H5int i;int *point=&i;指针和指向指针和指向指针变量只能指向和其同类型的变量,指针变量只能指向和其同类型的变量,不能指向其它类型的变量,也不能指向常不能指向其它类型的变量,也不能指向常量和表达式。量和表达式。C+允许将一个常量经允许将一个常量经强制强制类型转换类型转换后赋值给指针变量。后赋值给指针变量。int *p
6、= (int *)0 x2000; /初始化指针变量初始化指针变量p,使其值为,使其值为0 x2000float *f= (float *)100;/初始化指针变量初始化指针变量f,使其值为,使其值为100 如果在定义指针变量时没有初始化,其值如果在定义指针变量时没有初始化,其值是随机的、不确定的(静态存储类型、文是随机的、不确定的(静态存储类型、文件作用域类型的除外件作用域类型的除外,=0)。)。 例例:定义指针变量,使其指向另一个变量。定义指针变量,使其指向另一个变量。 int i, *p;/指针指针p的值是随机的的值是随机的p=&i;/指针赋值,使其指向变量指针赋值,使其指向变量
7、ip p指向不确指向不确定,不能用定,不能用 例:例:通过指针变量,输入通过指针变量,输入/输出数据。输出数据。 #include void main(void) int a, b, *p1, *p2;p1=&a; p2=&b; /指针指针p1指向指向a,p2指向指向bcin*p1*p2; /通过指针为变量通过指针为变量a、b输入输入coutatbendl;/直接输出直接输出a、bcout*p1t*p2ab;/输入输入a、b p1=&a;p2=&b; /p1、p2分别指向分别指向a、b if(ab) p=p1; p1=p2; p2=p; /交换指针交换指针p1与
8、与p2的指向的指向 coutatbendl; cout*p1t*p2endl; bp1p2a&a&b48bp1a&a&b4p28交换前交换前交换后交换后 对于指针变量,系统也为其分配地址,同样可对于指针变量,系统也为其分配地址,同样可以定义一个变量来存放其地址。以定义一个变量来存放其地址。 int x,*p1,*p2; p1=&x; p2=&p1; 二级指针变量的定义和赋初值方法如下:二级指针变量的定义和赋初值方法如下: *=初值初值;p2p1x&p1&x可以缺省可以缺省7.2.3 多级指针多级指针 在在+语言中,把这种指针型变量
9、称为语言中,把这种指针型变量称为“指针的指针指针的指针”,意为这种变量是指向指,意为这种变量是指向指针变量的指针变量,也称针变量的指针变量,也称多级指针多级指针。 通常使用的多级指针是通常使用的多级指针是二级指针二级指针,相对,相对来说,前面介绍的指针变量可以称为来说,前面介绍的指针变量可以称为“一一级指针级指针”。int *ptr=&i, *pptr=&ptr;但是:但是:pptr=&i; pptr=ptr;则:则: *ptr相当于相当于i *ptr=5相当于相当于i=5 *pptr也相当于也相当于i *pptr=8相当于相当于i=8 *pptr相当于相当于ptr *
10、pptr=&i相当于相当于ptr=&i非法非法,基类基类型不符型不符设有:设有:7.3.1 指针与一维数组指针与一维数组 一级指针与一维数组的关系十分密切。一级指针与一维数组的关系十分密切。指向一维数组的指针变量,实际上是指向指向一维数组的指针变量,实际上是指向一维数组元素的指针变量。可以利用指向一维数组元素的指针变量。可以利用指向一维数组的指针变量,完成对数组数据的一维数组的指针变量,完成对数组数据的操作处理。操作处理。int a5,*p,*p1;p=a;p1=&a0p指向指向ap1指向指向a0 int a10, *p; p=&a4; /指针指针p指向数组指向
11、数组a的元素的元素a4 *p=4;/*p=4等同于等同于a4=4 a+; /错误错误,数组名不能赋值数组名不能赋值 p+; /正确正确,p指向指向a5数组名为一常指针,数组名为一常指针,不能赋值和修改不能赋值和修改 说明一个指针变量说明一个指针变量( (注意类型要与数组元素注意类型要与数组元素相同相同) )并使之指向数组的某个元素,则可以使并使之指向数组的某个元素,则可以使用该指针变量来操作数组。用该指针变量来操作数组。 intint a10,b10; a10,b10; intint * *ptraptra, ,* *ptrbptrb; ; ptraptra=&a0; =&a0
12、; ptrbptrb=b; =b; 由于指针使用的灵活性由于指针使用的灵活性, ,可以在一个数组可以在一个数组定义后再用指针对数组进行处理。定义后再用指针对数组进行处理。 例例: :用指针访问数组用指针访问数组.cpp总结总结( (对一维数组对一维数组):):1)1)数组名等同于数组第数组名等同于数组第0 0个元素的地址,也个元素的地址,也就是数组的起始地址就是数组的起始地址, ,相当于一个常指针相当于一个常指针。2)2)指针指向数组的首地址后,其值指针指向数组的首地址后,其值+i+i后指向后指向数组的第数组的第i i个元素。个元素。3)3)指针指向数组指针指向数组a a的首地址后的首地址后,
13、 ,可以用指针代可以用指针代替数组名使用替数组名使用, ,* *(point+i)(point+i)、* *(a+i)(a+i)、aiai、pointipointi、* *aiai、* *pointipointi等同等同, ,都是都是表示一维数组的第表示一维数组的第i i个元素。个元素。 若若pointpoint指向指向a2, a2, *(point+i)表示什么表示什么? 指针变量的运算主要有三种:指针变量的运算主要有三种:赋值赋值运算、运算、算术算术运算和运算和关系关系运算。运算。 1.赋值运算赋值运算 int a, *pa; pa=&a; 把一个变量的地址赋予指向相同数据类型的指
14、把一个变量的地址赋予指向相同数据类型的指针变量。针变量。 int a, *pa=&a, *pb; pb=pa; 相同类型指针赋值,把变量相同类型指针赋值,把变量a的地址赋予指针变的地址赋予指针变量量pb7.3.2 指针的运算指针的运算 同类型指针赋值的含义是什么同类型指针赋值的含义是什么? char *ptr; ptr=I love you!; 把字符串的首地址赋予指针变量把字符串的首地址赋予指针变量 char *str; cin.getline(str);/错误错误 指针变量指针变量str未赋值,指向不确定未赋值,指向不确定 可以对指针变量赋可以对指针变量赋0值。指针变量赋值。指针变
15、量赋0值值后称为后称为空指针空指针,空指针不指向任何地方。,空指针不指向任何地方。 int *p=0; /p不指向任何地方不指向任何地方 或或 int *p=NULL; /p不指向任何地方不指向任何地方NULLNULL相当于相当于0 0指针指针#define NULL 0#define NULL 0 2.指针的算术运算指针的算术运算 int a5, *pa; pa=a; /pa指向数组指向数组a,也就是指向,也就是指向a0 pa=pa+2; /pa指向指向a2,即,即pa的值为的值为&pa2 一般的,在一般的,在指针指向一个数组后指针指向一个数组后,指针加减,指针加减一个整数的算术运算
16、才有实际意义。指针变一个整数的算术运算才有实际意义。指针变量加减一个整数量加减一个整数n的含义是将指针指向的位的含义是将指针指向的位置向前或向后置向前或向后移动移动n个元素个元素。指针偏移指针偏移 一般的,当有了定义一般的,当有了定义“int a10, *p=a; ”后,有:后,有: *(p+1)=2; /p+1为为a1地址地址 *(a+1)=2; /a+1为为a1地址地址 *+p=2; / +p为为a1地址地址 p=p+1; *p=2; /p=p+1与与+p等价等价 a1=2; /直接对数组元素赋值直接对数组元素赋值 p1=2; /指针名作数组名用指针名作数组名用 这些行是等价的,都是使这些
17、行是等价的,都是使a1为为2。 int c=7,b=5,a=3,*p=&a; /设设&a=2000H357a2000Hb2004Hc2008Hp 2000H则有则有( (* *运算符是左结合的运算符是左结合的) ):( (* *p)+;p)+; / /相当于相当于a+a+。表达式为。表达式为3,a=4,p3,a=4,p不变不变 * *p+;p+; / / * *p+p+首先首先* *p p ,然后,然后p=p+1,p=p+1,指针指向指针指向b b, /表达式为表达式为3, p3, p2004H,a2004H,a不变不变 +* *p p / /相当于相当于+(+(* *p)p)
18、,就是,就是* *p=p=* *p+1p+1,即,即a=4a=4 * *+p+p / /相当于相当于* *(+p)(+p),首先:,首先:p=p+1,p=p+1,然后取然后取* *p p。 /即即p p先指向先指向b b,再取,再取b b的内容。表达式为的内容。表达式为5 5, /p p2004H2004H357a2000Hb2004Hc2008Hp 2000H(*p)+、+*p*p+、*+p4p 2004H357a2000Hb2004Hc2008Hp 2000H a 注意进行算术运算的是指针本身还是指针注意进行算术运算的是指针本身还是指针指向的对象指向的对象 两个指针变量之间只能做两个指针变
19、量之间只能做减法减法算术运算。只算术运算。只有有指向同一数组指向同一数组的两个指针变量之间的减法的两个指针变量之间的减法才有意义。两指针相减所得之差是两个指针才有意义。两指针相减所得之差是两个指针所指数组元素之间相差的元素个数。所指数组元素之间相差的元素个数。 指针变量之间的加法和乘除法没有意义指针变量之间的加法和乘除法没有意义 设有:设有:int a10, *p1, *p2; p1=&a2; p2=&a5; 则:则:p2-p1的值为的值为3,就是,就是p2、p1所指数组所指数组元元素下标的差素下标的差。 指向同一数组的两指针变量进行关系运算可指向同一数组的两指针变量进行关系运
20、算可表示它们所指数组元素之间的关系。表示它们所指数组元素之间的关系。设:设:int a10,*p1=&a0,*p2=&a5;则:则:p2p1 值为真,因为值为真,因为p2的值大于的值大于 p1的值。即的值。即&a5&a0 p2=p1 值为假,因为值为假,因为p1和和p2不是不是 指向同一个变量指向同一个变量(值不同值不同) p1!=0 值为真,因为值为真,因为p1指向了指向了 a0,不是空指针。,不是空指针。3.指针的关系运算指针的关系运算 例:例:使用指针处理数组使用指针处理数组 void main(void) int a10, i; int *p; for(
21、i=0;iai; for(p=a;p=a+9; p+ ) cout*pt; p=ap=a使使p p指向数组指向数组a a;a+9a+9为一常指针,指向数为一常指针,指向数组组a a的最后一个元素,的最后一个元素,p=a+9p=a+9表示指针表示指针p p指向指向移动时,不能超出数组最后一个元素。移动时,不能超出数组最后一个元素。 for(p=a;p=a+9; ) cout*p=pe。 过程如下图所示:过程如下图所示:16782345109a0a5 a6 a7a1 a2 a3 a4a9a8pbpe101234567897.3.3 指针与二维数组指针与二维数组 二维数组是二维数组是“数组的数组数组
22、的数组”,即二维数组,即二维数组是由若干个是由若干个一维数组所组成一维数组所组成的。的。二维数组有三种地址:二维数组有三种地址:数组地址数组地址、行地址行地址和和元素地址元素地址。设有定义设有定义“int a34;”,则三种地址为:,则三种地址为: 数组首地址:数组首地址:a 行地址:行地址:a+0、a+1、a+2 元素地址:元素地址:a i 或或a i +j或或&a i j 等等 int a34;/设数组设数组a的首地址是的首地址是2000Ha0a1a22000H2010H2020Ha00 a01 a02 a03a10 a11 a12 a13a20 a21 a22 a23a2000H
23、 2004H 2008H 200CH 数组首地址是数组首地址是2000H2000H,三个行地址分别是,三个行地址分别是2000H2000H、2010H2010H和和2020H2020H,各数组元素地址从,各数组元素地址从2000H2000H到到202CH202CH连续分布。连续分布。 a0、a1、a2为组成二维数组为组成二维数组a a的的3 3个个一维数组名字一维数组名字( (一维数组名是元素指针一维数组名是元素指针) )。 下面分析二维数组名与其所分解成的多下面分析二维数组名与其所分解成的多个一维数组名之间的关系。个一维数组名之间的关系。a=&a0;a=&a0;/0/0行地址
24、行地址, ,& &区分为行地址区分为行地址a0=a0=* *a;a;/0/0行行0 0列元素地址列元素地址, ,* *区分为元素地址区分为元素地址a+i=&ai; a+i=&ai; ai=ai=* *( (a+ia+i););一维数组名是一个元素指针一维数组名是一个元素指针二维数组名是一个行指针二维数组名是一个行指针ai : :表示第表示第i i行第行第0 0列元素的地址列元素的地址a+i : :表示第表示第i i行地址行地址( (偏移偏移i i行行) )&ai:表示第表示第i行地址行地址,&不表示取地址不表示取地址,用来区用来区 分元素地址和行
25、地址分元素地址和行地址.*(a+i):表示第表示第i行第行第0列元素的地址列元素的地址, *不表示不表示 取内容取内容,用来区分元素地址和行地址用来区分元素地址和行地址.元素指针元素指针ai前加前加&转换成行指针转换成行指针 a+i=&ai行指针行指针(a+i)前加前加*转换成元素指针转换成元素指针 *(a+i)=ai 元素指针算术运算是偏移多少元素元素指针算术运算是偏移多少元素行指针算术运算是偏移多少行行指针算术运算是偏移多少行结合指针偏移的概念理解结合指针偏移的概念理解元素指针和行指针是不同的指针元素指针和行指针是不同的指针* *的的4 4种作用种作用: :乘、指针定义、取
26、内容、区分为元素乘、指针定义、取内容、区分为元素地址地址( (运算符运算符&)&)a00=*a0=*(*a);ai0=*ai=*(*(a+i);aij=*(ai+j)=*(*(a+i)+j);&aij=ai+j=*(a+i)+j; 表示形式表示形式含义含义a数组名数组名,起始地址起始地址,0行地址行地址a +0第第0行行起始地址起始地址a0第第0行第行第0列列元素地址元素地址*a,*(a+0)第第0行第行第0列元素地址列元素地址*a,*(a+0),*a0,*(*(a+0)+0)元素元素a00a+i,&ai第第i行起始地址行起始地址a+i+j,&ai+j第
27、第i+j行起始地址行起始地址ai,*(a+i)第第i行第行第0列元素地址列元素地址*(a+i)+j,ai+j,&aij,*&ai+j第第i行第行第j列元素地址列元素地址*(*(a+i)+j),*(ai+j),*(&aij),*(*&ai+j),aij第第i行第行第j列元素列元素aIj二维数组地址和元素的表示法二维数组地址和元素的表示法使用二维数组名、指向运算符和取地址使用二维数组名、指向运算符和取地址运算符,二维数组元素有着多种表示方法,运算符,二维数组元素有着多种表示方法,例如例如(优先级优先级()*): *(a+1)+2=&a12 *(*(a+1)+
28、2)=a12 *(a+1)=*(a1)=*(&a10)=a10 (*(a+1)1 =(a1)1=c1=a11 /c=a1 *(a+1)1=*(a+1)1) =*(c1)=*(&c10)=c10 =a20 /c=a+1,行指针行指针 例例:指针访问二维数组指针访问二维数组.CPP 7.3.4 指针数组指针数组 由由同类型指针同类型指针所组成的数组称为指针数组。或者当某所组成的数组称为指针数组。或者当某个数组被定义为指针类型,就称这样的数组为指针数个数组被定义为指针类型,就称这样的数组为指针数组。组。指针数组的每个元素都是一个指针变量指针数组的每个元素都是一个指针变量。 定义指针数
29、组的一般格式为:定义指针数组的一般格式为: *; 可以给指针数组赋初值,赋初值有多种方式,同普可以给指针数组赋初值,赋初值有多种方式,同普通的数组。通的数组。 定义指针变量时的定义指针变量时的数据类型数据类型可以选取任何基本数可以选取任何基本数据类型,也可以是结构体类型、枚举类型或类类型。据类型,也可以是结构体类型、枚举类型或类类型。 设有:设有:“int a,b,c,*p3=&a,&b,&c; ”,数组名数组名指针个数指针个数初始化地初始化地址址 b a c&a &b &cp 定义一整型数组和指针数组,通过指针数组来输定义一整型数组和指针数组,
30、通过指针数组来输出整型数组。出整型数组。 void main(void) int a=10,20,30,40,50,60;int *p=&a0,&a1,&a2,&a3,&a4,&a5;/初始化指针数组,每个指针数组元素指向一个初始化指针数组,每个指针数组元素指向一个实型数组元素实型数组元素for(int i=0;i6;i+) cout *pi t; / *pi就是就是aicoutendl; 输出结果:输出结果:10 20 30 40 50 6010 20 30 40 50 60void main(void) a5=1,3,5,7,9, *pa5
31、, *p=pa, i; for(i=0;i5;i+) pai=&ai; cout*pt; p+; 97531a&a4&a3&a2&a1&a0papapp=p+1;p=p+1;指向指向papa数组下一个元素数组下一个元素13579p=&pai指针数组的首地址是一个二级指针指针数组的首地址是一个二级指针 例例:指针数组指针数组.cpp 7.3.5 指向二维数组的指针指向二维数组的指针 一维数组名是一个一级指针,二维数组名呢?一维数组名是一个一级指针,二维数组名呢? 二维数组名不能赋值给一级指针和二级指针二维数组名不能赋值给一级指针和二级指针
32、对于一个对于一个m列的二维数组列的二维数组aNM,可以定义一个,可以定义一个指向它的指针:指向它的指针:“int (*p)M; ”。就可以赋值:。就可以赋值:“p=a; ”。这里的指针。这里的指针p称为称为“指向数组的指针指向数组的指针”。 定义指向数组的指针的一般形式为:定义指向数组的指针的一般形式为: (*) 指向二维数组的指针可以用来代替二维数组名指向二维数组的指针可以用来代替二维数组名 使用指向二维数组的指针输出二维数组中的使用指向二维数组的指针输出二维数组中的元素。元素。 void main() int a34=0,1,2,3,4,5,6,7,8,9,10,11; int (*p)4
33、, i, j; p=a; /指针指针p指向二维数组指向二维数组a(起始地址)(起始地址) for(i=0;i3;i+) /使用相对于使用相对于a数组起始地址的偏移量数组起始地址的偏移量 for(j=0;j4;j+) /用指针用指针+偏移量生成临时指针偏移量生成临时指针 cout*(*(p+i)+j)t; /使用行指针使用行指针p+偏移量偏移量 cout*(pi+j)t; /使用列指针使用列指针pi+偏移量偏移量 cout*(*(a+i)+j)t; /使用行指针使用行指针a+偏移量偏移量 cout*(ai+j)n; /使用列指针使用列指针ai+偏移量偏移量 指向二维数组的指针.cpp7.4 指针
34、与函数指针与函数 在在C+中,指针与函数的关系密切而复杂。中,指针与函数的关系密切而复杂。与数组名一样,与数组名一样,函数名函数名也是一个常指针。函数也是一个常指针。函数的的参数参数可以是指针,函数的可以是指针,函数的返回值返回值也可以是指也可以是指针。还可以定义针。还可以定义指向函数指向函数的指针。的指针。 指针作函数参数,形参要求是指针变量,指针作函数参数,形参要求是指针变量,实参要求分为以下几种情况。实参要求分为以下几种情况。 实参为数组名实参为数组名 实参为地址实参为地址 实参为指针实参为指针一、实参用数组名,形参用指针变量一、实参用数组名,形参用指针变量void main(void)
35、 int a 10; . f(a, 10); .f(int *x, int n ) .实参数组实参数组形参指针形参指针7.4.1 指针作为函数参数指针作为函数参数 #define N 10/选择排序选择排序 void sele_sort(int *p) /形参为指针形参为指针,指向实参数组,指向实参数组 int i,j,k,temp;for(i=0;iN-1;i+) k=i; /设左端点元素值最小,记下其下标设左端点元素值最小,记下其下标i for(j=i+1;jN;j+) /与最小元素与最小元素ak比较比较if(pjpk)k=j; /记下较小元素下标记下较小元素下标j if(k!=i) /最
36、小元素和左端点元素交换最小元素和左端点元素交换 temp=pi; pi=pk; pk=temp; 指针名作数组名用指针名作数组名用数组方式排序数组方式排序 void main()int aN,i;cout请输入请输入N个整数:个整数:n;for(i=0;iai;sele_sort(a); /数组名作实参调用排序函数数组名作实参调用排序函数cout排序后的数据为:排序后的数据为:n;for(i=0;iN;i+) /输出排序后的数组输出排序后的数组coutait;coutn; void sele_sort(int *p) /形参为指针形参为指针,指向实参数组,指向实参数组 int temp,*p1
37、,*p2,*p3;for(p1=p;p1p+N-1;p1+) p3=p1; /p3指向左端点,假设这个元素最小指向左端点,假设这个元素最小 for(p2=p1+1;p2p+N;p2+) /p2指向的元素与最小元素比较指向的元素与最小元素比较if(*p2ab; if(ab) swap( &a,&b ); coutatbb) swap( &a,&b ); /主调,传地址主调,传地址 void swap (int *p1,int *p2) /被调被调 通过形参指针,交换实参变量通过形参指针,交换实参变量主调函数主调函数被调函数被调函数ap2p14&b&
38、b&a&ab9三、实参形参均为指针变量三、实参形参均为指针变量void main(void) int a 10,*p; p=a; . f(p, 10); .f(int *x, int n ) .实参指针实参指针形参指针形参指针实参指针变量调用前必须赋值实参指针变量调用前必须赋值接收的是接收的是地址的值地址的值 例:输入例:输入10个整数,将其中最小的数与第一个数对个整数,将其中最小的数与第一个数对换,把最大的数与最后一个数对换。换,把最大的数与最后一个数对换。 void exchang(int *p,int n) /指针作形参指针作形参 int i, j=0, k=0, t;f
39、or(i=0;ipj)j=i; /j为最大值位置为最大值位置 if(pipk)k=i; /k为最小值位置为最小值位置if(k!=0) t=p0; p0=pk; pk=t; /交换最小值和交换最小值和p0if(j!=n-1) t=pn-1; pn-1=pj; pj=t; /交换最大值和交换最大值和pn-1 void main() int a10=4,3,5,7,2,6,1,9,8,0,*pa,i;pa=a;exchang(pa,10);for(i=0;i10;i+)coutait;coutn; 指针在作实参指针在作实参前必须赋值!前必须赋值! 在函数调用时,实参传递给形参的是实参指针的在函数调用
40、时,实参传递给形参的是实参指针的值,为值,为传值方式传值方式。在被调函数中对形参指针的任。在被调函数中对形参指针的任何修改都不会影响实参指针的值何修改都不会影响实参指针的值(但可能影响实参但可能影响实参指针指向的对象指针指向的对象)。调用后,实参指针和形参指针调用后,实参指针和形参指针指向同一对象。指向同一对象。 利用指针作函数参数实现数据的利用指针作函数参数实现数据的双向传递双向传递不是指不是指指针参数本身,而是指指针参数本身,而是指隐藏在指针后面隐藏在指针后面的的指针指指针指向变量向变量,指针参数本身依然是单向传值。,指针参数本身依然是单向传值。 传址本质上还是传值,只是被调函数获得了主调
41、传址本质上还是传值,只是被调函数获得了主调函数中的一个指针。函数中的一个指针。7.4.2 返回值为指针的函数返回值为指针的函数 返回指针值的函数简称为返回指针值的函数简称为指针函数指针函数。 定义指针函数的一般形式为:定义指针函数的一般形式为: *(); 例如例如:int *a(int x,int y);表示返回值表示返回值为指针为指针函数名函数名参数与一般参数与一般函数一样函数一样 使用函数求两个变量的最大值。使用函数求两个变量的最大值。 #include void main() int a, b, * pmax; int *max(int*,int* ); coutab;pmax=max(
42、&a, &b);coutmax=*pmax*b?a:b;return p;/ 返回指针返回指针p p 例:设有一结构体,包含学号、姓名和年龄,例:设有一结构体,包含学号、姓名和年龄,用返回值为指针的函数完成结构体数据输入。用返回值为指针的函数完成结构体数据输入。 分析:本程序应定义一个结构体类型分析:本程序应定义一个结构体类型student,包括三个成员。程序由,包括三个成员。程序由2个函数组个函数组成:输入函数和主函数。成:输入函数和主函数。 student *input(); /输入函数,返回指针输入函数,返回指针; 主函数负责定义变量、调用输入函数,输主函数负责定义变量、
43、调用输入函数,输出结构体变量中的数据。出结构体变量中的数据。 struct student /定义结构体类型定义结构体类型 int num;char name20;int age; stu; /定义结构体变量定义结构体变量stu student *input() /返回值指针指向结构体变量返回值指针指向结构体变量 student *ps=&stu; /结构体指针指向全局变量结构体指针指向全局变量coutps-numps-nameps-age;return ps; /返回的指针不能指向局部变量返回的指针不能指向局部变量 主调函数中要主调函数中要能访问能访问psps指向指向的变量的变量 v
44、oid main() student *p;p=input(); /input返回指针返回指针cout学号:学号:num,姓名:,姓名:name,年龄:,年龄:agen; 函数所返回的指针必须是指向一个在函数所返回的指针必须是指向一个在主主调函数中可以访问的变量调函数中可以访问的变量。不能是指向被。不能是指向被调函数中的局部变量。否则,引用返回的调函数中的局部变量。否则,引用返回的指针就不能得到正确的结果。指针就不能得到正确的结果。7.4.3 指向函数的指针指向函数的指针 函数虽然不是变量,但是它在内存中占有一函数虽然不是变量,但是它在内存中占有一定的空间。函数的首地址就是该函数的入口地址,定
45、的空间。函数的首地址就是该函数的入口地址,它可以赋给指针变量,使得指针变量指向函数,它可以赋给指针变量,使得指针变量指向函数,指向函数的指针简称为指向函数的指针简称为函数指针函数指针。 函数指针可以用如下形式说明:函数指针可以用如下形式说明: (*指针变量名)(指针变量名)();); 例如:例如:int (*p)(int, int); 指向函数,函数要符合条件指向函数,函数要符合条件函数值为函数值为整形指针整形指针函数要有两函数要有两个整形参数个整形参数定义指针定义指针 引用指向函数的指针调用函数完成加法。引用指向函数的指针调用函数完成加法。 int func(int a,int b) ret
46、urn a+b; void main() int (*p)(int a,int b);/该函数返回值为整型,有两个整型参数该函数返回值为整型,有两个整型参数 p=func;/使指针指向函数使指针指向函数 cout(*p)(100,200)n;/调用函数调用函数 程序运行结果:程序运行结果:300指向函数的指针指向函数的指针 指向函数的指针指向的是一种特定函数,指向函数的指针指向的是一种特定函数,引用时,该指针所指向函数的引用时,该指针所指向函数的返回值类型、返回值类型、参数个数、参数类型以及顺序参数个数、参数类型以及顺序,须与定义,须与定义指针时一致。指针时一致。 函数指针可以作为函数的参数函
47、数指针可以作为函数的参数 int f1(int a) /整型函数整型函数f1,要求,要求1个整型实参个整型实参 int f2(int a,int b)/整型函数整型函数f2,要求,要求2个整型实参个整型实参 void func(int (*p1)(int), int (*p2)(int,int) /函数有两个形参,均为指向函数的指针函数有两个形参,均为指向函数的指针 int a, b, i, j; a=(*p1)(i); /调用函数调用函数f1,i作实参作实参 b=(*p2)(i, j); /调用函数调用函数f2,i、j作实参作实参 void main() func(f1, f2) /将函数名
48、将函数名f1,f2传递给传递给func函数函数 函数指针应用函数指针应用 1.求定积分求定积分 2.牛顿切线法求解方程根牛顿切线法求解方程根 7.5 const 指针指针 使用使用const定义的指针称为定义的指针称为常指针常指针(或指针常量),(或指针常量),常指针有三种情况常指针有三种情况: 1一般格式为一般格式为(最常用最常用): const *= const放在放在*左边,表示指针指向的内存的内容不可左边,表示指针指向的内存的内容不可通过指针来修改通过指针来修改! int a, b; const int *p=a; *p=5; /错误,不能通过错误,不能通过p修改修改a的值的值 a=1
49、0; /正确,正确,a可修改可修改 p=&b; /正确正确p可改指可改指 *p=5; /错误错误,不能通过不能通过p修改修改b的值的值 常用作函数参数,禁止在被调函数中修改指针指向常用作函数参数,禁止在被调函数中修改指针指向的对象的对象p为常指针为常指针 第二种第二种const指针,其一般格式为:指针,其一般格式为: * const = 这种类型的指针定义中,这种类型的指针定义中,const在在*和变量名和变量名之间,表示指针变量的指向不可以改变之间,表示指针变量的指向不可以改变! 例如:例如:int num=0,k; int *const p= # /p指向指向num
50、 *p=5; /正确,可以修改正确,可以修改num的值的值 p=&k;/错误,错误,p不能改指向其它变量不能改指向其它变量 第三种第三种const指针,其一般格式为:指针,其一般格式为: const *const = 这种这种const指针是前两种的结合指针是前两种的结合,使得指向的使得指向的内容和地址都不能发生变化。内容和地址都不能发生变化。 例如:例如:double pi = 3.14159; const double *const ptr = π 这时,既不能这时,既不能通过通过ptr修改修改pi的值,也不能改的值,也不能改变常指针变常指针ptr的指向的指向。这种类
51、型的指针较少使。这种类型的指针较少使用。用。 使用使用const将大大改善程序的健壮性。将大大改善程序的健壮性。 另外另外const 的一些强大的功能在于它在函数的一些强大的功能在于它在函数声明中的应用。声明中的应用。在一个函数声明中,在一个函数声明中,const 可以修饰函数的返回值,或某个参数;对于可以修饰函数的返回值,或某个参数;对于类的成员函数,还可以修饰整个函数。类的成员函数,还可以修饰整个函数。 void fun(const char *s1); /s1为常指针为常指针 void fun1( ) const; /类成员函数类成员函数fun1( )为常函数为常函数,不允许在其中修改类
52、的数据成员不允许在其中修改类的数据成员 const int fun2( ); /常返回值常返回值,不能被修改不能被修改7.6 void型指针表示该指针可以指向任意类型的数据表示该指针可以指向任意类型的数据无类型指针无类型指针任何类型的指针都可以赋给它任何类型的指针都可以赋给它若将它赋给其他类型指针若将它赋给其他类型指针,需进行强制类型转换需进行强制类型转换.int a,*pi=&a; void *p1=pi; int *pi2=(int*)p1;不能直接进行算术运算不能直接进行算术运算char pc10;void*p=pc;p+;/ unknown size常用作函数的指针参数,编写通
53、用程序常用作函数的指针参数,编写通用程序7.7 指针与字符串指针与字符串 字符串可以用字符串可以用字符数组字符数组表示。借助字符数表示。借助字符数组和字符串处理函数,可以很好的存储和组和字符串处理函数,可以很好的存储和处理字符串。处理字符串。 存储和处理字符串还可以存储和处理字符串还可以用指针用指针,使用指,使用指针比用字符数组处理字符串更容易。针比用字符数组处理字符串更容易。 用字符指针处理字符串。用字符指针处理字符串。 char *str=“I am a student”; /取内存中字符串常量首地址取内存中字符串常量首地址 coutstrn; str=”I love china!” co
54、utstrn;strI a m a s t u d e n0tI l o v e c h i n a ! 0输出输出:I am a student I love china! 用字符指针处理字符串。用字符指针处理字符串。 char *str=“I am a student”,*p=str; coutstrn; /整体输出整体输出str while(*p) cout*p+; /逐个字符输出逐个字符输出str coutn; for(int i=0;istrlen(str);i+) /输出输出str cout*(str+i); coutn;* *p p代表一个字符代表一个字符*(str+i)代表代表
55、一个字符一个字符StrStr为一串字符,为一串字符,* *p p为一个字符为一个字符0 将字符串将字符串a复制到字符串复制到字符串b。 void main(void) char a =“I am a student”, b20; char *p1=a,*p2=b; while(*p2+=*p1+); /逐字符复制逐字符复制 coutatcoutbendl; I a m a s t u d e n0t p1p2*p2+=*p1+Ia mep1p1p1p1p1p1p1p1p1p1p1p1p1p1p2p2p2p2p2p2p2p2p2p2p2p2p2p2asutdn t 例:输入例:输入5个字符串,从
56、中找出最大的字符个字符串,从中找出最大的字符串并输出。要求用二维字符数组存放这串并输出。要求用二维字符数组存放这5个个字符串,用指针数组元素分别指向这字符串,用指针数组元素分别指向这5个字个字符串,用一个二级指针变量指向这个指针符串,用一个二级指针变量指向这个指针数组。数组。 分析:分析:本例处理的是字符串,需要用本例处理的是字符串,需要用到字符串处理函数中的字符串输入、字符到字符串处理函数中的字符串输入、字符串输出、字符串比较等标准函数。串输出、字符串比较等标准函数。 程序中要含有一行:程序中要含有一行: #include void main()char a580, *p5, *q, *ma
57、x; int i;for(i=0;i5;i+) /pi指向指向a的第的第i行行 pi=ai; /ai是第是第i行的首地址行的首地址for(i=0;i5;i+) cin.getline(pi,80); /输入输入5个字符串存入字符数组个字符串存入字符数组aFortranC+PascalBasicFoxprop0p1p2p3p4a2a1a4a3a0 max=&p0; /设当前最大字符串是字符组中第设当前最大字符串是字符组中第1行行 q=&p1; /让二级指针变量让二级指针变量q指向指针数组第指向指针数组第2行行 for(i=1;i5;i+,q+) if(strcmp(*max,*q
58、)0)max=q; /*如果当前最大字符串小于二级指针如果当前最大字符串小于二级指针q指向指向的指针数组元素指向的字符串的指针数组元素指向的字符串,则重新记录最则重新记录最大字符串大字符串*/ cout*max*q i=2, max=&a0, q=&a2, *max*q i=4, max=&a2, q=&a4, *max*q *max=a2=“Pascal”FortranC+PascalBasicFoxprop0p1p2p3p4a2a1a4a3a0maxqmaxqqq 例:将例:将5个计算机语言名字符串按字母顺序个计算机语言名字符串按字母顺序升序排序并输出。升序
59、排序并输出。 分析:定义一个有分析:定义一个有5个元素的字符个元素的字符指针数组指针数组c,初始化使其指向,初始化使其指向5个字符串。个字符串。 再使用再使用2个个二级字符指针二级字符指针,指向数组,指向数组c的的元素。接下来使用元素。接下来使用“选择排序选择排序”法对其排法对其排序。和对数字数组排序一样。序。和对数字数组排序一样。 void main(void) char *c =Forth,Basic, Java,C+,Pascal; char *temp, *p1, *p2;/二级指针二级指针p1用作外层变量用作外层变量,p2用作内层变量用作内层变量 for(p1=&c0; p1
60、&c4; p1+) for(p2=p1+1; p20) /交换前后指针所指字符串交换前后指针所指字符串 temp=*p1; *p1=*p2; *p2=temp; for(int i=0;i5;i+) coutciendl; 输出结果:输出结果:Basic C+ Forth Java Pascalc0c1c2c3c4ForthBasicJavaC+Pascalc0c1c2c3c4ForthBasicJavaC+Pascal排排序序前前排排序序后后以下程序判断输入的字符串是否以下程序判断输入的字符串是否“回文回文”,若是回文,输出,若是回文,输出YESYES。void main(void)
61、 char s81, *pi, *pj; int n; cin.getline(s); n=strlen(s); pi=s; pj=_; /pi指向串开始,指向串开始,pj指向最后指向最后 while(*pi= ) pi+; /跳过前导空格跳过前导空格 while(*pj= ) _; while( ( _) &(*pi=*pj) ) pi+; _; if( ) cout“NO”endl; else cout“YESn”;pipjs+n-1pj-pj-pit; /设输入为设输入为e fun(st, t); coutstrendl;void fun(char *s, char c) int i=0, j=0; for(; si!=0; i+) if(si!=c) sj+=si; sj=0; return;输出输出:tachr必须以必须以00结束结束teacher0stsijijirjiajiicji0当当si等于字符等于字符c c时,时,i i前进,前进,j j不动不动hjic et et指针形式小结指针形式小结intint i i, * *ipip, f()f(), * *fpfp()(), ( (* *fp
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024高考化学一轮复习第一部分考点18化学能和热能强化训练含解析
- 2024高考化学一轮复习解题指导8物质结构与性质的命题分析规范演练含解析新人教版
- 2024高考历史一轮复习方案专题四世界政治制度的演变与发展第10讲英国代议制和美国1787年宪法教学案+练习人民版
- 2024高考地理一轮复习第二十单元中国地理考法精练含解析
- 红外热像技术检测墙体保温
- 2024年渤海石油职业学院高职单招职业技能测验历年参考题库(频考版)含答案解析
- 技术质量部年终工作总结
- 第一课1法律的基本特征教材课程
- 二零二五年度货运合同标的货物运输与保险责任详细条款2篇
- 2024年陕西省核工业二一五医院高层次卫技人才招聘笔试历年参考题库频考点附带答案
- 英语-辽宁省大连市2024-2025学年高三上学期期末双基测试卷及答案
- 2024年意识形态风险隐患点及应对措施
- 2025版新能源充电桩加盟代理合作协议范本3篇
- 2025年广东省揭阳市揭西县招聘事业单位人员11人历年高频重点提升(共500题)附带答案详解
- 空调年度巡检报告范文
- 静脉输液反应急救流程
- 反诈知识竞赛题库及答案(共286题)
- 2025届江苏省淮安市高三一模语文试题讲评课件
- 儿童保健服务和管理项目可行性研究报告参考模板
- 公路自然灾害防治对策课件
- 耳鸣中医临床路径
评论
0/150
提交评论