谭浩强版C程序设计第6章指针.ppt

上传人:wj 文档编号:30871498 上传时间:2024-09-13 格式:PPT 页数:60 大小:302.54KB
下载 相关 举报
谭浩强版C程序设计第6章指针.ppt_第1页
第1页 / 共60页
谭浩强版C程序设计第6章指针.ppt_第2页
第2页 / 共60页
谭浩强版C程序设计第6章指针.ppt_第3页
第3页 / 共60页
谭浩强版C程序设计第6章指针.ppt_第4页
第4页 / 共60页
谭浩强版C程序设计第6章指针.ppt_第5页
第5页 / 共60页
点击查看更多>>
下载资源
资源描述

谭浩强版C程序设计第6章指针.ppt

《谭浩强版C程序设计第6章指针.ppt》由会员分享,可在线阅读,更多相关《谭浩强版C程序设计第6章指针.ppt(60页珍藏版)》请在冰豆网上搜索。

谭浩强版C程序设计第6章指针.ppt

第第6章章指针指针本章要点本章要点n指针的概念指针的概念n数组与指针数组与指针n字符串与指针字符串与指针n函数与指针函数与指针n指针数组和指向指针的指针指针数组和指向指针的指针n引用引用6.1指针的概念指针的概念1.内存地址内存地址计算机的内存储器被划分成一个个的计算机的内存储器被划分成一个个的存储单元存储单元,这些存储单元按一定的规则这些存储单元按一定的规则编号编号,这个,这个编号编号就是存就是存储单元的储单元的地址地址。

每个存储单元的大小为一个字节,每个单元有每个存储单元的大小为一个字节,每个单元有一个唯一的地址。

一个唯一的地址。

200000002.变量的地址变量的地址在程序中定义的所有变量,都要分配相应的存储在程序中定义的所有变量,都要分配相应的存储单元,不同类型的数据所需要的存储空间的大小不同。

单元,不同类型的数据所需要的存储空间的大小不同。

系统分配给变量的内存空间的起始单元地址称为该系统分配给变量的内存空间的起始单元地址称为该变变量的地址量的地址。

如如:

intI,K;I=3;K=5;000020002004IK353.内存单元的访问方式内存单元的访问方式n在程序中一般通过变量名访问在程序中一般通过变量名访问(存取存取)内存单元内存单元.这种按变量地址存取变量值的方式称为这种按变量地址存取变量值的方式称为直接存直接存取方式取方式,或或直接访问方式直接访问方式.n间接存取间接存取(间接访问间接访问)方式方式是指将变量是指将变量I的的地址存地址存放在另一个变量放在另一个变量J中中,通过变量通过变量J访问变量访问变量I的值的值.2000000020002004200635IKJ4.指针与指针变量指针与指针变量n指针:

指针:

一个变量的一个变量的地址地址也称为该变量的也称为该变量的指针指针。

n指针变量:

指针变量:

用于存储其它变量的指针用于存储其它变量的指针(即地址即地址)的变量。

的变量。

n指针变量的定义:

指针变量的定义:

数据类型数据类型*指针变量名;指针变量名;如:

如:

int*p1;float*p2;char*p3;6.2.指针变量的使用指针变量的使用1.指针变量的赋值指针变量的赋值n通常把被指向的变量的地址赋给指针变通常把被指向的变量的地址赋给指针变量量如:

如:

int*p1,a=3;p1=&a;&:

取地址运算符取地址运算符注意:

注意:

不能用一个整数给一个指针变量赋值不能用一个整数给一个指针变量赋值.一个指针变量只能指向同一个类型的变一个指针变量只能指向同一个类型的变量量.20003p1a20006.2.指针变量的使用指针变量的使用2.指针变量的引用指针变量的引用间接访问指针变量所指向的存储单元间接访问指针变量所指向的存储单元.指针运算符指针运算符(*)如:

如:

