《C语言程序设计d》课件-第六讲 指针_第1页
《C语言程序设计d》课件-第六讲 指针_第2页
《C语言程序设计d》课件-第六讲 指针_第3页
《C语言程序设计d》课件-第六讲 指针_第4页
《C语言程序设计d》课件-第六讲 指针_第5页
已阅读5页,还剩45页未读 继续免费阅读

下载本文档

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

文档简介

西安电子科技大学计算机学院1目前的知识不能解决的问题动态存储管理函数通过return语句返回多个数据一些复杂数据结构的实现链表树图西安电子科技大学计算机学院2地址与指针程序执行原理图...加载器外存CPU操作系统内存程序数据数据对象在生存期间都有存储位置,占据一定数量的存储单元存储位置就是内存地址存储单元的内容就是数据对象的值西安电子科技大学计算机学院3地址与指针如果把地址值也当作一种数据,存储地址值的变量就是指针变量,简称指针变量p的值(0x2000)变量x的值(5)指针变量p(地址0x1000)整数变量x(地址0x2000)内存...intx=5;int*p=&x;西安电子科技大学计算机学院4指针就是内存地址指针没有类型,但指针指向的对象具有类型[注]无论指针变量指向什么类型的变量,指针自身只占据4个字节(32位系统)的内存单元地址与指针注:通常会把指针指向的对象的类型称为指针的类型西安电子科技大学计算机学院5地址与指针指针的相关操作指针赋值:将程序对象的地址存入指针变量间接访问:通过指针变量存储的地址访问该地址对应的对象西安电子科技大学计算机学院6主要内容10.1指针变量的定义和使用10.2指针的相关问题10.3指针作为函数参数10.4指针与数组10.5指针数组西安电子科技大学计算机学院710.1指针变量的定义和使用西安电子科技大学计算机学院8定义指针变量语法:目标数据对象类型:指针指向的数据对象的类型,用于确定指针指向的对象占据多少存储单元指针变量名称:任何合法标识符表示定义的是指针变量int*p,*q,n;//p和q是指针变量,n是普通整型变量char*s,ch;//s是指针变量,ch是普通字符变量目标数据对象类型*

指针变量名称;西安电子科技大学计算机学院9指针变量赋值将程序对象的地址存入指针变量,通过取地址运算符(&)可取得程序对象的地址int*p,*q,n=10;p=&n;q=p;???p10n(&n为0x12F0)???q0x12F0p10n???qp0x12F010n0x12F0q西安电子科技大学计算机学院10指针变量赋值int*p,a[10];p=&a[1];???pa[0]a[1]a[9]…&优先级和其他一元运算符相同,从右向左结合pa[0]a[1]a[9]…间接访问(pointer1.c)访问指针指向的对象获取指针所指向对象的值访问方法:*指针变量优先级和其他一元运算符相同,从右向左结合间接访问(pointer1.c)int*p,*q,n=10,m,a[10];p=&n;q=p;m=*p+*q*n;++*p;(*p)++;*p+=*q+n;q=&a[0];*q=*p/12;p10nqm=n+n*n=110;//m=110++n;

//n=11n++;

//n=12n+=n+n;

//n=36a[0]=n/12;

//a[0]=3a[0]a[1]a[9]…m西安电子科技大学计算机学院13间接访问间接访问的过程(pointer2.c)step1.通过指针的值(地址)找到对应的内存单元step2.通过指针的类型确定数据占据多少内存单元step3.将找到的内存单元内存储的数据按照指针的类型转换为相应数据int*p,n=0x00000130;char*q;p=&n;q=p;printf("%d%c",*p,*q);//???30010000npq西安电子科技大学计算机学院1410.2指针的相关问题西安电子科技大学计算机学院15野指针指针在未初始化时指向哪里不确定,不能用*间接引用指针指向的对象,这样的指针称为野指针int*p;*p=2;printf("%d",*p);编译时警告p未初始化,执行时出错西安电子科技大学计算机学院16另一种类型的野指针intn=10,*p=&n;假设n存储在地址为0x1000的内存单元p0x100010np0x100017n*p=17;p=17;p1717n地址为17的存储单元???西安电子科技大学计算机学院17空指针(NULL)定义指针变量时如果暂时不知道要指向哪里,应该先给指针变量赋予空指针NULL(数值0),表示哪里也不指向当指针变量被赋予空指针,不能用*间接引用指针指向的对象int*q=NULL;*q=2;printf(“%d”,*q);编译器不会警告,执行时出错西安电子科技大学计算机学院18通用指针与指针类型转换(pointer3.c)通用指针指向的对象类型不确定,此时用void作为指针的类型可以把任何类型的指针赋值给通用类型指针通用类型指针不能够用*运算符间接引用被指对象。void*gp;intn=10,*p=&n;floatf=2.5;void*gp1=p,*gp2=&f;intn=10;floatf=2.5;void*gp1=&n,*gp2=&f;printf("%d%f",*gp1,*gp2);//编译错误西安电子科技大学计算机学院19通用指针与指针类型转换为了访问通用指针指向的对象需要进行指针类型转换转换方法:(类型*)通用指针intn=10,*p1;floatf=2.5,*p2;void*gp1=&n,*gp2=&f;p1=(int*)gp1;p2=(float*)gp2;printf("%d%f",*p1,*p2);//正确西安电子科技大学计算机学院20通用指针与指针类型转换为了访问通用指针指向的对象需要进行指针类型转换转换方法:(类型*)通用指针intn=10,*p1;floatf=2.5,*p2;void*gp1=&n,*gp2=&f;p1=(int*)gp2;p2=(float*)gp1;printf("%d%f",*p1,*p2);//运行结果不正确一个通用指针可以转换为任何类型的指针,但是否具有正确的意义,取决于该指针实际指向的数据类型西安电子科技大学计算机学院2110.3指针作为函数参数西安电子科技大学计算机学院22函数调用时实参按值传递voidswap(intx,inty){intt;

}intmain(){inta=5,b=3;

printf("a=%d;b=%d\n",a,b);swap(a,b);printf("a=%d;b=%d\n",a,b);return0;}swap函数数据区53xymain函数数据区53abswap函数数据区main函数数据区53ab35xy

