C语言程序设计基础 教学课件-第9章 指针2_第1页
C语言程序设计基础 教学课件-第9章 指针2_第2页
C语言程序设计基础 教学课件-第9章 指针2_第3页
C语言程序设计基础 教学课件-第9章 指针2_第4页
C语言程序设计基础 教学课件-第9章 指针2_第5页
已阅读5页,还剩56页未读 继续免费阅读

下载本文档

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

文档简介

数组的指针和指向数组的指针变量指向数组元素的指针变量的定义与赋值:(与指向变量的指针变量相同。)如:inta[10];(定义a为包含10个整型数据的数组)int*p;(定义p为指向整型变量的指针变量)p=&a[8];(p指向数组元素a[8])p=a;(p指向数组元素a[0],首地址)数组的指针和指向数组的指针变量C语言规定:数组名代表数组的首地址。p=&a[0];p=a;两个语句等价在定义指针变量的同时可赋初值:int*p=&a[0];或int*p=a;每一句等价于:int*p;p=&a[0];两句。图9.12指向数组元素的指针变量p&a[0]13151719pa[0]:a[9]数组的指针和指向数组的指针变量通过指针引用数组元素假设p=&a[5];那么:a[5]=8;等价于*p=8;c规定:p=p+1:新p指向数组的下一元素。P=P+1:意味着新p比原p的地址值多d个字节〔d为一个数组元素所占的字节数〕。数组的指针和指向数组的指针变量如果开始p指向a[0](即p=&a[0]),那么:〔1〕p+i和a+i:均为a[i]的地址(&a[i])。〔2〕*(p+i)或*(a+i):均为a[i]的值(a[i])。〔3〕指向数组的指针变量也可以带下标,如p[i]与*(p+i)等价:也均为a[i]。图*(p+i)a数组a[0]a[1]a[2]a[i]a[9]pp+1,a+1p+i,a+ip+9,a+9数组的指针和指向数组的指针变量据上所述,引用一个数组元素有二法:〔1〕下标法:如a[i]形式;〔2〕指针法:如*(a+i)或*(p+i)。其中a是数组名,p是指向数组元素的指针变量,且其初值p=a。[例9.5]用三种方法输出数组全部元素。(1)下标法main(){inta[10];inti;for(i=0;i<10;i++)scanf("%d",&a[i]);printf("\n");for(i=0;i<10;i++)printf("%d",a[i]);}

(2)通过数组名计算数组元素地址,找出元素的值main(){inta[10];inti;for(i=0;i<10;i++)scanf("%d",&a[i]);printf("\n");for(i=0;i<10;i++)printf("%d",*(a+i));}(3)用指针变量指向数组元素main(){inta[10];int*p,i;for(i=0;i<10;i++)scanf("%d",&a[i]);printf("\n");for(p=a;p<(a+10);p++)printf("%d",*p);}数组的指针和指向数组的指针变量使用指针变量时,有几个问题要注意:〔1〕P++合法;但a++不合法〔a是数组名,代表数组首地址,是常数地址。〕〔2〕要注意指针变量的当前值。

[例9.6]main(){int*p,i,a[10];p=a;for(i=0;i<10;i++)scanf("%d",p++);printf("\n");p=a;for(i=0;i<10;i++,p++)printf("%d",*p);}〔如果没有p=a;第二个printf语句将出问题。)数组的指针和指向数组的指针变量〔3〕注意指针变量的有关运算:假设先使指针指向数组a,即有p=a,那么:p++(或p+=1〕:p将指向下一元素,即a[1]。*p++:等价于*〔p++),先*p,得a[0];P再自增1,新的p指向a[1]。*(p++)与*(++p):*(p++)是先取*P的值,后使P加1;*(++p)是先使p加1,后取*p的值。数组的指针和指向数组的指针变量(*p)++:表示p所指向的元素值加1(即a[0]++),而不是指针值p加1。如果p指向a数组的第i个元素,那么:*(p--)相当于a[i--],先取p值做*运算,再使p自减。……