int*p1,a=3;p1=&a;inta1;a1=*p1;*p1=5;注意注意:

指针变量必须指向具体内存地址才能引用指针变量必须指向具体内存地址才能引用.如:

如:

int*p;*p=10;20003p1a2000例例通过指针变量存取变量的值通过指针变量存取变量的值#includevoidmain()inta,*p1;doubleb,*p2;charc,*p3;p1=&a;p2=&b;p3=&c;*p1=10;*p2=11.2;*p3=A;coutaendl;coutbendl;coutcendl;程序运行结果为:

程序运行结果为:

1011.2A100x2000ap111.20x2004bp2A0x200Ccp3例例6.2输入输入a和和b两个数,按从小到大的顺序输出两个数,按从小到大的顺序输出#includevoidmain()inta,b;int*p1,*p2,*p;coutab;p1=&a;p2=&b;if(*p1*p2)p=p1;p1=p2;p2=p;coutmin=*p1max=*p2endl;程序运行结果为:

程序运行结果为:

请输入两个整数:

3010min=10max=30&ap1&bp2p30a10b&bp1&ap2&ap30a10b3.指针作为函数的参数指针作为函数的参数指针作为函数的参数,传递的是变量的地址,可以实现指针作为函数的参数,传递的是变量的地址,可以实现地址地址传递传递。

例例6.3指针作为函数参数,被调函数中交换参数值指针作为函数参数,被调函数中交换参数值#includevoidswap(int*x,int*y);voidmain()inta,b;a=10;b=20;swap(&a,&b);couta,bendl;voidswap(int*x,int*y)inttemp;temp=*x;*x=*y;*y=temp;程序运行过程中变量值的变化分析程序运行过程中变量值的变化分析yyb10ax20by&ax&b10temp20ax20by10temp&aax&bb10temp&a&btemp10a20&a&b2010(a)(b)(c)(d)程序运行结果为:

程序运行结果为:

2020,1010比较数值型参数比较数值型参数#includevoidswap(intx,inty);voidmain()inta,b;a=10;b=20;swap(a,b);couta,bendl;10a10x20b20y1020xy10temp2020xy10temp2010xy10tempvoidswap(intx,inty)inttemp;temp=x;x=y;y=temp;注意:

值传递时,函数的实参与形参在内存中占用不同的存储空间,值注意:

值传递时,函数的实参与形参在内存中占用不同的存储空间,值只能由实参传递给形参,而形参的变化并不会影响实参。

只能由实参传递给形参,而形参的变化并不会影响实参。

比较以下函数比较以下函数#includevoidswap(int*x,int*y);voidmain()inta,b;a=10;b=20;swap(&a,&b);couta,bendl;voidswap(int*x,int*y)int*temp;temp=x;x=y;y=temp;voidswap(int*x,int*y)int*temp;*temp=*x;*x=*y;*y=*temp;#1.指针运算指针运算n指针运算包括指针运算包括算术运算算术运算、关系运算关系运算与与赋值赋值运算运算。

n指针可以与整数进行指针可以与整数进行加减运算加减运算,结果,结果与与指针所指向的数据类型指针所指向的数据类型有关。

有关。

p+n表示指针表示指针p当前所指向位置后面第当前所指向位置后面第n个同类型数据的个同类型数据的地址,地址,p-n表示指针表示指针p当前所指向位置前面当前所指向位置前面第第n个同类型数据的地址。

个同类型数据的地址。

6.3指针与数组指针与数组例例指针与整数的加减运算指针与整数的加减运算#includevoidmain()inta,*p1,*p2;doubleb,*p3,*p4;p1=&a;p3=&b;coutp1p3endl;p2=p1+1;/p1+1与与p3+1的含义不同,与指针数据类型有关的含义不同,与指针数据类型有关p4=p3+1;coutp2p4endl;p2=p1-1;/p1-1与与p3-1的含义不同,与指针数据类型有关的含义不同,与指针数据类型有关p4=p3-1;coutp2p4endl;p2=p1+5;p4=p3+5;coutp2p4endl;程序运行结果为:

