c语言课件第10章指针.ppt
《c语言课件第10章指针.ppt》由会员分享,可在线阅读,更多相关《c语言课件第10章指针.ppt(77页珍藏版)》请在三一办公上搜索。
1、第十章 指 针,掌握指针与指针变量的概念;掌握数组的指针和指针数组的使用;掌握字符串指针和指向字符串的指针变量的使用;掌握指针函数和函数指针的使用;了解指向指针的指针的概念及其使用。,预 备 知 识,内存:CPU处理的数据都保存在内存中。内存分为一个个单元,这些单元顺序排列,每一个单元有一个称为内存地址的编号,对内存数据的访问都是通过地址进行的。高级语言用变量等高级概念把内存单元、地址等低级概念掩盖起来,使我们在写程序时不必关心硬件的细节,但内存与地址仍是最基本的概念。存储单元的最小单位是字节。,1.内存的概念,地址:为了对内存中的某个存储单元进行访问,要为它编号,这种编号称为内存地址。通过地
2、址我们就能够访问该地址所标识的存 储单元。,2.地址的概念,变量的地址:每一个变量在内存中总占用几个连续的 字节,开始字节的地址,就是变量的地址。,2007,存储单元,10.1 指针及其相关概念,指针:一个变量的地址称为该变量的指针。许多高级语言都把程序对象的地址作为一种数据,称之为地址值或指针值。指针变量:若一个变量专用于存放另一个变量的地址(指针),则该变量称为指针变量。换句话说,以地址为值的变量称为指针变量,简称指针。,指针的对象:当把变量的地址存入指针变量后,我们就可以说这个指针指向了该变量。,变量的存取方法:直接存取和间接存取。,10.2 变量的指针和指向变量的指针变量,一、指针变量
3、的定义,例如:int*ptr1,*ptr2;,指针变量的类型:说明该指针所指向的变量的类型。,在定义指针变量时要注意以下几个问题:,变量名ptr2前面的“*”不能省略,如果写成 int*ptr1,ptr2;则ptr2被定义为整型变量,而非整型指针变量。,定义中的“*”表示所定义的变量是指针变量,但 指针变量名是ptr1、ptr2,而非*ptr1、*ptr2。,指针变量只能指向定义时所规定类型的变量。这个规定的类型称为该指针变量的“基类型”。,如:上例中ptr1、ptr2只能指向整型变量,不 能指向实型或字符型变量。其“基类型”相同,都是整型。,定义指针变量后,并未确定该变量指向何处。也就是说该
4、变量的值是不确定的。在引用指针 变量前必须首先让它指向一个变量,这一点非 常重要。,二、指针变量的运算,指针运算符(“&”和“*”),“&”(取地址运算符):取变量的存储地址,“*”(取值运算符):取指针所指向变量的内容,例如:&a 是求变量a的地址。,ptr指向了i变量,*ptr表示i的值,即3,我们还可以用这种方法实现对变量的改变:,*ptr=15;等价于 i=15;,由此可见:通过指针运算符“*”可以引用一个变量。如:当ptr已经指向变量i后,*ptr就等同于i。,*ptr,&i,进一步理解“&”和“*”:,等价于,指针的赋值运算(=),指针的赋值运算:就是把地址赋值给指针变量。,指针的
5、赋值运算可以是以下三种方式:,使用取地址运算符,把地址值赋值给指针变量。,如:int i,*pi;pi=,把指针变量的值赋给另一个指针变量。,如:int i,*pa,*pb;pa=,给指针变量赋值为符号常量NULL。,说明:NULL是一个空指针,表示该指针变量的值没有意义。作用是为了避免对没有被初始化的指针变量的非法引用。NULL 的定义在“stdio.h”中。,如:int*pi;pi=NULL;,说明:,在定义指针变量时,可以立即将一个地址值 赋给指针变量,这就是指针变量的初始化。指针变量的初始化也是指针的赋值运算。,如:float flt,*f_ptr=,注意:这不是给*f_ptr赋值。,
6、指针变量间的赋值和引用应保证基类型相同。,若有定义:int*p,i;float*q,x;,则:q=,移动指针的运算,1指针的+、运算,说明:,指针与整型值加减的结果是指针,表示使该指针指向该指针下移或上移存储单元个数(整型值)之后的内存地址。存储单元的大小就是该指针的数据类型所需的内存大小。,例如:ptr+n(指针ptr,n为整数)这个指针值代表的内存单元的地址是:ptr+n*d(其中d是指针所指向变量的数据类型所占内存字节数),即指针移动了n个元素。,指针与指针的加运算毫无意义,所以指针与指针 没有加运算。,指针与指针的减运算要求相减的两个指针属于同 一类型,其结果是整数,表示两个指针之间的
7、数 据的个数。其结果值的计算公式是:,ptr1-ptr2=(ptr1的值-ptr2的值)/指针的数据类型所占的字节数,例如:int*ptr1,*ptr2,*ptr3,x;int ary5=2,4,8,16,32;ptr1=,x 的值是3,2指针的+、-、+=、-=运算,+、+=:是移动指针到下一个或下几个存储单元。,-、-=:是移动指针到上一个或上几个存储单元。,例如:int*ptr,ary5=2,4,6,8,10;ptr=ary;ptr+=3;ptr-;,想一想:*ptr+和(*ptr)+有什么区别?,关系运算,基类型相同的两个指针进行比较运算,其意义是两个指针的位置比较,结果是逻辑值。,指
8、针运算的程序举例:把a,b按大小顺序输出。,main()int*p1,*p2,*p,a,b;a=45;b=76;p1=,输出结果:a=45,b=76,max=76,min=45,三、指针变量作为函数参数,指针可以用作函数参数,这在调用函数希望改变参数的值时非常有用。,例如:用指针变量编写实现两个数的交换的函数,void swap(int*p1,int*p2);main()int x1=100,x2=200;printf(x1=%d,x2=%dn,x1,x2);swap(,void swap(int*p1,int*p2)int temp;temp=*p1;*p1=*p2;*p2=temp;,图示
9、交换过程中存储单元内容的变化:,1,2,3,4,5,6,想一想:如果函数的参数不用指针而用整型变量,能否实现值的交换?为什么?,通过函数调用得到n个要改变的值的方法:,在主调函数中设n个变量,用n个指针变量指向它们;,将指针变量作实参,将这n个变量的地址传给所调用 的函数的形参;,通过形参指针变量,改变该n个变量的值;,主调函数中就可以使用这些改变了值的变量。,注意:不能企图通过改变指针形参的值而使指 针实参的值改变。如:上例swap函数中不能写成:temp=p1;p1=p2;p2=temp;,10.3 数组的指针和指向数组的指针变量,一、概念,数组的指针:是数组的起始地址。数组元素的指针:是
10、数组元素的地址。当指针变量指向数组或数组元素时,它就是指向数组的指针变量。,C规定:,数组名代表数组的首地址(起始地址),也就是数组第一个元素的地址。,当指针变量p指向数组的某个元素时,p+1指向数组的下一个元素。假设一个整型元素占两个字节,p+1是使p的地址加2个字节。,如:int a10,*p;则:p=a;与 p=等价称指针变量p指向数组元素a0,p+i、a+i、&ai 都是ai的地址。,二、数组元素的引用,1.用下标法引用数组元素,如:a3=45;b25=200;,2.用指针法引用数组元素,假如:int a10,*p,i;p=a;,则:*(p+i)、*(a+i)则代表元素ai,*(p+i
11、)也可以写成pi,程序举例:输出10个元素数组中的全部元素。,方法二:通过数组名计算数组元素地址,找出元素的 值。main()int a10=54,65,8,2,3,56,8,21,57,98,i;for(printf(n),i=0;i10;i+)printf(%4d,*(a+i);,方法一:下标法。main()int a10=54,65,8,2,3,56,8,21,57,98,i;for(printf(n),i=0;i10;i+)printf(%4d,ai);,方法三:用指针变量指向数组元素 main()int a10=54,65,8,2,3,56,8,21,57,98,*p,i;p=a;f
12、or(printf(n),i=0;i10;i+)printf(%4d,*p+);,以上三种方法,利用指针变量效率最高。,说明:指针变量与数组名的区别:,指针变量是地址变量,数组名是地址常量。即指针变量的内容可以在程序运行过程中被改变;而数组名一旦被定义,它的地址就不能再改变了。,例如:int i,*p,a6;则:p=,不能给常量赋值,利用指针变量编程时特别要注意指针变量 的当前值。,例如:通过指针变量输入输出a数组元素。main()int*p,i,a10;p=a;for(i=0;i10;i+)scanf(%d,p+);printf(“n”);for(i=0;i10;i+)printf(“%6d
13、”,*p+);,应插入语句 p=a;,注意:*p+、*(p+)、(*p)+、*(+p)的含义,三、数组名作函数的参数,例如:f(int arr,int n)main()int array10;f(array,10);,现在解释:实际上,能够接受并存放地址值的只能是指针变量。因此,C编译系统都是将形参数组名作为指针变量来处理的。上例中f(int arr,int n)等价于 f(int*arr,int n)。arri=*(arr+i),使用形参数组的概念只是为了与实参数组对应,直观,便于理解而已。,例:从10个数中找出其中最大值和最小值(用数组)。,main()void max_min(int a
14、,int n,int*max,int*min);int i,a=2,4,1,6,7,32,45,75,45,90,max,min;printf(The original array=);for(i=0;iai)*min=ai;,上例中如果形参数组用指针变量,则程序如下:,main()void max _min(int*x,int n,int*max,int*min);int i,a10=2,4,1,6,7,32,45,75,45,90,max,min;for(printf(The original array=),i=0;i*x)*min=*(x+i);,数组名做函数参数小结:,注意:用指针变
15、量作实参时一定要有确定的值。,例a:实参和形参都用数组名,main()int a10;f(a,10);,f(int x,int n),例b:实参用数组名,形参用指针变量,main()int a10;f(a,10);,f(int*x,int n),例c:实参、形参都用指针变量,main()int a10,*p;p=a;f(p,10);,f(int*x,int n),例d:实参为指针变量,形参用数组名,main()int a10,*p;p=a;f(p,10);,f(int x,int n),本章程序举例:,习题10.1:输入3个整数,按由小到大的顺序输出。,void swap(int*p,int*
16、q);main()int a,b,c,*p1=,习题10.14:将n个数按输入时顺序的逆序排列,用 函数实现。,void inverse(int*a,int n);main()int i,a10=2,4,1,6,7,32,45,75,450,89;for(puts(),i=0;i10;i+)printf(%5d,ai);inverse(a,10);for(puts(),i=0;i10;i+)printf(%5d,ai);void inverse(int*x,int n)0 1 2 3 4 5 6 7 8 9 int*i=x,*j=x+n-1,t;for(;ij;i+,j-)t=*i;*i=*j
17、;*j=t;*i*j,10.4:有N个数,使前面各数顺序向后移M个位置。,main()int num20,m,n,i;printf(nm=n=);scanf(%d%d,作业(均要求用指针实现)(1)任意输入5个整数,按由大到小的顺序输出;(2)写一个函数 select(int n,double a,double b,double x),它将数组b中大于x的数顺序复制到数组a中。a数组的内容为空,n是两个数组的大小。,四、二维数组的指针,1二维数组的地址概念,在C语言中,一个二维数组可以看成是一个一维数组,该一维数组中的每个元素又是一个包含若干元素的一维数组。,假如有定义:int a34;,则C
18、语言编译程序认为a数组是由a0,a1,a23个元素组成的一维数组,而a0和a1,a2又分别是包含4个元素的一维数组名,分别代表a数组元素的起始地址(即a0是第0行元素的首地址,a1是第1行元素的首地址)。因此,a和ai是两个基类型不同的指针常量。,2通过地址引用二维数组元素,假如有定义:int a34,i,j;(其中0i 3,0j 4),则:ai和*(a+i)(无条件等价)都是第i行数组的首地址,也是第i行第0列(第1列)元素的地址;那么ai+j、*(a+i)+j、&a00+4*i+j都是第i行第j列元素的地址。,数组a中任意元素aij的引用可以表示成如 下几种形式:aij、*(ai+j)、*
19、(*(a+i)+j)、(*(a+i)j、*(&a00+4*i+j),二维数组的数组元素(一维数组)的首地址的运算(各班长的地址的运算),int a34首地址数组元素a(排长)a0*(a+0)a00 a01 a02 a03a1*(a+1)a10 a11 a12 a13a2*(a+2)a20 a21 a22 a23,排0班1班2班,二维数组一维数组,班长战士,一维数组的数组元素及地址运算(各班战士及地址运算),0班长地址a0*(a+0)0班j战士的地址*(a+0)+j0班j战士*(*(a+0)+j)|a00 a01 a02 a03 1班长地址a1*(a+1)1班j战士的地址*(a+1)+j1班j战
20、士*(*(a+1)+j)|a10 a11 a12 a13 2班长地址a2*(a+2)2班j战士的地址*(a+2)+j2班j战士*(*(a+2)+j)|a20 a21 a22 a23,3通过一个行指针变量引用二维数组的元素,例如:假若有语句 int a34,(*p)4;p=a;,注意:*p两侧的圆括号不可缺少。,则:p是一个指针变量,它指向由4个整型元素组成的一 维数组。,例:使用行指针变量访问九九乘法表的数组元素。,main()float fa99,(*pf)9=fa;int i,j;for(i=0;i9;i+)for(j=0;j=i;j+)*(*(pf+i)+j)=(i+1)*(j+1);f
21、or(i=0;i9;i+)for(j=0;j=i;j+)printf(“%f”,faij);/或者 printf(%f,*(*(pf+i)+j);,习题10.9:写一函数,将一个33的矩阵转置。,main()int a33=1,2,3,4,5,6,7,8,9,i,j;for(i=0;i3;i+)for(puts(),j=0;j3;j+)printf(%6d,aij);transpose(a);for(i=0;i3;i+)for(puts(),j=0;j3;j+)printf(%6d,aij);transpose(int(*p)3)int i,j,t;for(i=0;i3;i+)for(j=0;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 课件 10 指针

链接地址:https://www.31ppt.com/p-6504346.html