数组的指针和指向数组的指针变量数组名作函数参数main()|f(b,n){inta[10];|intb[],n;a[0]=5;…...|{……..f(a,10);|b[0]==5(真)…...…...|b[n-1]==b[9](真)…...|……}|}数组的指针和指向数组的指针变量]“数组倒序〞算法示意图:(a[i]值与a[j]值交换,0≤i≤m,m=(n-1)/2,)3791106754224576011973imj图9.16[例9.7]源程序voidinv(x,n)intx[],n;{intt,i=0,j=n-1;m=(n-1)/2;for(;i<=m;i++,j--){t=x[i];x[i]=x[j];x[j]=t;}return;}(注:红色代码与书上的不同〕main(){staticinta[10]={0,1,2,3,4,5,6,7,8,9};inti;inv(a,10);printf(“数组已被反序为:\n");for(i=0;i<10;i++)printf("%d,",a[i]);printf(“\n〞);}结果:9,8,7,6,5,4,3,2,1,0数组的指针和指向数组的指针变量9.3.4指向多维数组的指针和指针变量一、多维数组的地址今以二维数组为例,设二维数组的数组名为a。两种不同性质的地址值:行地址与元素地址a与*a、*(a+0)、a[0]:前者第0行首地址;后者第0行第0列元素的地址.a+i与*(a+i)、a[i]:前者第i行首地址;后者第i行第0列元素的地址.

2000120023200452006720089201011201213201415201617201819202021202223aa+1a+2a[0]+1a[0]+2a[0]+3图9.25行地址,元素地址的表示法二维数组多种地址的表示形式:(图9.25的对应表)表示形式含义地址

a二维数组第0行首地址2000a[0],*(a+0),*a第0行第0列元素地址2000a+1第1行首地址2008a[1],*(a+1)第1行第0列元素地址2008a[1]+2,*(a+1)+2,&a[1][2]第1行第2列元素地址2012*(a[1]+2),*(*(a+1)+2),a[1][2]第1行第2列元素的值元素值为13二、多维数组的指针元素的指针变量定义:与指向普通变量的指针变量相同。p=p+1:新p将指向下一个数组元素。(即:这种指针变量p加1的移动量以数组的一个元素为单位〕由二维数组的首地址计算元素a[i][j]的地址:(设二维数组每行有m个元素,且p1=&a[0];)思路:〔1〕元素a[i][j]前面共有多少个元素?〔im+j〕个〔2〕元素a[i][j]的指针比a[0][0]的指针应加几?所以:p2=p1+(im+j);即p2=&a[0][0]+im+j;a[2][3]i=2j=3mn图(p1=&a[0][0],p2=&a[2][3]:p2=p1+im+j=p1+11)数组的指针和指向数组的指针变量定义:int(*p)[4];那么定义了p为指向一个包含4个元素的一维数组的指针变量〔行指针变量〕。假设:有一个行长为4的二维数组a[n][4],且初始化:p=a;(p指向第0行〕那么:p+1:指向第1行之首p+i:指向第i行之首(注:这种p指针变量加1的移动量以数组行长为单位〕数组的指针和指向数组的指针变量注:两种等值而性质不同的指针值:p与*p,p+1与*(p+1),p+i与*(p+i),(前者为行指针值,增值单位为一行的总地址长;后者为元素指针,增值单位为一个元素地址长。)三、多维数组的指针作函数参数例、score:实参数组名,average()和search():被调函数。函数调用与函数定义形式:(数组行长为4:score[][4])average(*score,12);search(score,2);voidaverage(p,n)voidsearch(p,n)float*p;intn;float(*p)[4];intn;{.{.....}}字符串的表示形式1、用字符数组实现〔已学过〕:main(){staticcharstring[]="ILoveChina!";printf("%s\n",string);}运行时输出:ILoveChina!2、用字符指针实现:字符指针变量的定义:char*p;main(){char*string=“ILoveChina!〞;(初始化string)printf("%s\n",string);}运行时也输出:ILoveChina!char*str=“Ilovechina〞;等价于以下两句:char*str;str=“china〞;以上语句的含义:定义str为指针变量,它指向字符型数据,且赋值语句把字符串“Ilovechina〞的首地址赋给了指针变量str.字符串指针变量的性质:p+1后;新p指向下一字符。9.4.2字符串指针作函数参数1.用字符数组名作参数〔已学过〕2.用指向字符串的指针变量作参数:如:StringCopy(s,t)char*s,*t;{while(*s++=*t++);}以上循环语句相当于:while(*t!=‘\0’){*s=*t;s++;t++;}归纳起来,作为函数参数,有四种情况:实参形参1、数组名数组名2、数组名字符指针变量3、字符指针变量字符指针变量4、字符指针变量数组名9.4字符串的指针和指向字符串的指针变量9.4.3字符指针变量与字符数组之区别1、值的区别:字符数组元素存字符;字符指针变量中存放字符的地址。2、赋初值的方式:staticcharstr[]=“Ilovechina!〞;char*a=“Ilovechina!〞;3、赋值的方式:字符数组:a[0]=‘I’;a[1]=‘’;a[2]=‘L’;….;字符指针变量:char*a;a=“ILoveChina!〞;但应注意:赋给a的不是字符,而是字符串的首地址。4、赋初值时,字符指针变量有两种等价方式:char*a=“ILoveChina!〞;或:char*a;a=“ILoveChina!〞;对字符数组初始化时:staticcharstr[14]=“ILoveChina!〞;〔正确〕不能等价于:charstr[14];str[]=“ILoveChina!〞;〔错误〕即数组不能在赋值语句中整体赋值。5.假设a是字符指针变量,在用以下语句时:scanf(“%s〞,a);首先a应有确定值,即应先使a指向数组的开头。main(){char*a="ILoveChina";a=a+7;printf("%s",a);}程序输出结果:China!7、用指针变量指向一个格式字符串。如:char*format;format=“a=%d,b=%f\n〞;那么以下两句等同:printf(format,a,b);printf(“a=%d,b=%f\n〞,a,b);函数的指针和指向函数的指针变量9.5.1用函数指针变量调用函数函数指针变量的定义:如:float(*p)();定义了p指向float型函数。函数名:代表函数的入口地址。假设:intmax(x,y);int(*p)();p=max;那么:c=max(5,8);相当于c=(*p)(5,8);〔两种等价调用函数的方式〕max(x,y)intx,y;{intz;if(x>y)z=x;elsez=y;return(z);}main(){intmax〔〕;int〔*p)();inta,b,c;p=max;scanf("%d,%d",&a,&b);c=(*p)(a,b);printf("a=%d,b=%d,max=%d",a,b,c);}函数名代表函数的入口地址,“p=max〞的作用是:使p指向函数的入口地址(见以以下图〕。maxp指令1指令2……函数的指针和指向函数的指针变量9.5.2把指向函数的指针变量作函数参数实参函数名:f1f2

sub(x1,x2)int(*x1)(),(*x2)();/*定义函数指

{inta,b,i,j;针变量x1,x2*/…..a=(*x1)(i);---相当于a=f1(i);b=(*x2)(i,j);---相当于a=f2(i,j);……}为何在sub中不直接调用f1,f2函数呢?〔目的使sub函数具有通用性,不仅可调用f1,f2函数;还可调用其它函数。〕9.6返回指针值的函数一个函数可以带回整型值、实型值、字符型值,也可以带回指针型的数据,即地址。返回指针值的函数,一般定义形式为:类型标识符*函数名〔参数表〕;例如:int*a(x,y);a是函数名,调用它后能得到一个指向整型9.6返回指针值的函数数据的指针〔地址〕。x,y是函数a的形参。这个函数前面有一个*,表示此函数是指针型函数〔函数值是指针〕。9.7指针数组和指向指针的指针9.7.1指针数组的概念一个数组,其元素均为指针类型数据,称为指针数组,也就是说,指针数组中的每一个元素都是指针变量。定义形式为:类型标识*数组名[数组长度说明]例如:int*p[4]9.7指针数组和指向指针的指针“int*p[4]〞的含义:定义了一个数组p,它有四个元素,每个数组元素〔指针变量〕都可指向一个整型变量。注意:不要写成int(*p)[4]的形式,这时的p是指向一维数组的指针变量。指针数组比较适合用来指向假设干个字符串。9.7指针数组和指向指针的指针用指针数组指向假设干个字符串,可使字符串处理更方便。9.7指针数组和指向指针的指针9.7.2指向指针的指针定义〔例如〕:char**p;p是这样的一个指针变量,它指向另一个字符指针变量*p,(即*p是指向字符型数据的指针变量,而p又是指向*p的指针变量〕。9.7指针数组和指向指针的指针程序中,如果*p直接指向某一对象〔字符串〕,那么p间接指向该字符串对象。即*p是p间接指向的对象的地址,而**p那么是p间接指向的对象的值。9.7指针数组和指向指针的指针9.7.3指针数组作main函数的形参例如:main(argc,argv)argc,argv就是main函数的形参。main函数是由系统调用的,当处于操作命令状态下,输入main函数所在的文件名,系统就调用main函数。main函数的形参从何处得到?9.7指针数组和指向指针的指针main函数的形参所对应的实参是在操作命令中给出的。也就是在一个命令行中包括命令名和需要传给main函数的参数。命令行的一般形式为:命令名参数1参数2…参数n命令名和参数之间用空格分隔。main函数的形参argc是指命令行中参数的个数。9.7指针数组和指向指针的指针例如,假设有一目标文件名为file1,今想将两个字符串“China〞,“Beijing〞作为传给main函数的参数,命令行可写为:file1ChinaBeijing命令执行后,main函数中的参数argc将为3,而main函数中的第二个参数argv是一个指向字符串的指针数组,其数组元素分别指9.7指针数组和指向指针的指针向命令行的各个参数〔参数均为字符串,注意命令名file1也作为一个参数〕。即argv[0]是指向字符串“file1〞的首地址,argv[1]是指向字符串“China〞的首地址,argv[2]是指向字符串“Beijing〞的首地址。9.7指针数组和指向指针的指针带参数的main函数的形式应为如下:main(argc,argv)intargc;char*argv[];{......}9.8有关指针的数据类型和指针运算的小结一、有关指针的数据类型〔如下表〕inti;定义整型变量i。int*p;p为指向整型变量的指针变量。inta[n];定义整型数组a,它有n个元素。int*p[n];定义指针数组p,它由n个指向整型数据的指针元素组成。int(*p)[n];p为指向含n个元素

温馨提示

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

评论

0/150

提交评论