《c程序设计授课》课件-第07章 指针_第1页
《c程序设计授课》课件-第07章 指针_第2页
《c程序设计授课》课件-第07章 指针_第3页
《c程序设计授课》课件-第07章 指针_第4页
《c程序设计授课》课件-第07章 指针_第5页
已阅读5页,还剩55页未读 继续免费阅读

下载本文档

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

文档简介

第7章指针*重点与难点7.1变量的地址与指针7.2指针变量的定义、初始化和引用7.3指针与函数7.4指针运算7.5指针与一维数组7.6字符指针与字符串7.7指针数组7.8指针和二维数组7.9指向指针的指针7.10返回指针值的函数7.11指向函数的指针*本章小结*作业重点与难点重点:指针的概念;指针变量的定义、初始化;指针作函数的参数。难点:区分并掌握各类指针的使用。概述指针是C语言中的一个重要概念,也是C语言的一个重要特色。正确而灵活地运用指针,可以使程序简洁、紧凑和高效。指针可以有效地表示复杂的数据结构;能动态分配内存;方便地使用字符串;方便地使用数组;实现地址传递和直接处理内存等。指针的学习方法初学者比较怕使用指针,因为容易出错。学习方法(1)注重概念的理解(2)适当辅助画示意图可以帮助理解(3)适当采用类比方法(4)多上机实践7.1变量的地址与指针地址和指针的概念内存地址用户数据区变量名…

…20003i20026j20049k…

…30102000i_pointer…

…变量的地址每一个变量使用时对应内存中的相应存储单元,内存单元的首地址就是变量的地址。变量的地址也叫变量的指针。存放变量指针(地址)的变量叫指针变量。通过指针变量访问所指变量的值的方式,是“间接访问”i_pointer20003i2000例7.1输出变量的值和变量的地址main(){intx;x=55;printf("x=%d\n",x);printf("xaddr=%x\n",&x);}运行结果:x=55xaddr=ffde7.2指针变量的定义、初始化和引用7.2.1指针变量的定义和初始化7.2.2指针变量的引用7.2.1指针变量的定义和初始化定义的一般形式

存储类型数据类型*指针变量名

举例:inta,*p;初始化

p=&a;&a100papx、*px与&px表示形式含义px指针变量,存放的是变量地址*px指针变量所指的目标变量a&px指针变量本身占用的存储区域的地址已知int*px,a;px=&a;&a100pxa、*px&px7.2.2指针变量的引用普通变量通过变量名获得变量的值;而通过指针变量获得的是一个变量的地址,再由该地址间接获得变量的值。两种运算(1)取地址运算符:&

int*p,x;p=&x;(2)间接访问运算符:*

*p

等价于x;

&*p<=>&(x)<=>&x;*&x<=>*p<=>x例7.2验证指针变量和目标变量的关系main(){intx,*px;px=&x;x=55;printf("&px=%u\n",&px);printf("Command\t&x\tpx\tx\t*px\n");printf("px=&x\n");printf("x=55");printf("\t%u\t%u",&x,px);printf("\t%d\t%d\n",x,*px);x=65;printf("x=65");printf("\t%u\t%u\t%d\t%d\n",&x,px,x,*px);*px=75;printf("*px=75");printf("\t%u\t%u\t%d\t%d\n",&x,px,x,*px);}例7.2程序的输出

&px=65500Command&xpxx*pxpx=&xx=5565498654985555x=6565498654986565*px=75654986549875757.3指针与函数参数指针变量可以如简单变量一样作为函数的参数。指针变量作函数的参数,传递给函数的是一个地址,即按地址传递,实参变量和形参变量共用同一内存单元。例7.4指针变量作函数参数,完成数据交换voidswap(int*pa,int*pb){inttemp;temp=*pa;*pa=*pb;*pb=temp;}main(){inta=5,b=9;printf("\nBefore:a=%d,b=%d",a,b);

swap(&a,&b);printf("\nAfter:a=%d,b=%d",a,b);}交换过程图示a5b9temppapa&apb&bswap函数调用开始a9b5swap函数调用结束(实参值已经改变)错在那里?voidswap(int*pa,int*pb){int*temp=pa;pa=pb;pb=temp;}a5pa&apb&bb9swap(&a,&b)a5b9调用结束a5pa&apb&bb9交换过程temp&a注意指针变量作函数的参数也要遵循实参向形参单向值传递。函数调用完毕,形参指针也一定被释放。但在函数中对数据的操作结果影响实参的值。7.4指针运算1、指针变量可以与整型量相加、减

