电工电子技术基础教程(第2版)第9章

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

第9章指针本章要点指针的定义、引用和运算方法数组、函数和字符串与指针的关系本章难点指针变量的引用指针作为函数参数的运用预备知识内存:就是内部存储器,是由存储单元组成的。它的特点是存储单元是线性连续的。存储单元的最小单位是字节。1.内存的概念地址:为了访问内存中的某个存储单元,我们要为它编号,这种编号称为内存地址。通过地址我们就能够访问该地址所标识的存储单元。2.地址的概念变量的地址:变量在内存中总占用几个连续的字节,开始字节的地址,就是变量的地址。2007存储单元9.1指针的概述指针:一个变量的地址称为该变量的指针。指针变量:若一个变量专用于存放另一个变量的地址(指针),则该变量称为指针变量。指针的对象:当把变量的地址存入指针变量后,我们就可以说这个指针指向了该变量。变量的存取方法:直接存取和间接存取。直接存取:直接根据变量名存取数据。间接存取:通过指针变量存取相应变量的数据。9.2变量的指针和指向变量的指针变量一、指针变量的定义一般形式:类型标识符*变量名;例如:int*ptr1,*ptr2;指针变量的类型:指明了该指针指向的内存空间所存储的数据类型。在定义指针变量时要注意以下几个问题:⑴变量名ptr2前面的“*”不能省略,如果写成int*ptr1,ptr2;则ptr2被定义为整型变量,而非整型指针变量。⑵定义中的“*”表示所定义的变量是指针变量,但指针变量名是ptr1、ptr2,而非*ptr1、*ptr2。⑶指针变量只能指向定义时所规定类型的变量。这个规定的类型称为该指针变量的“基类型”。如:上例中ptr1、ptr2只能指向整型变量,不能指向实型或字符型变量。其“基类型”相同,都是整型。⑷定义指针变量后,并未确定该变量指向何处。也就是说该变量的值是不确定的。在引用指针变量前必须首先让它指向一个变量,这一点非常重要。二、指针变量的运算㈠指针运算符(“&”和“*”)“&”(地址运算符):取变量的存储地址。“*”(引用运算符):是取指针所指向变量的内容。例如:&a是求变量a的地址。ptr指向了i变量,*ptr表示i的值,即3我们还可以用这种方法实现对变量的改变:*ptr=15;等价于i=15;由此可见:通过指针运算符“*”可以引用一个变量。如:当ptr已经指向变量i后,*ptr就等同于i。进一步理解“&”和“*”:“&”运算和“*”运算是一对互逆运算。&*ptr&iptr*&i*ptri等价于㈡指针的赋值运算(=)指针的赋值运算:就是把地址赋值给指针变量。指针的赋值运算可以是以下三种方式:⑴使用取地址运算符,把地址值赋值给指针变量。如:inti,*pi;pi=&i;⑵把指针变量的值赋给另一个指针变量。如:inti,*pa,*pb;pa=&i;pb=pa;⑶给指针变量赋值为符号常量NULL。说明:NULL是一个空指针,表示该指针变量的值没有意义。作用是为了避免对没有被初始化的指针变量的非法引用。NULL的定义在“stdio.h”中。如:int*pi;pi=NULL;说明:⑴在定义指针变量时,可以立即将一个地址值赋给指针变量,这就是指针变量的初始化。指针变量的初始化也是指针的赋值运算。如:floatflt,*f_ptr=&flt;注意:这不是给*f_ptr赋值。⑵指针变量间的赋值和引用应保证基类型相同。若有定义:int*p,i;float*q,x;则:q=&i;╳p=&x;╳㈢移动指针的运算•指针的加减运算(+、-)•指针的自加自减运算(++,--,+=,-=)1.指针的+、-运算指针±整数指针-指针+、-说明:⑴指针与整型值加减的结果是指针,表示使该指针指向该指针下移或上移存储单元个数(整型值)之后的内存地址。存储单元的大小就是该指针的数据类型所需的内存大小。例如:ptr+n(指针ptr,n为整数)这个指针值代表的内存单元的地址是:ptr+n*d(其中d是指针所指向变量的数据类型所占内存字节数),即指针移动了n个元素。⑵指针与指针的加运算毫无意义,所以指针与指针没有加运算。⑶指针与指针的减运算要求相减的两个指针属于同一类型,其结果是整数,表示两个指针之间的数据的个数。其结果值的计算公式是:ptr1-ptr2=(ptr1的值-ptr2的值)/指针的数据类型所占的字节数例如:int*ptr1,*ptr2,*ptr3,x;intary[5]={2,4,8,16,32};ptr1=&ary[0];ptr2=&ary[3];ptr3=ary;x=ptr2-ptr1;x的值是32.指针的++、--、+=、-=运算++、+=:是移动指针到下一个或下几个存储单元。--、-=:是移动指针到上一个或上几个存储单元。例如:int*ptr,ary[5]={2,4,6,8,10};ptr=ary;ptr+=3;ptr--;想一想:*ptr++和(*ptr)++有什么的区别?㈣关系运算基类型相同的两个指针进行比较运算,其意义是两个指针的位置比较,结果是逻辑值。指针运算的程序举例:把a,b按大小顺序输出。main(){int*p1,*p2,*p,a,b;a=45;b=76;p1=&a;p2=&b;if(*p1*p2){p=p1;p1=p2;p2=p;}printf(a=%d,b=%d,max=%d,min=%d,a,b,*p1,*p2);}输出结果:a=45,b=76,max=76,min=45三、指针变量作为函数参数指针可以用作函数参数,这在调用函数希望改变参数的值时非常有用。例如:用指针变量编写实现两个数的交换的函数voidswap(int*p1,int*p2);main(){intx1=100,x2=200;printf(x1=%d,x2=%d\n,x1,x2);swap(&x1,&x2);printf(x1=%d,x2=%d\n,x1,x2);}voidswap(int*p1,int*p2){inttemp;temp=*p1;*p1=*p2;*p2=temp;}图示交换过程中存储单元内容的变化:123456想一想:如果函数的参数不用指针而用整数,能否实现值的交换?为什么?通过函数调用得到n个要改变的值的方法:⑴在主调函数中设n个变量,用n个指针变量指向它们;⑵将指针变量作实参,将这n个变量的地址传给所调用的函数的形参;⑶通过形参指针变量,改变该n个变量的值;⑷主调函数中就可以使用这些改变了值的变量。注意:不能企图通过改变指针形参的值而使指针实参的值改变。如:上例swap函数中不能写成:temp=p1;p1=p2;;p2=temp;9.3数组的指针和指向数组的指针变量一、数组的指针和指向数组的指针变量的概念数组的指针:是数组的起始地址。数组元素的指针:是数组元素的地址。当指针变量指向数组或数组元素时,它就是指向数组的指针变量。C规定:⑴数组名代表数组的首地址(起始地址),也就是第一个元素的地址。⑵当指针变量p指向数组时,p+1指向数组的下一个元素。假设一个整型元素占两个字节,p+1是使p的地址加2个字节。如:inta[10],*p;则:p=a;与p=&a[0];等价称指针变量p指向数组元素a[0]p+i、a+i、&a[i]都是a[i]的地址。二、数组元素的引用1.用下标法引用数组元素如:a[3]=45;b[2][5]=200;2.用指针法引用数组元素假如:inta[10],*p,i;p=a;则:⑴*(p+i)、*(a+i)则代表元素a[i]⑵*(p+i)也可以写成p[i]⑶*(p+i)、*(a+i)、a[i]、p[i]等价,都代表数组a的第i+1个元素。程序举例:输出10个元素数组中的全部元素。方法二:通过数组名计算数组元素地址,找出元素的值。main(){inta[10]={54,65,8,2,3,56,8,21,57,98},i;for(printf(\n),i=0;i10;i++)printf(%4d,*(a+i));}方法一:下标法。main(){inta[10]={54,65,8,2,3,56,8,21,57,98},i;for(printf(\n),i=0;i10;i++)printf(%4d,a[i]);}方法三:用指针变量指向数组元素main(){inta[10]={54,65,8,2,3,56,8,21,57,98},*p,i;p=a;for(printf(\n),i=0;i10;i++)printf(%4d,*p++);}以上三种方法,利用指针变量效率最高。说明:⑴指针变量与数组名的区别:指针变量是地址变量,数组名是地址常量。即指针变量的内容可以在程序运行过程中被改变;而数组名一旦被定义,它的值就不能被改变了。例如:inti,*p,a[6];则:p=&i;√a=&i;a++;a+=i;不能给常量赋值⑵利用指针变量编程时特别要注意指针变量的当前值。例如:通过指针变量输入输出a数组元素。main(){int*p,i,a[10];p=a;for(i=0;i10;i++)scanf(%d,p++);for(printf(“\n”),i=0;i10;i++)printf(“%6d”,*p++);}应插入语句p=a;注意:*p++、*(p++)、(*p)++、*(++p)的含义三、数组名作函数的参数例如:f(intarr[],intn){……}main(){intarray[10];……f(array,10);……}现在解释:实际上,能够接受并存放地址值的只能是指针变量。因此,C编译系统都是将形参数组名作为指针变量来处理的。上例中f(intarr[],intn)等价于f(int*arr,intn)。使用形参数组的概念只是为了与实参数组对应,直观,便于理解而已。例:从10个数中找出其中最大值和最小值。voidmax_min(inta[],intn,int*max,int*min);main(){inti,a[]={2,4,1,6,7,32,45,75,45,90},max,min;for(printf(Theoriginalarray=),i=0;i10;i++)printf(%5d,a[i]);max_min(a,10,&max,&min);printf(max=%dmin=%d,max,min);}voidmax_min(inta[],intn,int*max,int*min){inti;*max=*min=a[0];for(i=0;in;i++){if(*maxa[i])*max=a[i];if(*mina[i])*min=a[i];}}上例中如果形参数组用指针变量,则程序如下:voidmax_min(int*x,intn,int*max,int*min);main(){inti,a[10]={2,4,1,6,7,32,45,75,45,90},max,min;for(printf(Theoriginalarray=),i=0;i10;i++)printf(%5d,a[i]);max_min(a,10,&max,&min);printf(=%dmin=%d,max,min);}voidmax_min(int*x,intn,int*max,int*min){inti;*max=*min=*x;for(i=1;in;i++,x++){if(*max*x)*max=*x;if(*min*x)*min=*x;}}数组名做函数参数小结:如果有一个实参数组,想在函数中改变此数组的元素的值,实参与形参都可用数组名或指针变量其对应关系有以下4种情况:⑴实参与形参都用数组名;⑵实参用数组名,形参用指针变量;⑶实参、形参都用指针变量;⑷实参为指针变量,形参用数组名。注意:用指针变量作实参时一定要有确定的值。例:实参、形参都用指针变量的形式main(){inta[10],*p;p=a;……f(p,10);……}f(int*x,intn){……}例:实参为指针变量,形参用数组名。main(){inta[10],*p;p=a;……f(p,10);……}f(intx[],intn){……}四、二维数组的指针1.二维数

1 / 73
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功