c语言基础教程_第七章__指针,免费版.doc_第1页
c语言基础教程_第七章__指针,免费版.doc_第2页
c语言基础教程_第七章__指针,免费版.doc_第3页
c语言基础教程_第七章__指针,免费版.doc_第4页
c语言基础教程_第七章__指针,免费版.doc_第5页
已阅读5页,还剩46页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

免费版第七章 指针7.1.1 什么是指针 指针是一种特殊的变量。它的特殊性表现在哪些地方呢?由于指针是一种变量,它就应该具有变量的三要素:名字、类型和值。于是指针的特殊性就应表现在这兰个要素上。指针的名字与一般变量的规定相同,没有什么特殊的地方。指针的值是某个变量的地址值。因此我们说指针是用来存放某个变量地址值的变量。指针的值与一般变量的值是不同的,这是指针一个特点。这就是说,指针是用来存放某个变量的地址值的,当然被存放地址值的那个变量是已经定义过的,并且被分配了确定的内存地址值的。一个指针存放了哪个变量的地址值,就说该指针指向那个变量。指针的第二个特点就表现在它的类型上,指针的类型是该指针所指向的变量的类型,而不是指针本身值的类型,因为指针本身值是内存的地址值,其类型自然是int型或lang型。而指针的类型是由它所指向的变量的类型决定。由于指针可以指向任何一种类型的变量C语言中所允许的变量类型,因此,指针的类型是很多的,例如,int型,char型,float型、数组类型、结构类型、联合类型,还可以指向函数、文件和指针等。 下面通过一个例子,进一步对指针的两个特点加深理解。例如, int a=5,*P; 这里,说明了变量a是int型的,并且赋了初值。在说明语句中,P表示P是一个指针,括号(,)是说明符,它说明后面的变量不是一般变量,而是指针,并且P是一个int型指针,意味着P所指向的变量是一个int型变量。假定,要指针P指向变量a,由于指针是用来存放变量的地址值的,因此,要将变量a的地址贼给指针P,变量a的地址表示为肠,这里邑是运算符,表示取其后面变量的地址值。如果有 p=&a; 则P是指向变量a的指针。假定a被分配的内存地址是3000h, P和a的关系如下图所示: 图中标明变量a的内存地址为30O0,变量P的内存地址为3500H,变量a的值(即内容)为5,而指针P的值为3000H,可见指针P是用来存放变量a的地址值的。C语言中关于地址值的表示有如下规定: (1)一般变量的地址值用变量名前加运算符&表示。例如,变量x的地址值为&x等。 (2)数组的地址值可用数组名表示,数组名表示该数组的首元素的地址值。数值中某个元 素的地址值用&,运算符加上数组元素名。例如: int a10,*p1,*p2; P1=a; p2=&a5; 这里,*p1和*p2是指向int型变量的指针,pl=a;表示指针P1指向a数组的首元素;P2=&a5;表示指针p2指向数组a的数组元素a5的指针。 (3)函数的地址值用该函数的函数名来表示,指向函数的指针可用它所指向的函数名来赋值。 (4)结构变量的指针用尽运算符加结构变量名来表示,结构变量的成员的地址也用邑运 算符加结构变量的成员名来表示。关于结构变量和结构变量的成员将在结构一章中讲解。 关于&运算符的用法需要注意的是它可以作用在一般变量名前、数组元素名前、结构变量名前和结构成员名前等,而不能作用在数组名前,也不能作用在表达式前和常量前。 综上所述,对指针的含意应作如下理解:指针是一种不同于一般变量的特殊变量,它是用来存放某个变量的地址值的,它存放哪个变量的地址就称它是指向那个变量的指针。指针的类型不是它本身值的类型,而是它所指向的变量的类型。简单地说,对指针应记住如下两点: (1)指针的值是地址值。 (2)指针的类型是它的所指向变量的类型。7.1.2 指针的表示 在明确了指针的含意以后,接着要学会正确地表示指针。 它在表示上也有差别。应记住各种不同类型指针的表示。 (1)指向基本类型变量的指针表示如下: 指向int型变量的指针。例如: int * pI, p2; 这里,P1和p2是两个指向整型变量的指针,p1和p2前的*是表示指针的说明符。 指向。har型变量的指针,例如: char*pcl,*pc2; 这里,pcl和pc2是两个指向字符型变量的指针。 指向float型变量的指针,例如: float*pf1,*pf2, double * pdl,pd2; 这里,pfl和pf2是两个指向单精度浮点型变量的指针。pdl和pd2是两个指向双精度浮点型变量的指针。 (2)指向数组的指针表示如下: 一般地,认为指向数组的指针就是指向该数组首元素的指针,例如: int a53,(*pa)3; 其中,a是一个二维数组的数组名,pa是一个指向数组的指针名。pa是一个指向每列有3个元素的二维数组的指针。例如, Pa=a; 则表示指针pa指向二维数组a指向数组的指针的表示与指针数组的表示很相似,使用时要注意其区别。例如: float m32,*P13,(*p2)2; 这里,m是一个二维数组名,p1是一个一维一级指针数组名。所谓指针数组就是数组的元素为指针的数组。P1是指针数组名,数组p1有3个元素,每个元素是一个一级指针,该指针指向float型变量,p2是一个指向数组的指针,它指向一个每列有2个元素的二维数组。可见,p1和p2的表示形式很相似,前者是指针数组,后者是指向数组的指针,其含意是完全不同的。 指向数组元素的指针一般是指向该数组的任何一个元素。例如; float n105,*p; p=&n51; 这里,P是一个指向float型变量的指针,将数组n的某个元素的地址值,如&n51赋给该指针P,则P便是一个指向数组n的某个元素的指针。一般地,指向数组元素的指针是一个指向该数组元素所具有的类型的变量的指针,它与指向数组的指针在表示上是有区别的。 (3)指向函数的指针表示如下: int(,pf)(); 这里,pf是一个指向函数的指针,它所指向的函数的返回值为int型数。 指向函数的指针与指针函数在表示_L要区别开口下面的pf是一个指针函数: int*pf(); 这里,pf是一个返回值为int型数的指针函数。所谓指针函数是一种返回值为指针的函数。 (4)指向指针的指针表示如下: int * *pp; 这里,PP是一个指向指针的指针,即是一个二级指针。所谓二级指针是指它所存放的地址是一个一级指针的地址值,即它所指向的是一个一级指针。所以,二级指针又称为指针的指针。同样,三级指级所存放的是一个二级指针的地址值,该二级指针又存放着一级指针的地址值,该一级指针才存放某个变量的地址值。所以,三级指针是指针的指针的指针。依此类推。 关于结构变量的指针和文件指针以后再讲解。7.1.3 指针的赋值 前面已经讲过,指今十的值是地址值,因此,给指针赋值或赋初值要是一个地址值亡各种变量的地址值的表示方法前面已经讲过了。所以给指针赋值不是一件困难的事情。1.赋值和赋初值 给指针可以赋值,也可以赋初值。 赋值是用一个赋值表达式语句进行;赋初值是在说明或定义指针的同时给它赋值。 不论是赋值还是赋初值,对一般的指针都是给予一个相对应的地址值;对于指针数组,则按其数组的赋值或赋初值方法进行赋值。例如: intx,*p=&.x; 这是给指向int型变量指针P赋初值,即将int型变量二的地址值赋给了P.如果写成赋值的方式,如下所示: intx,*P; p=&x; 又例如, floaty23*PY2=Y0,Y1; 这是给一个指针数组PY赋初值,PY是一个具有2个元素的指针数组,它的每个元素是一个float型的指针,这里Y0和y1是用来表示二维数组y的两个行地址,即将数组Y看成是三行三列的一个数组,每一行是一个一维数组,它由3个元素组成。由此可见,一个二维数组可以表示为一个一维的指针数组,该指针数组的每个元素对应二维数组的每一行。上例又可写成赋值的形式,如下所示: float y23,*PY2; PY0=y0 PY1=yl; 或者, int i float y23,*PY2; for(i=0;i=s) putchar(*ch); putchatr(n); 执行该程序输出结果如下 Hgfedcba 说明:该程序中,s是数组名,ch是一个指向s数组第8个元素的指针,即指向该字符串的结束符。(记住:数组元素是从第。个数起!)通过while循环,eh指针每次减1.通过putchar()函数将字符串从最后一个字符开始输出,形成逆序输出直到该字符串首字符被输出为止。7.3.2 数组元素的指针表示 数组元素可以用指针表示,也可以用下标表示,而用指针表示比用下标表示可提高速度。 因此,尽量采用指针表示。 下面讨论一维数组、二维数组和三维数组的元素的各种表示方法。 1.一维数组 假定a是一个一维数组,其定义格式如下: int a10; 该数组元素的下标表示为: ai,i=0,1,,9. 该数组元索的指针表示为: *(a+i),i=0,1,,9. 因为a为该数组的首元素地址,a+-i为该数组第1个元素的地址,而*(a+i)则为该数组的第i个元素的值。 一维数组的指针表示很简单,使用数组名(实际上指向数组首元素的指针)可以很方便地表示出数组各元素的值,实际上数组是按一定顺序存放在内存,由于各元素类型相同,即每个元素占用的内存单元的字节数也相同,因此,只是知道首元素的地址,便一可通过指针加1办法来访问数组的所有元素。例7.7们分析下列程序输出结果。 main() ( static inta=0,1,2,3 int *p=a; printf(%d,%d,%dn.a1,p2,*(p+3); 执行该程序输出结果如下: 1,2,3 说明:程序中是个指向数组a,a是一个维数组名。a1是该数组的第1个元素(数组元素是从0数起,P是一个指向数组a首元素的指针,p2表示与*(p十2)是等价的,即表示a2元素,而*(p+3)表示了a习元素。因此,有上述结果。例7.8分析下列程序的输出结果。 maim() static int a=l,3,5,7,9); int i, * p; for(p=a,i=O;p十i=a+4;p+,i+) printf (%4d,*(p十i); prints(n); for(p-=a+4.i=0;i5;i+) printf( %4d,p一1); printf(n); 执行该程序输出结果如下; 1 5 9 9 7 5 3 1 说明:该程序中,a是一维数组名,P是指向数组a的指针。第一个for循环时,P指向a数组的a0元素,第二个for循环时,p指向a数组的a5元素。 第一个for循环将顺序输出a数组中的某些元素,在Printf ( )函数中,使用*(p+i)来代替数组a的各元素值它等价于ai 第二个for循环中,printf ()函数的参数是p-1,该参数等价于*(p-i),p开始时指向数组a的a5元素,i由0逐次增加到5,于是按其相反顺序输出a数组中5个元素。例7.9编程把一个int型数组中的若干个元素按相反顺序存放。 #define N 8 int bN=8,7,6,5,4.3,2,1, main() int i,n,j,t; printf (The original array ; n); for(i=0=i=n;i+) printf (%4d,*(b+1); printf(n); n= (N一1)/2; for(i=o;i=n,i+) j=N-1-i; t=bi bi=t; printf(The array has been inverted;n); for(i=0,i,9,10,11,12); main() int i.j; fnr(i=0;printf (n),i3;i+) for (j=0;j, *(b2+3),(*(b+l)2; 执行该程序输出如下结果: 1 2 3 4 5 6 7 8 9 10 11 12 5 3 12 7 说明:该程序出现了5处二维数组元素的不同表示形式。其中*(*b+i十j)相当于bi j,*(b+1)相当于blo,*(*b+2)相当于b02,*(b2+3)相当于b23.(*(b+1)2相当于bl2.因此,会有上述结果。 例7.12二假定有5个学生,每人有3门功课的成绩,编程输出每个学生的平均分数。 编程如下: float acore53=86,90,78,86,84,96,91,76,88, 90,77,66,78,97,68; main() int i j float aver5; for(i=0;i5,i+) averi=0,0 for(i=0;i5;i+) for(j=0;j3;j+) *averi/=3; for(i=0.ijk 行、列用指针,组用下标表示: (*(*(c十i)+j)k 行用下标,列、组用指针表示: *(*(ci+j)+k) 行、组用指针,列用下标表示: *(*(c+i)j+k) 行、列、组都用指针表示: *(*(*(c+i)+j)+k) 三维数组元素共有卜述9种表示方法。 下面给出三维数组的各种地址的表示方法: 行地址表示为:c+i或&ci等形式。 行、列地址表示为:*(c+i)+j,ci+j,&cij等形式。 行、列、组地址(即元素地址)表示为: *(*(c+1)+j)+k,*(ci+j)+k,&cijk等形式。例7.13分析下列程序的输出结果。 int a223=1*2,3,4,5,6),7,8,9,10,11,12); main() int i j k a001=20 *(a01+2)=21 (*(a+1)01=22 (*(a1+1)0=23 *(*(a0+1)+1)=24 for(j=O;j2;j+) for(j=O;j2;j+) for(k=o;k3.k+) printf(%4d,*(*(*(a

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论