程序设计基础章 指针_第1页
程序设计基础章 指针_第2页
程序设计基础章 指针_第3页
程序设计基础章 指针_第4页
程序设计基础章 指针_第5页
已阅读5页,还剩86页未读 继续免费阅读

下载本文档

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

文档简介

会计学1程序设计基础章指针5.1.1指针的概念

按变量名访问存取变量的方式称为“直接访问”方式intv=2,k;k=v*v;printf(“%d\t”,k);第1页/共91页通过另一个变量p访问变量v的方式;称为“间接访问”的方式。须将变量v的地址存放在指针变量中指针变量第2页/共91页指针变量指针变量是一种特殊的变量;指针变量的值是另一个变量的地址;

通过指针变量的值(地址)可以访问到该地址对应的变量(目标变量);通常称指针变量指向目标变量;

第3页/共91页5.1.2

指针变量的定义类型说明符*指针变量名;如int*pint;pint是指向整型变量的指针变量

char*pchar;pchar是指向字符型变量的指针变量目标变量的类型指针类型说明符第4页/共91页思考pint和pchar占用内存单元的字节数是否相同?

相同的在32位微机系统中,所有的指针变量在内存中占4个字节,而无论该指针变量指向什么类型的变量第5页/共91页注意区别

inta,bb,*c;char*p,*q,ch;float*pf1,num1,*pf2;第6页/共91页注意在使用指针前,必须给(已定义过的)指针赋于目标变量的地址值。第7页/共91页5.1.3指针的赋值

C语言提供一元运算符&可以获取变量的地址intanint;int*pint;

pint=&anint;或初始化方式intanint;int*pint=&anint;取地址运算符第8页/共91页

pint指向anintpintanint&anint&pint&anint………////////第9页/共91页可以将指针初始化为空指针。

int*pint=0;或

int*pint=NULL;空指针代表该指针没有指向任何变量if(pint!=NULL){

…}#defineNULL0第10页/共91页注意1int*

组成一个整体,代表指向整形变量的指针类型

float*pf;某种类型的指针变量只能指向该类型的变量

floatradius;int*pint;pint=&radius;目标变量类型指针变量名错误第11页/共91页注意2指针变量只能存放已定义变量的地址不能为指针变量赋予任意的一个地址

不能将一个整数(无论什么进制)直接赋给一个指针变量(除0外)。

如pchar=0x100;pchar=num;

错误第12页/共91页思考如何间接访问指针所指向的目标变量?第13页/共91页*运算符称为指针运算符或间接访问运算符或取内容运算符若p是指针变量,则*p代表p所指向的目标变量间接访问

第14页/共91页例如intvalue;charch;int*pv=&value;char*pc=&ch;

pv的目标变量value可表示为*pv,pc的目标变量ch可表示为*pc,即*pv和value等效,*pc和ch等效

注意:通过指针访问和变量名访问目标变量结果一样,但内部过程不一样&pv和&pc表示指针针变量本身地址直接访问间接访问第15页/共91页注意区别*(语用规则)

i*jint*pi;

*pi=200;乘法运算符指针说明符指针运算符第16页/共91页指针变量不能与普通变量相互赋值

int*pn,num;char*pc,ch;

pn=num;或

num=pn;

pc=ch;或ch=pc;错误第17页/共91页相同数据类型的指针变量之间可以相互赋值。如:inta,*pa,*pb;pa=&a;//pa指向a

pb=pa; //pb指向a第18页/共91页分析

int*ptr,x,y; ptr=&x;x=1; y=*ptr;*ptr=2;x,y的值是?第19页/共91页注意:指针变量的地址

指针也是变量,指针变量的地址是指它本身的内存地址注意区分:指针变量的地址VS目标变量的地址第20页/共91页例:直接访问间接访问

inta,b;

int*p1,*p2;

a=100;b=10;

p1=&a;p2=&b;printf(″%d,%d\n″,a,b);printf(″%d,%d\n″,*p1,*p2);第21页/共91页变量、变量地址、指针与指针地址

intu=5,v,*pu,*pv;pu=&u;v=*pu;pv=&v;printf("u=%d&u=%xpu=%x*pu=%d&pu=%x",u,&u,pu,*pu,&pu);printf("\nv=%d&v=%xpv=%x*pv=%d&pv=%x",v,&v,pv,*pv,&pv);u=5&u=ffccpu=ffcc*pu=5&pu=ffd0v=5&v=ffcepv=ffce*pv=5&pv=ffd2第22页/共91页例

