版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、7.1 地址和指针的概念地址和指针的概念7.2 指针变量的定义和指针变量的基类型指针变量的定义和指针变量的基类型7.3 给指针变量赋值给指针变量赋值7.4 对指针变量的操作对指针变量的操作7.5 指针在函数方面的应用指针在函数方面的应用使用指针,实现了使用指针,实现了“间接访问间接访问”变量,变量,这只是一个过程,其实质是可以达到方便这只是一个过程,其实质是可以达到方便地引用数组,提高计算机的运行效率,调地引用数组,提高计算机的运行效率,调用函数时可以修改或返回多个参数值,还用函数时可以修改或返回多个参数值,还可以描述更复杂的数据结构,可以描述更复杂的数据结构,为了加为了加深读者对指针重要性的
2、理解,下面我们举深读者对指针重要性的理解,下面我们举一函数调用的实例。一函数调用的实例。例例77.11 欲想调用欲想调用fun函数,计算出两函数,计算出两个数相加和相减的值,然后在个数相加和相减的值,然后在main函数中函数中显示结果。显示结果。程序如下:程序如下:fun ( int x , int y ) int add=0 , sub=0 ; add=x+y ; sub=xy ;main ( ) int a , b , add=0 , sub=0 ; scanf ( %d %d , &a , &b ) ; printf ( a=%d , b=%d n , a , b ) ; fun ( a
3、 , b ) ; printf ( %d + %d =%d n , a , b , add ) ; printf ( %d %d =%d n , a , b , sub ) ;假设程序运行时给变量假设程序运行时给变量a输入输入8,给变,给变量量b输入输入5,程序运行结果:,程序运行结果:a=8 , b=58 + 5=08 5=0程序运行结果与我们程序运行结果与我们“想象想象”的不一的不一致,为什么呢?其原因是致,为什么呢?其原因是fun 函数中变量函数中变量add和和sub与与main函数中变量函数中变量add和和sub各自各自占用自己的存储单元,因此占用自己的存储单元,因此fun函数中变量函
4、数中变量add存放的两个数的求和值无法传回到存放的两个数的求和值无法传回到main函数的变量函数的变量add中,同理,中,同理,fun函数中函数中变量变量sub存放的两个数的相减值也无法传回存放的两个数的相减值也无法传回到到main函数的变量中。下面我们修改一下函数的变量中。下面我们修改一下源程序,借助指针,将源程序,借助指针,将fun函数中运行的结函数中运行的结果传回到果传回到main函数中。函数中。定义指针变量的一般形式如下:定义指针变量的一般形式如下:类型名类型名 *指针变量名指针变量名1,*指针变量名指针变量名2,;例如:例如:int *pi , *pj ;以上定义语句中,以上定义语句
5、中,pi和和pj都是用户标都是用户标识符,表示具体的变量名,现在每个变量识符,表示具体的变量名,现在每个变量名前加一星号名前加一星号“*”说明符,用来说明所定说明符,用来说明所定义的变量是指针变量。义的变量是指针变量。注意:变量名前的星号注意:变量名前的星号“*”不可省不可省略,若省略了星号略,若省略了星号“*”说明符,就变成了说明符,就变成了普通整型变量。普通整型变量。int是数据类型名,在这里,说明了是数据类型名,在这里,说明了pi和和pj是两个指向整型(是两个指向整型(int类型)变量的指类型)变量的指针,也就是说变量针,也就是说变量pi和和pj中只能存放中只能存放int类类型变量的地址
6、,这时我们称型变量的地址,这时我们称int是指针变量是指针变量pi和和pj的基类型。又如:的基类型。又如:double *pd ;char *s1 , *s2 ; 在这里定义了三个指针变量在这里定义了三个指针变量pd、s1和和s2,其中指针变量,其中指针变量pd的基类型为的基类型为double类类型,在指针变量型,在指针变量pd中,只能存放中,只能存放double类类型变量的地址,指针变量型变量的地址,指针变量s1和和s2的基类型的基类型为为char类型,在指针变量类型,在指针变量s1和和s2中只能存中只能存放放char类型变量的地址。又如:类型变量的地址。又如:int *p ;以上是定义了一
7、个指向指针的指针变以上是定义了一个指向指针的指针变量量p,该指针变量,该指针变量p只能存放基类型为只能存放基类型为int类类型的指针变量的地址。又如:型的指针变量的地址。又如:int *pi , *p , k ;以上语句是在同一语句中,同时定义以上语句是在同一语句中,同时定义了指针变量了指针变量pi、指向指针的指针变量、指向指针的指针变量p和变和变量量k,这是允许的。,这是允许的。任何一个指针变量都是用于存放它所任何一个指针变量都是用于存放它所指向变量的地址,只要能存放地址就可以指向变量的地址,只要能存放地址就可以了,为何还要区别不同的基类型呢?了,为何还要区别不同的基类型呢?其原理是:不同的
8、数据类型变量,其原理是:不同的数据类型变量,c语言系统为它们开辟的存储空间的字节数语言系统为它们开辟的存储空间的字节数是不同的,是不同的,int类型的数据存储空间是类型的数据存储空间是2个字节,个字节,float类型的数据存储空间是类型的数据存储空间是4个字节,个字节,系统表示每一个存储空间的地址时,是取系统表示每一个存储空间的地址时,是取该存储空间的第该存储空间的第1个字节的地址作为该变量个字节的地址作为该变量存储空间的地址。那么当一个基类型为存储空间的地址。那么当一个基类型为int类型的指针变量类型的指针变量p指向了一个指向了一个int类型的变类型的变量量a时,是将该变量时,是将该变量a所
9、占的所占的2个字节的存储个字节的存储空间中的第空间中的第1个字节存储空间的个字节存储空间的“地址地址”存存入指针变量入指针变量p中,如图中,如图7-2(b)所示。)所示。图图7-2 指针和指针所指向的对象指针和指针所指向的对象所以根据指针变量所以根据指针变量p中存放的中存放的“地地址址”,只能寻找到变量,只能寻找到变量a第第1个字节的存储个字节的存储空间,如果只提取变量空间,如果只提取变量a所占存储空间第所占存储空间第1个字节的数据,显而易见不是个字节的数据,显而易见不是int类型变量类型变量a的原值,因为变量的原值,因为变量a的原值是通过的原值是通过2个字节个字节来存储的数据。此时我们可以通
10、过指针变来存储的数据。此时我们可以通过指针变量量p的基类型解决问题,知道了变量的基类型解决问题,知道了变量a的第的第1个字节的地址,再根据指针变量个字节的地址,再根据指针变量p的基类型的基类型为为int类型,系统就将从变量类型,系统就将从变量a的第的第1个字节个字节所在的地址开始,连续提取所在的地址开始,连续提取2个字节中的数个字节中的数据,此时的数据就是据,此时的数据就是int类型变量类型变量a的原值。的原值。同理,基类型为同理,基类型为float类型的指针变量,根据类型的指针变量,根据指针变量中存放指针变量中存放float类型变量的地址值,可以寻类型变量的地址值,可以寻找到所需存储空间中的
11、第找到所需存储空间中的第1个字节所在位置,然个字节所在位置,然后再根据基类型为后再根据基类型为float类型,连续地提取类型,连续地提取4个字个字节中的数据,作为被访问的数据,这才是节中的数据,作为被访问的数据,这才是float类类型变量中存放的真实数据。由此,我们可以看到型变量中存放的真实数据。由此,我们可以看到指针变量在定义时,其基类型是何等的重要。因指针变量在定义时,其基类型是何等的重要。因此,定义什么样的基类型指针变量,该指针变量此,定义什么样的基类型指针变量,该指针变量只能存放什么样类型变量的地址,两者必须一致,只能存放什么样类型变量的地址,两者必须一致,否则就可能出现了张冠李戴的错
12、误现象。否则就可能出现了张冠李戴的错误现象。“&”是求地址运算符,该运算符为是求地址运算符,该运算符为单目运算符,用于求变量的地址,且该变单目运算符,用于求变量的地址,且该变量必须为内存变量。量必须为内存变量。例如:例如:int k=1 , j =2 , *q1 , *q2 , *p ; float x=4.5 ; q1=&k ; q2=&j ;以上第三条语句,是把变量以上第三条语句,是把变量k的地址的地址赋给了指针变量赋给了指针变量q1,使指针变量,使指针变量q1中存放中存放了变量了变量k的地址,或称指针变量的地址,或称指针变量q1指向了变指向了变量量k。同理,以上第四条语句,是把变量。同理
13、,以上第四条语句,是把变量j的地址赋给了指针变量的地址赋给了指针变量q2,使指针变量,使指针变量q2中存放了变量中存放了变量j的地址,或称指针变量的地址,或称指针变量q2指指向了变量向了变量j。注意:在使用注意:在使用 & 运算符求变量的地址,运算符求变量的地址,并赋给指针变量时,一定要确保所求地址并赋给指针变量时,一定要确保所求地址的变量数据类型与存放该变量地址的指针的变量数据类型与存放该变量地址的指针变量基类型一致。变量基类型一致。接上例,如执行接上例,如执行 p=&x ; 语句,则是语句,则是绝对错误的。为什么?请读者想一想!绝对错误的。为什么?请读者想一想!读者还记得在前面调用读者还记
14、得在前面调用 scanf 函数时,函数时,其函数调用格式中,输入数据所对应的各其函数调用格式中,输入数据所对应的各变量名之前都必须加运算符变量名之前都必须加运算符 & ,这就是我,这就是我们所说的求地址运算符。们所说的求地址运算符。scanf 函数把从终函数把从终端读入的数据依次放入这些地址所代表的端读入的数据依次放入这些地址所代表的存储单元中,也就是说存储单元中,也就是说scanf 函数要求输入函数要求输入项是地址值。因此接上例,项是地址值。因此接上例,scanf ( %d %d , &k , &j ) ; 语句和语句和scanf ( %d %d , q1 , q2 ) ; 语句是等价的,都
15、是将终端输语句是等价的,都是将终端输入的整型数据存入到变量入的整型数据存入到变量k和变量和变量j所在的所在的存储单元中。存储单元中。可以把指针变量的值赋给指针变量,可以把指针变量的值赋给指针变量,但一定要确保这两个指针变量的基类型是但一定要确保这两个指针变量的基类型是相同的。相同的。接上例:接上例:p=q1 ;执行以上语句后,使指针变量执行以上语句后,使指针变量p也存也存放了变量放了变量k的地址,也就是说指针变量的地址,也就是说指针变量p和和q1同时指向了变量同时指向了变量k。为了使指针变量有一确定的数值,除为了使指针变量有一确定的数值,除了给指针变量赋一地址值外,当指针变量了给指针变量赋一地
16、址值外,当指针变量没有指向的对象时,也可以给指针变量赋没有指向的对象时,也可以给指针变量赋null值,此值为空值。例如:值,此值为空值。例如:int *p ; p=null ; 表示指针变量表示指针变量p的值为空。的值为空。null是在是在stdio.h头文件中定义的预头文件中定义的预定义符,因此在使用定义符,因此在使用null时,应该在程时,应该在程序的前面出现预定义命令行:序的前面出现预定义命令行:# include stdio.h 。null的代码值为的代码值为0,所以语句,所以语句p=null ;等价于:等价于:p=0 ;,都是表示指针,都是表示指针变量变量p是一个空指针,没有指向任何
17、对象。是一个空指针,没有指向任何对象。当指针变量中存放了一个确切的地址当指针变量中存放了一个确切的地址值时,通过指针可以用值时,通过指针可以用“间接运算符间接运算符”(*)来引用该地址所代表的存储单元。来引用该地址所代表的存储单元。例如:例如: int *p , i=10 , j ; p=&i ; j=*p ;第二条语句是把变量第二条语句是把变量i的地址赋给了指的地址赋给了指针变量针变量p,第三条语句是把指针变量,第三条语句是把指针变量p所指所指向的变量向的变量i存储单元的值存储单元的值10赋给变量赋给变量j。“*”号在这里是一个号在这里是一个“间接运算符间接运算符”,它为单目运算符,与运算对
18、象自右至左结它为单目运算符,与运算对象自右至左结合,且运算对象必须为一个地址对象。合,且运算对象必须为一个地址对象。例如:例如: j=*&i ;该语句中该语句中“&”运算符求出变量运算符求出变量i的地的地址,址,“*”运算符取变量运算符取变量i地址中的值地址中的值10赋赋给变量给变量j。例如:例如: int *pp , *p , k=20 , j ; p=&k ; pp=&p ; j=*pp ;以上语句执行后的结果是:把变量以上语句执行后的结果是:把变量k的地址的地址赋给了指针变量赋给了指针变量p,把指针变量,把指针变量p的地址赋给了指的地址赋给了指向指针的指针变量向指针的指针变量pp,这种关
19、系如图,这种关系如图7-4所示。所示。最后一条语句是把变量最后一条语句是把变量k中的值中的值20赋给了变量赋给了变量j,这条语句使用了两个这条语句使用了两个“间接运算符间接运算符”,*p表示表示获取指针变量获取指针变量p中的值(此值为变量中的值(此值为变量k的地址值),的地址值),*pp表示通过指针变量表示通过指针变量p,再获取变量,再获取变量k中的值中的值20。图图7-4 变量变量pp、p和和k之间的关系之间的关系例如:例如: int *p , k=0 ; p=&k ; *p=150 ;以上第三条语句是把整数以上第三条语句是把整数150存入变存入变量量k中。中。 *p=*p +1 ; 或或
20、*p+=1 ;以上语句是获取指针变量以上语句是获取指针变量p所指向的所指向的存储单元存储单元k中的值中的值150,然后加,然后加1再放入指针再放入指针变量变量p所指向的存储单元所指向的存储单元k中,此时变量中,此时变量k中中存放的数值为存放的数值为151。例如:例如: int *p , *p , k ; p=&k ; pp=&p ; *pp=200 ;以上第四条语句是将整数以上第四条语句是将整数200存入变存入变量量k中。中。例例77.33 指针指向三个变量,通过指针指针指向三个变量,通过指针运算选出数值最小的那个数并打印出来。运算选出数值最小的那个数并打印出来。main() int a ,
21、b , c , min , *pa , *pb , *pc , *pmin ; p a = & a ; p b = & b ; p c = & c ; pmin=&min ; scanf ( %d %d %d , pa , pb , pc ) ; /* 将键盘输入的三个整数依次放入变将键盘输入的三个整数依次放入变量量a、b、c中中 */ printf ( a=%d , b=%d , c=%d n , a , b , c ) ; *pmin= *pa ; /* 假定变量假定变量a中的数值最小,将其中的数值最小,将其放入变量放入变量min */ if (*pmin *pb ) *pmin= *pb ; /* 若若b中的数值比中的数值比min小,将其放入变量小,将其放入变量min */ if (*pmin *pc ) *pmin= *pc ; /* 若若c中的数值比中的数值比min小,将其放入变量小,将其放入
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年学校工作计划(2篇)
- 教研组工作计划
- 2026年新能源培训数据资产管理合同
- 2026年文旅承运元宇宙内容制作协议
- 2026年AI集成产业园区运营协议
- 村委宣传教育工作制度
- 村庄清洁行动工作制度
- 预警信息发布工作制度
- 领导信访包片工作制度
- 领导干部蹲点工作制度
- 2026天津市管道工程集团有限公司人才引进招聘3人笔试模拟试题及答案解析
- 《特种设备使用管理规则 TSG08-2026》解读
- 光伏场区工程总承包EPC招标文件
- 资金计划编制流程
- 2024年杭州市临空建设投资集团有限公司招聘笔试参考题库附带答案详解
- 路基工程防护施工培训课件
- 江阴职业技术学院单招《语文》考试参考题库(含答案)
- ROHS-2.0培训教材资料
- 7.2万有引力定律说课课件
- 建筑工程绿色施工评价标准概述(PPT 90张)
- GB/T 33588.2-2020雷电防护系统部件(LPSC)第2部分:接闪器、引下线和接地极的要求
评论
0/150
提交评论