版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第八章应用指针编制程序指针是C语言中广泛使用的一种数据类型,是最能体现C语言特色的部分,也是C语言的灵魂。第一节概述指针与内存地址:为了区分存储体内的存储单元,将它们逐一进行编号,这些编号称为“内存地址”。内存地址在程序运行过程中起到寻找变量内存中存放数值的作用,就像用一个指针指向了一个变量,因此变量的内存地址称为该变量的“指针”。•1指针的概念–变量与地址内存中每个字节有一个编号-----地址内存0…...程序中:inti;2000200120022003floatk;i编译或函数调用时为其分配内存单元k2005…...变量是对程序中数据存储空间的抽象–指针与指针变量•指针:一个变量的地址•指针变量:专门存放变量地址的变量叫~指针…...200020012002200320042005整型变量i10变量的内容变量的地址变量i_pointer2000指针变量指针变量2006变量地址(指针)指向地址存入指针变量变量变量值–&与*运算符•含义含义:取变量的地址•两者关系:互为含义:取指针所指向变量的内容逆运算优先级:2•理解优先级:2结合性:自右向左结合性…...:自右向左单目运算符优先级:2•理解优先级:2结合性:自右向左结合性…...:自右向左单目运算符i_pointer*i_pointer&i_pointer200010i2000200120022003200420052006整型变量i10i_pointer&i&(*i_pointer)i_pointer=&i=&(*i_pointer)i*i_pointer*(&i)i=*i_pointer=*(&i)变量i_pointer2000指针变量i_pointer-----指针变量,它的内容是地址量*i_pointer----指针的目标变量,它的内容是数据&i_pointer---指针变量占用内存的地址–直接访问与间接访问•直接访问:按变量地址存取变量值•间接访问:通过存放变量地址的变量去访问变量…...例i=3;-----直接访问2000整型变量i20012002200320042005200610203变量i_pointer2000指针变量例*i_pointer=20;-----间接访问例k=i;--直接访问k=*i_pointer;--间接访问…...2000200120022003200420052006整型变量i10整型变量k10变量i_pointer2000指针变量•2指针变量指针变量与其所指向的变量之间的关系i_pointer变量ii*i_pointer20003&ii_pointer*i_pointeri=3;*i_pointer=3–指针变量的定义•一般形式:[存储类型]数据类型*指针名;例int*p1,*p2;float*q;表示定义指针变量合法标识符指针变量本身的存储类型staticchar*name;指针的目标变量的数据类型不是‘*’运算符注意:1、int*p1,*p2;与2、指针变量名是p1,p2,不是*p1,*p23、指针变量只能指向定义时所规定类型的变量4、指针变量定义后,变量值不确定,应用前必须先赋值int*p1,p2;例:“直接访问”:直接通过变量名存取数值的方式。如:intk;表示变量k的地址scanf(“%d”,&k);printf(“%d\n”,k);表示变量k的值在本程序段中就是直接访问变量k(包括存取数值)。“间接访问”:将变量地址存入到另一指针变量中,再通过该指针变量来存取变量的数值的方式。intk=100100int*pk&k&kpk=&k;通过指针变量pk就可以间接访问变量k了。【例8.1】运用指针变量间接访问变量的值。程序如下:#include<stdio.h>main(){定义指针变量ptr1和ptr2ptr1指inta=-35,b[5]={1,2,3,4,5};向变量aint*ptr1,*ptr2;ptr1=&a;ptr2=&b[0];直接访问ptr2指printf("a=%d,b=%d\n",a,b[0]);向数组bprintf("a=%d,b=%d\n",*ptr1,*ptr2);}间接访问运行程序第二节指针变量一、指针变量的定义及初始化指针变量定义及初始化的一般格式:数据类型*指针变量名[=初值];功能:定义指向给定“数据类型”的变量或数组的指针变量,并同时为指针变量赋“初值”。如:int*ptr1;float*ptr2;char*ptr3;•指针变量指针变量与其所指向的变量之间的关系i_pointer变量ii*i_pointer20003&ii_pointer*i_pointeri=3;*i_pointer=3–指针变量的定义•一般形式:[存储类型]数据类型*指针名;例int*p1,*p2;float*q;表示定义指针变量合法标识符指针变量本身的存储类型staticchar*name;指针的目标变量的数据类型不是‘*’运算符注意:1、int*p1,*p2;与2、指针变量名是p1,p2,不是*p1,*p23、指针变量只能指向定义时所规定类型的变量4、指针变量定义后,变量值不确定,应用前必须先赋值int*p1,p2;–指针变量的初始化一般形式:[存储类型]数据类型*指针名=初始地址值;例inti;int*p=&i;赋给指针变量,不是赋给目标变量变量必须已说明过类型应一致例inti;例int*p=int*p=&i;&i;inti;int*q=p;用已初始化指针变量作初值例main(){inti;staticint*p=&i;..............不能用auto变量的地址去初始化static型指针}()指针变量必须先赋值,再使用例main(){inti=10;…...int*p;*p=i;printf(“%d”,*p);2000200120022003200420052006整型变量i10}危险!指针变量p随机例main(){inti=10,k;int*p;p=&k;*p=i;printf(“%d”,*p);}指针变量定义及初始化的说明:1.允许一次定义多个指针变量并赋初值。2.“数据类型”指所定义的指针变量用来存放何种类型变量的地址,因此也称为指针变量的基类型。3.定义指针变量时,指针变量名前必须有一个“*”,4.。初值(表示地址的数据)的形式通常有三种:此处为定义指针变量的标志,不是“指针运算符”“&变量名”、“&数组元素”和“数组名”。二、指针变量的引用指针变量引用的一般形式:*指针变量功能:间接引用所指针变量所指向的值。【例8.2】用指针变量进行数据的输入、输出。程序如下:#include<stdio.h>main(){intm,*p;scanf("%d",&m);p=&m;printf("%d\n",*p);}运行程序【例8.3】改变指针变量指向的变量的值。程序(1)#include<stdio.h>main(){inta=3,b=5,t;int*ptr1=&a,*ptr2=&b;t=*ptr1;*ptr1=*ptr2;*ptr2=t;printf("a:value%d\tb:value%d\n",a,b);printf("*ptr1:value%d\t*ptr2:value%d\n",*ptr1,*ptr2);}运行程序执行过程:ptr1a&a3tptr2b3&b5黄色箭头表示数据传递方向交换后输出结果为:a:value5b:value3*ptr1:value5*ptr2:value3程序(2)#include<stdio.h>main(){inta=3,b=5;int*ptr1=&a,*ptr2=&b,*t;t=ptr1;ptr1=ptr2;ptr2=t;printf("a:value%d\tb:value%d\n",a,b);printf("*ptr1:value%d\t*ptr2:value%d\n",*ptr1,*ptr2);}运行程序执行过程:ptr1a&b&a3tptr2b&a&b&a5交换后输出结果为:a:value3b:value5*ptr1:value5*ptr2:value3三、指针变量的运算1.C语言中两个关于指针的运算符:&运算符:取地址运算符,&m即是变量m的地址。*运算符:指针运算符,*ptr表示其所指向的变量。*运算和&运算之间的关系:“&”和“*”都是单目运算符;优先级高于所有的双目运算符;结合性均为自右向左;“取地址符&”与“指向运算符*”如有:intk,*pk;pk=&k;之间是互逆的。则:*pkk;*(&k)*pkk&(*pk)&kpk。2.与指针变量相关的其它运算:除了“取地址运算”和“指向运算”外,TurboC仅允许对指针变量作三种运算:指针变量的比较运算(关系)、指针变量的减法运算、指针变量与一个整数的加减运算。(1)指针变量的比较运算在内存中,假设两个指针变量p,q指向同一个数组,则允许对p、q进行比较运算。如:p指针所指元素位于q所指元素之后时,则p>q的值为1,否则值为0。两指针p、q指向同一元素时,则p==q的值为1。(2)指针变量的减法运算当两指针变量p,q指向同一数组时,p-q的结果为p所指元素与q所指元素之间相隔的元素的个数(不是地址值之差,也不是变量值之差)。(3)指针变量与整数的加减运算一个指针指向一个数组时,指针与一个整数n相加或相减,表示将指针向后或向前移动了n个元素。四、指针变量作函数的参数使用指针类型做函数的参数,实际上是将一个变量的地址传向另一个函数。由于被调函数中获得了变量的地址,该地址空间中的数据变更在函数调用结束后将被物理地址保留。【例8.4】输入两个变量的值,按由大到小的顺序输出。程序如下:#include<stdio.h>main(){voidchang();/*函数声明*/int*p1,*p2,a,b,*t;运行程序scanf("%d,%d",&a,&b);p1=&a;p2=&b;chang(p1,p2);/*函数调用*/printf("%d,%d\n",*p1,*p2);}voidchang(int*pt1,int*pt2){intt;if(*pt1<*pt2)/*交换内存变量的值*/{t=*pt1;*pt1=*pt2;*pt2=t;}}程序运行时内存中数据的存放其指向关系p1p1&aa&aap1apt13pt15p1a&a3&a&a&a5p2bp2p2p2b&b5&bb&bb&b3pt25pt23&b&b程序结果:3,5<回车>5,3【例8.5】输入a、b、c3整数,按由大到小输出。程序如下:#include<stdio.h>swap(int*pt1,int*pt2){inttemp;temp=*pt1;*pt1=*pt2;*pt2=temp;exchange(int*q1,int*q2,int*q3){}if(*q1<*q2)swap(q1,q2);if(*q1<*q3)swap(q1,q3);if(*q2<*q3)swap(q2,q3);}运行程序main(){inta,b,c,*p1,*p2,*p3;scanf("%d,%d,%d",&a,&b,&c);p1=&a;p2=&b;p3=&c;exchange(p1,p2,p3);printf("\n%d,%d,%d\n",a,b,c);}程序结果;9,0,10<回车>10,9,0第三节指针与数组一、用指向一维数组的指针变量处理数组元素对一维数组的引用,既可以用传统的数组元素的下标法,也可使用指针的表示方法。例如:inta[10],*ptr;ptr=a;或ptr=&a[0];由于a(数组名)就是数组的首地址,&a[0]是数组元素a[0]的地址(也是数组的首地址),因此两条赋值操作效果完全相同。指针变量ptr即为指向数组a的指针变量。TurboC规定指针对数组的表示法:(1)ptr+n与a+n表示数组元素a[n]的地址,即&a[n]。对整个a数组来说,共有10个元素,n的取值为0~9,则数组元素的地址就可以表示为ptr+0~ptr+9或a+0~a+9,与&a[0]~&a[9]保持一致。(2)知道了数组元素的地址表示方法,*(ptr+n)(指针下标法)和*(a+n)(地址法)就表示为数组的各元素即等效于a[n](下标法)。(3)指向数组的指针变量也可用数组的下标形式表示为ptr[n],其效果相当于*(ptr+n)。【例8.6】(1)采用指针下标法输入输出数组各元素。程序如下:#include<stdio.h>main(){intn,a[10];int*ptr=a;for(n=0;scanf("%d",ptr+n);printf("output!\n");for(n=0;printf("%4d",*(ptr+n));printf("\n");n<=9;n++)n<=9;n++)}运行程序ptr图8-8循环结束后的指针变量指针变量的值在循环结束后,(ptr+9)指向数组的尾部的后面,但指针变量ptr仍然指向数组首地址。说明:在程序中要注意*ptr++所表示的含义。*ptr表示指针所指向的变量;ptr++表示指针所指向的变量地址加1个变量所占字节数,具体地说,若指向整型变量,则指针值加2,若指向实型,则加4,依此类推。而printf(“%4d”,输出指针指向的变量的值,然后指针变量加1。循环结束后,指针变量指向如图8-9所示:*ptr++)中,*ptr++所起作用为先a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]运行程序(2)利用指针法输入输出数组各元素#include<stdio.h>main(){intn,a[10];int*ptr=a;for(n=0;n<=9;n++)scanf("%d",ptr++);printf("output!\n");ptr=a;for(n=0;n<=9;n++)printf("%4d",*ptr++);printf("\n");}/*指针变量重新指向数组首址*/运行程序运行程序(1)、(2)均可获得如下结果:1234567890<回车>output!1234567890a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]1234567890ptpt程序(1)、(2)的运行结果一致,但运行结束后指针变量的指向却不相同,为什么?【例8.7】用一维数组的指针解决冒泡法排序问题。#include<stdio.h>main(){intn,i,j,k,x,a[10];int*p=a;/*定义指针变量p让它指向a*/for(i=0;i<10;i++)scanf("%d",p+i);/*用指针变量输入数组元素*/for(k=1;k<10;k++)/*循环控制比较轮数*/for(j=9,i=0;i<10-k;i++,j--)if(*(p+j)<*(p+j-1)){x=*(p+j);*(p+j)=*(p+j-1);*(p+j-1)=x;}/*交换相邻两元素的值*/for(i=0;i<10;i++)printf("%5d",*(p+i));/*输出排序后的结果*/printf("\n");}运行程序二、指针与二维数组由于数组元素在内存中是连续存放的。给指向整型变量的指针传递数组的首地址,则该指针也可以指向二维数组。如有定义:int*ptr,a[3][4];若赋值:ptr=a;则用ptr++就能访问数组的各元素。【例8.8】用指针法输入输出二维数组各元素。程序如下:#include<stdio.h>main(){inta[3][4],*ptr;inti,j;ptr=a[0];for(i=0;for(j=0;scanf("%d",ptr++);ptr=a[0];for(i=0;{i<3;j<4;i++)j++)/*指针的表示方法*/i<3;i++)}for(j=0;j<4;j++)printf("%4d",*ptr++);printf("\n");}运行程序三、数组的指针作函数的参数【例8.9】调用函数,求一维数组中的最大元素。分析:首先假设一维数组中下标为0的元素是最大和用指针变量指向该元素。后续元素与该元素一一比较,若找到更大的元素,就替换。函数的形式参数为一维数组,实际参数是指向一维数组的指针。程序如下:#include<stdio.h>main(){intsub_max();/*函数声明*/intn,a[10];运行程序int*ptr=a;intmax;for(n=0;scanf("%d",&a[n]);max=sub_max(ptr,10);printf("max=%d\n",max);n<=9;n++)/*输入数据*//*实参是指针*/}intsub_max(b,i)/*函数定义,形参为数组*/intb[],i;{inttemp,j;temp=b[0];for(j=1;if(temp<b[j])temp=b[j];return(temp);j<=i-1;j++)}四、字符指针与字符串字符指针的定义:char*pc;字符指针的赋值:char*pc,c;pc=&c;用字符串为字符指针初始化:char*pc=“TurboC”;字符数组与字符指针的区别:(1)字符数组可以是:charc[]=“book”;但不能是:charc;c[]=“book”;字符指针可以是:char*pc=“book”;也可以是:char*pc;pc=“book”;(2)当用字符串常量初始化时:字符数组获得了串中所有的字符(内容),字符指针获得了串首的地址(与串内字符无关)。【例8.10】使用字符指针输出字符串。程序如下:#include<stdio.h>main(){charstr[20];char*p=str;gets(str);printf("%s\n",p);}运行程序【例8.11】用指向字符串的指针变量处理两个字符串的复制。注意:若将串1复制到串2,要保证串2的长度大于或等于串1。#include<stdio.h>main(){charstr1[30],str2[20];char*ptr1=str1,*ptr2=str2;printf("inputstr1:");gets(str1);printf("inputstr2:");gets(str2);printf("str1------------str2\n");printf("%s.......%s\n",ptr1,while(*ptr2)*(ptr1++)=*(ptr2++);*ptr1='\0';printf("str1------------str2\n");printf("%s------------%s\n",str1,str2);运行程序}/*输入str1*//*输入str2*/ptr2);/*字符串复制*//*写入串的结束标志*/第四节指针与函数一、函数型指针的定义指向函数的指针变量的一般定义形式:类型如:int(*p)();说明:类型标识符为一个指针名,(不是函数名),该指(*标识符)()为被指针所指函数的返回值的类型;针只能指向函数;括号中为空,但必须有,表示该指针是专指函数的。二、函数型指针的赋值用函数名为指针初始化,表示指针指向该函数。int(*pf)();/*定义函数型指针*/intf();/*声明函数f*/pf=f;/*让指针pf指向函数f()*/说明:(1)当函数型指针指向了某一函数后,此函数的调用可以用函数名,也可以用指针;(2)函数型指针定义之后,不是固定指向某一个函数,可以先后指向不同的函数;(3)用函数名为指针赋值时,不必用参数;(4)用函数指针调用函数时,用(*p)代替原函数名;(5)对指向函数的指针变量,像p+n,p++,p--等运算是没有意义的。【例8.12】用指向函数的指针求a和b中的大者。#include<stdio.h>main(){intmax(int,int);int(*p)();inta,b,c;p=max;scanf("%d,%d",&a,&b);c=(*p)(a,b);printf("a=%d,b=%d,max=%d\n",a,b,c);}intmax(intx,inty){intz;if(x>y)z=x;elsez=y;return(z);}运行程序三、指针型函数调用函数,通常得到一个返回值,带回主调函数。如果返回值为一个指针,则该函数就是指针型函数。指针型函数的定义:格式:类型*标识符(参数表)说明:类型为指针所指变量的类型;标识符为函数名,不是指针名;参数为函数的形参。例如:int*a(intx,inty)【例8.13】编一指针型函数求二维数组中的最大值,并返回它的地址。程序如下:#include<stdio.h>#defineM3#defineN4int*max(inta[][N],intm){int*p,i,j;/*p存放最大元素的地址*/p=a;/*p指向数组a的第一个元素*/for(i=0;i<m;i++)for(j=0;j<N;j++)if(*p<*(*(a+i)+j))p=*(a+i)+j;return(p);/*地址作为函数值返回*/}运行程序main(){inta[M][N],i,j,*p;for(i=0;i<M;i++)for(j=0;j<N;j++)scanf("%d",&a[i][j]);p=max(a,M);for(i=0;i<M;i++){printf("\n");for(j=0;j<N;j++)printf("%5d",a[i][j]);}printf("\nmaxofais%d\n",*p);}运行程序第五节指针数组一、指针数组的定义类型*标识符[长度]如:int*pa[3];说明:类型指的是数组中所有指针的类型;标识符是一个数组名,定义的是一个数组,而不是定义一个指针;长度是数组中所含指针的个数。二、指针数组的初始化指针数组是由若干个指针变量组成的数组,因此必须用地址值为指针数组初始化。【例8.14】将若干个字符串按字母顺序输出。#include<stdio.h>main(){voidsort(char*name[],intn);voidprint(char*name[],intn);char*name[]={"Followme","Basic","GreatWall","Fortran","
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年光伏发电项目租赁合同简要
- 2024年信贷合同违约处理办法
- 2024年专有:项目资料保护协议
- 通信设备采购合同实施方案
- 2024年工程分包团队合作协议
- 2024年展销会策划与实施合同
- 2024年官方版买卖居间合同
- 2024年产品分销合作框架协议
- 企业职业生涯发展资源共享协议
- 2024年劳动合同追诉期限详解
- GB/T 7715-2014工业用乙烯
- 企鹅排队课件
- 部编版五年级语文上册《快乐读书吧》优秀课件
- 初中数学规律探索公开课完整教学课件
- 小学综合实践活动课课程标准
- 国家开放大学《现代汉语专题》章节自测参考答案
- 高三体育与健康教案
- 2022-2023学年天津市河西区高一年级上册学期期中数学试题【含答案】
- 国家开放大学《终身学习与职业发展》形考任务参考答案
- 山东省潍坊市2022-2023学年高二上学期期中考试语文试题 word版含答案
- 备用金申请单(完美版)
评论
0/150
提交评论