程序运行结果为:

0x0012FF7C0x0012FF6C0x0012FF800x0012FF740x0012FF780x0012FF640x0012FF900x0012FF94n指向同一种数据类型的指针可以进行关系运算。

指向同一种数据类型的指针可以进行关系运算。

两个相同类型的指针相等,表示这两个指针指向两个相同类型的指针相等,表示这两个指针指向同一个地址。

同一个地址。

n指针也可以与指针也可以与0进行比较运算,如果进行比较运算,如果p=0成立,成立,我们称我们称p是一个是一个空指针空指针,即指针,即指针p还没有具体指向。

还没有具体指向。

n为了避免使用没有指向的指针,在定义指针变量为了避免使用没有指向的指针,在定义指针变量时,可以将其时,可以将其初始化为初始化为0(也可以写成(也可以写成NULL)。

)。

指针的关系运算指针的关系运算例例:

使用空指针使用空指针#includevoidmain()inta,*p=NULL;coutpendl;if(p!

=NULL)*p=10;cout将将10赋值给赋值给p所指向的地址所指向的地址endl;elsecoutp是空指针,不能使用!

是空指针,不能使用!

endl;p=&a;coutpendl;if(p!

=NULL)*p=10;cout将将10赋值给赋值给p所指向的地址所指向的地址endl;elsecoutp是空指针,不能使用!

是空指针,不能使用!

endl;程序运行结果为:

程序运行结果为:

0x00000000p是空指针,不能使用!

0x0012FF7C将10赋值给p所指向的地址n数数组组在在内内存存中中是是连连续续存存放放的的,每每个个数数组组元元素素都都占占用用存存储储单单元元,有有相相应应地地址址,所所以以指指针针可可以以指指向数组元素向数组元素.如如:

inta10,*p;p=&a5;*p,a5含义相同含义相同2.指向数组元素的指针指向数组元素的指针n数数组组名名就就是是数数组组的的首首地地址址(第第一一个个元元素素的的地地址址),指指针针可可以以与与整整数数进进行行加加减减运运算算,利利用用这这一性质可以方便地通过指针引用数组元素。

一性质可以方便地通过指针引用数组元素。

如如:

inta10,*p;则则:

p=a;p=&a0;含义相同含义相同p+ia+i含义相同含义相同*(p+i)*(a+i)ai含义相同含义相同注注:

又称又称变址运算符变址运算符.ai的地址为的地址为:

a+i*dn指向数组元素的指针变量也可带下标指向数组元素的指针变量也可带下标,如如pi.2.指向数组元素的指针指向数组元素的指针例例使用指针输出数组中的所有元素使用指针输出数组中的所有元素#includevoidmain()inta6=1,2,3,4,5,6;int*p;p=a;for(inti=0;i6;i+)cout*p;p+;coutendl;程序运行结果为:

程序运行结果为:

123456123456ap例例6.5输出数组中的全部元素。

输出数组中的全部元素。

n下标法下标法#includeusingnamespacestd;intmain()inta10;inti;for(i=0;iai;coutendl;for(i=0;i10;i+)coutai;coutendl;return0;n用指针变量指向数组元素用指针变量指向数组元素#includeusingnamespacestd;intmain()inta10;inti,*p=a;for(i=0;i*(p+i);/输入输入a0a9coutendl;for(p=a;p(a+10);p+)cout*p;coutendl;return0;比较比较n下标法每次通过变址运算符计算数组下标法每次通过变址运算符计算数组元素的地址元素的地址,指针变量直接指向元素指针变量直接指向元素,不必每次都重新计算地址不必每次都重新计算地址,故效率高故效率高.n但是但是,用下标法比较直观用下标法比较直观,能直接知道能直接知道第几个元素第几个元素.注意注意n指针变量可能指向数组以后的内存单元指针变量可能指向数组以后的内存单元,在使在使用指针变量指向数组元素时用指针变量指向数组元素时,应应切实保证切实保证指向指向数组中有效的元素数组中有效的元素.n注意指针变量自加自减运算及其所指向的元素注意指针变量自加自减运算及其所指向的元素.np+使使p指向下一个元素指向下一个元素n*p+先得到先得到p所指变量值所指变量值,再使再使p加加1.等同于等同于*(p+).n*(+p)先使先使p加加1,再得到再得到p所指变量值所指变量值.n(*p)+表示表示p所指向的所指向的元素值元素值加加1.例例:

