C语言教程第八章.ppt
《C语言教程第八章.ppt》由会员分享,可在线阅读,更多相关《C语言教程第八章.ppt(55页珍藏版)》请在三一办公上搜索。
1、第八章,指针,1/55,8.1 指针的概念8.2 指针变量的定义和引用8.3 指针与数组8.4 指针与字符串8.5 指针数组与指向指针的指针8.6 返回指针值的函数8.7 本章要点小结8.8 本章程序举例,2/55,8.1 指针的概念,一、数据的存取,1、内存地址,内存的每个字节都有一个编号,这个编号称为“内存地址”。,程序中的每个数据都对应着内存中的一个地址,从该地址开始的一个或多个字节用来存放该数据。,int i,j,k;,i,j,k,2、内存单元的地址和内存单元的内容的区别:,若i=3,j=5;,从图中可以看出它们的区别。,3/55,程序编译后已经没有i、j、k这些变量名了,而是将变量名
2、转换为变量的地址,计算机通过内存地址对变量进行存取。,二、直接访问和间接访问,1、直接访问方式:,、i=3;,、j=i+2;,、printf(%d,i);,、scanf(%d,、k=i+j;如何执行?,按变量的地址存取变量的方式,2、间接访问方式:,语言中可以定义整型变量、实型变量、字符型变量,各自存放相应类型的数据;另外还可以定义和使用一种特殊类型的变量,用来存放变量的地址。,4/55,假设已经定义变量 ip 用来存放整型变量的地址,它被分配到内存单元3000和3001。,ip,通过执行语句:ip=将整型变量i 的地址存放到变量ip中,即ip的值为变量i所对应的内存单元的起始地址2000。,
3、2000,现在要存取i的值可以这样做:先找到存放i的地址的内存单元地址(3000和3001),从中取出变量i的地址(2000),然后再对2000和2001单元进行存取这就称为间接访问。,3、关于“指向”的含义:,变量ip的值为2000,即变量i的地址,这样就在ip和i之间建立了一种联系:,5/55,通过变量ip知道变量i的地址,从而找到变量i的内存单元,因此说变量ip指向变量i,用箭头表示这种“指向”关系。,4、为了表示将数值10送到变量i中,可以有两种表示方法:,、将10送到变量i所标志的单元中;,10,、将10送到变量ip所指向的单元中;,10,6/55,三、指针与指针变量,通过地址能找到
4、所需的变量单元,可以说:地址“指向”该变量单元。因此,把一个变量的地址称为该变量的“指针”。,如果一个变量专门用来存放另一个变量的地址,则称它为“指针变量”。指针变量的值(即指针变量中存放的值)是指针(地址)。,注意区分“指针”和“指针变量”这两个概念。,四、说明,、程序中定义的每个变量在编译后都占有各自的内存单元,系统是通过内存地址对变量进行存取的;,7/55,、数据所占有的内存单元个数是由其数据类型决定的;,、首地址:即第一个单元的地址;,、表示地址的数与整数的区别;,、变量i、j的地址可能相邻,也可能不相邻,是由系统分配的,我们不必关心。,8/55,8.2 指针变量的定义和引用,8.2.
5、1 概述,1、指针运算符:*,为了表示指针变量和它所指向的变量之间的联系,用“*”表示指向的关系。,如:ip代表指针变量,*ip表示ip所指向的变量。即*ip也代表一个变量。,9/55,例:,、若:ip=&i;,i=5;,*ip=5;,结论:*ip与i等价。,、x=i+1;,x=*ip+1;,2、取地址运算符:&,它与一个变量连用,以得到该变量的内存地址。,3、说明:,、取地址运算符只能作用于变量:,不能作用于常量、表达式或寄存器变量:,、不能把整数赋值给一个指针变量:ip=3000;,、不能把一个指针变量的值赋值给一个整型变量:x=ip;,10/55,8.2.2 指针变量的定义与赋值,一、指
6、针变量的定义,1、格式:,类型名*指针变量名;,其中:、“*”表示定义的是指针变量;、“类型名”用来指定该指针变量可以指向的变量的类型;,2、例:,int i,*ip;,int*p1,*p2;,float x,*xp;,char*cp1,*cp2;,3、说明:,、“*”只表示定义的变量为指针变量,但指针变量名中并不包含“*”;*是指针变量的标志,不可丢掉;,、指针变量定义时,指定了它所指向的变量的数据类型;,ip=,p1=,xp=,cp1=,xp=,11/55,指针变量定义时必须指定其所指向的变量的数据类型,而且使用过程中只能指向同一种类型的变量。,、指针变量定义后,系统为变量分配一个存储单元
7、,用来存放地址;根据存储单元的长度分为大存储模式(长指针,4 Byte)和小存储模式(短指针,2 Byte);,、指针变量定义后,若不赋值,其值是不确定的。,二、指针变量的赋值,1、赋值语句:,int i,j,*p1,*p2;,p1=,char ch,*cp1,*cp2;,cp1=,2、初始化:,int x=4;,int x;x=4;,int i,*p1=,int i,*p1;p1=,12/55,3、说明:,、指针变量定义后,若不赋值,其值是不确定的;,、可以给指针变量赋空值(NULL),使指针变量不指向任何变量;,ip=NULL;,#define NULL 0,、指针变量的值为空值(NULL
8、)与未对指针变量赋值,意义不同;,、只能是同类型变量的地址进行赋值;,int i,*ip;char ch,*cp;,ip=,ip=,、可以将数组名或函数名赋给某些类型的指针变量;,int a10,*ip;,ip=,ip=a;,、不能将一个整型量(或任何其它非地址类型的数据)赋给一个指针变量;,int*ip;,ip=3000;,13/55,4、分析有关指针的程序时,画图是很好的方法:,若有:int i,*p;,p=,i=5;,int i,*p;,p=,&i,i=5;,5,8.2.3 指针变量的引用,int a,*p1,*p2;p1=,int a,*p1,*p2;,p1=,&a,printf(%x
9、,p1);,p2=p1;,&a,*p1=3;,3,printf(%d,*p1);,14/55,1、两个运算符:&和*,&:取地址运算符;,*:指针运算符(间接访问符);,2、说明:,、&既可作用于一般变量,也可作用于指针变量;,、*只能作用于指针变量;,、表达式中的*p与变量定义中的*p含义不同;,int i,*p=,、int a,*p=,int a,*p;p=,int a,*p;*p=,3、指针变量可以进行的操作:,int a,*p1,*p2;,、赋值:,p1=,p2=p1;,、输出:,printf(%x,p1);,、取内容:,*p1=5;,a=5;,printf(%d,*p1);,15/5
10、5,例8.1,#include void main()int a1=11,a2=22;int*p1,*p2;p1=,&a1,&a2,*p1,*p2,&a1,*p2,*p2,多个指针可以指向同一个存储单元。但在某一时刻,一个指针变量只能指向一个存储单元,因为指针变量在某一时刻只能存放一个变量的地址值。,Eg801.cpp,16/55,例8.2,#include void main()int a1=11,a2=22;int*p1,*p2,*p;p1=,&a1,&a2,*p1,*p2,&a1,&a2,*p1,*p1,&a1,*p2,*p2,使两个指针交换指向,Eg802.cpp,17/55,例8.3
11、,#include void main()int a1=11,a2=22,t;int*p1,*p2;p1=,&a1,*p1,&a2,*p2,11,22,11,交换两个指针变量所指向变量的值,Eg803.cpp,18/55,反映了指针变量的引用方法:,、将变量的地址赋给指针变量(p1=&a1),、将一个指针变量赋给另一个指针变量(p2=p1),、通过指针变量间接访问它所指向的变量(*p1),4、*和&运算符的进一步说明:,、若有:p1=则*p1等价于a;,&*p1,&(*p1),&a,、*&a,*(&a),*p,a,、(*p)+,等价于:a+,不同于:*p+,*p+,*(p+),19/55,8.
12、2.4 指针作为函数参数,题目:输入两个整数a、b,按大小顺序输出。,#include void swap(int x,int y)int temp;temp=x;x=y;y=temp;void main()int a,b;printf(nInput a,b:);scanf(%d%d,注意:语言中的函数调用采用“传值”方式,即单向传递方式。,即:主调函数可以将实参的值传递给被调函数的形参,但不能通过改变形参的值而改变实参的值。,Eg804.cpp,20/55,#include void swap(int*px,int*py)int temp;temp=*px;*px=*py;*py=temp;
13、void main()int a,b,*p1,*p2;printf(nInput a,b:);scanf(%d%d,&a,&b,8,5,Eg805.cpp,21/55,#include void swap(int*px,int*py)int*temp;*temp=*px;*px=*py;*py=*temp;void main()int a,b,*p1,*p2;printf(nInput a,b:);scanf(%d%d,*temp是指针变量temp所指向的变量,但temp中并无确定的地址值,其值不确定;*temp所指向的单元也不确定。因此,对*temp赋值可能会破坏系统的正常工作状况。,应该将
14、*px的值赋给一个整型变量,用整型变量作为临时存储空间实现*px和*py的交换。,22/55,#include void swap(int*px,int*py)int*p;p=px;px=py;py=p;void main()int a,b,*p1,*p2;printf(nInput a,b:);scanf(%d%d,&a,&b,&b,&a,Eg806.cpp,23/55,如果想通过函数调用得到几个要改变的值,可以:,、在主调函数中设n个变量;,、将n变量的地址作为实参传给所调用的函数的形参;,、通过形参指针变量,改变该n个变量的值;,、主调函数就可以使用这些改变了的值;,例8.5 编写函数,
15、求一维数组中的最大值和最小值。,void search(int x,int n),int*pmax,int*pmin,*pmax=*pmin=x0;,for(i=1;in;i+),if(*pmaxxi)*pmax=xi;,if(*pminxi)*pmin=xi;,int a20,max,min;for(i=0;i20;i+)scanf(%d,search(a,20,Eg807.cpp,24/55,8.3 指针与数组,8.3.1 指向数组元素的指针变量,1、几个概念,、一个变量有地址,称变量的地址为该变量的指针;,、每个数组都有一个起始地址,数组的起始地址称为数组的指针;,、一个数组包含若干元素
16、,每个数组元素都在内存中占用一定的存储单元,即都有相应的地址,数组元素的地址称为数组元素的指针;,、指针变量可以指向变量,当然也可以指向数组和数组元素;,、数组元素的指针变量就是专门用来存放数组元素地址的变量。,2、定义:,类型名*指针变量名,int a10;int*p;,int a10,*p;,25/55,3、赋值:,p=,&a0,4、说明:,、语言中的数组名代表数组首地址,即第0号元素的地址;,p=,p=a;,、定义时可以进行初始化:,int*p=,int*p;p=,int*p;*p=,int*p=a;,26/55,8.3.2 通过指针访问一维数组,1、数组元素的引用:,int a10,*
17、p;,p=a;,*p=5;,a0=5;,p=,*p=5;,a3=5;,2、语言规定:无论数组的数据类型如何,若指针变量p已指向数组中的某一元素,则p+1指向同一数组中的下一个元素(而不是将p简单的加1),例如:,、int x10,*p=x;,对于指向整型数组的指针变量p,p+1意味着使p在原值的基础上加2个字节,以使它指向下一元素;,、float x10,*p=x;,对于指向float型数组的指针变量p,p+1意味着使p在原值的基础上加4个字节,以使它指向下一元素;,27/55,总之:设d是一个数组元素所占的字节数,则p+i表示指针移动了i个元素,而它实际的地址变化为:p+i*d。,3、在使用
18、指针变量引用数组时,应注意以下问题:,、给指针赋初值的方法:,p=a;或p=,、p+1或a+1实际上表示数组元素a1的地址(&a1);则p+i或a+i表示数组的第i个元素的地址(&ai);,、*(p+i)或*(a+i)表示p+i或a+i所指向的数组元素,即ai;,、指向数组的指针变量也可以带下标;如:pi与*(p+i)等价;,、若p已经指向某个数组元素ai,则p+j表示指向数组元素ai+j;,综上,可以用两种方法来引用一个数组元素:,、下标法:用ai或pi来引用数组a中的第i号元素;,、指针法:用*(p+i)或*(a+i)来引用数组中的第i号元素;,可见:任何由数组下标完成的操作都能由指针来实
19、现;,ai,*(p+i),&ai,p+i,Eg808.cpp,28/55,4、在使用指针变量时,要注意以下几个问题:,、可以使用p+使指针变量p的值不断改变:,for(p=a;p(a+10);p+)printf(%4d,*p);,for(p=a;a(p+10);a+)printf(%4d,*a);,、在程序运行期间,要始终注意指针变量当前所指向的是哪一个元素;,Eg809.cpp,29/55,可以执行p+等操作使p指向不同的数组元素,通过*p访问不同的数组元素。但要始终注意p当前所指向的是哪一个数组元素!,通过指针在函数间传递一维数组:,编译系统都是将形参数组名作为指针变量来处理的。,f(in
20、t x,int n);,f(int*x,int n);,可以通过xi、*(x+i)来访问实参数组元素。,要求实参为指向数组首元素的指针:,a 或 p,f(a,10);,f(p,10);,(p=a;),30/55,小结,int a10,*p;p=a;或 p=,p为指向数组元素的指针,语言规定:数组名表示数组的首地址,即第0个元素的地址;即数组名是指向数组第0个元素的指针常量。,a+i,p+i,表示数组第 i 个元素的地址(&ai),即指向第 i 个元素的指针,*(a+i),*(p+i),表示数组的第 i 个元素(ai),ai,pi,表示数组的第 i 个元素(ai),数组第 i 个元素地址的表示方
21、法:,&ai,a+i,p+i,&pi,数组第 i 个元素的表示方法:,ai,*(a+i),*(p+i),pi,31/55,8.3.3 通过指针在函数间传递一维数组,1、数组元素作为函数参数:,void swap(int x,int y);,swap(a1,a2);,2、数组名作为函数参数:,void f(int x,int n);,f(a,10);,数组名代表数组首地址。用数组名作实参,调用函数时是把数组首地址传递给形参,而不是把数组的值传给形参。,x,x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,实际上能够接受并存放地址值的只能是指针变量,编译系统都是将形参数组名作为指针变量来
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 教程 第八
链接地址:https://www.31ppt.com/p-6503878.html