int*p1,*p2,*p,a,b;

scanf(“%d,%d”,&a,&b);

p1=&a;p2=&b;

if(a<b)

{p=p1;p1=p2;p2=p;}

printf(″a=%d,b=%d\n″,a,b);

printf(″max=%d,min=%d\n″,*p1,*p2);第23页/共91页运行情况如下:5,9↙a=5,b=9max=9,min=5第24页/共91页图示第25页/共91页与上例比较

int*p1,*p2,t,a,b;

scanf(”%d,%d”,&a,&a);

p1=&a;p2=&b;printf(″a=%d,b=%d\n\n″,a,b)

if(a<b)

{t=*p1;*p1=*p2;*p2=t;}

printf(”a=%d,b=%d\n\”,a,b);第26页/共91页5.2指针运算指针是一种值为地址值的特殊变量相关的运算有四类:对指针赋值;取地址运算“&”和取内容运算“*”;加、减;比较;第27页/共91页“&”和“*”互为逆运算如:

intx,*ptr=&x;

则&(*ptr)表示指针ptr的值*(&x)表示变量x第28页/共91页例指针运算符“&”和“*”

intu1,u2,v=3;int*pv; u1=2*(v+5); pv=&v; u2=2*(*pv+5); printf("u1=%du2=%d",u1,u2);程序运行结果:

u1=16u2=16第29页/共91页指针与整数的加减运算指针变量p已指向(数组中的)一个元素

p+1指向(同一数组中的)下一个元素

p-1指向(同一数组中的)上一个元素。第30页/共91页指针与整数的加减运算指针变量p加上或减去一个整数n后结果仍然是一个相同类型的指针,表示:由指针当前所指向的位置向前或向后移动n个数据元素后的位置(注意:不是移动n个字节)。程序中“p+n”或“p-n”代表的实际地址(以字节编址):

p中地址值±n*sizeof(数据类型)

第31页/共91页指针自增、自减单目运算也分前置和后置运算,也都是以指针所指向的数据元素为移动单位当它们与其他运算符组成一个表达式时,应注意其优先顺序和结合性。第32页/共91页如,p为指针变量:

v=*p++;“*”与“++”的优先级高于“=”,而“*”与“++”两个单目运算符的优先级相同,其结合性为从右到左。相当于

v=*(p++);辨识:v=(*p)++;v=*++p;v=(*p)++;第33页/共91页在一定条件下,两个指向同种数据类型的指针可以相减。如,指向同一数组的两个指针相减,其差表示这两个指针所指向的数组元素之间所相差的元素个数。指针相减的运算并不是两个指针中的值(地址)的单纯相减第34页/共91页指针相减的运算

int*px,*py; staticinta[6]={10,20,30,40,50,60}; px=&a[0]; py=&a[5]; printf("px=%xpy=%x\n",px,py); printf("pypx=%x",pypx);程序运行结果:

px=194py=19e pypx=5实际地址相差10个字节间隔5个元素第35页/共91页4、指针的关系运算同种数据类型的指针进行关系运算表示它们所存放的地址之间的关系

<,>,==,!=第36页/共91页指针间允许4种关系运算

<

>两指针所代表的地址的大、小关系

==!=判断两指针是否代表同一地址,即是否指向同一数据。第37页/共91页

指针不能与一般数值进行关系运算,但指针可以和零(NULL)之间进行等于或不等于的关系运算,如:

p==0;p!=0; 或p==NULL;p!=NULL;用于判断指针p是否为空指针。第38页/共91页假设pa和pb为两个有效且为指向基本类型的指针变量,pa!=NULL,pb!=NULL,下列命题:若pa==pb,则*pa==*pb;若*pa==*pb,则pa==pb;正确错误第39页/共91页综上所述,由于指针的运算实质上是地址运算,因此,指针运算是有限的,除了四类运算外,其他运算都是非法的。赋值*&加、减关系第40页/共91页5.3指针与数组对数组元素的访问是采用的下标法在C语言中,指针和数组之间存在密切的联系。在引入指针变量后,可以利用一个指向数组的指针来完成对数组元素的访问,这种方法称为指针法。第41页/共91页5.3.1指针与一维数组一个数组名实际上是一个指针常量(数组首地址的符号地址)数组名代表数组的第一个元素的地址。

