收藏 分销(赏)

第八章-指针(课堂PPT).ppt

上传人:w****g 文档编号:10764944 上传时间:2025-06-13 格式:PPT 页数:74 大小:777KB 下载积分:16 金币
下载 相关 举报
第八章-指针(课堂PPT).ppt_第1页
第1页 / 共74页
第八章-指针(课堂PPT).ppt_第2页
第2页 / 共74页


点击查看更多>>
资源描述
Click to edit Master title style,Click to edit Master text styles,Second level,Third level,Fourth level,Fifth level,第,8,章 指 针,指针,是,C,语言中的一个重要概念,是,C,语言的,精华、灵魂,。,1.,内存单元地址,程序中定义了变量后,在,编译时,系统就给这个变量分配内存单元。内存中每一个内存单元都有一个编号,这就是“,地址,”。,内存单元地址,就是编译后系统分配给变量的,内存空间位置,。,例如:,int i,j,k;,8,.1,地址和指针的概念,内存用户数据区,变量,k,变量,j,变量,i,2000,2002,2004,其中,2000,为,i,的地址,2002,为,j,的地址,2004,为,k,的地址,数据在内存中的存取方式:,直接访问方式,和,间接访问方式。,直接访问方式:,按变量地址存取变量值。,间接访问方式:,把一个变量的地址放在另一个变量中,。,内存单元的内容,内存单元,中存放的,数值,。,例如:,i=3;j=6;,在,2000,单元中存放数值,3,,,3,即为,内容,。,在,2002,单元中存放数值,6,,,6,即为,内容,。,变量,i,变量,j,6,3,2000,2002,例:,printf(%d,i);,其执行是这样的:,根据变量名与地址的对应关系,,找到变量,i,的地址,2000,,然后从由,2000,开始的两个字节中取出数据(即变量的值,3,),把它输出。,这种按变量地址存取变量值的方式称为“,直接访问”方式。,例如,我们定义一个变量,i_pointer,,用来存放整型变量,i,的地址:,i_pointer=,/*,把变量,i,的地址,赋给变量,i_pointer*/,这时,i_pointer,的值,就是变量,i,所占用的内存单元的,起始地址,(,2000,)。,如何存取变量,i,的值?,变量,i,变量,j,2000,6,3,2000,2002,变量,i_pointer,3010,间接访问方式,:,通过存储在某一个内存单元中的地址去存取该地址所指向的内存单元中的变量值。,要存取变量,i,的值,先要找到存放,i,的地址的变量(,i_pointer,),从中取出,i,的地址(,2000,),然后到,2000,、,2001,字节中取出,i,的值(,3,)。,表示将数值,3,送到变量中,有两种方法:,将,3,送到变量,i,所标志的单元中。,将,3,送到变量,i_pointer,所“,指向,”的单元中。,所谓“,指向,”就是通过地址来体现的。,(如右图所示),由于通过地址可以找到所需的变量单元,因此可以说,,地址“,指向,”该内存单元,。在,C,语言中,,将地址形象化地称为,“,指针,”。,一个变量的地址称为该变量的“,指针,”,。例如地址,2000,是变量,i,的指针。,如果有一个变量,专门用来存放另一个变量的地址(即指针),则它称为“,指针变量,”。如前面所说的,i_pointer,变量称为,指针变量。,指针变量的值是指针(地址)。,注意:,(1)“,指针”和“指针变量”这两个不同的概念。,(2),通过指针变量如何访问变量,i,的值?(,间接访问,),2000,i,3,2000,i,3,2000,i_pointer,变量的指针,就是变量的地址。存放变量地址的变量是,指针变量,,用来指向另一个变量。指针变量和它所指向的变量之间,用“,*,”,表示“,指向,”。,例如,i_pointer,代表指针变量,*,i_pointer,是,i_pointer,所指向的变量。,8.2,变量的指针和指向变量的指针变量,*i_pointer,2000,3,2000,i_pointer,i,可以看到,*,i_pointer,也代表一个变量,它和变量,i,是同一回事。下面两个语句作用相同:,i=3;,*i_pointer=3;,第个语句的含义是将,3,赋给指针变量,i_pointer,所指向的变量。,8.2.1,定义一个指针变量,指针变量是专门用来存放地址的,因此必须定义为“,指针类型,”。,指针变量定义的一般形式,:,基类型 *指针变量名,指针变量的基类型,用来指定该指针变量可以指向的变量的类型。,例如,:int *pointer_1,*pointer_2;,(指向整型变量,的指针变量,),float *pointer_3;,(指向实型变量,的指针变量,),char *pointer_4;,(指向字符型变量,的指针变量,),注意,:,1.,指针变量前面的“,*,”表示该变量是指针变量。,指针变量名,是,pointer_1,、,pointer_2,,而不是*,pointer_1,、*,pointer_2.,2.,在定义指针变量时必须指定基类型。,不同类型的数据在内存中所占的字节数是不同的。,指针变量的类型说明,是为了告诉系统按变量中的地址从内存选取,几个字节,的数据进行操作,便于 指针的移动和指针的运算操作。,3.,一个指针变量只能 指向同一类型的变量,即存放同一类型变量的地址。,怎样使一个指针变量指向另一个变量呢?可以使用赋值语句。,例如:,float x;,char ch;,float *pointer_3;,char *pointer_4;,pointer_3=,pointer_4=,例:,int k,i=5;,int *pointer;,pointer=,k=,*pointer,;,printf(%d,k);,printf(%d,*pointer,);,2000,(,地址,),pointer,2000,5,(,数据,),*,pointer,i,2000,输出变量,i,的值,5,k,的值为5,8.2.2,指针变量的引用,指针变量中只能存放地址(指针),,不能将一个整型量或任何其它非地址类型的数据赋给一个指针变量。,例如赋值语句:,pointer_1=2000;,(不合法),有关地址的运算符,:,1.,&,取地址运算符。,2.,*,指针运算符(或称“间接访问”运算符)。,例如,:&a-,表示变量,a,的地址,*,p-,表示指针变量,p,所指向的变量(地址,p,所指的单元中存放的值),main(),int a,b;,int*pointer_1,*pointer_2;/*,定义指针变量,指向整型变量*,/,a=100;,b=10;,pointer_1=/*,使,pionter_1,指向,a*/,pointer_2=/*,使,pionter_2,指向,b*/,printf(%d,%dn,a,b);,printf(%d,%dn,*pointer_1,*pointer_2,);,例,8.1,通过指针变量访问整型变量。,运行结果:,100,,,10,100,,,10,&a,(,地址,),pointer_1,100,(,数据,),*pointer_1,a,&b,(,地址,),pointer_2,10,(,数据,),*pointer_2,b,pointer_1,指向,a,,*,pointer_1,就是变量,a,。,pointer_2,指向,b,,*,pointer_2,就是变量,b,。,&,和,*的优先级相同,按,自右向左,方向结合。因此,先执行,*,pointer_1,的运算,,它的执行结果就是变量,a,,,再执行,&,运算,则,&*,pointer_1,的最后结果与,&,a,相同,即取变量,a,的地址。,(见图示,1,),&a,&b,pointer_2,b,a,pointer_1,图示,1,*pointer_1,*pointer_2,a,&a,&a,pointer_2,b,pointer_1,图示,2,*pointer_2,*pointer_1,下面对“,&,”,和“,*,”,运算符再做些说明:,如有,pointer_1=,pointer_2=,则 表达式,&*,pointer_1,的含义是什么?,pointer_2=,如果有,pointer_2=,则结果如何?,先执行,&a,运算,得,a,的地址,再执行,*,运算,,得变量,a,的值。,所以,表达式,*&,a,和表达式,*,pointer_1,的含义是相同的,它们等价于变量,a,。,即*,&a,与,a,等价。,(3),(*pointer_1)+,相当于,a+,,,变量,a,的值加,1,。,(4),*pointer_1+,相当于 *,(pointer_1+),。,这是由于*和,+,优先级别相同,结合方向是,自右而左,。,+,在,pointer_1,的右侧,是“后加”,因此,先执行,*,pointer_1,,,取出,a,的值,,然后,指针,pointer_1,加,1,,这时,pointer_1,就不再指向,a,了。,注意:,(3),和,(4),的运算结果是不同的。,a,pointer_1,&a,5,*pointer_1,*&a,(2),如有,pointer_1=,则表达式,*,&a,的含义是什么?,main(),int a,b,*p1,*p2,*p;,scanf(%d,%d,p1=,p2=,if(ab),p=p1;,p1=p2;,p2=p;,printf(a=%d,b=%dn,a,b);,printf(max=%d,min=%dn,*p1,*p2);,例,8.2,输入整数,a,和,b,,按先大后小的顺序输出,a,和,b,。,&a,&b,p1,p2,5,9,a,b,p,&b,&a,p1,p2,5,9,a,b,p,&a,运行结果,:,a=5,b=9,max=9,min=5,实际上并没有交换,a,和,b,。算法不交换整型变量的值(变量,a,和,b,中的值没有改变),而是交换两个指针变量的值(即变量,a,和,b,的地址),使,p1,指向大的数,,p2,指向小的数。,8.2.3,指针变量作为函数参数,例:对输入的两个整数按大小顺序输出。,#include,void,main,(),void swap,(,int*,,,int*,),;,int,,;,int*pointer_,,*,pointer_,;,scanf,(,,,,);,pointer_,;,pointer_2,;,if,(),swap,(,pointer_,,,pointer_2,);,printf,(,,,,);,void,swap,(,int*,,,int*,),int temp,;,temp,*,1,;,*;,*,temp,;,例:对输入的三个整数按大小顺序输出。,#include,void main(),int a,b,c,*p1,*p2,*p3;,scanf(%d,%d,%d,p1=,exchange(p1,p2,p3);,printf(n%d,%d,%d n,a,b,c);,void 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);,void swap(int*pt1,int*pt2),int temp;,temp=*pt1;,*pt1=*pt2;,*pt2=temp;,一个变量有地址,一个数组包含若干元素,每个元素在内存中占用存储单元,它们也应该有相应的地址。一个变量既然可以指向变量,当然也可以指向数组和数组元素。,所谓,数组的指针,是指 数组的,起始地址。,数组元素的指针,是,数组元素的地址,。,例如:,int a10,i,*p,*p1;,p=a;,或,p=,p1=,a0,a1,a6,.,.,&a0,&a1,&a6,a,p,p1=&a6,p1,8.3,数组的指针和指向数组的指针变量,引用数组元素可以用下标法(如,a3,),也可以用指针法,即通过指向数组元素的指针找到所需的元素。使用指针法能使目标程序质量高(占用内存少,运行速度快)。,8.3.1,指向数组元素的指针,例如,:,int a10;,int *p;,.,p=,指向数组元素的指针变量,其定义与普通指针变量的定义相同。,把元素,a0,的地址赋给,p,即,p,指向 数组,a,的第,0,个元素。,因为数组名表示数组的首地址,所以它,等价于,p=a;,应注意数组,a,并不代表整个数组,,而是把数组,a,的首地址赋给指针变量,p,,不是把数组,a,的各个元素赋给,p,。,指针变量定义的同时 可以,赋初值,:,int a10;,int *p=,定义时也可以写成如下形式:,int*p=a;,相当于,int*p;,p=,a,数组,a0,a1,a2,ai,p,*(p+i),a10,&a0,假设已经定义了数组和一个指针变量,int a10;,int*p=a;,.,*p=1;,数组元素的引用可以用,1.,下标法,:,ai,2.,指针法,:,*(a+i),或*,(p+i),其中,p,为指向数组,a,的指针变量,初值,p=a;,下标法比较直观,程序容易阅读,指针表示,8.3.2,通过指针引用数组元素,对,p,当前所指的元素 赋整数值,1,注意,:,C,规定:,p+1(,或,p+),指向同一数组的下一个元素,(,不是地址值简单加,1),。,p+1,代表的实际地址是,p+1d,(,d,是一个数组元素所占的字节数)。,当,p,的初值为,a,的首地址时,p+i,或,a+i,就是,ai,的地址,因为,a,代表了数组的首地址。,*,(p+i),或,*,(a+i),所指的数组元素就是,ai,的内容。,实际上,,是变址运算符,对,ai,的处理,是将,ai,按,a+i,计算地址,然后找出此地址单元中的值。,指向数组的指针变量也可以带下标,如,:,pi,等价于,*,(p+i),,即,ai,。,a,数组,a0,a1,a2,ai,p+1,或,a+1,p,p+2,或,a+2,p+i,或,a+i,*(p+i),p+9,或,a+9,a9,例,8.5,输出数组中全部元素,:四,种方法。,main(),int a10=1,2,3,4,5,6,7,8,9,10;,int*p,i;,printf(n,下标法,:n);,for(i=0;i10;i+),printf(%d,ai);,printf(n,指针法,(,数组名,),:n);,for(i=0;i10;i+),printf(%d,*(a+i);,printf(n,指针法,(,指针变量,),:n);,p=a;,for(i=0;i10;i+),printf(%d,*(p+i);,printf(n,指针法,(,指针变量,),:n);,for(p=a;pa+10;,p+,),printf(%d ,*p);,printf(n);,否!,a+,的操作是非法的,因,a,是常量,。,能否改成如下形式,?,for(p=a;ap+10;,a+,),printf(%d,*a),几种方法的比较:,下标法和指针法(数组名)执行效果是相同的。编译系统先将,ai,转换为*,(a+i),,即先计算元素地址,因此这两种方法找数组元素比较费时。,指针变量法是直接指向数组元素,,p+,的自加操作比较快,。,用下标法比较直观,。,例,8.6,通过指针变量输入输出数组,a,的,10,个元素,main(),int *p,i,a10;,p=a;,for(i=0;i10;i+),scanf(%d,printf(n);,p=a;,for(i=0;i10;i+),printf(%d,*p+);,如果输出时没有语句,p=a;,程序将,?,P,是地址,不要加,&,出错,因输入时已改变了指针,p,的指向。,p+,a,数组,a0,a1,ai,p+,p,a9,(1),p+(,或,p+=1),,使,p,指向下一个元素,即,a1,。,(2),*p+,,,相当于,*,(p+),,先执行,*,p,,后执行,p+,。,(3),*p+,和,*,(+p),作用不同。,*,p+,是取出,a0,的值,后,p+,;,*,(+p),是先使,p,加,1,,再取*,p,,即 取出,a1,的值。,(4),(*p)+,表示,p,所指向的元素值加,1,,即,(a0)+,,如若,a0=3,,则,(a0)+,的值为,4,。,(5),如果,p,指向,a,数组中第,i,个元素,则:,*,(p-),相当于,ai-,,先对,p,进行“*”运算,再使,p-,。,*,(+p),相当于,a+i,,先使,p+,,再作“*”运算。,*,(-p),相当于,a-i,,先使,p-,,再作 “*”运算。,注意:指针变量的运算。若,p=a,;,则,:,一、多维数组的地址,例,.,二维数组,int a34=1,3,5,7,9,11,13,15,17,19,21,23;,分析二维数组的性质:,a,是一个数组名,包含,3,个元素:,a0,,,a1,,,a2,。,每个元素又是一个一维数组,包含,4,个元素。,a0,a1,a2,a,数组,a,a+1,a+2,(2008),(2000),(2016),8.3.4,指向多维数组的指针和指针变量,a0,a1,a2,a,23,21,19,17,15,13,11,9,7,5,3,1,从二维数组的角度看,,a,代表整个二维数组的,首地址,,也就是,第,0,行的首地址,。,若,a,的首地址为,2000,,因为每一行,4,个元素,占用,8,个字节,所以则,a+1,的首地址为,2008,,,a+2,的首地址为,2016,。,故,a+1,代表第,1,行的首地址,即,a1,的地址;,a+2,代,表第2行的首地址,即,a2,的地址,。,由于,a0,与*,(a+0),等价,,a1,与*,(a+1),等价,,ai,与*,(a+i),等价,,因此,ai+j,与,*,(a+i)+j,等价,它们都是元素,aij,的地址,。,故:元素,aij,的地址,表示是,:,ai+j,或 *,(a+i)+j,而,*,(*(a+i)+j),或,*,(ai+j),是元素,aij,的值,。,2000 2002 2004 2006,1 3 5 7,2008 2010 2012 2014,9 11 13 15,2016 2018 2020 2022,17 19 21 23,a,a0,a1,a2,a0 a0+1 a0+2 a0+3,a0,、,a1,、,a2,既然是一维数组名,则它们应代表一维数组的首地址。,a0,代表,第,0,行,一维数组中,第,0,列,元素的地址,即,&a00,;,a0+1,代表,第,0,行第,1,列元素的地址,即,&a01,。,a1,代表,第,1,行,一维数组中,第,0,列,元素的地址,即,&a10,;,。,a2,代表,第,2,行,一维数组中,第,0,列,元素的地址,即,&a20,。,。,表,10.1,表示形式,含 义,地 址,二维数组名,数组首地址,,0,行首地址,2000,第,0,行第,0,列元素地址,2000,第,1,行首地址,2008,第,1,行第,0,列元素地址,2008,第,1,行第,2,列元素地址,2012,第,1,行第,2,列元素的值 元素值为,13,a,a0+0,*(a+0),*a,a+1,&a10,a1+0,*(a+1),a1+2,*(a+1)+2,&a12,*(a1+2),*(*(a+1)+2),a12,a,a+1,a+2,2022,23,2020,21,2018,19,2016,17,2014,15,2012,13,2010,11,2008,9,2006,7,2004,5,2002,3,2000,1,a0+3,a0+2,a0+1,a0+0,牢记,:二维数组名(如,a,)是指向,行,的,因此,a+1,中的“,1,”,表示,一行元素,。一维数组名(如,a0,、,a1,)是指向,列,的,,a0+1,中的“,1”,代表一个元素。,在,行,指针前面加一个,*,,就,转换为列,指针。如,a,、,a+1,(行)*,a,、*,(a+1),(列),在,列,指针前面加一个,&,,就转换为行指针,.,如,a0,(列),&a0,(行,等价于,&*a,,即与,a,等价),例,8.11,输出二维数组有关的值。,#define FORMAT%d,%dn”,main(),int a34=1,3,5,7,9,11,13,15,17,19,21,23;,printf(FORMAT,a,*a);1,printf(FORMAT,a0,*(a+0);2,printf(FORMAT,3,printf(FORMAT,a1,a+1);4,printf(FORMAT,5,printf(FORMAT,a2,*(a+2);6,printf(FORMAT,7,printf(FORMAT,a10,*(*(a+1)+0);8,(假设系统给数组,a,分配的首地址为,2000,),则运行结果是:,注意:,a,是二维数组名,代表数组首地址,不能企图用*,a,来得到,a00,的值。,*,a,相当于*,(a+0),,即,a0,,它是第,0,行地址。,a,是行指针,*,a,是列指针,指向,0,行,0,列元素。*,a,是,0,行,0,列元素的值。,a+1,指向第一行首地址,不能企图用*,(a+1),得到,a10,的值,而应该用*,(a+1),求,a10,元素的值。,2000,2000,2000,2000,2000,2000,2008,2008,2008,2008,2016,2016,2016,2016,9,9,例,8.12,用指针变量输出数组元素的值。,main(),int a34=1,3,5,7,9,11,13,15,17,19,21,23;,int *p;,for(,p=a0,;pa0+12;p+),printf(%4d,*p);,运,行结果:,1 3 5 7,9 11 13 15,17 19 21 23,p-a0,:为相距的单元个数,不是字节数,若:,a0 2000,p 2008,则:,p-a0=,4,1.,指向数组元素的指针变量,二、指向多维数组的指针变量,2123,19,17,111315,9,7,5,3,1,p,a,if(,p-a0,)%4=0),printf(n);,数组元素在数组中的位置,:,计算某个指定的数组元素在数组中的位置(即相对于数组起始位置的,相对位移量,):设,a,是大小为,nm,的二维数组,则,元素,aij,在数组中的,相对位置,的计算公式为:,i*m+j,若,p,是一个指针变量,指向二维数组,a,的首地址:,p=&a00,或,p=a0,,则,元素,aij,的地址为,p+i*m+j,,,故,aij,可以表示成:,*,(p+i*m+j),。,如,a12,位置是:,1*4+2,如,a12,地址是:,p+1*4+2,则,a12,的,值是,:*(p+1*4+2),a12,m,n,a,,,p,以前的例子都是输出数组全部元素,若是输出某个指定的数组元素该怎么办呢?,应该事先计算出该元素在数组中的位置。,2.,指向由,m,个整数组成的一维数组的指针变量,数组指针,由于*运算符的级别低于,,为了定义指针变量,p,,就必须表示成,(*p),的形式。,定义一个,数组指针,变量,p,指向包含,4,个元素的一维数组。,定义方法:,int(*p)4;,a0,a1,a2,a,数组,p,p+1,p+2,*p,有,4,个整型元素,即 指针,p,指向含有,4,个整型元素的一维数组,,,p,的值就是该一维数组的首地址,,p,是数组指针。,(*p)3,(*p)2,(*p)1,(*p)0,p,*p,(数组),若定义:,int a34;,p=/*p,指向,a0*/,则,p+1,不是指向,a01,,而是,a1,,,p,的增值以一维数组的长度为单位。故,aij,可表示为:*,(*(p+i)+j),。,例,8.13,输出二维数组任一行任一列元素的值。,main(),int a34=1,3,5,7,9,11,13,15,17,19,21,23;,int (*p)4,i,j;,p=a;,scanf(%d,%d,printf(a%d%d=%dn,i,j,*(*(p+i)+j);,p,p+2,1 3 5 7,9 11 13 15,17 19 21 23,运行结果:,输入:,1,2,输出:,a12=13,说明:,aij,的地址,可以表示为,:,*(p+i)+j,。,注意,*,(p+i)+j,不能写成,p+i+j,。,对于,数组指针,p,,,p=a,;则,p,指向二维数组,a,的第一行首地址,。,对于,指针变量,p,,,p=a0,;,则,p,指向二维数组,a,的第一行第一列元素首地址,,而,p=a;,是不合法,的。,void average(float *p,int n),float*p_end;,float sum=0,aver;,p_end=p+n-1;,for(;p=p_end;p+),sum=sum+(*p);,aver=sum/n;,printf(average=%6.2n,aver);,void search(float(*p)4,int n),int j;,printf(the score of No.%d are:n,n);,for(j=0;j4;j+),printf(%5.2f ,*(,*(p+n),+j),);,由于,p,指向一维数组,因此,*,(p+n),是第,n,行的首地址,*,(p+n)+j,是 第,n,行第,j,列元素的地址。,运行结果:,average=82.25,the score of No.2 are:,90.00 99.00 100.00 98.00,最后一个元素的地址,从指向第一个元素起,依次指向下一个元素,例,8.15,在上例中,找出有一门以上不及袼的学生,输出其全部成绩。,void search(float(*p)4,int n),int i,j,flag;,for(j=0;jn;j+),flag=0;,for(i=0;i4;i+),if(*(*(p+j)+i)60),flag=1;,if(flag=1),printf(No.%d fails,his scores are:n,j+1);,for(i=0;iy?x:y);,调用,p,所指向的函数,8.7.1,指针数组,指针数组,数组元素均为指针类型数据,,即每个元素都是指针变量。,指针数组的定义形式,:,类型标识 *数组名,数组长度,例如:,int*p4,例如:若干个字符串的排序和查找。,由于字符串本身就是一个字符数组,而各个字符串的长度又不同,因此用二维数组处理不太方便。,如果用指针数组,使各元素分别指向各个字符串,那么只要改变指针数组中各元素的指向,就可对所指的字符串进行排序。,注意与,int(*p)4,的区别,!,8.7,指针数组和指向指针的指针,由于,的优先级高于*,,p,先与,结合表示数组,然后,p,再与*结合,表示数组是指针类型,,int,表示每个数组元素指向一个整型变量,.,例如:有若干字符串,,长短不一,Follow me,BASIC,Great Wall,FORTRAN,Computer design,F o l l o w m e 0,B A S I C 0,G r e a t w a l l 0,F O R T R A N 0,C o m p u t e r d e s i g n 0,Follow me,BASIC,Great Wall,FORTRAN,Computer design,name0,name1,name2,name3,name4,指针数组,name5,字符串,可以分别定义一些字符串,然后用指针数组中的元素分别指向各字符串。如果想对字符串排序,不必改动字符串的位置,只需改动指针数组中各元素的指向。这样,各字符串的长度可以不同,且移动指针要比移动字符串所花的时间少得多。,void print(char*name ,int n),int i;,for(i=0;in;i+),printf(,%s,n,namei,);,#include ,main(),void sort(char*name ,int n);,void print(char*name ,int n);,char*name=Follow me,BASIC,Great Wall,FORTRAN,Computer design;,int n=5;/*,字符串个数,*,/,sort(name,n);,print(name,n);,void sort(char*name ,int n),char*temp;,int i,j,k;,for(i=0;i,n-1,;i+),k=i;,for(j=,i+1,;j0),k=j;,if(k!=i),temp=namei;,namei=namek;,namek=temp;,例,8.27,将,n,个字符串按字母顺序(由小到大)排序输出,(,设,n=5),运行结果:,BASIC,Computer design,FORTRAN,Follow me,Great Wall,name0 Follow me,name1 BASIC,name2 Great Wall,name3 FORTRAN,name4 Computer design,定义形式,:,类型标识 *变量名,例如,:,char*p,由于*是从右到左结合,因此,*,p,相当于,*,(*p),表示,p,是指针变量,表示指针变量,p,指向的还是一个指针,即,:,*p,也是指针变量,表示指针变量,p,指向一个字符型指针变量,char*(*p),&*p,&ch,B,p *p ch,*p,得到字符,B,8.7.2,指向指针的指针,例如:,char *name5;,char *p;,p=name+2;,printf(,%o,n,*p);,printf(,%s,n,*p);,例,8.28,使用指向指针的指针,main(),char*name=Follow me,BASIC,Great Wall,FORTRAN,Computer design;,char *p;,int j;,p=name;,for(j=0;j5;j+),printf(%sn,*(p+j);,以,%o,输出,name2,的值,(,地址,),以,%s,输出,name2,的字符串,Great Wall,运行结果:,Follow me,BASIC,FORTRAN,Great Wall,Computer design,main(),int a5=1,3,5,7,9;,int *num5=,int *p,j;,p=num;,for(j=0;j5;j+),printf(%dt,*p);,p+;,例,8.29,运行结果:,13579,地址 值,值,地址,1,地址,2,值,地址,1,地址,2,地址,3,地址,n,值,。,指针变量,1,指针变量,2,指针变量,3,指针变量,n,变量,单级间址,二级间址,多级间址,8.8.1,指针类型的小结,8.8,指针类型和指针运算的小结,定 义,含 义,int i;,定义整型变量,i,int*p;,p,为指向整型数据的指针变量,int an,定义整型数组,a,,它有,n,个整型元素,int*pn;,定义指针数组,p,,它有,n,个指向整型数据的指针元素组成,int (*p)n,p,为指向含,n,个元素的一维数组的指针变量,int f();,f,为带回整型函数值的函数,int*p();,p,为带回一个指向整型数据的指针的函数,,int (*p)();,p,为指向函数的指针,该函数返回一个整型数据,int *p;,p,是一个指针变量,它指向一个指向整型数据的指针变量,指针运算有如下几种:,1.,指针变量 可以和整数进行加(减),例如:,p+,p-,p+i,p-i,p+=i,p-=i;,注意:,p+1,指的是加,1,个单位,即,p,所指向的变量占用的内存字节数,,如,p,是指向,整型变量的指针,则加,2,个字节。,2.,指针变量可以赋值(,赋地址,),例如:,p=,p=array;,(array,是数组名,),或,p=,p=max;,(max,是函数名),p1=p2;,(p2,是指向某个变量的指针,赋给指针变量,p1),p=1000;,是不允许的。,3.,指针变量可以赋空值,即不指向任何变量。例如:,p=NULL,;,(NULL,表示整数,0,),在,stdio.h,中有定义:,#define NULL 0,任何指针变量或地址都可以与,NULL,作相等或不相等的比较,如,if(p=NULL),4.,两个指针变量可以相减,即,p2-p1,,表示两个指针之间的元素个数。,但,p1+p2,无意义。,5.,若两个指针指向同一个数组的元素,则可以进行比较,,例如:,p1p2 ,p1=p2 .,p1,p2,8.8.2,指针运算小结,它可以用来表示指向一个抽象的数据类型,。例如:,char *p1;,void *p2;,p1=(char*)p2;,把,p2,强制转换为指向字符变量的指针。,也可以将一个函数定义为,(void*),类型,例如:,void*fun(char ch1,char ch2),指针是,C,语言中重要的概念。使用指针的优点是:,(,1,)提高效率;,(,2,)被调函数可以改变主调函数的值,即可以返回多个值;,(,3,)可以实现动态存储分配。,8.8.3 void,指针类型,指针变量如何定义,指针和地址的关系,如何对指针进行运算?,如何定义和使用以下对象:指针数组、数组指针、指针的指针、函数指针、返回值为指针的函数。,如何使用字符指针?,如何通过指针来改变函数实在参数的值?,什么是命令行参数?如何正确使用?,本 章 要 点,习 题 八 (一),(一)填空,(1),写出建立图一所示的存储结构所需的定义语句:,char_.,(2),写出,图一所示的存储结构所需的赋值语句:,_=B;p=_.,(3),写出用指针变量,p,输出字符变量的语句:,printf(%cn,);,(二)填空,(1),写出建立图二所示的存储结构所需的定义语句:,int _,_;,(2),写出,图二所示的存储结构所需的赋值语句:,p=_;,(3),写出用指针变量,p,输出数组,s,每一个元素值的语句:,for(j=0;j6;j+),printf(%dt,_);,(4),要使,p,指向数组的最后一个元素,改变,p,的表达式是,。,B,p,指针变量 字符变量,(图一),0,1,4,9,16,25,(图 二),数组,s6,指针,p,(三)填空,(1),写出建立图三所示的存储结构所需的定义语句:,float _,_,_;,(2),写出,图三所示的存储结构所需的赋值语句:,k=_;s=_;p=_;,(3),用指针变量,s,输出,k,的值语句:,;,(4),用指针变量,p,输出,k,的值的语句:,;,1.34,p s k,(图 三),(四)写出以下程序运行结果。,(1)#include,main(),int a,*ap;,a=100;ap=,printf(%d,%dn,a,*ap);,a=200;,printtf(%d,%dn,a,*ap);,*ap=300;,printf(%d,%dn,a,*ap);,(2)#include,main(),char s=hello;,printf(%s,s+2);,(3)int a=5,6,7,8,10;,main(),int *p=a+3;,printf(%d,%d,%dn,*p,*(p+1),*p+1);,(4)main(),int c=1,7,12,*p;,p=c;,printf(%d,*+p);,(5)#include,main(),char *ap,*s;,int j,n;,s=Happy New Year;,ap=s;,for(n=0;*s!=0;+s,+n),;,for(j=0;jtest hello worl d,(2)#include,main(),int a=10,b=80;,int *p1=,printf(1.a=%d,b=%d,*p1=%d,*p2=%dn,a,b,*p1,*p2);,*p1=20;,printf(2.a=%d,b=%d,*p1=%d,*p2=%dn,a,b,*p1,*p2);,*p2=30;,printf(3.a=%d,b=%d,*p1=%d,*p2=%dn,
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服