高级语言程序设计 课件 第7章 指针_第1页
高级语言程序设计 课件 第7章 指针_第2页
高级语言程序设计 课件 第7章 指针_第3页
高级语言程序设计 课件 第7章 指针_第4页
高级语言程序设计 课件 第7章 指针_第5页
已阅读5页,还剩37页未读 继续免费阅读

付费下载

下载本文档

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

文档简介

第7章指针7.1指针和指针变量

指针和数组7.2

指针和字符串7.37.4指针和函数7.5指针数组本章内容导读本章主要介绍指针和指针变量,以及使用指针变量引用变量、字符串、一维数组元素的方法。同时介绍指针数组的定义和指针数组元素的使用。通过学习本章,读者应掌握以下内容:掌握地址、指针和指针变量的概念;掌握指针变量指向数组元素、数组或字符串的方法;掌握指针变量引用一维数组元素、二维数组元素或字符串中字符的方法;了解指针数组的概念和使用方法。地址:一个变量名代表内存中的一个存储单元,每个存储单元都有一个编号,即“地址”。

房间—变量名房客—变量值房间号—地址编译或函数调用时为变量分配内存单元1、指针7.1指针和指针变量内存中每个字节均有一个编号——地址

inti,j;charch;floatf;i=5;j=3;ch='H';f=3.14;

53'H'3.14ijchf……………………2000200220042005200920012003200620072008例如intmain(void)

{intnum;

scanf("%d",&num);

printf("num=%d\n",num);

}C编译程序编译到变量定义语句时,将变量num登录到“符号表”中。符号表的关键属性有两个:一是“标识符名(id)”,二是该标识符在内存空间中的“地址(addr)”。为描述方便,假设系统分配给变量num的2字节存储单元为3000和3001,则起始地址3000就是变量num在内存中的地址。变量值的存取──通过变量在内存中的地址进行

系统执行scanf("%d",&num);和printf("num=%d\n",num);时,存取变量num值的方式有两种:1、指针7.1指针和指针变量直接访问──直接利用变量的地址进行存取(1)上例中scanf("%d",&num);的执行过程:用变量名num作为索引值,检索符号表,找到变量num的起始地址3000;然后将键盘输入的值(假设为3)送到内存单元3000和3001中。此时,变量num在内存中的地址和值。(2)printf("num=%d\n",num);的执行过程与scanf相似.首先找到变量num的起始地址3000,然后从3000和3001中取出其值,最后将它输出。间接访问──通过另一变量访问该变量的值

1、指针7.1指针和指针变量例如,假设定义了一个指针变量num_pointer,它被分配到4000、4001单元,其值可通过赋值语句num_pointer=#得到。此时,指针变量num_pointer的值就是变量num在内存中的起始地址3000。通过指针变量num_pointer存取变量num值的过程:首先找到指针变量num_pointer的地址(4000),取出其值3000(正好是变量num的起始地址);然后从3000、3001中取出变量num的值(3)。比较两种访问方式之间的关系,可以用某人甲(系统)要找某人乙(变量)类比。一种情况是,甲知道乙在何处,直接去找就是(即直接访问)。另一种情况是,甲不知道乙在哪,但丙(指针变量)知道,此时甲可以这么做:先找丙,从丙处获得乙的去向,然后再找乙(即间接访问)。1、指针7.1指针和指针变量例inti;int*p=&i;变量必须已说明过类型应一致例

int*p=&i;

inti;(

)例inti;int*p=&i;int*q=p;用已初始化指针变量作初值定义格式[存储类型]数据类型符*指针变量名[=初始地址值],…;2、指针变量的定义和初始化7.1指针和指针变量说明(1)“*”表示定义一个指针变量。指针变量的前面必须有“*”号。(2)在定义指针变量的同时也可以定义普通变量或数组等。(3)“数据类型符”是指针变量所指向变量的数据类型,可以是任何基本数据类型,也可以是其它数据类型。这个数据类型符不是指针变量中存放的数据类型,而是指针变量所指向的变量或数组的数据类型。(4)“初始地址值”通常是&变量名、&数组元素或一维数组名,这里的变量或数组必须是已经定义过的。(5)在定义指针变量时,可以只给部分指针变量赋初值。(6)指针变量的初始化,除了可以是已定义变量的地址,也可以是已初始化的同类型的指针变量,也可以是NULL(空指针)。(7)指针变量初始化时,指针变量的“数据类型符”必须与其“初始地址值”是同一类型。2、指针变量的定义和初始化7.1指针和指针变量…...…...2000200420062005整型变量i10指针变量pi2001200220032000指针