inta[100];则a代表&a[0]当指针变量指向一维数组的第1个元素,指针变量名就可以当成一维数组名使用;也可以通过指针移动方式访问数组元素。int*p=a;或int*p=&a[0];第42页/共91页通过数组首地址访问数组元素的方式数组元素的下标变量访问:a[i]指针加偏移量类型的间接地址访问:*(p+i)数组名作地址值的直接地址访问:

*(a+i)指针作为数组名的下标变量方式:p[i]

第43页/共91页即访问一个数组元素,可以用:下标法:a[i]

指针法:*(p+i)地址法:*(a+i)

指针下标法:p[i]

第44页/共91页第45页/共91页下标法和指针法的关系a为数组名:a[i]等价于*(a+i)p为指向数组元素的指针:p[i]等价于*(p+i)

第46页/共91页例如inta[20],*p;

p=a;

或p=&a[0];则下标为i的元素可表示为:

a[i],*(a+i),p[i],*(p+i),下标为i的元素的地址可表示为:

&a[i],a+i,&p[i],p+i第47页/共91页思考inta[20],*p;p=&a[2];

则p[i]代表?第48页/共91页注意数组名是指针常量,不是指针变量,不能给数组名赋值。intdata[10],*p;

数组名data和指针p均与地址相关,但:data是一个指针常量,其值是由编译程序给定的数组起始地址,是不能改变的指针p是一个指针变量,在程序运行中可以改变,它可以指向任一个数组元素,也可以指向其它任意整型变量。第49页/共91页以下语句是合法的:

p=data; p++;p=p+3;以下语句是非法的:

data=p;data++; data=data+3;第50页/共91页例

指针与数组的关系

intdata[10],i,*p; for(i=0;i<10;i++) data[i]=i+1; p=data; for(i=0;i<10;i++){ printf("*(p+%d)=%d\t",i,*(p+i));

printf("data(%d)=%d\n",i,data[i]);}第51页/共91页程序运行结果

*(p+0)=1data(0)=1*(p+1)=2data(1)=2*(p+2)=3data(2)=3*(p+3)=4data(3)=4*(p+4)=5data(4)=5*(p+5)=6data(5)=6*(p+6)=7data(6)=7*(p+7)=8data(7)=8*(p+8)=9data(8)=9*(p+9)=10data(9)=10第52页/共91页表达式*(p+i)和data[i]是等价的是用指针法和下标法来表示访问数组元素的两种不同形式。第53页/共91页指针方式访问数组元素,计算和

intiarray[10]={0,2,4,6,8,10,12,14,16,18};intsum=0,i;int*iptr=iarray;/*指针指向数组*/for(i=0;i<10;i++){sum+=*iptr;

iptr++;}printf(”sumis%d\n”,sum);

运行结果为:sumis90第54页/共91页数组的求和元素运算,有五种方法

intsum1,sum2,sum3,sum4,sum5;intiarray[]={1,4,2,7,13,32,21,48,16,30};int*iptr;intsize,n;

size=sizeof(iarray)/sizeof(*iarray);for(n=0;n<size;n++)/*方法1*/sum1+=iarray[n];下标变量法第55页/共91页

iptr=iarray;/*方法2*/for(n=0;n<size;n++)sum2+=*iptr++;

iptr=iarray;/*方法3*/for(n=0;n<size;n++)sum3+=*(iptr+n);指针法指针法第56页/共91页

iptr=iarray;/*方法4*/for(n=0;n<size;n++)sum4+=iptr[n];for(n=0;n<size;n++)/*方法5*/sum5+=*(iarray+n);地址引用法指针下标法第57页/共91页获取数组起始地址的两种方法数组名

p=arr;数组的首元素地址。

p=&arr[0];第58页/共91页指针访问二维数组指针可访问一维数组,也可访问多维数组inta[5][4],*pa;pa=a[0]等效pa=a或 pa=&a[0][0];pa=a[4]等效pa=&a[4][0];第59页/共91页5.3.2指针与结构数组structinfo{shortnum;charname[5];}; structinfomyinfo,*p_info;若p_info=&myinfo;则可以用指针访问结构成员第60页/共91页第61页/共91页三种存取结构成员的方式通过结构变量名和成员运算符(.)

myinfo.num通过指向结构的指针、指针运算符(*)和成员运算符(.)(*p_info).num通过指向结构的指针和成员运算符()

p_infonum第62页/共91页结构数组和指向结构的指针把结构数组和指向结构的指针结合起来使用通过指针来存取结构数组中元素及各元素的成员。第63页/共91页例:输入同学的信息并按身高排序

p_stu=stu+1;