p+n将指针变量前移;p-n

将指针变量后移;移动量n*d

字节(其中:字符型d=1;整型d=2;浮点型d=3)2、指针变量间可以进行比较运算

p1>p2;p1==NULL3、两个指针变量的相减:局限于指向同一数组。

p-q

等于p和q之间的元素个数7.5指针与一维数组a数组a[0]a[1]*(p+2)a[2]、*(a+2)a[3]a[4]a[5]a[6]a[7]a[8]a[9]pp+2int*p,a[10];p=a;p=p+2;元素引用方法下标法:a[i]指针法:*(a+i)或*(p+i)数组元素引用方法比较a[i]、*(a+i)、p++a[i]<==>*(a+i)等价,效率相同p++与a+i:前者是自增1,后者是普通的加法。指针法效率较高,但程序可读性不如下标法。注意数组名a是个常量,所以a++是不对的。*p++与*++p

其中*与++优先级同,结合方向自右向左。(*p)++例7.8通过函数实现数组反序。ij012345678910反序程序voidinvert(intarr[],intn){inttemp,i=0,j;for(j=n-1;i<j;i++,j--){temp=arr[i];arr[i]=arr[j];arr[j]=temp;}}voidinvert(int*arr,intn){inttemp,*pi,*pj;pi=arr;pj=arr+n-1;for(;pi<pj;pi++,pj--){temp=*pi;*pi=*pj;*pj=temp;}}课堂训练1、有一个长度为10的一维数组,通过指针传递,编写如下函数:(1)输入函数:输入10数据;(2)排序函数:对10个数有小到大排序;(3)输出函数:在屏幕上显示排序结果。7.6字符指针和字符串C语言中,没有专门的字符串类型,它可以采用以下两种形式:(1)字符数组的方法

charstr[]="Itisastring.";(2)字符指针的方法

char*str;str="Itisastring.";例7.10字符指针的使用main(){charstr[20],*str_p;str_p=str;scanf("%s",str_p);printf("Stringstr:%s",str);printf("\nStringstr_p:%s",str_p);str_p="Changed!";printf("Stringstr:%s",str);printf("\nStringstr_p:%s",str_p);}程序运行情况:China↙Stringstr:ChinaStringstr_p:ChinaStringstr:ChinaStringstr_p:Changed!例7.11字符指针main(){char*str_p;scanf("%s",str_p);printf("%s",str_p);}str_p没有具体的指向,虽然也可以运行,但是危险的!在编写指针程序时,请留意每一个警告错误!例7.12动态内存申请#include<alloc.h>main(){char*str_p;str_p=(char*)malloc(20);if(str_p==NULL){printf("outofmemory!");exit(0);}scanf("%s",str_p);printf("%s",str_p);free(str_p);

str_p="Changed!";printf("\n%s",str_p);}7.7指针数组一维指针数组的定义形式:类型名*数组名[数组长度]

指针数组:如整型数组一样。整型数组的每一个元素都是整型;指针数组的每一个元素都是指针。例7.14指针数组的使用main(){inti;char*a[5]={"Dog","Cat","Mouse","Rabbit","Crocodile"};for(i=0;i<5;i++)printf("\n%s",*(a+i));}a数组a[0]Doga[1]Cata[2]Mousea[3]Rabbita[4]Crocodile例7.15main函数的参数main(intargc,char*argv[]){inti;printf("\nargc=%d",argc);printf("\ncommandname:%s",argv[0]);for(i=1;i<argc;i++)printf("\nArgumentNo.%d:%s",i,argv[i]);}7.8指针和二维数组7.8.1二维数组的地址7.8.2指向二维数组的行指针变量7.8.1二维数组的地址2000120023200452006720089201011201213201415201617201819202021202223aa+1a+2a[0]a[0]+1a[0]+2a[0]+3二维数组与指针表示形式含义地址a二维数组名,指向一维数组a[0],即第0行首地址2000a[0],*(a+0),*a第0行第0列元素地址2000a+1,&a[1]第1行首地址2008a[1],*(a+1)第1行第0列元素a[1][0]的地址2008a[1]+2,*(a+1)+2,&a[1][2]第1行第2列元素a[1][2]的地址2012*(a[1]+2),*(*(a+1)+2),a[1][2]第1行第2列元素a[1][2]的值元素值13注意!

