收藏 分享(赏)

C语言教程之指针.pdf

上传人:精品资料 文档编号:11125842 上传时间:2020-02-08 格式:PDF 页数:18 大小:174KB
下载 相关 举报
C语言教程之指针.pdf_第1页
第1页 / 共18页
C语言教程之指针.pdf_第2页
第2页 / 共18页
C语言教程之指针.pdf_第3页
第3页 / 共18页
C语言教程之指针.pdf_第4页
第4页 / 共18页
C语言教程之指针.pdf_第5页
第5页 / 共18页
点击查看更多>>
资源描述

1、第七章 指 针【学习目标】( 1)能够使用指针。( 2)理解指针、数组、字符串间的密切关系。( 3)能够使用指针通过按引用调用向函数传递参数。( 4)理解如何使用函数指针。指针是 C语言中一种重要的数据类型,也是 C语言的精华。正确而灵活地运用它,可以处理各种复杂的数据结构,能使程序简洁、紧凑、高效。每一位学习和使用 C语言的人,都应当深入地学习和掌握指针。本章将介绍指针的基础知识和指针的使用方法。指针的概念比较复杂,使用也比较灵活,因此初学时应多思考、多比较、多上机,在实践中掌握它。7.1 指针的概念对程序中定义的某个变量,编译时根据它的数据类型给它分配一定长度的内存空间。如整型变量分配 2

2、个字节,字符型变量 1个字节,双精度变量分配 8个字节内存 中的每个字节都被按顺序进行编号,就好像旅馆中的每个房间和它的房间号,我们把每个字节的编号叫做该字节的地址。在地址所对应的单元存放数据,就相当于旅馆客房中住旅客一样。迄今为止,我们的操作对象是基本类型和数组类型的变量,这些变量都存放具体的变量值,要标识的和处理的对象也都是变量本身。然而在不少使用场合,例如,系统程序设计中必须涉及到对变量存放地址的加工,通过地址获得存放于地址中的变量本身。7.1.1 内存的访问方式对内存变量的存取有两种方式:直接访问、间接访问。1. 直接访问每个变量对应自己的地址,数据输出就是根据变量和地址的对应关系找到

3、变量地址,然后从地址中取出数据。数据输入就是将值送到变量所在存储单元中。如图 7-1所示, i=2、 j=6、 k=8通过变量 i、 j、 k来访问存储单元。2. 间接访问将变量对应的地址放入另一个存储变量中,输出数据时先找到存放地址的单元地址,从中取出地址,然后到该地址所指单元取出数据。如图 7-1所示,如变量 i,不知道其值及地址,而只知道它的地址放在 3000、 3001中,因此可通过存放地址的单元找到变量 i的对应地址 2000,再由地址 2000找到最终要访问的变量 i的值 2。页码,1/18第七章 指 针2010-5-31http:/ i_pointer, 赋值 i_pointer

4、= 【说明】 定义中的标识符就是变量名,“ *”表示其后的变量为指针变量。 一个指针变量只能指向同一个类型的变量,即只能存放同一类型变量的地址。例如:int a, b; /*定义两个整型变量 a和 b*/int *p1, *p2; /*定义两个指向整型变量的指针变量 p1和 p2*/float *p3; /*定义一个指向实型变量的指针变量 p3*/char *p4; /*定义一个指向字符型变量的指针变量 p4*/一个指针变量定义后,就可以用来存放变量地址了。但刚定义的指针变量未经赋值时,并不指向任何变量,要想使它有确定的指向,必须将变量的地址赋给该指针变量。例如:int a=2;int *p;

5、p=内存用户数据区 2000 2 变量 i2002 6 变量 j2004 8 变量 k3000 2000 变量 i_pointer图 7 1 变 量存放示意 图p ap a2”(指针变量 p得到变量 a的地址)后,指针变量 p才指向变量 a,如图 7-2所示。7.2.2 指针变量的引用指针变量定义后就可以对它进行赋值、输出值、访问其所指向的变量等操作。但请注意:指针变量只能存放地址,不要将非地址类型的数据赋值给一个指针变量。1. 指针运算符指针运算符有如下两个:( 1) /*定义两个整型变量 a和 b*/int *p1, *p2; /*定义两个指向整型变量的指针变量 p1和 p2*/a=50;

