




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第6章指针
6.1地址与指针内存是计算机的一个重要组成部分,存放“正在”使用的数据和“正在”执行的程序。内存单元的基本单位是字节。为了方便对内存的访问,每一个内存单元都有一个编号,这个编号就是内存的地址。C程序中的每一个变量、每一个函数,在内存中都会对应一定的内存单元。
00000002┇20002002┇┇3540图6.1
内存单元中存放的数据即为内存单元中的内容。如图2000单元中存放的数据是35,2002单元中存放的数据是40。在C程序的声明部分,需要对程序中用到的变量进行说明,如intx,y说明了两个整型变量x和y。对于这些变量,C编译程序在编译时会在内存中分配相应的内存单元,x和y实际上就是内存单元的符号地址。例如:在程序中如果有语句:
x=68;
y=x+3;
则计算机会在x单元中存入数据68,然后将x单元的数据68加上3后将结果71存入y单元。如图6.2所示。00000002┇20002002┇┇68图6.2xy71说明:①编译程序会在内存中选取空闲的单元分配给变量x和y,这里不妨假设x为2000单元,y为2002单元。②在ANSIC中,一个整型变量占两个字节。C程序中的每一个函数经过编译后,生成的目标代码在内存中是连续存放的,函数目标代码的起始地址称作函数的首地址,也叫入口地址。在C语言中,函数名本身就代表着函数的入口地址。6.1.2指针1.指针在计算机中,对一个内存单元的访问是通过地址来实现的,地址“指向”需要操作的内存单元。因此在C语言中,把地址形象地称为指针。C语言中定义的变量在内存中都对应一定的内存单元,也就对应一个地址。变量对应的地址称作变量的指针。所谓函数的指针就是函数的入口地址。2.指针变量在计算机中,地址也是用二进制数表示的,也是数据(如2001,2002),所以地址也可以存放在另一个变量中。用来存放指针数据的变量叫作指针变量。例如在某C程序中定义了一个变量a,假设a的地址是3005,可以定义一个变量pointer,用于存放a的地址3005。则pointer就是一个指针变量。既可以定义一个指针变量用来存放变量的地址,也可以定义一个指针变量用来存放函数的入口地址。用来存放变量地址的指针变量称作指向变量的指针变量,简称指针变量;用来存放函数入口地址的指针变量称作指向函数的指针变量。有了指向变量的指针变量的概念,对变量的访问就可以间接进行。图6.3是直接访问和间接访问的示意图:直接访问:利用变量名a将86送入存储单元。
a=86间接访问:利用指针变量pointer访问变量a。
pointer=&a/*变量a的地址送指针变量pointer*/*pointer=86/*将86送入存储单元*/图6.3直接访问和间接访问的示意图6.2指针变量6.2.1指针变量的定义
C语言规定程序中使用的变量必须先定义,指定其类型。编译程序根据变量的类型分配内存单元。指针变量是用来存放地址的,必须定义成“指针类型”。指针变量定义的形式为:基类型*指针变量名 “基类型”表示指针变量所指向的变量的类型, “*”表示定义的是指针变量。例如: int*pointer; 定义了一个指针变量pointer,指向整型变量,也就是说变量pointer只能用来存放整型变量的地址。再如: float*p1,*p2;定义了两个指针变量p1和p2,它们是指向实型变量的,也就是说变量p1和p2只能用来存放实型变量的地址。6.2.2指针变量的使用
指针变量的使用包括给指针变量赋值(使指针指向某个变量)通过指针引用存储单元(引用指针变量所指向的变量) 移动指针。1.指针变量的赋值可以给指针变量赋地址值,且地址值必须是基类型变量的。为此C语言提供了取地址运算符&,它的作用是取得变量所占用的存储单元的首地址。例如,语句“inta,*pointer;”之后,可以有语句:
pointer=&a;目的是将变量a的地址值赋给指针变量pointer。
注意变量a的类型和指针变量pointer的基类型必须一致。下面的定义和语句是错误的:
floata; int*pointer pointer=&a;也可以在定义指针变量的同时对其初始化,例如:
inta; int*pointer=&a;也可以给指针变量赋空值NULL。例如:
p=NULL;NULL是在stdio.h头文件中定义的预定义符,因此如果程 序中使用了NULL,应该在程序前出现预定义行: #definenull0。
NULL的代码值为0,所以上述语句等价于:
P=0;
注意:这时指针p是一个“空”值,或者说它不指向任何内存单元。2.通过指针访问变量 可以使用指针访问它所指向的变量。C语言提供了指针运算符*(也称为间接访问运算符),它的作用是通过指针变量间接访问它所指向的变量。【例6.1】通过指针变量访问变量。main(){intx; /*定义整型变量x*/floaty;/*定义实型变量y*/int*px=&x;/*定义指向整型变量的指针变量px,并指向x*/float*py=&y;/*定义指向实型变量的指针变量py,并指向y*/*px=20;/*通过指针变量px给变量x赋值*/*py=19.600;/*通过指针变量py给变量y赋值*/*px=*px/2;/*通过指针变量px访问变量x*/y=y+10; printf("*px=%d,*py=%6.3f\n",*px,*py);printf("x=%d,y=%6.3f\n",x,y);}
间接访问运算符(*)必须出现在运算对象的左边,运算对象或者是地址或者是存放地址的指针变量。例如:
j=*(&i);表达式&i求出变量i的地址,间接访问运算符*取出地址中存放的内容,然后赋给变量j。 运算符*和&的优先级相同,因此上例可以写成:j=*&i。【例6.2】输入x和y并求和。请注意x、y和px、py的异同。main(){intx,y;int*px=&x,*py=&y;printf("usingx,y:\nenterx,y:");scanf("%d%d",&x,&y);printf("x=%d,y=%d,x+y=%d\n",x,y,x+y);printf("*px=%d,*py=%d,*px+*py=%d\n",*px,*py,*px+*py);printf("usingpx,py:\nenterx,y:");scanf("%d,%d",px,py);/*通过指针输入x,y*/printf("x=%d,y=%d,x+y=%d\n",x,y,x+y);printf("*px=%d,*py=%d,*px+*py=%d\n",*px,*py,*px+*py);}【例6.3】注意&运算符和*运算符混合使用的情况。main(){intx=3,y=4,z,*px,*py;z=*&x;px=&x;py=&y;py=&*px;printf("x=%d,y=%d,z=%d\n",x,y,z);printf("*px=%d,*py=%d\n",*px,*py);}如图所示:图(a)是执行了语句“px=&x;”和“py=&y;”时的情况,图(b)是执行了语句“py=&*px;”的情况。可以看出,当执行px=&x后,*px和*&x是相同的,都是和变量x等同的,&x表示取x的地址,再加上*表示取这个地址的内容,即x的值,执行z=*&x后,z取得x的值。【例6.4】输入a和b两个整数,按先大后小顺序输出。main(){inta=5,b=9,temp;if(a<b){temp=a;a=b;b=temp;}printf("\na=%d,b=%d",a,b);}程序运行结果如下:a=9,b=5
在这个程序中,当a<b时,a和b的内容进行了交换。【例6.5】重新编写例6.4。main(){inta=5,b=9;int*pa=&a,*pb=&b,*p;if(a<b){p=pa;pa=pb;pb=p;}printf("\na=%d,b=%d",a,b);printf("\nmax=%d,min=%d",*pa,*pb);}程序运行结果如下:a=5,b=9max=9,min=5例6.5中的a和b的内容并没有交换,通过指针的交换实现了数据的先大后小输出。交换前指针的情况如图6.5(a),交换后的指针情况如图6.5(b)。6.3一维数组的指针6.3.1指向数组的指针变量类似于指向简单变量的指针。只要将数组的首地址(或数组名)赋给指针变量。inta[10];int*p;则语句:
p=&a[10];(或p=a;)称p指针为指向数组a的指针变量。6.3.2一维数组的指针
指针变量既然可以指向变量,当然也可指向数组和数组元素。一维数组的指针是指数组在内存中的起始地址,一维数组元素的指针是指数组元素在内存中的起始地址。如果指针变量p就是指数组a的指针变量,则对数组的引用可以用以下访问方式:a[i],p[i],*(a+i),*(p+i)等。(i为相应数组元素的下标)【例6.6】输出数组元素的三种方法(1)通过数组名由于数组名就是数组的首地址,所以也可以通过数组名输出数组元素。main(){inta[10],i;for(i=0;i<10;i++)scanf(“%d”,&a[i]);printf(“\n”);for(i=0;i<10;i++)printf(“%d”,*(a+i));}(2)下标法main(){inta[10],i;for(i=0;i<10;i++)scanf(“%d”,&a[i]);printf(“\n”);for(i=0;i<10;i++)printf(“%d”,a[i]);}(3)指针法main(){inta[10],*p,i;for(i=0;i<10;i++)scanf(“%d”,&a[i]);printf(“\n”);for(p=a;p<(a+10);p++)printf(“%d”,*p);}【例6.7】输入4个同学的成绩并求平均成绩.#include”stdio.h”main(){floatscore[4],*p,sum=0,aver;inti,j;printf(”Input4scores:\n”);for(i=0;i<4;i++)scanf(“%f”,&score[i]);p=score;for(j=0;j<4;j++)sum=sum+*(p+j);aver=sum/4.;printf(“aver=%5.2f\n”,aver);}6.4指针与字符串
6.4.1指向字符串的指针变量C语言对字符串常量是按字符数组处理的,在内存中开辟了一个字符数组存放字符串常量,因此可以使用字符型指针变量指向字符串常量。例如:char*p=”Iamstudent”;或char*p;p=”Iamstudent”;
1.用数组实现对字符串的访问【例6.8】#include”stdio.h”main(){chard[]=“Iam
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 地方课程课题申报书
- 亚马逊购买店铺合同范本
- 动漫授权协议合同范本
- mcn公司合伙合同范例
- 合同范本理解写好
- 个人软件销售合同范本
- 合伙餐饮采购合同范本
- 知识产权保护高地建设的实施计划
- 推动农业新质生产力发展路径探索
- 民营经济高质量发展推动力的关键措施
- (必刷)湖南省医学院校高职单招职业技能测试必会题库(含往年真题)
- 2025《医药企业防范商业贿赂风险合规指引》解读课件
- 血透病人皮肤瘙痒课件
- 2025年度船舶焊接维修工程合同范本资料下载
- 贵州茅台课程设计
- 充电桩的建设合作方案
- 工业摄像头知识培训课件
- 2024-2025学年六年级数学人教版上册寒假作业(综合基础复习篇含答案)
- DB33T 1134-2017 静钻根植桩基础技术规程
- 楼梯塑料滴水线施工方案
- 航天器空间飞行器动力学与控制考核试卷
评论
0/150
提交评论