变量的内容

变量的地址inti,*pi;i=10;pi=&i;2、指针变量的定义和初始化7.1指针和指针变量内存地址──内存中存储单元的编号(1)计算机系统的内存中,拥有大量的存储单元(容量为1字节)。为了方便管理,必须为每一个存储单元编号,这个编号就是存储单元的“地址”。每个存储单元都有一个惟一的地址。(2)在地址所标识的存储单元中存放数据。注意:内存单元的地址与内存单元中的数据是两个完全不同的概念。变量地址──系统分配给变量的内存单元的起始地址2、指针变量的定义和初始化7.1指针和指针变量给指针变量赋值格式:指针变量=地址型表达式直接使用指针变量格式:指针变量名通过指针变量引用所指向的变量格式:*指针变量名3、指针变量的一般使用7.1指针和指针变量

取地址运算符&:取变量的地址,单目运算符、右结合性。

指针运算符*:取指针变量所向指地址中的内容,与&为互逆运算。单目运算符、右结合性。例:inti=5,j,*pi;

pi=&i;例:j=*pi;相当于j=i;4000指针变量pi整型变量i5*pi&i

pi=&i=&(*pi)i=*pi=*(&i)4、指针的基本运算7.1指针和指针变量输出结果:x=6,y=9MAX=9,MIN=6…...…...指针变量px

指针变量p20002008200220042006

指针变量py

整型变量y

整型变量x6200692008200620082006【例7-1】输入x、y两个整数,按先大后小的顺序输出x、y。#include<stdio.h>intmain(void){

intx,y,*px,*py,*p;

scanf("%d%d",&x,&y);

px=&x;py=&y;

if(x<y){p=px;px=py;py=p;}

printf("x=%d,y=%d\n",x,y);printf("MAX=%d,MIN=%d\n",*px,*py);return0;}运行输入:69指针变量指向一维数组的方式在数据定义语句中用赋初值的方式

*指针变量=数组名;在程序中用赋值的方式

指针变量=数组名;将指针变量指向一维数组元素的方式在数据定义语句中用赋初值的方式

*指针变量=&数组名[下标];在程序中用赋值的方式

指针变量=&数组名[下标];当指针变量指向一维数组时,引用下标为i的一维数组元素的方法

*(指针变量+i)

*(数组名+i)

指针变量[i]

数组名[i]1、指针和一维数组7.2指针和数组数组元素的四种表示方法a[0]a[1]a[2]a[3]a[9]...aa+9a+1a+2地址元素下标法a[0]a[1]a[2]a[9]a[0]a[1]a[2]a[3]a[9]...pp+9p+1p+2地址元素指针法*p*(p+1)*(p+2)*(p+9)a[i]

p[i]

*(p+i)

*(a+i)*a*(a+1)*(a+2)*(a+9)p[0]p[1]p[2]p[9]区别:数组名a是地址常量,不可实现其自身的改变,如a++或&a非法;而数组指针p是地址变量,p++和&p合法。例inta[10],*p;

p=a;//

p=&a[0];

或int*p=&a[0];或int*p=a;a[0]a[1]a[2]a[3]a[9]...整型指针p&a[0]p1、指针和一维数组7.2指针和数组

赋值运算例pi=&i;//将变量i地址p

i=pi;//()不能把pi的值整型变量

p=array;//将数组array首地址pp=&array[i];//将数组元素地址pp1=p2;//指针变量p2值p1pj=0;//空指针,相当于pj=NULL;2、指针变量的运算7.2指针和数组算术运算例p指向float数,则p+1

p+14例p指向int型数组,且p=&a[0];

则p+1指向a[1]例inta[10];int*p=&a[2];p++;*p=1;例inta[10];int*p1=&a[2];int*p2=&a[5];

则:p2-p1=3;a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]a数组pp+1,a+1p+i,a+ip+9,a+91若p=&i;则p

n&isizeof(i)np++,p--,p+n,p-n,p+=n,p-=n的含义

若p1与p2指向同一数组,则p1-p2=两指针间元素个数

(p1-p2)/sizeof(i)p1+p2无意义关系运算:表示两个指针变量所指向地址位置的前后关系。若px和py指向同一数组,则px<py表示p1指的元素在前px>py表示p1指的元素在后px==py

表示p1与p2指向同一存储单元px==0

表示px为空指针

