08第八章指针.ppt
《08第八章指针.ppt》由会员分享,可在线阅读,更多相关《08第八章指针.ppt(74页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、1/74第八章第八章 指针指针8.1 寻找保险箱密码寻找保险箱密码 8.2 角色互换角色互换8.3 冒泡排序冒泡排序8.4 加密变换问题加密变换问题 8.5 任意个整数求和问题任意个整数求和问题*2/74本章要点本章要点在变量、内存单元和地址之间是什么关系在变量、内存单元和地址之间是什么关系?如何定义指针变量,怎样才能使用指针变量如何定义指针变量,怎样才能使用指针变量?什么是指针变量的初始化什么是指针变量的初始化?指指针针变变量量的的基基本本运运算算有有哪哪些些?如如何何使使用用指指针针改改变变量的值变变量的值?指针作为函数参数的作用是什么?指针作为函数参数的作用是什么?如何通过指针实现函数调
2、用返回多个值如何通过指针实现函数调用返回多个值?如何利用指针实现内存的动态分配?如何利用指针实现内存的动态分配?3/748.1 寻找保险箱密码寻找保险箱密码指针指针变量变量的的定义定义密码存放在某个寄存箱内,如果我们知道这个寄存箱密码存放在某个寄存箱内,如果我们知道这个寄存箱的名字,就能够找到密码的名字,就能够找到密码如果不知道密码所在的寄存箱名字,知道该寄存箱的如果不知道密码所在的寄存箱名字,知道该寄存箱的地址也照样能够取出密码地址也照样能够取出密码如果寄存箱的地址也不知道,但是有另外一个地方存如果寄存箱的地址也不知道,但是有另外一个地方存放这个寄存箱的地址,也能顺藤摸瓜,间接找到密码放这个
3、寄存箱的地址,也能顺藤摸瓜,间接找到密码4/74一一.指针的概念指针的概念int x=20,y=1,z=155;printf(%d,x;)直接访问直接访问:通过变量名访问:通过变量名访问间接访问间接访问:通过另一个变量访问通过另一个变量访问把变量的地址放到另一变量中把变量的地址放到另一变量中使用时先找到后者使用时先找到后者再再从中取出前者的地址从中取出前者的地址1000 20 x1002 1 y1004 155 z2000 1000 px2002地址地址 指针变量指针变量 内存单元内存单元地址地址 内容内容 变量变量5/74 内存单元内存单元地址地址 内容内容 变量变量1000 20 x100
4、2 1 y1004 155 z2000 1000 px2002指针变量指针变量:存放地址的变量:存放地址的变量某个某个变量变量的地址的地址指向指向指针指针地址地址int x=20,y=1,z=155;printf(%d,x;)6/74指针变量所指向的变量的类型指针变量所指向的变量的类型指针变量的名字指针变量的名字二二.指针变量的定义指针变量的定义指针变量专门用来存放地址,因此必须定义为指针变量专门用来存放地址,因此必须定义为指针类型指针类型指针变量定义的一般形式指针变量定义的一般形式:类型标识符类型标识符 *标识符标识符例如:float*fp;int*p;都是合法的指针变量定义指针声明符指针声
5、明符注意:注意:int*p中,指针变量名是中,指针变量名是p,不是,不是*p*是指针声明符是指针声明符7/74变量的指针就是变量的地址变量的指针就是变量的地址指针变量是指向一个变量的地址的变量指针变量是指向一个变量的地址的变量可以用赋值语句使一个指针变量指向一个变量,可以用赋值语句使一个指针变量指向一个变量,通通过指针间接访问那个变量过指针间接访问那个变量指针变量中只能存放地址,因此,不能将其它非地址指针变量中只能存放地址,因此,不能将其它非地址类型的数据赋给指针变量类型的数据赋给指针变量有关地址的运算符有关地址的运算符:&-取地址运算符取地址运算符*-指针运算符指针运算符(即间接访问运算符即
6、间接访问运算符)指针的指针的基本运算包括基本运算包括有关地址的运算和指针赋值运算有关地址的运算和指针赋值运算三三.指针的基本运算指针的基本运算8/74&a*p-表示变量表示变量 a 的地址的地址(变量变量a的指针的指针)-表示指针变量表示指针变量 p 所指向的变量所指向的变量(地址地址p所指的单元中存放的值所指的单元中存放的值)*p就可以和普通变量一样参与运算或被赋值就可以和普通变量一样参与运算或被赋值例如例如:inti,*p;i=5;p=&i;2000(地址地址)p5(数据数据)*p地址地址2000i注意注意:1.:1.定义时定义时“*”“*”表示该变量是指针变量,而后面表示该变量是指针变量
7、,而后面的标识符就是该指针变量的变量名的标识符就是该指针变量的变量名 2.2.一个指针变量只能指向同一类型的变量一个指针变量只能指向同一类型的变量1.取地址运算和间接访问运算取地址运算和间接访问运算当当p=&i后,后,*p与与i相同相同例如例如:int*p,a;p=&a;*p=3;9/74inta=3,*pointer1,*pointer2;pointer1=&a;pointer2=pointer1;2.指针赋值运算指针赋值运算例如:例如:把把a的地址赋给的地址赋给pointer1,即即pointer1指向指向apointer2也指向也指向a&apointer1&aa3pointer2*poi
8、nter1*pointer2注意注意:1.:1.变量的地址只能赋给相同类型的指针变量变量的地址只能赋给相同类型的指针变量 2.2.相同类型的指针之间才能相互赋值相同类型的指针之间才能相互赋值10/74定义指针变量后,在没有给指针变量赋值之前,定义指针变量后,在没有给指针变量赋值之前,指针变量的值是不确定的指针变量的值是不确定的注意注意:不能使用没有赋值的指针不能使用没有赋值的指针在定义指针变量时可以对指针变量赋初值在定义指针变量时可以对指针变量赋初值例如:int a;int*p1=&a;int*p2=p1;四四.指针指针变量变量的的初始化初始化11/74main()inta,b;int*poi
9、nter1,*pointer2;a=100;b=10;pointer1=&a;pointer2=&b;printf(%d,%dn,a,b);printf(%d,%dn,*pointer1,*pointer2);1.&*pointer1-?2.*&a-?3.(*pointer1)+-?*pointer1+-?这里,由于这里,由于pointer1指向指向a,因此因此*pointer1的值的值就是变量就是变量a定义指向整型变量的指针变量定义指向整型变量的指针变量使使pionter1指向指向a使使pionter2指向指向b指针变量应用指针变量应用例:例:12/74p1p236abp&a&bmain()
10、inta,b,*p1,*p2,*p;scanf(%d,%d,&a,&b);p1=&a;p2=&b;if(ab)p=p1;p1=p2;p2=p;printf(a=%d,b=%dn,a,b);printf(max=%d,min=%dn,*p1,*p2);例例:输入整数输入整数a和和b,按大小顺序输出按大小顺序输出实际上没有交换实际上没有交换a和和b,而是使而是使p1指向大的数指向大的数,p2指向小的数指向小的数p1p2abp&a&a&b36&b&a13/74以下程序运行后以下程序运行后,a的值是:的值是:main()inta,k=4,m=6,*p1,*p2;p1=&k;p2=&m;a=p1=&m;
11、printf(“%d”,a);A)4B)1C)0D)运行时出错,运行时出错,a无定值无定值 14/74intx,*p;p=&x;则则&*p相当于相当于_A、pB、*pC、xD、*&x 下列程序段的输出结果是下列程序段的输出结果是_。int*p,*q,k=1,j=10;p=&j;q=&k;p=q;(*p)+;printf(%d,*q);A1 B2C10D11 15/74int*p,x;p=&x,则则(*p)+相当于相当于_。A、p+B、x+C、*(p+)D、&x+下列正确的定义是下列正确的定义是_。A、intx=3,*p=1;B、intx=3,*p;C、intx=3,*p=x;D、int*p=&
12、x=3;16/748.2 角色互换角色互换指针指针作为函数的参数作为函数的参数函数参数包括实参和形参,两者类型要一致函数参数包括实参和形参,两者类型要一致,可以是可以是指针类型。指针类型。指针作函数的参数时指针作函数的参数时,将一个变量的地址传送到函数中,将一个变量的地址传送到函数中,使实参和形参共用同一块内存单元。使实参和形参共用同一块内存单元。如果实参是某个变量的地址,相应的形参就是指针。如果实参是某个变量的地址,相应的形参就是指针。17/74main()inta,b,*pa,*pb;scanf(%d%d,&a,&b);pa=&a;pb=&b;if(ab)swap(pa,pb);print
13、f(%d%dn,a,b);printf(%d%dn,*pa,*pb);例如例如:用一个函数将两个整数用一个函数将两个整数a和和b按大小顺序输出按大小顺序输出swap(int*p1,int*p2)intt;t=*p1;*p1=*p2;*p2=t;交换两个指针所交换两个指针所指的单元中的值指的单元中的值12abpapbp1p221值传递,地值传递,地址未变,址未变,但存放的变量的值改变了但存放的变量的值改变了18/7412swap(intx,inty)intt;t=x;x=y;y=t;?main()inta,b,*pa,*pb;scanf(%d%d,&a,&b);pa=&a;pb=&b;if(ab
14、)swap(a,b);printf(%d%dn,a,b);printf(%d%dn,*pa,*pb);12abpapb21xy思考?思考?19/74swap(int*p1,int*p2)int*p;p=p1;p1=p2;p2=p;?main()inta,b,*pa,*pb;scanf(%d%d,&a,&b);pa=&a;pb=&b;if(ab)swap(pa,pb);printf(%d%dn,a,b);printf(%d%dn,*pa,*pb);思考?思考?p1p212abpapb值传递,形参指针的改变值传递,形参指针的改变不会影响实参不会影响实参20/74要通过函数调用来改变主调函数中某个变
15、量的值:要通过函数调用来改变主调函数中某个变量的值:(1)在主调函数中,将该变量的地址或者指向该变量的在主调函数中,将该变量的地址或者指向该变量的指针作为实参指针作为实参(2)在被调函数中,用指针类型形参接受该变量的地址在被调函数中,用指针类型形参接受该变量的地址(3)在被调函数中,改变形参所指向变量的值在被调函数中,改变形参所指向变量的值注意注意:1.:1.可以通过让实参指针变量和形参指针变量指向可以通过让实参指针变量和形参指针变量指向主调函数中的同一变量,在主调函数中获得该主调函数中的同一变量,在主调函数中获得该变量的新值变量的新值 2.2.不能通过改变形参指针的值来改变实参指针的不能通过
16、改变形参指针的值来改变实参指针的指向,因为,指针变量也是单向的指向,因为,指针变量也是单向的 值传递值传递 swap(int*p1,int*p2)int t;t=*p1;*p1=*p2;*p2=t;swap(int x,int y)int t;t=x;x=y;y=t;swap(int*p1,int*p2)int*p;p=p1;p1=p2;p2=p;21/74例:输入年和天数,输出对应的月和日。例:输入年和天数,输出对应的月和日。如:输入如:输入2000和和61,输出,输出3和和1分析:通过指针实现函数调用返回多个值分析:通过指针实现函数调用返回多个值 自定义函数自定义函数month_day(y
17、ear,yearday,*pmonth,*pday),用用2个指针作为函数的参数,带回个指针作为函数的参数,带回2个结果(个结果(月和日)月和日)#include void main()int day,month,year,yearday;void month_day(int year,int yearday,int*pmonth,int*pday);printf(input year and yearday:);scanf(%d%d,&year,&yearday);month_day(year,yearday,&month,&day);printf(%d-%dn,month,day);22/
18、74void month_day(int year,int yearday,int*pmonth,int*pday)int k,leap;int tab 213=0,31,28,31,30,31,30,31,31,30,31,30,31,0,31,29,31,30,31,30,31,31,30,31,30,31,;leap=year%4=0&year%100!=0|year%400=0;for(k=1;yearday tableapk;k+)yearday=yearday -tableapk;*pmonth=k;*pday=yearday;inputyearandyearday:2000613
19、-1monthdaypmonthpday3123/748.3 冒泡排序冒泡排序指针指针和和数组数组一一.指针、数组、地址间的关系指针、数组、地址间的关系数组的指针数组的指针数组元素的指针数组元素的指针数组元素的引用数组元素的引用-数组的起始地址数组的起始地址-数组元素的地址数组元素的地址-下标法、下标法、指针法指针法(指针法(指针法-通过指向数组元素的指针找到所需的元素)通过指向数组元素的指针找到所需的元素)数组名代表一个地址,它的值是数组首元素的地址,即数组的起始地址数组名代表一个地址,它的值是数组首元素的地址,即数组的起始地址例:例:inta10;a+i是距数组是距数组a的基地址的第的基地
20、址的第i个偏移,即元素个偏移,即元素ai的地址的地址任何由数组下标来实现的操作都能用指针来完成任何由数组下标来实现的操作都能用指针来完成数组名是一个特殊的固定地址,可以把它看作是常量指针数组名是一个特殊的固定地址,可以把它看作是常量指针24/741.指向数组元素的指针变量的指向数组元素的指针变量的定义与赋值定义与赋值指向数组元素的指针变量的定义指向数组元素的指针变量的定义与普通的指针变量的定义相同与普通的指针变量的定义相同a0a1ai.&a0&a1&aiap=a;或或p=&a0pinta10,i,*p,*p1;如果有如果有p1=&aip1例如:inta10;int*p;.p=&a0;把把a0元
21、素的地址赋给元素的地址赋给p,(即即p指向指向a数组的第数组的第0个元素个元素)等价于等价于p=a(因为数组名表因为数组名表示数组的首地址示数组的首地址)inta10;int*p=&a0;相当于相当于int*p;p=&a0;等价于等价于int*p=a;在定义指针变量时可以赋初值在定义指针变量时可以赋初值25/74注意注意:1.C语言中规定语言中规定p+1(或或p+)指向数组的下一个元素指向数组的下一个元素(并不是地址值简单加并不是地址值简单加1)当当p的初值为的初值为a的首地址时的首地址时,2.p+i或或a+i就是就是ai的地址,因为的地址,因为a代表了数组的首地址代表了数组的首地址3.*(p
22、+i)或或*(a+i)所指的数组元素就是所指的数组元素就是ai-变址运算符变址运算符4.指向数组的指针变量也可以带下标指向数组的指针变量也可以带下标,如如:*(p+i)等价于等价于pi2.通过指针引用数组元素通过指针引用数组元素int a10;int*p=a;.*p=1;对对p当前所当前所指的元素指的元素赋整数值赋整数值1p+1或或a+1pp+2或或a+2p+i或或a+i*(p+i)a数组数组p+9或或a+9a0a1a2aia926/74数组元素的引用可以用数组元素的引用可以用(1)下标法:)下标法:ai 或或 (2)指针法:指针法:*(a+i)或或*(p+i)例如例如:inta10,*p,i
23、;输出数组输出数组a的元素的元素for(i=0;i10;i+)printf(%d ,ai);for(i=0;i10;i+)printf(%d ,*(a+i);p=a;for(i=0;i10;i+)printf(%d ,*(p+i);for(p=a;pa+10;p+)printf(%d ,*p);下标法下标法:指针法指针法:for(p=a;ap+10;a+)printf(%d,*a)?如果如果X注意注意:*p+由于由于*和和+的优先级相同,的优先级相同,结合方向同为自右至左,因此等结合方向同为自右至左,因此等价于价于*(p+),作用是先得到作用是先得到p所指向的变量的所指向的变量的值值(即即*p
24、),然后再使然后再使p=p+127/743.指针的算术运算和比较运算指针的算术运算和比较运算double*p,*q;lq-p两个相同类型的指针相减,表示它们之间相隔的两个相同类型的指针相减,表示它们之间相隔的存储单元的数目存储单元的数目lp+1指向下一个存储单元指向下一个存储单元lpq两个相同类型指针可以用关系运算符比较大小两个相同类型指针可以用关系运算符比较大小C C语言中指针的算术运算包括语言中指针的算术运算包括:两个相同类型的指针相减两个相同类型的指针相减指针加上或减去一个整数指针加上或减去一个整数其他操作其他操作(指针相加、相乘和相除,或指针加上和减指针相加、相乘和相除,或指针加上和减
25、去一个浮点数去一个浮点数)都是非法的。都是非法的。例如:例如:28/74#include void main(void)double a2,*p,*q;p=&a0;q=p+1;printf(%dn,q-p);printf(%dn,(int)q-(int)p);pq3000 a0地址 内容 数组元素3008 a1 aa+1指针指针p和和q之间元素的个数之间元素的个数指针指针p和和q之间的字节数之间的字节数地址值地址值整数整数18例如:例如:29/74设变量定义为设变量定义为inta2=1,3,*p=&a0+1;则则*p的值是的值是_。A、2B、3C、4D、&a0+1 inta4;则表达式则表达式
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 08 第八 指针
限制150内