第10章指针类型.ppt
《第10章指针类型.ppt》由会员分享,可在线阅读,更多相关《第10章指针类型.ppt(140页珍藏版)》请在课桌文档上搜索。
1、,第10章 指针类型,10.1 指针与指针变量 10.2 指针与数组 10.3 指针与字符串 10.4 指针与结构体 10.5 指针与链表 10.6 指针与函数 10.7 指针作基类型 10.8 程序设计举例习 题 十,10.1 指针与指针变量,10.1.1 指针变量的定义,1.定义方法 形式:类型标识符*变量标识符;定义存放指定类型数据地址的指针变量。,例如:(1)int*p1,*p2,*p3;定义指向整型数据的指针变量p1、p2、p3。(2)float*q1,*q2,*q3;定义指向实型数据的指针变量q1、q2、q3。(3)char*r1,*r2,*r3;定义指向字符型数据的指针变量r1、
2、r2、r3。,(4)struct date int year;int month;int day;*t1,*t2,*t3;定义指向struct date类型数据的指针变量t1、t2、t3。,说明:(1)指针变量可与普通变量混合定义,指针变量的定义与普通变量的定义用变量名前加“*”区分。例如:int i,*p;/*定义整型变量i,指针变量p*/(2)空指针“NULL”是一特殊的指针数据,表示空地址,相当于整型数据中的0,字符数据中的空格。,(3)指针变量只能用于存放指定类型数据的地址。如以上定义的一些指针变量,p1、p2、p3只能存放整型数据的地址,q1、q2、q3只能存放实型数据的地址,r1、
3、r2、r3只能存放字符型数据的地址,t1、t2、t3只能存放struct date型数据的地址。,(4)指针变量不能直接赋以具体地址值,不能从键盘输入值。指针变量通过间接赋以相关数据的地址,或调用存储空间分配函数得到值。例如:int i,j,k;int*p1=&i,*p2=&j,*p3=&k;/*p1得到i的地址,p2得到j的地址,p3得到k的地址*/,(5)指针类型隐含在指针变量的定义中。例如,在上面定义指针变量p1、p2、p3时,实际上在背后隐含定义了一指向整型数据的指针类型,从形式上可以将int*看成是指向整型数据的指针类型。与数组定义一样,通过typedef可以将指针类型与指针变量分离
4、。例如,上面定义的指针变量p1、p2、p3,可以改用如下形式:typedef int*INTPOINT;INTPOINT p1,p2,p3;,(6)指针变量本身占有2字节的存储空间。(7)“void*”指针类型定义的指针变量,不指向哪一种特定类型的数据,在实际使用时通过强制类型转换成指向特定类型的数据。,2.指针变量所指向的变量特定类型的数据,例如,对指针变量p1、p2、p3,假定已有值,*p1、*p2、*p3代表指针变量p1、p2、p3所指向的数据,也就是p1、p2、p3的值对应的存储单元里存放的数据,称为指针变量所指向的变量,简称指针指向变量。如果指针变量p1、p2、p3分别存放整型变量i
5、、j、k的地址,则p1指向i,p2指向j,p3指向k。图10-1来直观反应指针变量与指针指向变量的关系。,图 10-1,指针指向变量*p1、*p2、*p3相当于整型变量i、j、k。例如:int*p=&i;scanf(“%d”,p);/*等价于scanf(“%d”,&i)*/printf(“%d”,*p);/*等价于printf(“%d”,i)*/,10.1.2 指针的运算,1.引用运算 1)取地址运算(&)取地址运算“&”,对指针变量进行取地址运算,可以得到指针变量本身的地址。,2)取内容运算(*)取内容运算“*”,前称指针运算,用于获取地址数据对应存储单元的内容。取内容运算的优先级与取地址运
6、算优先级相同,也为第2级,结合性亦为右结合。对指针变量,进行取内容运算可以得到指针变量所指向的数据。取内容运算与取地址运算实质上是一对互逆运算。例如:int a,*p=&a;*(&a)就是a,&(*p)就是p;p指向a,*p与a等价。,2算术运算 指针变量可以进行有限的算术运算。1)加减运算 指针变量“加上”或“减去”一个整数n,相当于指针变量加上或减去n个指针所指向数据的存储单位,即指针由当前指向位置向后或向前移动n个指针所指向数据的存储单位。加减运算常用于数组的处理。对指向一般数据的指针,加减运算无实际意义。例如:int a10,*p=a,*x;x=p+3;/*实际上是p加上3*2个字节赋
7、给x,x指向数组的第三个分量*/,对于不同基类型的指针,指针变量“加上”或“减去”一个整数n所移动的字节数是不同的。例如:float a10,*p=a,*x;x=p+3;/*实际上是p加上3*4个字节赋给x,x依然指向数组的第三个分量*/,2)自增自减运算 指针变量自增、自减运算具有上述运算的特点,但有前置后置、先用后用的考虑,务请小心。例如:int a10,*p=a,*x;x=p+;/*x指向数组的第一个分量,p指向数组的第二个分量*/x=+p;/*x、p均指向数组的第二个分量*/*p+相当于*(p+)。*(p+)与(*p)+含义不同,前者表示地址自增,后者表示当前所指向的数据自增。,3)指
8、针相减 指针相减得到两指针之间数据的个数,一般用于数组处理。,3.关系运算 两指针的关系运算表示两指针的先后位置关系,一般用于数组处理。除空指针外,不能进行指针与一般数值的关系运算。,10.1.3 利用指针处理简单数据,通过指向简单数据的指针变量来处理数据的步骤是:(1)定义以相应简单数据类型为基类型的指针变量。即定义指向简单数据的指针变量。(2)在指针变量与要处理的数据之间建立关联。只需将相应数据的地址赋给指针变量。(3)使用指针所指向的变量来完成数据处理。,例如,要利用指针处理float数据x:(1)float*p;(2)p=&x;(3)*p即x,例 10-1 利用指针,求两个整数的和。/
9、*程序10-1,利用指针,求两个整数的和*/main()int i,j;int*p,*q;/*定义指针变量*/int sum;p=&i;q=&j;/*建立关联*/scanf(%d,%d,p,q);sum=*p+*q;/*使用*/printf(%d,%dn,*p,*q);printf(和=%dn,sum);,例 10 2 指针运算示例。/*程序10-2,指针运算*/main()char c=a;char*p=&c;int a1,a2;int*p1,*p2;a1=100;p1=&a1;a2=(*p1)/3+7;p2=&a2;printf(a1=%d,a2=%d,*p1=%d,*p2=%dn,a1,
10、a2,*p1,*p2);a1=(*p1)+;a2=*p2+;,printf(a1=%d,a2=%d,*p1=%d,*p2=%dn,a1,a2,*p1,*p2);printf(%c,%cn,c,*p);运行结果:a1=100,a2=40,*p1=100,*p2=40 a1=101,a2=40,*p1=101,*p2=随机值(p2指向a2后一个数据单元)a,a,10.1.4 指针作函数参数,例 10 3 将两个整数按从小到大的顺序输出。,先定义一个函数,用指针变量作参数,实现两个数的交换,然后在主函数中调用它,完成两个整数从小到大的顺序输出。,/*程序10-3,将两个整数顺序输出*/void ex
11、chang(p1,p2)/*交换两个数*/int*p1,*p2;int p;p=*p1;*p1=*p2;*p2=p;/*结果通过*p1、*p2带回*/,main()int a,b;int*r,*s;scanf(%d,%d,&a,&b);r=&a;s=&b;if(ab)exchang(r,s);printf(%d,%dn,a,b);输入数据:9,4运行结果:4,9,说明:(1)若在函数中交换指针变量的值,则实参r、s并不改变,指针参数亦是传值。例如:int*p;p=p1;p1=p2;p2=p;不要希望如此能完成处理。,(2)函数中交换值时不能使用无值的指针变量作临时变量。例如:int*p;*p=
12、*p1;*p1=*p2;*p2=*p;p无值,*p无意义,问题由此产生。,10.2 指针与数组,10.2.1 指向一维数组的指针变量,可以利用指向一维数组的指针变量,完成数组数据的操作处理,具体步骤如下:(1)定义与数组相同基类型的指针变量。即定义指向数组的指针变量。(2)在指针变量与要处理的数组(元素)之间建立关联。只需将相应数组的首地址赋给指针变量。(3)使用指针所指向的变量来完成数组元素(数组)的操作处理。,例如,要利用指针处理整型数组a:(1)定义指针变量:int*p;。(2)建立关联:p=a;或p=&a0;。p+i是下标为i的数组分量的地址。(3)使用:*p即a0,*(p+i)即ai
13、。*p+是p当前指向的数组分量的下一个分量。如此得到处理数组的指针法。,与指针法相类似的是处理数组的位移法,或称首地址法。通过数组的首地址计算出下标为i的数组的元素地址(a+i),*(a+i)即ai。指针法中p是变量,用来存放数组元素的地址。位移法中a是常量,代表数组的首地址。,例 10-4 分别用下标法、指针法、位移法输入、输出数组元素。方法一:,/*程序10 4 1,下标法实现数组的输入、输出*/main()int a10;int i;for(i=0;i10;i+)scanf(%d,&ai);printf(n);for(i=0;i10;i+)printf(%3d,ai);,方法二:/*程序
14、10 4 2,指针法实现数组的输入、输出*/main()int a10;int i,*p;/*定义指针变量*/p=a;/*建立关联*/for(i=0;i10;i+)scanf(%d,p+);printf(n);for(p=a;pa+10;p+)/*使用*/printf(%3d,*p);,方法三:/*程序10 4 3,位移法实现数组的输入、输出*/main()int a10;int i,;for(i=0;i10;i+)scanf(%d,&ai);printf(n);for(i=0;i10;i+)printf(%3d,*(a+i);,10.2.2 数组作函数参数,例 10 5 求n个整数的最大值、
15、最小值。求n个数的最大值的一般方法我们已非常熟悉,在这里主要考察引入指针处理数组后,数组作函数参数的应用。假定不超过100个数,数据输入输出在主函数中完成,求最大值、最小值用一个函数完成,n个数用参数传递,最大值、最小值使用全局变量。,方法一:形参用指针,实参用数组名。程序如下:/*程序10 5 1,求n个整数的最大值、最小值*/define L 100int max,min;main()int aL;int n,i;void max-min();printf();scanf(%d,&n);printf(请输入%d个数:,n);,for(i=0;imax)max=*(p+i);if(*(p+i
16、)min)min=*(p+i);,运行结果:请输入数的个数n:6请输入6个数:32 54 7 88 13 49最大值=88,最小值=7,方法二:形参用数组,实参用指针。程序如下:/*程序10 5 2,求n个整数的最大值、最小值*/define L 100int max,min;main()int aL,*p;int n,i;void max-min();printf(请输入数的个数n:);scanf(%d,&n);printf(请输入%d个数:,n);for(i=0;in;i+)scanf(%d,&ai);,p=a;max-min(p,n);/*调用函数*/printf(最大值=%4d,最小值
17、=%4dn,max,min);void max-min(b,x)/*求最大值、最小值函数*/int b,x;int i;max=min=b0;/*最大值、最小值初始化为第一个数据*/for(i=1;imax)max=bi;if(bimin)min=bi;,方法三:形参用指针,实参用指针。程序如下:,/*程序10 5 3,求n个整数的最大值、最小值*/define L 100int max,min;main()int aL,*p;int n,i;void max-min();printf(请输入数的个数n:);scanf(%d,&n);printf(请输入%d个数:,n);for(i=0;in;
18、i+)scanf(%d,&ai);,p=a;max-min(p,n);/*调用函数*/printf(最大值=%4d,最小值=%4dn,max,min);void max-min(q,x)/*求最大值、最小值函数*/int*q,x;int i;max=min=*q;/*最大值、最小值初始化为第一个数据*/for(i=1;imax)max=*(q+i);if(*(q+i)min)min=*(q+i);,10.2.3 指向二维数组的指针变量,1.二维数组的指针,对于二维数组,相当于一张二维表格,存储按行按列存放。二维数组具有首地址、行地址、元素地址等相关指针。数组名代表首地址,称为二维数组的指针;行
19、地址是二维数组中一行的首地址,二维数组中一行相当于一个一维数组;元素地址是二维数组的具体分量地址。,例如,对二维整型数组a45,相当于下面的二维数据表:第0列 第1列 第2列 第3列 第4列 第0行:a00,a01,a02,a03,a04,相当于一维数组a0第1行:a10,a11,a12,a13,a14,相当于一维数组a1第2行:a20,a21,a22,a23,a24,相当于一维数组a2 第3行:a30,a31,a32,a33,a34,相当于一维数组a3,(1)a代表整个二维数组的首地址,也就是第 0 行的首地址。也可用a0、&a00表示。(2)ai代表第i行的首地址。整个二维数组也相当于一个
20、一维数组a0、a1、a2、a3,基于一维数组的处理方法,第i行的首地址还可用*(a+i)、a+i、&ai、&ai0表示。请注意*a表示 0 行首地址,而非a00。,(3)ai+j代表aij的地址。aij的地址还可用*(a+i)+j表示。请注意aij的地址不能用(a+i)+j表示,因为此时实际表示的是第(i+j)行的地址。aij相对a00的绝对地址可用a0+i*5+j计算。如果每行有m个元素,aij相对a00的绝对地址可用a0+i*m+j计算。当然&aij是我们早就知道的aij的地址。,(4)基于上面的分析,引入指针后,二维数组的分量aij可表示成:aij*(ai+j)*(*(a+i)+j)*(
21、a0+i*m+j)相应得到处理二维数组的多种形式位移法。,例10-6 输出一个指定的二维数组。程序如下:/*程序10-6,输出一个指定的数组*/main()static int a45=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20;int i,j;for(i=0;i4;i+)for(j=0;i5;j+)printf(%6d,*(a0+i*5+j);printf(n);,运行结果:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 输出语句也可以是:printf(%6d,*(*(a+i)+j
22、);,2.指向二维数组元素的指针变量,利用指向二维数组元素的指针变量,可以完成二维数组数据的操作处理,这也就是处理二维数组的指针法。(1)定义与数组相同基类型的指针变量。(2)在指针变量与要处理的数组(元素)之间建立关联。(3)使用指针所指向的变量来完成数组元素(数组)的操作处理。,例 10 7 输出同例10 6指定数组。/*程序10 7,输出指定数组*/main()static int a45=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20;int*p;for(p=a0;pa0+20;p+)if(p-a0)%5=0)printf(n);/
23、*每行输出5个元素*/printf(%6d,*p);,运行结果:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20,3指向整个一维数组的指针变量 一个二维数组相当于多个一维数组。通过指向整个一维数组的指针变量,也可以完成对二维数组数据的操作处理,这也是处理二维数组的指针法。例如:int(*p)5;定义了一个指向具有5个分量的一维数组的指针变量p,p的增值以指向的一维数组为单位,一维数组的5个分量可用(*p)0、(*p)1、(*p)2、(*p)3、(*p)4表示。a是上面定义的数组,如果p=a,则p+i指向a数组的第i行,*(p+i)+j指向a数
24、组的第i行第j列分量,*(*(p+i)+j)即aij。,例10-8 输出上例二维数组中某行某列分量的值。采用指向整个一维数组的指针变量来处理。程序如下:/*程序10-8,输出上例二维数组中某行某列分量的值*/main()static int a45=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20;int i,j;int(*p)5;/*定义指向整个一维数组的指针变量p*/p=a;/*建立关联*/scanf(%d,%d,&i,&j);printf(a%d%d=%d,i,j,*(*(p+i)+j);/*输出aij*/,输入数据:3,4 运行结果:
25、a34=12 请注意:(1)定义指向整个一维数组的指针变量必须用“()”,否则定义的是指针数组,指针数组在本章10.7节中做了介绍。(2)指向整个一维数组的指针变量不能指向数组的元素,只能指向二维数组的行。,10.3 指针与字符串,10.3.1 字符串的指针表示,例10-9 字符串的指针表示。main()char*str1;char*str2=computer;scanf(%s,str1);printf(%s,str1);printf(%sn,str2);输入数据:HUNAN运行结果:HUNAN computer,说明:(1)char*str=computer;等价于:char*str;str
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 10 指针 类型
链接地址:https://www.desk33.com/p-679823.html