p==NULL若p1与p2不指向同一数组,比较无意义2、指针变量的运算7.2指针和数组【例7-2】使用指针变量。#include<stdio.h>inta[]={0,1,2,3,4};intmain(void){

inti,*p;

for(i=0;i<=4;i++)printf("%d\t",a[i]);

putchar('\n');

for(p=&a[0];p<=&a[4];p++)printf("%d\t",*p);

putchar('\n');

for(p=&a[0],i=1;i<=5;i++)printf("%d\t",p[i]);

putchar('\n');

for(p=a,i=0;p+i<=a+4;p++,i++)

printf("%d\t",*(p+i));

putchar('\n');

return0;}a[0]a[1]a[2]a[3]a[4]01234p0123401234123425637024指向字符串的指针变量在数据定义语句中用赋初值的方式*指针变量=字符串在程序中用赋值的方式指针变量=字符串;

指向字符数组的指针变量可以将一个字符串赋值给一个字符数组,也可以赋值给一个字符指针变量。7.3指针和字符串#include<stdio.h>intmain(void){

staticchars1[]="IloveChina!";

printf("%s\n%c\t%c\n",s1,s1[0],*(s1+3));

return0;}IloveChis1[0]s1[1]s1[2]s1[3]s1[4]s1[5]s1[6]s1[7]s1[8]s1[9]s1s1[10]s1[11]s1[12]s1[13]n!a\0字符串表示形式字符数组方式IloveChina!Io7.3指针和字符串字符指针方式

#include<stdio.h>intmain(void){char*s2="IloveChina!";char*s3,c;char*s4="w";s3=&c;*s3='H';s2=s2+2;printf("%s\t%c\t%s\n",s2,*s3,s4);return0;}IloveChin!a\0w\0s4cs2字符指针初始化:把字符串首地址赋给stringchar*s2;s2="IloveChina!";s2LoveChina!HwHs3字符数组与字符指针的区别对字符数组整体赋值只能在初始化时进行;而对指针变量赋值,既可在初始化时进行,又可在其他地方赋值。

str是地址常量;cp是地址变量,cp接受键入字符串时,必须先开辟存储空间。例charstr[10];scanf("%s",str);(

)而char*cp;scanf("%s",cp);(

)改为:char*cp,str[10];cp=str;scanf("%s",cp);(

)char*cp;charstr[20];

charstr[20];str="IloveChina!";(

)char*cp;cp="IloveChina!";(

)7.3指针和字符串对于一维数组数组名a表示数组的首地址,即&a[0]。数组名a是地址常量。

a+i是元素a[i]的地址,即&a[i]。

a[i]

*(a+i)

ainta[10];7.3指针和字符串对于二维数组a是数组名,包含三个元素

a[0]、a[1]和a[2]。每个元素a[i]又是一个一维数组,包含4个元素。aa+1a+2*(*(a+0)+1)*(a[0]+1)inta[3][4];a[0]a[1]a[2]200020082016200020022008201020162018a[0][0]a[0][1]a[1][0]a[1][1]a[2][0]a[2][1]a[0][2]a[0][3]a[1][2]a[1][3]a[2][2]a[2][3]行指针与列指针a[0]+1a[1]+1a[2]+1*(a+0)+1*(a+1)+1*(a+2)+1

对于二维数组inta[3][4]:a——二维数组的首地址,即第0行的首地址a+i——第i行的首地址a[i]*(a+i)——第i行第0列的元素地址a[i]+j*(a+i)+j——第i行第j列的元素地址*(a[i]+j)*(*(a+i)+j)a[i][j]a+i=&a[i]=a[i]=*(a+i)=&a[i][0],

值相等,含义不同a+i

&a[i],表示第i行首地址,指向行a[i]

*(a+i)

&a[i][0],表示第i行第0列元素地址,指向列inta[3][4];a[0]a[1]a[2]200020082016200020022008201020162018a[0][0]a[0][1]a[1][0]a[1][1]a[2][0]a[2][1]a[0][2]a[0][3]a[1][2]a[1][3]a[2][2]a[2][3]aa+1a+2表示形式含义地址a二维数组名,数组首地址a[0],*(a+0),*a第0行第0列元素地址a+1第1行首地址a[1],*(a+1)第1行第0列元素地址a[1]+2,*(a+1)+2,&a[1][2]第1行第2列元素地址*(a[1]+2),*(*(a+1)+2),a[1][2]第1行第2列元素值20002000200820082012137.3指针和字符串inta[3][4];a[0][0]a[0][1]a[1][0]a[1][1]a[2][0]a[2][1]a[0][2]a[0][3]a[1][2]a[1][3]a[2][2]a[2][3]二维数组元素表示形式:(1)a[1][2](2)*(a[1]+2)(3)*(*(a+1)+2)(4)*(&a[0][0]+1*4+2)地址表示:(1)a+1

