C语言课件指针PPT

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

第7章指针许建龙xujianlong126@126.com2020/3/52内容提要指针的概念;–难点:对指针数据类型的理解数组的下标法引用和指针法引用;–难点:二维数组的地址和指针概念利用字符指针存取字符串;–难点:字符数组和字符指针的区别与联系指针数组应用;–难点:指向数组的指针与指针数组的区别–带参数的main函数;动态内存分配函数及其应用;–难点:一维、二维动态数组的实现–动态数据结构(在第8章介绍)2020/3/53为什么引入指针的概念指针为函数提供修改变量值的手段指针为C的动态内存分配系统提供支持指针为动态数据结构(如例链表、队列、二叉树等)提供支持指针可以改善某些子程序的效率2020/3/54计算机内的存储部件,所有指令和数据都保存在内存内速度快,但是掉电即失可以随机访问–只要指明要访问的内存单元的地址,就可以立即访问到该单元–地址是一个无符号整数,其字长一般与主机相同–内存中的每个字节都有唯一的一个地址–地址按字节编号,按类型分配空间内存(RandomAccessMemory)地址(Address)2020/3/55寻址方式如何读写内存中的数据?–通过变量的地址访问变量所在的存储单元两种寻址方式直接(寻址)访问–直接按变量地址(或变量名)来存取变量内容的访问方式间接(寻址)访问–通过指针变量来间接存取它所指向的变量的访问方式0内存用户数据区┇20003变量i20026变量j20049变量k┇30102000变量i_pointer2020/3/56关于指针的原则学习原则–一定要学会–其实通常的应用很简单与使用变量几乎无异使用原则–永远要清楚每个指针指向的类型–永远要清楚指针指向的位置是什么2020/3/57指针(Pointer)的概念指针也是一种数据类型指针变量–具有指针类型的变量,专门存放地址数据的变量变量的指针–变量的地址2020/3/58如何定义指针变量?定义指针变量int*p;–定义了一个指针变量p,简称指针pp是变量,int*是类型–p里保存一个地址。此时这个地址是哪呢(p指向哪呢)?指针变量初始化–p=&a;–*p就像普通的变量一样使用,其值是p指向的内存的内容(在上例和a等价,但寻址方式不同)–p可以动态(任意)地指向不同内存,从而使*p代表不同的变量2020/3/59inti,*p;p=&i;int*p;float*q;p=q;inti;float*p;p=&i;int*p;p=100;指针变量只存放地址!一个指针变量不能指向与其类型不同的变量!我是真的,你猜对了吗?应在类型相同的指针变量之间赋值2020/3/510&与*操作符&用来取变量的地址–inti,*p;p=&i;–int*p,a[10];p=a;–int*p,a[10];p=&a[0];–int*p,a[10];p=&a[5];*用来存取指针所指地址单元的内容–inti,*p;p=&i;*p=0;–int*p,a[10];p=a;*p=0;–int*p,a[10];p=&a[0];*p=0;–int*p,a[10];p=&a[5];*p=0;2020/3/511指针的指向指针指向非其定义时声明的数据类型,将引起warningvoid*类型的指针可以指向任意类型的变量指针在初始化时一般int*p=NULL;–NULL表示空指针,即无效指针–但它只是逻辑上无效,并不是真正地无效如果指针指向一个非你控制的内存空间,并对该空间进行访问,将可能造成危险如int*p;*p=10;(危险的用法)2020/3/512指针变量与其它类型变量的对比共性–在内存中占据一定大小的存储单元–先定义,后使用特殊性–它的内容只能是地址,而不能是数据–必须初始化后才能使用,否则指向不确定的存储单元–只能指向同一基类型的变量–可参与的运算:加、减一个整数,自增、自减、关系、赋值2020/3/513指针运算(1/4)算术运算int*p,a[10];p=a;p++;/*p的值增加多少?*/指针的加减运算是以其指向的类型的字长为单位的6000600160026003600460056006p-1pp+12020/3/514指针运算(2/4)int*p,*q,a[10];p=a;q=&a[5];–q-p–q=p+3;指针运算不能乱算–一般只进行指针和整数的加减运算,同类型指针之间的减法运算–其它运算,比如乘法、除法、浮点运算、指针之间的加法等,并无意义,所以也不支持2020/3/515指针运算(3/4)关系运算只有指向同一种数据类型的两个指针才能进行关系运算。值为1或0–pqpqp==q指针不与非指针量进行比较,但可与NULL(即0值)进行等或不等的关系运算–判断p是否为空指针–P==NULL–p!=NULL2020/3/516指针运算(4/4)赋值运算指针在使用前一定要赋值为指针变量赋的值必须是一个地址main(){int*p;scanf(%d,p);…}main(){inta,*p=&a;scanf(%d,p);…}错!2020/3/517指针与函数指针既然是数据类型,自然可以做函数的参数和返回值的类型指针做参数的经典例子:–两数的互换2020/3/518voidSwap(int*x,int*y){inttemp;temp=*x;*x=*y;*y=temp;}main(){inta,b;a=15;b=8;Swap(&a,&b);printf(a=%d,b=%d,a,b);}voidSwap(intx,inty){inttemp;temp=x;x=y;y=temp;}main(){inta,b;a=15;b=8;Swap(a,b);printf(a=%d,b=%d,a,b);}程序1程序2例7.2:编写函数实现两数的互换主调函数被调函数实参形参结果有何不同?2020/3/519主调函数被调函数main(){inta,b;a=15;b=8;Swap(a,b);printf(a=%d,b=%d,a,b);}voidSwap(intx,inty){inttemp;temp=x;x=y;y=temp;}1515ab实参形参88xyab程序1xy2020/3/520简单变量作函数参数图7-3Swap函数调用前后参数变化的示意图1581581581515881581515a)调用Swap函数(b)执行Swap函数c)从Swap函数返回tempxybmain函数Swap函数①②③aaatemptempxxyybb2020/3/521主调函数被调函数main(){inta,b;a=15;b=8;Swap(&a,&b);printf(a=%d,b=%d,a,b);}voidSwap(int*x,int*y){inttemp;temp=*x;*x=*y;*y=temp;}&a&a实参形参&b&b*x*yab程序2xy15ab82020/3/522指针变量作函数参数图7-5用指针变量作函数参数实现两数互换函数的示意图158815&a&b&a&b15(a)调用Swap函数(b)执行Swap函数aabb*x*x*y*yyyxx&a&bmain函数Swap函数temptemp②①③2020/3/523swap函数的几种错误形式(1/3)参数单向传递voidSwap(intx,inty){inttemp;temp=x;/*x,y为内部变量*/x=y;y=temp;}2020/3/524swap函数的几种错误形式(2/3)参数单向传递voidSwap(int*p1,int*p2){int*p;p=p1;/*p1,p2为内部变量*/p1=p2;p2=p;}2020/3/525swap函数的几种错误形式(3/3)指针p没有确切地址voidSwap(int*p1,int*p2){int*p;/*指针p未初始化*/*p=*p1;*p1=*p2;*p2=*p;}2020/3/526例7.3:打印出最高分及其学号voidFindMax(floatscore[],longnum[],intn,float*pMaxScore,long*pMaxNum){inti;*pMaxScore=score[0];*pMaxNum=num[0];for(i=1;in;i++){if(score[i]*pMaxScore){*pMaxScore=score[i];*pMaxNum=num[i];}}}2020/3/527例7.4:日期转换问题任意给定某年某月某日,打印出它是这一年的第几天已知某一年的第几天,计算它是该年的第几月第几日staticintdayTab[2][13]={{0,31,28,31,30,31,30,31,31,30,31,30,31},{0,31,29,31,30,31,30,31,31,30,31,30,31}};2020/3/528计算某年某月某日是这一年的第几天/*函数功能:对给定的某年某月某日,计算出它是这一年的第几天函数参数:整型变量year、month、day,分别代表年、月、日函数返回值:这一年的第几天*/intDayofYear(intyear,intmonth,intday){inti,leap;/*若year为闰年,则leap值为1,就用第2行元素dayTab[1][i]计算,否则leap值为0,用第1行dayTab[0][i]计算*/leap=((year%4==0)&&(year%100!=0))||(year%400==0);for(i=1;imonth;i++){day=day+dayTab[leap][i];}returnday;/*返回计算出的day的值*/}2020/3/529计算某年的第几天是该年的第几月第几日/*函数功能:对给定的某一年的第几天,计算它是这一年的第几月第几日函数入口参数:整型变量year,存储年整型变量yearDay,存储这一年的第几天函数出口参数:整型指针pMonth,指向存储这一年第几月的整型变量整型指针pDay,指向存储第几日的整型变量函数返回值:无*/voidMonthDay(intyear,intyearDay,int*pMonth,int*pDay){inti,leap;leap=((year%4==0)&&(year%100!=0))||(year%400==0);for(i=1;yearDaydayTab[leap][i];i++){yearDay=yearDay-dayTab[leap][i];}*pMonth=i;/*将计算出的月份值赋值给pMonth所指向的变量*/*pDay=yearDay;/*将计算出的日号赋值给pDay所指向的变量*/}2020/3/530字符串(String)与字符数组、字符指针字符串–一串以'\0'结尾的字符在C语言中被看作字符串–用双引号括起的一串字符是字符串常量,C语言自动为其添加'\0'终结符–C语言并没有为字符串提供任何专门的表示法,完全使用字符数组和字符指针来处理字符数组–每个元素都是字符类型的数组charstring[100];字符指针–指向字符类型的指针char*p;数组和指针可以等同看待,上面三者本质上是一回事2020/3/531字符指针变量与字符数组的区别定义方法不同charstr[10];char*ptr;赋值方法和含义不同charstr[10];str=”china”;/*错误*/strcpy(str,”china”);/*正确*/char*ptr;ptr=”china”;2020/3/532字符指针变量与字符数组的区别在定义一个数组时,在编译时即分配单元,有确定地址,而定义一个字符指针变量时,如未对它赋初值,则其所指数据是不定的,因而使用是危险的。例如,输入字符串时charstr[10];scanf(%s,str);/*正确*/char*a;scanf(%s,a);/*错误*/应为:char*a;charstr[10];a=str;s

1 / 71
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功