t=x;x=y;y=t;执行前执行后西安电子科技大学计算机学院23如果参数传递的值是变量地址voidswap(int*x,int*y){intt;

}intmain(){inta=5,b=3;

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

swap(&a,&b);printf("a=%d;b=%d\n",a,b);return0;}

t=*x;*x=*y;*y=t;执行前执行后swap函数数据区xymain函数数据区53abswap函数数据区main函数数据区35abxy西安电子科技大学计算机学院24指针作为函数参数示例用一个函数实现两个整数除法,要求返回整除的商和余数用return语句不能返回两个值用参数返回值,参数必须是指针形式voiddivision(intx,inty,

int*qp,int*rp){

*qp=x/y;*rp=x%y;}intmain(){intq,r;

division(40,3,&q,&r);

printf(“40/3yield");printf("quotient=%d",q);printf("remainder=%d\n",r);return0;}西安电子科技大学计算机学院25指针作为函数参数的常见错误voidswap(int*x,int*y){intt;t=*x;*x=*y;*y=t;}intmain(){intp,n;scanf(“%d”,n);scanf(“%d”,p);swap(p,&n);return0;}n和p的值会被当作地址传入函数,但由于n和p的值不确定,因此函数调用可能出错,即使不出错,输入的值也不会保存在n和p中西安电子科技大学计算机学院2610.4指针与数组西安电子科技大学计算机学院27数组在内存中的实现数组名是一个内存地址,称为数组首地址数组元素从首地址开始连续存放访问数组元素的方法:数组名[下标]inta[4];????0x10000x10040x10080x100C地址数组元素通过数组名和下标引用数组元素的本质是:&a[i]=a

+i×sizeof(a[0])既然数组名是内存地址,就可以用一个指针变量来表示28指向数组元素的指针数组元素是一个普通变量,具有唯一地址与数组同类型的指针变量可以指向数组的任一元素int*p1,*p2,*p3,*p4;inta[10]={0,1,2,3,4,5,6,7,8,9};p1=&a[0];p2=p1;p3=&a[5];p4=&a[10];0a[0]159……?a[1]a[5]a[9]a[10]p1p2p3p4等价于p1=a;29指针运算1.指针和数值n(变量、常量)的加减法前提:指针变量指向数组中的某个元素意义:表示将指针向前或向后移动n个元素inta[10]={0,1,2,3,4,5,6,7,8,9};int*p1=a,*p2;p1+=2;*p1=5;*(p1+6)=0;p2=p1+3;p2--;p1指向a[2]给a[2]赋值给a[8]赋值p2指向a[5]p2指向a[4]p1指向a[0]指针不指向数组时没有任何意义30指针运算2.两个指针变量相减前提:两个指针变量指向同一个数组意义:得到两个指针之间的元素个数inta[10]={0,1,2,3,4,5,6,7,8,9};int*p1=a,*p2;intn;p2=&a[5];n=p2-p1;p1++;n=p1-p2;p2指向a[5]n=5两个指针变量相加没有任何意义n=-4p1指向a[1]p1指向a[0]31指针运算3.两个指针变量比较大小前提:两个指针变量指向同一个数组意义:得到两个指针之间的位置关系inta[10];int*p1=a,*p2=&a[10];inti=0;while(p1<p2

){

*p1=i;p1++;i++;}两个指针变量不在同一数组,比较没有任何意义p1指向a[0],p2指向a[10]通过指针p1依次给a的每个元素赋值i,循环结束条件是p1指向最后一个元素之后32指针运算4.对指针变量使用下标前提:指针变量指向数组意义:得到对应数组元素inta[10];int*p1=a;inti=0;for(i=0;i<10;i++){

p1[i]=i;}指针变量不指向数组时没有任何意义p1指向a[0]通过指针p1依次给a的每个元素赋值i,循环结束条件是i不超出数组元素个数p1[i]=p1

+i×sizeof(a[0])西安电子科技大学计算机学院33访问数组元素的几种模式inta[10];inti;for(i=0;i<10;i++){

a[i]=i;}inta[10];int*p1,*p2;for(p1=a,p2=a+10;p1<p2;p1++){

*p1=i;}inta[10];int*p1,*p2;for(p1=a,p2=a;p1-p2<10;p1++){

*p1=i;}inta[10];int*p1;for(p1=a;p1<a+10;p1++){

*p1=i;}西安电子科技大学计算机学院34取值运算符(*)和递增运算符(++)混合使用*和++优先级相同*和++都是右结合++有前缀和后缀两种形式前缀方式先自增再取值参与运算后缀方式先取值参与运算再自增取值运算符(*)和递增运算符(++)混合使用西安电子科技大学计算机学院35inta[10]={0,1,2,3,4,5,6,7,8,9},*p=a,n;n=*p++;n=*++p;++*p;n=*p;p++;++p;n=*p;a[2]++;n=a[0]p指向a[1]p指向a[2]n=a[2]36数组参数与指针数组作为函数形式参数时,实际是以指针的形式实现doubleaverage(

doublea[],intn){doublesum=0.0;inti;for(i=0;i<n;i++)sum+=a[i];returnsum/n;}doubleaverage(

double*a,intn){doublesum=0.0;inti;for(i=0;i<n;i++)sum+=a[i];returnsum/n;}intmain(){intb[20]={…}

average(b,20);return0;}传递的是数组首地址只对b[5]-b[10]求平均值如何处理??西安电子科技大学计算机学院37数组参数与指针doubleaverage(

doublea[],intn){doublesum=0.0;inti;for(i=0;i<n;i++)sum+=a[i];returnsum/n;}doubleaverage(

double*a,intn){doublesum=0.0;inti;for(i=0;i<n;i++)sum+=a[i];returnsum/n;}intmain(){intb[20]={…}

average(b+5,5);return0;}传递的是元素b[5]的地址西安电子科技大学计算机学院38示例1:用指针实现求字符串长度的函数intstrlen(char*s

){intn=0;while(*s!='\0'){++s;++n;}returnn;}intstrlen(char*s){char*p=s;while(*p!='\0')++p;returnp-s;}intmain(){chars1[]="hello,world!",*ps=s1;intlen;len=strlen(s1);len=strlen(ps);len=strlen("clanguage");return0;}调用以字符指针为形式参数的函数,实参可以是字符串常量字符数组(其中应存着字符串)指向字符串的指针西安电子科技大学计算机学院39示例2:用指针实现复制字符串的函数voidstrcpy(char*s,constchar*t){while((*s=*t)!='\0'

){s++;t++;}}voidstrcpy(char*s,constchar*t){while(*s=*t){s++;t++;}}voidstrcpy(char*s,constchar*t){while(*s++=*t++);}注意:运算符的优先级与结合顺序增量运算的作用与计算出的值赋值表达式的值西安电子科技大学计算机学院4010.5指针数组假设一个班有100人,每个人的姓名不超过20个字符,如何表示所有人的姓名?方法1:二维数组charnames[100][20];每个人的名字长度限定为不超过20个字符方法2:一维指针数组char*names[100]每个人的名字长度不固定…………names[0]names[1]names[99]20个连续字符names[0]names[1]names[99]…LimingLiuxiaodongWangpeng西安电子科技大学计算机学院42二维数组与一维指针数组的区别二维数组的所有元素在内存中连续存放,要求一块较大的连续内存(行数×列数)一维指针数组各个元素(指针)连续存放,但元素(指针)指向的内存区地址并不连续,只需要一块能连续存放元素(指针)的内存(行数)西安电子科技大学计算机学院43二维数组与一维指针数组的区别//以下为程序片段charnames1[100][20]={"Liming","Liuxiaodong",…};char*names2[100]={"Liming","Zhangxitong",…};inti=0;for(i=0;i<5;i++)printf("addressofnames1[

温馨提示

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

评论

0/150

提交评论