譬如:inta[3][4];,在二维数组中,a[0],a[1],a[2]不表示元素,它们都是行地址7.8.2指向二维数组的行指针变量行指针定义的形式如下:

类型名(*变量名)[长度]举例

int(*p)[4];例7.16二维数组的地址main(){inti,j;inta[3][4]={{0,0,0,0},{1,1,1,1},{2,2,2,2}};int(*p)[4]=a;for(i=0;i<3;i++)

printf("AddressofRow%d:%u,%u,%u\n",i,&a[i][0],a[i],p+i);for(i=0;i<3;i++){printf("Elementsofrow%d:",i);for(j=0;j<4;j++)printf("%d",*(*(p+i)+j));printf("\n");}}*(p+i):第i行首地址,*(p+i)+j:第i行j列元素首地址行指针与普通指针的比较已知int*p,(*q)[4],a[3][4];p=a;q=a;p++表示向前移动一个元素;q++表示向前移动一行;qp+1pq+1概念比较*与[]运算符的优先级相同,结合方向是从右向左。int*p[4];表示p[4]是数组,数组的每个元素指向整型变量。所以p是指针数组。int(*p)[4];表示p是一个指针变量,它指向包含4个元素的一维数组。即p是行指针。p+1表示下移一行。概念图示int*p[4];pint(*p)[4];1357911131517192123pp+27.9指向指针的指针定义的一般形式数据类型**指针变量名举例

char**p;举例:使用指向指针的指针main(){char*name[5]={"Followme","BASIC","GreatWall","FORTRAN","Computerdesign"};

char**p;inti;for(i=0;i<5;i++){

p=name+i;printf("\n%s",*p);}}指向指针的指针图示name指针数组(*p)name[0]name[1]name[2]name[3]name[4]字符串FollowmeBASICGreatWallFORTRANComputerdesignp例7.19指向指针的指针作函数参数voidswap(int**p,int**q){int*temp=*p;*p=*q;*q=temp;}main(){staticinta[5]={1,3,5,7,9};int*pa[5]={&a[0],&a[1],&a[2],&a[3],&a[4]};inti,j;for(i=0,j=4;i<j;i++,j--)swap(&pa[i],&pa[j]);for(i=0;i<5;i++)printf("%d",*pa[i]);}反序图示name指针数组(*pa)&a[0]&a[1]&a[2]&a[3]&a[4]数组aa[0]=1a[1]=3a[2]=5a[3]=7a[4]=9pa间接寻址通过指针变量访问所指变量的值,是一级间接寻址;通过指向指针的指针访问变量的值,是二级间接寻址;理论上,间接寻址可以延伸到多级,但级数越多,越难理解和越容易出错。7.10返回指针值的函数函数可以返回简单类型,譬如:整型、字符型、浮点型等,当然,也可以返回指针型。返回指针值的函数定义一般形式:

类型名*函数名(参数表);例7.20查找数字月份对应的英文名称。main(){char*month_name();char*pname;intn;scanf("%d",&n);pname=month_name(n);printf("%s",pname);}char*month_name(intn){staticchar*name[]={"Illegal","January","February","March","April","May","June","July","August","September","October","November","December"};return((n<1||n>12)?name[0]:name[n]);}程序运行情况:9↙September7.11指向函数的指针函数的指针:是函数的入口地址。函数名代表函数的入口地址。指向函数的指针变量:是能够存放函数入口地址的变量。定义的一般形式:函数类型名(*指针变量名)();例7.21指向函数的指针变量使用main(){int(*p)(),a,b,c;printf("\na,b:");scanf("%d%d",&a,&b);p=min;

c=(*p)(a,b);

printf("min=%d",c);

p=max;

c=(*p)(a,b);printf("\nmax=%d",c);}intmin(intx,inty){return((x<y)?x:y);}intmax(intx,inty){return(x>y?x:y);}例7.22函数指针变量作参数#include<stdio.h>#include<string.h>main(){voidcheck(char*,char*,int(*)());chars1[80],s2[80];printf("Enterstring1:");gets(s1);printf("Enterstring2:");ge

温馨提示

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

评论

0/150

提交评论