(2)&a[1][0](3)a[1](4)

*(a+1)(5)(int*)(a+1)行指针列指针地址表示形式:(1)&a[1][2](2)a[1]+2(3)*(a+1)+2(4)&a[0][0]+1*4+2【例7-3】将字符串t复制到s中,并返回被复制的字符个数。#include<stdio.h>intstrcpy(s,t)char*s,*t;{inti;i=0;while((*s=*t)!='\0'){s++;t++;i++;}return(i);}intmain(void){intn;char*ss,*tt;gets(ss);/*scanf("%s",ss);*/n=strcpy(*ss,*tt);printf("%d,%s",n,tt);return0;}while(*s++=*t++)i++;函数的参数不仅可以是整型、实型、字符型等数据类型,还可以是指针类型,因此可以像普通变量一样在函数间传递指针变量的值。指针变量作为函数参数指针变量,可以作为函数的形参,也可以作函数的实参。指针变量作实参时,形参和实参之间的数据传递方式本质上是“值传递”,即将指针变量的值(一个地址)传递给被调用函数的形参(必须是一个指针变量)。注意:被调用函数不能改变实参指针变量的值,但可以改变实参指针变量所指向的变量的值。1、指针作为函数参数7.4指针和函数#include<stdio.h>intmain(void){intx,y;scanf("%d,%d",&x,&y);if(x<y)swap(x,y);printf("\n%d\t%d\n",x,y);}swap(intx1,inty1){inttemp;temp=x1;x1=y1;y1=temp;return0;}【例7-4】将数从大到小输出(普通参数)。…...…...20002008200A2002200420067变量x

变量y(main)10

变量temp

变量y1

变量x1(swap)7710710COPY…...…...20002008200A20022004200610变量x

变量y(main)7值传递710#include<stdio.h>intmain(void){intx,y;

int*p1,*p2;

scanf("%d,%d",&x,&y);

p1=&x;p2=&y;

if(x<y)swap(p1,p2);

printf("\n%d\t%d\n",x,y);}swap(px,py)int*px,*py;{inttemp;

temp=*px;

*px=*py;

*py=temp;

return0;}…...20002008200A200220042006200C200E2010...710整型变量x

整型变量y(main)指针p1指针p220002002(swap)指针px指针py整型temp71020002002COPY7【例7-5】将数从大到小输出(指针参数)…...20002008200A200220042006200C200E2010...59整型变量x

整型变量y(main)指针p1指针p220002002710地址传递710数组名作为函数形参时,接收实参数组的首地址;数组名作为函数实参时,将数组的首地址传递给形参数组。数组及指向数组的指针变量作为函数参数以下4种形式等价(本质均是指针数据作函数参数)形参、实参均为数组名形参、实参均为指针变量形参为指针变量、实参为数组名形参为数组名、实参为指针变量2、数组名作为函数参数7.4指针和函数

定义

函数可以返回一个int型、float型、char型的数据,也可以返回一个指针类型数据,即返回一个地址。格式

函数类型*函数名([形参表])调用指针型函数的调用和一般函数的调用方法完全相同,但需要注意的是只能使用指针变量或指针数组元素接收指针型函数的返回值,不能使用数组名接收指针型函数的返回值,因为函数名是地址常量,不是地址型变量,不能接收地址型数据。

3、指针型函数7.4指针和函数【例7-6】在一个字符数组中查找一个给定的字符,如果找到则输出该字符开始的字符串,否则输出“NOFOUNDTHISCHARACTER”。#include<stdio.h>intmain(void){chars[80],*p,ch,*match();gets(s);ch=getchar();p=match(ch,s);if(p)printf("thereisthestring:%s\n",p);elseprintf("NOFOUNDTHISCHARACTER\n");}char*match(c,s)charc,*s;{intcount=0;

while(c!=s[count]&&s[count]!='\0')count++;

if(c==s[count])return(&s[count]);

return0;}输入:wertypooypiy输出:thereisthestring:ypooypi指针数组中的元素为指针变量,用于处理二维数组或多个字符串。定义格式[存储类型]数据类型符*指针数组名[数组长度];说明(1)指针数组名是标识符,前面必须加“

温馨提示

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

评论

0/150

提交评论