//p_stu指向stu[1]

for(i=1;p_stu<=stu+n;p_stu++,i++){…p_stu>height

…}

第64页/共91页5.4字符串指针可以利用字符数组或字符指针代表一个字符串字符数组

charstr[]=“hello”;字符串常量

“chengdu”第65页/共91页字符指针字符串常量和字符数组名都具有地址特性,因而可以把它们赋给一个字符指针这时,输出字符指针就是输出指针指向的字符串,如:printf(“%s”,pstr);而,输出字符指针指向的目标对象,就是输出指针指向的单个字符。如printf(“%c”,*pstr);

printf(“%c”,*(pstr+1));第66页/共91页字符指针变量和字符数组对字符数组只能对各个元素赋值

charstr[]=“hello”;//okscanf(“%s”,str);//ok注意范围

str=“love”;//error对字符指针变量,可以用字符串直接赋值:

char*p=“hello”;//ok

p=“IloveChina!”;//ok第67页/共91页字符指针变量和字符数组指针变量的值是可以改变的若字符指针变量p指向字符串,就可以用指针变量带下标或偏移的形式访问字符串中的字符,如p[i]、*(p+i)第68页/共91页字符数组中各元素的值是可以改变的(可以对它们再赋值和修改)若字符指针变量指向字符串常量,尽管可以对指针变量本身进行改变,但不能赋值和修改字符指针指向的字符串常量中的内容。

第69页/共91页chara[]=“House”;char*b=“House”;a[2]=’r’;//合法

b[2]=’r’;//非法,字符串常量不能改变

b=a;

b[2]=’r’;?第70页/共91页例用字符指针输出字符串

charstr[]="turboc"; char*ps=str; while(*ps){

putchar(*ps); ps++;

}

程序运行结果:

turbocputchar(*ps++);第71页/共91页例:

charbuffer[10]=“ABC”;char*pc;pc=“hello”;/*指针指向字符串常量*/printf(”%s\n”,pc);/*输出指针指向字符串hello*/

pc++;printf(”%s\n”,pc);/*输出指针指向字符串ello*/printf(”%c\n”,*pc);/*输出指针指向字符e*/

pc=buffer;printf(”%s\n”,pc);/*输出指针指向字符串ABC*/第72页/共91页字符串(常量)的输出char*point;point=“Thisisastring.”;printf(”%s”,point);输出:Thisisastring.第73页/共91页字符串复制—字符数组方式chara[]=“Iamaboy.”,b[20];

inti;

for(i=0;*(a+i)!=‘\0’;i++)*(b+i)=*(a+i);//等价于b[i]=a[i];

*(b+i)=‘\0’;//等价于b[i]=‘\0’;

printf(“stringais:%s\n”,a);

printf(“stringbis:%s\n”,b);第74页/共91页字符串复制—字符指针方式

chara[]=“Iamaboy.”,b[20],*p1,*p2;

inti;

p1=a;p2=b;

for(;*p1!=‘\0’;p1++,p2++)*p2=*p1;

*p2=‘\0’;//Why?printf(“%s”,b);p1和p2同步移动第75页/共91页使用指针,合并字符串s1和s2chars1[50],s2[20];char*p=s1,*q=s2;scanf(”s1=%s\ns2=%s”,s1,s2);while(*p!=‘\0’)/*找到s1中字符串的结尾*/p++;while(*q!=‘\0’)/*将s2合并到s1的后面*/*p++=*q++;

*p=‘\0’;printf(“%s\n”,s1);第76页/共91页

*p++=*q++;等价于*p=*q;q++;p++;第77页/共91页5.5指针数组一个数组中若每个元素都是一个指针,则称为指针数组。

char*proname[]={“FORTRAN”,“C”,“C++”};该数组的每个元素是指向字符串的字符指针第78页/共91页该字符数组的内存表示如下:22512259225B4400440244042251‘F’‘O’‘R’‘T’‘R’‘A’‘N’‘\0’‘C’‘\0’‘C’‘+’‘+’‘\0’……22522253225422552256225722582259225A225B225C225D225Echar*proname[]第79页/共91页指针数组与二维数组字符指针数组与二维字符数组的不同之处字符指针数组元素指向的字符串可以是不同的长度(节约空间)。

charname[3][8]={“FORTRAN”,“C”,“C++”};第80页/共91页按字典顺序对多个字符串排序

char*str[]={"turboc","turbopascal","basic","dbase","li

温馨提示

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

评论

0/150

提交评论