6、 b=10; p1= /*把变量 a的地址赋给 p1,使 p1指向变量 a*/p2= /*把变量 b的地址赋给 p2,使 p2指向变量 b*/printf(“%d, %d n“, a, b); /*输出变量 a和 b的值 */printf(“%d, %d n“, *p1, *p2); /*输出 p1、 p2所指向的变量的值 */运行结果为:50, 102. 指针运算符的运算法则 结合性。自右向左。若: int a, b, *p1, *p2;p1=p2=则: p= a=3;则:“ (*p)+;”相当于“ a+;”,即语句执行结果是 a的值为 4, p仍指向变量 a。“ *p+;”相当于“ *(p

7、+);”先执行 *p,即取出 a的值 3,然后 p值增 1,即 p不再指向变量 a,而是 a的下一个存储单元。【例 7-2】交换两个指针变量的指向。main( )int *p1, *p2, a, b, *p;图 7-2页码,3/18第七章 指 针2010-5-31http:/ a*p1 c*p2 b*p2p1= p2= printf (“n%d,%dn“, *p1, *p2);if (ab) swap(printf (“na=%d,b=%dn“, a, b);swap(int *pa,int *pb)int t;t=*pa; *pa=*pb; *pb=t; 运行结果:键盘输入 10, 50a=

8、50, b=10该程序中,变量的地址作实参,利用指针变量作形参接受实参传递过来的变量地址,使得形参 pa和 pb分别指向对象 a和 b,函数 swap( )执行后, pa和 pb指向的对象的值被交换了,也就是变量 a和 b的值被交换了,如图 7-5所示。int *p, *q;scanf(“%d, %d“, p= q=if (ab)swap(p, q);printf (“na=%d,b=%dn“, a, b);swap(int *pa,int *pb)int t;t=*pa; *pa=*pb; *pb=t; 指针变量做实参也是值传递,但是由于指针变量中存放的是地址,因而传递给形参的是所指对象的地

9、址,从而实现了两个变量值的交换,如图 7-6所示。通过以上分析可知,要想通过函数调用得到 n个要改变的值,可以用以下思想方法: 在主调用函数中设置 n个变量,并且用 n个指针变量指向它们; 然后将指针变量作实参,将这 n个变量的地址传给所调用的函数的形参; 通过形参指针变量改变该 n个变量的值; 主调用函数中就可以使用这些改变了值的变量。【例 7-6】输入 a、 b、 c三个整数,按大小顺序输出。/*排序输出 3个数的程序 T706.C*/void swap (int *pt1, int *pt2)int p;p=*pt1; *pt1=*pt2; *pt2=p;void exchange(in

10、t *q1, int *q2, int *q3; )if(*q1max)max=*p;else if (*pmin)min=*p;return;main( )int i,number10;printf(“enter 10 integer numbers:n“);for(i=0;i10;i+)scanf(“%d“,max_min_value(number,10);printf(“nmax=%d,min=%dn“,max,min);【说明】 在函数 max_min_value中求出的最大值和最小值放在 max和 min中。由于它们是全局变量,因此在主函数中可以直接使用。 函数 max_min_va

11、lue中的语句:max=min=*array;array是数组名,它接收从实参传来的数组 numuber的首地址。 *array相当于 *(“等价。 在执行 for循环时, p的初值为 array+1,也就是使 p指向 array1。以后每次执行 p+,使 p指向下一个元素。每次将 *p和max与 min比较,将大者放入 max,小者放 min。 函数 max_min_value的形参 array可以改为指针变量类型。实参也可以不用数组名,而用指针变量传递地址。7.3.3 字符串指针变量字符串指针变量的定义说明与指向字符变量的指针变量说明是相同的。对指向字符变量的指针变量应赋予该字符变量的地址

12、。如:char *s=“C Language“;表示 s是一个指向字符串的指针变量。把字符串的首地址赋予 s。它等效于:char *s;s=“C Language“;【例 7-13】输出字符串中第 n个字符后的所有字符。/*输出字符串中第 n个字符后的所有字符的程序 T713.C*/main( )页码,12/18第七章 指 针2010-5-31http:/ *ps=“this is a desk “;int n=10;ps=ps+n;printf(“%sn“,ps);运行结果为:desk在程序中对 ps初始化时,即把字符串首地址赋予 ps。执行 ps= ps+10之后, ps指向字符“ d”,

13、因此输出为“ desk”。【例 7-14】使用指针变量指向一个格式字符串,用于在 printf函数中输出二维数组的各种地址表示的值。/*利用指针变量在 printf函数中输出二维数组的各种地址表示的程序 T714.C*/main( )static int a34=0,1,2,3,4,5,6,7,8,9,10,11;char *PF;PF=“%d, %d, %d, %d, %dn“;printf(PF,a,*a,a0,printf(PF,a+1,*(a+1),a1,printf(PF,a+2,*(a+2),a2,printf(“%d,%dn“,a1+1,*(a+1)+1);printf(“%d,

14、%dn“,*(a1+1),*(*(a+1)+1);在 printf语句中用指针变量 PF代替了格式串。这是程序中常用的方法。【例 7-15】使用字符串指针作为参数,把一个字符串的内容复制到另一个字符串中,并且不能使用 strcpy函数。/*利用字符串指针复制字符串的程序 T715.C*/cpystr(char *pss,char *pds)while(*pds=*pss)!=0)pds+;pss+; main( )char *pa=“CHINA“,b10,*pb;pb=b;cpystr(pa,pb);printf(“string a=%snstring b=%sn“,pa,pb);在本例中,程

15、序完成了两项工作:一是把 pss指向的源字符串复制到 pds所指向的目标字符串中。二是判断所复制的字符是否为“ 0”,若是则表明源字符串结束,不再循环;否则, pds和 pss都加 1,指向下一字符。在主函数中,以指针变量 pa、pb为实参,分别取得确定值后调用 cprstr函数。由于采用的指针变量 pa和 pss, pb和 pds均指向同一字符串,因此在主函数和cprstr函数中均可使用这些字符串。也可以把 cprstr函数简化为以下形式:cprstr(char *pss,char*pds)while (*pds+=*pss+)!=0);即把指针的移动和赋值合并在一个语句中。进一步分析还可发

16、现“ 0”的 ASCII码为 0,对于 while语句只要表达式的值为非 0就循环,为 0则结束循环,因此也可省去“ != 0”这一判断部分,而写为以下形式:页码,13/18第七章 指 针2010-5-31http:/ (char *pss,char *pds)while (*pdss+=*pss+);表达式的意义可解释为:源字符向目标字符赋值,移动指针,若所赋值为非 0则循环,否则结束循环。这样使程序更加简洁。【例 7-16】例 7-15简化后的程序如下所示:/*利用字符串指针复制字符串的简化程序 T716.C*/cpystr(char *pss,char *pds)while(*pds+=

17、*pss+); main( )char *pa=“CHINA“,b10,*pb;pb=b;cpystr(pa,pb);printf(“string a=%snstring b=%sn“,pa,pb);用字符数组和字符指针变量都可实现字符串的存储和运算,但是两者是有区别的。使用时应注意以下几个问题: 字符串指针变量本身是一个变量,用于存放字符串的首地址。而字符串本身是存放在以该首地址为首的一块连续的内存空间中,并以“ 0“作为串的结束。字符数组是由若干个数组元素组成的,它可用来存放整个字符串。 对字符串指针方式char *ps=“C Language“;可以写为:char *ps;ps=“C L

18、anguage“;而对数组方式:static char st=“C Language“;不能写为:har st20;st=“C Language“;7.3.4 指针与二维数组1. 二维数组的地址设有整型二维数组 int a34=0,1,2,3,4,5,6,7,8,9,10,11,假设数组 a的首地址为 1000,则各下标变量的首地址及其值如图 7-9所示。C语言允许把一个二维数组分解为多个一维数组来处理。因此数组 a可以按行分解为三个一维数组,即 a0、 a1、 a2,每个一维数组又含有 4个元素。例如,一维数组 a0,含有 a00、 a01、 a02、 a03四个元素。从二维数组的角度来看,

19、 a是二维数组名, a代表整个二维数组的首地址,也是二维数组 0行的首地址,等于 1000。 a+1代表 1行的首地址,等于 1008, a+2代表 2行的首地址,等于 1016,如图 7-10所示。10000100211004210063100841010510126101471016810189102010102211页码,14/18第七章 指 针2010-5-31http:/ 1000。 *(a+0)或 *a是与 a0等效的,它表示一维数组 a00号元素的首地址,也为 1000。 printf(“%d,“,a);printf(“%d,“,*a);printf(“%d,“,a0);prin

20、tf(“%d,“,printf(“%dn“,printf(“%d,“,a+1);printf(“%d,“,*(a+1);printf(“%d,“,a1);printf(“%d,“,printf(“%dn“,printf(“%d,“,a+2);printf(“%d,“,*(a+2);printf(“%d,“,a2);printf(“%d,“,printf(“%dn“,printf(“%d,“,a1+1);printf(“%dn“,*(a+1)+1);printf(“%d,%dn“,*(a1+1),*(*(a+1)+1);2. 指向二维数组的指针变量a 1000a+1 1008a+2 1016 图

21、 10a0a1 a2 页码,15/18第七章 指 针2010-5-31http:/ (*指针变量名 )长度 其中,“类型说明符”为所指数组的数据类型,“ *”表示其后的变量是指针类型,“长度”表示二维数组分解为多个一维数组时,一维数组的长度,也就是二维数组的列数。应注意:“ (*指针变量名 )”两边的括号不可少,如缺少括号则表示是指针数组,意义就完全不同了。把二维数组 a分解为一维数组 a0、 a1、 a2之后,设 p为指向二维数组的指针变量。可定义为:int (*p)4它表示 p是一个指针变量,它指向包含 4个元素的一维数组。而 p+i则指向一维数组 ai。从前面的分析可得出 *(p+i)+

22、j是二维数组 i行 j列的元素的地址,而 *(*(p+i)+j)则是 i行 j列元素的值。【例 7-18】利用指向二维数组的指针变量实现二维数组数据的输出。/*利用指针变量实现二维数组数据的输出程序 T718.C*/main( )int a34=0,1,2,3,4,5,6,7,8,9,10,11;int(*p)4;int i,j;p=a;for(i=0;i3;i+)for(j=0;j4;j+) printf(“%2d “,*(*(p+i)+j);printf(“n“);3. 二维数组的指针作为函数参数一维数组的指针可以进行参数传递,二维数组的指针同样可以进行参数传递。【例 7-19】有 3个学

23、生,各 4门课程,计算总平均分数和查找第 n个学生的成绩。/*计算数据和查找数据的程序 T719.C*/main( )void average( ); void search( );static float score34=65,67,70,60,80,87,90,81,90,99,100,98;scanf(“%d“,average(*score,12);search(score,n);void average(p,n)float *p;int n;float *p_end;float sum=0,aver;p_end=p+n;for(;pp_end;p+)sum=sum+(*p);aver=

24、sum/n;页码,16/18第七章 指 针2010-5-31http:/ search(p,n)float (*p)4;int n;int i;printf(“the score of No.%d are :n“,n);for (i=0;i4;i+)printf(“%5.1f“,*(*(p+n)+i);printf(“n“); 程序运行结果为:average=82.25the score of No.2 are :90.0 99.0 100.0 98.0【例 7-20】在上题的基础上,查找有一门以上课程不及格的学生,打印出他们的全部课程的成绩。main( )void search( );sta

25、tic float score34=65,57,70,60,58,87,90,81,90,99,100,98;search(score,3);void search(p,n)float (*p)4;int n;int i,j,flag;for (j=0;jn;j+) /*查找人 */flag=0; /*不及格标志 */for(i=0;i4;i+) /*查找某人的成绩 */if(*(*(p+j)+i)60) flag=1;if(flag)printf(“No. %d is fail,his(her) scores are:n“,j+1);for (i=0;i4;i+)printf(“%5.1f

26、“,*(*(p+j)+i);printf(“n“);程序运行结果为:No.1 fails, his(her) scores are:65.0 57.0 70.0 60.0 No.2 fails, his(her) scores are:58.0 87.0 90.0 81.0页码,17/18第七章 指 针2010-5-31http:/ 结 七1. 指针的数据类型int *p; p为指向整型数据的指针变量。int (*p)n; p指向含 n个元素的一维数组。int *p( ); 返回值为指针的函数,指针指向整型数据。int *p; 二级指针变量。int (*p)n; p是一个指向指针的指针变量,被指向的指针变量指向一个含 n个整型数据的一维数组。2. 指针的运算指针变量加(减)一个整数,例如: p+、 p-、 p+i、 p-i、 p+=i、 p-=i等,实际上是执行 p+i*size(数据类型 )。3. 指针变量赋值:int a,bint *p1=p1=p2;页码,18/18第七章 指 针2010-5-31http:/

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

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报