指向同一个数组的两个指针的减法运算指向同一个数组的两个指针的减法运算#includevoidmain()inta10=1,2,3,4,5,6,7,8,9,10;int*p1,*p2;p1=a;p2=&a3;coutp2-p1endl;p1=&a2;p2=&a7;coutp2-p1endl;程序运行结果为:

程序运行结果为:

35ap112345678910p2a0a1a2a3a4a5a6a7a8a93.指针作为函数的参数接收数组地址指针作为函数的参数接收数组地址n数组名作为函数的参数实际上传递的是数数组名作为函数的参数实际上传递的是数组的首地址,进行的是组的首地址,进行的是地址传递地址传递,用指针变量用指针变量作函数参数作函数参数,同样可以接收实参传来的数组首同样可以接收实参传来的数组首元素的地址元素的地址。

例例6.6用选择法将用选择法将10个整数按由小到大的顺序个整数按由小到大的顺序排列。

排列。

要求要求:

将形参改为指针变量。

将形参改为指针变量。

函数函数voidselect_sort(int*p,intn)/用指针变量作形参用指针变量作形参inti,j,k,t;for(i=0;in-1;i+)k=i;for(j=i+1;jn;j+)if(*(p+j)*(p+k)k=j;/用指针法访问数组用指针法访问数组t=*(p+k);*(p+k)=*(p+i);*(p+i)=t;#includeusingnamespacestd;voidselect_sort(int*p,intn);intmain()inta10,i;coutentertheoriginlarray:

endl;for(i=0;iai;coutendl;select_sort(a,10);coutthesortedarray:

endl;for(i=0;i10;i+)coutai;coutendl;return0;主程序主程序说明说明n用指针变量作形参用指针变量作形参,接收实参数组名接收实参数组名,和数组名和数组名作形参作形参,本质上是一样的本质上是一样的.C+.C+编译系统将形参编译系统将形参数组名一律作为指针变量处理数组名一律作为指针变量处理.如如:

voidselect_sort(intarray,intn)处理为处理为:

voidselect_sort(int*array,intn)n在函数调用时在函数调用时不存在不存在占有内存空间的占有内存空间的形参数组形参数组,只为指针变量分配空间只为指针变量分配空间,形参数组和实参数组形参数组和实参数组共占同一段内存单元共占同一段内存单元.实参和形参的结合有实参和形参的结合有4种形式种形式实参实参形参形参数组名数组名数组名数组名数组名数组名指针变量指针变量指针变量指针变量数组名数组名指针变量指针变量指针变量指针变量注注:

实参数组名是常量实参数组名是常量,形参数组名是变量形参数组名是变量例例:

编写一个函数,将数组中的元素按照编写一个函数,将数组中的元素按照相反的顺序存放相反的顺序存放分析:

将数组名和元素个数作为函数的参数,可以分析:

将数组名和元素个数作为函数的参数,可以通过地址访问数组中的所有元素。

在函数中将数组通过地址访问数组中的所有元素。

在函数中将数组的第一个元素与最后一个元素交换,第二个元素与的第一个元素与最后一个元素交换,第二个元素与倒数第二个元素交换,一直进行到中间,即完成反倒数第二个元素交换,一直进行到中间,即完成反序存放。

序存放。

源程序源程序#includevoidinv(intx,intn);voidmain()inti,a10=0,1,2,3,4,5,6,7,8,9;cout原数组:

原数组:

endl;for(i=0;i10;i+)coutai;coutendl;inv(a,10);cout交换后的数组:

交换后的数组:

endl;for(i=0;i10;i+)coutai;coutendl;程序运行结果为:

程序运行结果为:

原数组:

0123456789交换后的数组:

9876543210voidinv(intx,intn)inttemp,i,j,m;m=(n-1)/2;for(i=0;i=m;i+)j=n-1-i;temp=xi;xi=xj;xj=temp;注意:

由于传递的是数组地址,因此形参注意:

由于传递的是数组地址,因此形参x和实参和实参a指向相同的内存地址,因此在函数指向相同的内存地址,因此在函数体中对体中对x的操作实际上就是对的操作实际上就是对a的操作的操作注意:

数组名作为函数参数传递的是数组首地址,因此也可以直接将形参改注意:

数组名作为函数参数传递的是数组首地址,因此也可以直接将形参改为指针,当数组名作为实参时,同样能够传递数组首地址。

将函数为指针,当数组名作为实参时,同样能够传递数组首地址。

将函数inv()做以做以下修下修改:

改:

voidinv(int*x,intn)int*i,*j,temp,m;m=(n-1)/2;for(i=x,j=x+n-1;ij;i+,j-)temp=*i;*i=*j;*j=temp;0123456789ixj4.多维数组与指针多维数组与指针

(1)多维数组元素的地址多维数组元素的地址(二维二维)n一个二维数组可以看成元素是一维数组的一一个二维数组可以看成元素是一维数组的一维数组维数组.如如:

inta34=1,3,5,7,9,11,13,15,17,19,21,23可以看成可以看成a是是3个元素的一维数组个元素的一维数组,每个元素又是每个元素又是4个个元素的一维数组元素的一维数组.a2a1a02321191715131197531a由此可见由此可见na指向指向a0(即即a=&a0).(a指向的是一维数组指向的是一维数组,不是二维数组的元素不是二维数组的元素)na+i指向指向ai(即即ai可表示为可表示为*(a+i).na0是首行一维数组名是首行一维数组名,它指向它指向a00(即即a0=&a00)(a0指向的是二维数组元素指向的是二维数组元素).nai+j指向指向ai中的第中的第j个元素个元素aij(即即aij可可表示为表示为*(ai+j)或或*(*(a+i)+j)a2a1a02321191715131197531aa+1a+2

(2)指向多维数组元素的指针变量指向多维数组元素的指针变量n指向数组元素的指针变量指向数组元素的指针变量定义指针变量的基类型为数组元素的类型定义指针变量的基类型为数组元素的类型例例6.7输出二维数组各元素的值。

输出二维数组各元素的值。

#includeusingnamespacestd;intmain()inta34=1,3,5,7,9,11,13,15,17,19,21,23;int*p;/p是基类型为整型的指针变量是基类型为整型的指针变量for(p=a0;pa0+12;p+)cout*p;coutendl;return0;n指向一维数组的指针变量指向一维数组的指针变量一般格式一般格式:

基类型名基类型名(*指针变量名指针变量名)常量表达式常量表达式例例6.8输出二维数组任一行任一列元素的值。

输出二维数组任一行任一列元素的值。

#includeusingnamespacestd;intmain()inta34=1,3,5,7,9,11,13,15,17,19,21,23;int(*p)4,i,j;cinij;p=a;cout*(*(p+i)+j)endl;return0;(3)指向数组元素的指针作函数参数指向数组元素的指针作函数参数n指向一维数组元素的指针作函数参数指向一维数组元素的指针作函数参数,可以接可以接收二维数组名作实参收二维数组名作实参.例例6.9输出二维数组各元素的值。

输出二维数组各元素的值。

#includeusingnamespacestd;intmain()voidoutput(int(*p)4);inta34=1,3,5,7,9,11,13,15,17,19,21,23;output(a);return0;voidoutput(int(*p)4)inti,j;for(i=0;i3;i+)for(j=0;j4;j+)cout*(*(p+i)+j);coutendl;6.4字符串与指针字符串与指针n字符串的访问方字符串的访问方法有法有3种种:

用字符数组用字符数组用字符串变量用字符串变量用字符指针用字符指针例例6.13将字符串将字符串str1复制为字符复制为字符串串tr2。

#includeusingnamespacestd;intmain()charstr1=IloveCHINA!

;charstr220,*p1,*p2;p1=str1;p2=str2;for(;*p1!

=0;p1+,p2+)*p2=*p1;*p2=0;p1=str1;p2=str2;coutstr1is:

p1endl;coutstr2is:

p2endl;return0;6.5函数与指针函数与指针1.用函数指针变量调用函数用函数指针变量调用函数n一个函数在编译时被分配一个入口地址一个函数在编译时被分配一个入口地址,函数名函数名代表函数入口地址代表函数入口地址,函数入口地址称为函数入口地址称为函数的指函数的指针针.n可以用一个指针变量指向函数可以用一个指针变量指向函数.n指向函数的指针变量的指向函数的指针变量的一般定义形式一般定义形式:

函数类型函数类型(*指针变量名指针变量名)(函数形参表函数形参表)例如:

例如:

int(*p)(int,int);就定义了一个函数指针就定义了一个函数指针p,它指向一个返回整型值,它指向一个返回整型值,有两个整型参数的函数。

有两个整型参数的函数。

n函数指针变量的赋值函数指针变量的赋值在在定定义义了了指指向向函函数数的的指指针针变变量量后后,在在使使用用此此函函数数指指针针之之前前,必必须须先先给给它它赋赋值值,使使它它指指向向一一个个函函数数的的入入口口地地址址。

由由于于函函数数名名是是函函数数在在内内存存中中的的首首地地址址,因因此此可可以以赋赋给给函函数数指针变量。

指针变量。

赋值的一般语法格式为:

赋值的一般语法格式为:

函数指针名函数指针名=函数名;函数名;例例如如,对对上上面面刚刚定定义义的的函函数数指指针针p,可可以以给给它它赋赋值值如如下下:

p=func1;其其中中,函函数数名名所所代代表表的的函函数数必必须须是是一一个个已已经经定定义义过过的的,和和函函数数指指针针具具有有相相同同返返回回类类型型的的函函数数。

并并且且等等号号后后面面只只需需写函数名而写函数名而不要写参数不要写参数,例如不要写成下列形式:

,例如不要写成下列形式:

p=func1(a,b);n函数指针变量的使用函数指针变量的使用当函数指针指向某函数以后,可以用下列形式调用函数:

当函数指针指向某函数以后,可以用下列形式调用函数:

(*指针变量)(实参表列)指针变量)(实参表列)例如:

(例如:

(*p)()(a,b),),它相当于它相当于funl(a,b)。

)。

必须指出的是:

指针的运算在这里是无意义的。

因为指必须指出的是:

指针的运算在这里是无意义的。

因为指针指向函数的首地址。

当用指针调用函数时,程序是从针指向函数的首地址。

当用指针调用函数时,程序是从指针所指向的位置开始按程序执行,若进行指针运算,指针所指向的位置开始按程序执行,若进行指针运算,程序的执行就不是从函数的开始位置执行,这就会造成程序的执行就不是从函数的开始位置执行,这就会造成错误。

错误。

例例6.14求和中的大者。

求和中的大者。

#includeusingnamespacestd;intmain()intmax(intx,inty);/函数声明函数声明int(*p)(int,int);/定义指向函数的指针变定义指向函数的指针变量量pinta,b,m;p=max;/使使p指向函数指向函数maxcinab;m=p(a

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 院校资料

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1