页数:108页文件大小:467.0 KB来源: C语言程序设计ppt课件
本课件从地址与指针的概念入手,说明指针变量的定义、引用与作函数参数的用法;随后讲解指向数组元素的指针与指针运算、指向字符串的指针及其与字符数组的区别,并介绍指向函数的指针、返回指针值的函数、指针数组与指向指针的指针。
第7章 指针
的概念。
2.掌握指针变量的定义、应用及作为参数的用法。
3.掌握指向数组的指针与指向数组的指针变量的概念、定义和应用。
4.掌握指向字符串的指针的定义和应用。
5.理解指向函数的指针的定义和用法。
6.了解返回指针值的函数的定义和应用,了解它与指向函数的指针变量的区别。
7.了解指针数组的定义和应用,掌握指针的指针的定义和应用,了解它指针数组与指向数组的指针变量的区别。
教学内容1.指针的定义2.指针
的操作3.针变量的初始化1.指针作为参数2.返回指针的函数3.函数指针4.函数体内的指针1.存储管理函数2.函数的使用1.一维数组和指针2.多维数组和指针3.用指针处理串4.指针数组
7.1 地址和指针的概念
计算机把内存的所有单元顺序排列,每个单元(字节)有一个顺序编号,称单元的地址或称为指针。
变量是对程序中数据存储空间的抽象
任何变量在其存在期间总有一个固定的地址。
变量地址可作为数据来操作。
7.1地址和指针的概念内存…………程序中:shorti;floatk;......每个字节有一个编号编译或调用时分配内存ki地址0000……20002001200220032004200520062007……
………二
指针变量专门存放变量地址的变量7.1地址和指针的概念变量p变量p的内容指针变量地址20002001…2013201420152016…变量i的内容短整型变量i变量i的地址指针20002000i内存
变量值的存取方式
直接存取直接按变量地址存取变量值的方式。
在程序中对变量进行存取操作,实际上是对某个地址的存储单元进行操作,变量和地址的联系由系统完成,用户无须知道变量的具体地址。
例
scanf("%d",&i)的执行过程是这样的:找到变量i的起始地址2000;然后将键盘输入的值10送到内存单元2000和2001中。printf("%d", i)的执行过程与scanf()很相似:首先找到变量i的起始地址2000,然后从2000和2001中取出其值,最后将它输出。间接存取指针变量
也是变量,也有自己的存储地址,设指针变量p中放的是变量i的地址,这时要访问i,可先找到p的地址,从中取出i的地址,再去访问i的内容,这种通过变量p间接得到变量i的地址,然后再存取i的值的方式称“间接存取”。
指针机制是一种间接访问其他对象的手段,目的是为了更灵活方便地对数据进行操作。
7.1地址和指针的概念指针变量p:一般变量i:2000(i的地址-指针)5(变量i的值)指向地址存入P中2000:
7.1 地址和指针的概念
指针变量的值只能是其他对象的地址,指针变量赋值就是把某个变量的地址赋给指针(这个过程称指针指向变量),因此,在程序运行的不同时刻,指针可以指向不同的变量。
指针的应用使程序代码更简洁、更高效。但使用指针会降低程序的可读性,使用不当,可能造成严重的错误甚至引起系统崩溃。
7.2 指针的定义
7.2 指针的定义
指针变量的值为某个内存单元的地址值(地址编号)。值的类型均为整型。(VC中占4个字节)
通过指针访问的对象有类型C语言规定,任何一个指针变量,只能指向具有某种特定类型的变量。定义中的类型名限定了指针变量可以关联的对象的范围。
指针变量也是变量像普通变量一样可以赋值、取值等。但要满足类型约束。7.2指针的定义、使用和运算
int*p1
//定义整型指针变量p1,用于指向整型变量。
float*p2;//定义浮点指针变量p2,用于指向实型变量。
char*s;//定义指向字符的指针变量s,也叫字符指针。
int*p, n; a[10];//指针变量可和其他变量一起定义。
'*'不可省略,否则变成普通变量的定义,如:int*p1,*p2;与int*p1,p2;//p2是普通变量
空指针
void指针
(void*)类型的指针叫通用指针,它可以指向任何变量,C语言允许直接把任何变量的地址作为指针赋给通用指针。
使用通用指针需要进行类型强制转换。
如:(void*)gp所指空间的数据是整型数据,p是整型指针,用下式转换:p=(int*)gp;7.2指针的定义、使用和运算
指针转换实际上没有带来指针值的任何变化
通用指针对被指的内容不提供任何有意义的类型信息,所以不能通过这种指针间接使用被指的内容。
通用指针的唯一用途就是提供一个指针值。可看成内存中每个字节的原始地址,无具体类型。7.2指针的定义、使用和运算
指针的操作
&放在变量名前面,取得该变量的地址;例如:若有定义intx,*p;把p=&x;把x的地址赋予p,即p指向了变量x。
scanf("%d", &x)scanf("%d", p)7.2指针的定义、使用和运算指针变量赋值通过
指针变量赋值,把一个指针变量的地址值赋给另一个指针变量,使这两个指针变量指向同一地址。
赋值号两边的指针变量的基类型必须一样。
例如:p和q都是整型指针,p指向整型变量,则执行q=p以后,q也指向变量x。
通过标准函数获得地址值可以通过调用库函数malloc和calloc在内存中开辟动态存储单元,并把单元地址赋值给指针变量。7.2指针的定义、使用和运算
间接运算
将一元运算符"*"放在指针变量名前(也可是地址前),效果是由一个指针得到被它指向的变量,可以像使用普通变量一样使用该表达式。
如:intm,*p,*q,n;p=&n;q=&m;
则:*q相当于n,*q相当于m。
间接使用:m=*p+*q作用与m=n+m相同。
间接赋值:*p=5,作用与n=5相同。
显然:*p出现在赋值号左边,代表指针所指的存储单元,*p出现在赋值号右边,代表指针所指的存储单元的内容。
7.2指针的定义、使用和运算
例1设int*p,k=0
p=&k;分析下面几行程序执行的过程和结果。
*p=100;//把整数100赋给k变量*p =*p+1;//取p所指单元的值,加1后//赋给p所指的存储单元k,//k变为101*p+=1;
//等价于k+=1;k变为102++*p;
//等价于++k,k变为103(*p)++;
//等价于(k)++,k变为1047.2指针的定义、使用和运算k0p→
移动指针
将移动指针就是对指针变量加上或减去一个整数,或通过赋值运算使指针变量指向相邻的存储单元。因此,只有当指针指向一串连续的存储单元时,指针移动才有意义。
对指针进行+、-运算中,数字“1”不再代表十进制数“1”,而是1个存储单元长度,如果整型变量存储单元长度是4个字节,整型指针移动1个存储单元就是移动4个字节,双精度型指针加1就是移动8个字节,依此类推。
7.2指针的定义、使用和运算
程序中移动指针时
不论指针的基类型是什么,只需简单地加、减一个数而不必去管它的具体长度,系统将会根据指针的基类型自动确定位移的字节数。
最常用的移动操作就是加一(++)和减一(--)操作。它们分别代表指针向地址值增大的方向移动一个存储单元和指针向地址值减少的方向移动一个存储单元。
两个指向同一串连续单元的指针可以进行相减的运算,结果是两个指针之间元素的个数,可以通过赋值使两个指针指向同一个单元。7.2指针的定义、使用和运算
例2顺序执行下面的操作
分析其意义和结果。
设int*p,*q,a;且p、q分别指向一片连续空间的第一个整数和最后一个整数。
++p;//p后移1个单元,指向第二个整数q--;//q前移1个单元,指向倒数第二个数。
a=*p++;//取出p所指单元内容赋给a,p后移a=q-p;//计算q和p间整型数个数将它赋给ap=q--;//将p指向q所指单元,指针q前移*p=10/2;//计算10/2的值,赋给p所指单元。
7.2指针的定义、使用和运算24……789qa:q-p538p
指针比较两个指针指向同一连续的存储单元时
可以在关系表达式中对其进行比较,判断指针的位置关系。
如果两个指针变量的值相等,表示它们指向同一个存储单元。
另外,还可进行是否是空(NULL)指针的判断。
指针基类型对指针的相关操作有一定的约束和限制,主要有以下几方面:
指针变量的初始化
指针变量在定义时可以用任何合法的指针(地址)值进行初始化。如:inta,*p=&a,*q=NULL包含了两个指针初始化部分。
局部自动变量、寄存器变量的值不确定,要有明确的变量关联后才能使用这些变量。7.2指针的定义、使用和运算
初始值是赋给指针变量
变量必须已说明过,类型应一致。如:inta,*p=&a;√是正确的。而int*p=&a;inta;×是错误的。
不能用auto变量的地址去初始化static型指针。例:inti;staticint*p=&i;×是错误的。7.2指针的定义、使用和运算
例3用指针指向变量
main(){ inta,b,min,*pa,*pb,*pmin; pa=&a; pb=&b; pmin=&min; scanf("%d%d",pa,pb); printf("a=%d,b=%d\n",a,b); if(*pa<*pb)*pmin=*pa; else*pmin=*pb; printf("min=%d\n",min); } 7.2指针的定义、使用和运算运行结果:23 677.3 函数与指针
概述已知C语言中函数的一般形式为:类型名函数名([形参表])//头部{说明部分//函数体语句部}
C语言函数参数的传递机制是值传递
函数中形参的改变并不能改变对应实参的值,把数据从被调函数返回到调用函数的唯一途径是通过return语句返回函数值,限定了函数只能返回一个数据。
在函数中使用指针,可以突破这些限制,函数定义中的各部分:参数、函数名、返回值及函数体内,都可以使用指针。
本节讨论这方面的情况。
指针作为函数参数
函数中,通过形参操作的存储单元与实参所指的是同一单元,因此实参的值发生了改变。利用此形式,可以把两个或两个以上的数据从被调用函数中返回到调用函数。
例4*交换两个变量值
的函数voidswap(int*p,int*q){intt;//t非指针t=*p;*p=*q;*q=t;/int(*p1)[4]=a;int*p2=a[0];7.4数组和指针形参实参数组名intx[][4]数组名a指针变量int(*q)[4]数组名a数组名intx[][4]指针变量p1指针变量int(*q)[4]指针变量p1指针变量int*q指针变量p2
13*编写函数输出二维数组a中最大值及所
在的行号和列号。
分析:设a为整型数组,依题意,函数需返回多个值,从return返回最大值,行号和列号通过指针修改主程序保存行号和列号的变量值得到。
使用行指针引用二维数组元素的方法编写程序。
#defineM3
#defineN4intmax(p,prow,pcol)int(*p)[N],*prow,*pcol;{inti,j,mx=*(p[0]);*prow=0;*pcol=0;for(i=0;i<M;i++)for(j=0;j<N;j++)if(*(p[i]+j)>mx){mx=*(p[i]+j);*prow=i;*pcol=j;}return(mx);}7.4数组和指针
#include<stdio.h>main(){ inta[M][N]={ 1,2,3,4,5,6,7,8,9,0,1,2 } ; introw,col,mx; mx=max(a,&row,&col); printf("max=%d,",mx); printf("row=%d,",row); printf("col=%d\n",col); } 运行结果:max=9, row=2, col=0使用指针处理字符串
初始化方式使字符指针指向字符串如
用赋值运算使指针指向一个字符串如:char*str;str="stringone";与第一种初始化方法完全等价。
用字符数组指向字符串
str是指针变量,可多次赋值;a是数组名,表示地址常量,不能赋值,且a的大小固定,预先分配存储单元。
类型、大小不同。str是指针,a是数组。它们的存储表示如图所示。7.4数组和指针OKstr:a:OK
例14*分析
下面一段程序的输出本题是一组关于++和*运算符的练习,目的是熟悉字符指针对字符串的控制操作。
main(){ chars[]="ABCDEF"; char*str=s; printf("%c",*str); printf("%c",*str++); 7.4数组和指针//取str的内容,str指向'A'运行结果:AACCEABEDEF\0FEDCBAAAstrsprintf
printf("%c",(*str)++); printf("%c\n",++*str); printf("%s\n",s); } 运行结果:AACCEABEDEF7.4数组和指针ABEDEF\0FEDCBAstrsC++str运算,指向'C',再取str的内容取str的内容,然后str的内容加1,'C'修改为'D'ECD先对str的内容运算加1操作,'D'修改为'E',然后,取str的内容E取s的内容,s指向'A'AACCEABEDEF使用字符指针处理字符串和字符数组
字符串输入时,输入项可以是字符数组,也可以是字符指针。字符指针必须已经指向确切的、足够大的存储空间,以便输入字符能放在它所指的具体单元中。
例15*计算字符指针所指字符串的长度。分析:逐个统计串中的字符个数,直到遇到串结束符'\0'为止。7.4数组和指针
#include
<stdio.h>intlength(char*str){intn=0;while(*str++!='\0')n++;returnn;}
main(){ char*str1="goodMorning!"; charstr2[]="goodAfternoon!",*str3=""; printf("%slen:%d\n",str1,length(str1)); printf("%slen:%d\n",str2,length(str2)); printf("str3len:%d\n",length(str3)); } 7.4数组和指针7.4数组和指针运行结果:Good Morning! len: 13Good Afternoon! len: 15str3 len: 0例16*编写函数
实现字符串反转的操作分析:本例实现的方法是利用两个字符指针s和p,分别指向应该进行交换的两个字符,s从字符串的首字符向末字符移动,p从字符串的末字符向首字符移动,直到两个指针相遇,如果原字符串长度是奇数,结束时s=p,如果原字符串长度是偶数,结束时s>p。
如下图所示。
7.4数组和指针7.4数组和指针\0sp
#include
<stdio.h>voidrevstr(char*s){char*p=s,c;while(*p)p++;//到结束符停止p--;//退回最后一个有效字符while(s<p)//用交换并移动指针{c=*s;*s++=*p;*p--=c;}}
main(){ charstr[]="goodMorning!"; revstr(str); printf("str=%s\n",str); } 7.4数组和指针7.4数组和指针运行结果:str = Good Morning!str = !gninroM dooG例17*编写函数
实现字符串连接的操作分析:scat(char*dest,char*src);函数将src所指字符串的内容连接到dest所指字符串后面,覆盖dest串末的结束符'\0',要求dest所指字符串的空间足够容纳合并后的字符串。
7.4数组和指针
#include
<stdio.h>char*scat(char*dest,char*src){char*p=dest;while(*p)p++;//移到第一串的结束符处while(*p++=*src++);//接在结束符处return(dest);}
main(){ char*str,*s2="abcde"; chars1[20]="12345"; str=scat(s1,s2); printf("2:%s\n",str); } 7.4数组和指针7.4数组和指针运行结果:1:12345, abcde2:12345abcde例18*编写函数
实现字符串比较的操作分析:函数为scomp(char*s1,char*s2)将s1和s2进行比较:
若s1串<s2串,函数返回负数。
从两个字符串的初始位置开始,将对应位置上的字符进行比较,直到遇到对应位置上有不等的字符或其中的一个串到达了串尾,将两串当前字符的值相减,作为函数值返回。
7.4数组和指针
charscomp
(char*s1,char*s2){while((*s1==*s2)&&(*s1)&&(*s2)){s1++;s2++;}return(*s1-*s2);}
main(){ chars1[20]="comparestring",s2[20]; intresult; gets(s2); result=scomp(s1,s2); if(result>0)printf("%s>%s\n",s1,s2); elseif(result==0)printf("%s=%s\n",s1,s2); elseprintf("%s<%s\n",s1,s2); } 7.4数组和指针指针数组指针本身
也是数据,也可以作为数组的元素,如果数组中的元素均为指针类型数据,则称这个数组为指针数组。
指针数组中每一个元素都相当于一个指针变量。
一维指针数组的定义形式:类型名*数组名[数组长度];
例如,int*pa[5];
定义一个有5个整型指针为数组元素的一维数组。
用它表示另一个整型数组元素大小关系,如图。
7.4数组和指针7.4数组和指针pa&a[1]&a[4]&a[2]&a[3]&a[0]a45613367
字符指针数组表示的字符串数组
第6章中介绍了用二维字符数组表示字符串数组的方法,包括它在定义时的初始化方法,现在,我们可以定义字符型指针数组并通过赋初值来构成字符串数组。
例如:char*pa[10];
pa是一个字符指针数组,类型是(char*)。
指针数组最多的用途是用来表示一组字符串,它使字符串的处理更加灵活。
例如用字符指针数组pa组织大型程序的错误信息,可将错误号与pa下标对应,方便组织错误信息的输出。
7.4数组和指针
字符指针数组的初始化
*day[]定义7个元素的字符指针数组,建立7个字符串常量,对数组元素进行了初始化。
7.4数组和指针7.4数组和指针day0123456\0nuS\0noM\0euT\0deW\0uhT\0irF\0atS
字符指针数组与二维字符数组比较如
charc1[][6]={"red","green","blue"};char*c[]={"red","green","blue"};7.4数组和指针7.4数组和指针指针数组表示的字符串c[0]c[1]c[2]连续存储可能有很多空的单元。
\0der\0neerg\0eulb分散存储靠指针联系,可能出现字符串丢失。
二维数组表示的字符串\0derc1[0]\0neergc1[1]\0eulbc1[2]
例19编写程序比较若干种高级语言的名字
分析如果想避免排序过程中过多的数据交换,本例的思路应该对你会有启发。排序过程中,交换指针变量的值,这种方法比交换数组元素的值效率要高。
charsort
(char*a[],intn ){char* temp ;inti, j, k ;for(i=0; i<n-1;i++){k = i;for(j=i+1; j<n; j++)if(strcmp(a[k],a[j])>0)k = j;if(k != i){temp = a[i];a[i] = a[k];a[k] = temp;}}}7.4数组和指针7.4数组和指针# include<stdio.h>
main(){ char*ln[]={ "PAS","BAS","FOR","VC","ADA" } ; inti, m ; m=sizeof(ln)/sizeof(char*); sort(ln, m) ; for( i=0; i<m; i++ )printf ("%s ",ln[i]) ; } 运行结果:ADA BASFORPAS VC7.4 数组和指针
4数组和指针ln01234\0SAP\0SAB\0ROF\0CV\0ADA排序前指针数组ln01234\0SAP\0SAB\0ROF\0CV\0ADA排序后指针数组
指向指针的指针
指针变量的内容是数据地址,如果数据本身是个指针,该指针变量就是指针的指针。如:每个指针数组元素都是其他数据的地址,指向指针数组元素的指针就是指向指针的指针。
变量的定义形式char**p;
p的前面有两个*号,根据*运算符的结合性,**p相当于*(*p),根据指针变量的定义形式,*p是一个字符指针,p是指向这个指针的变量。
7.4数组和指针7.4数组和指针stringp*p
20*编写程序使用指向指针
main(){ char*name[]={ "PAS", "BAS", "FOR", "VC", "ADA" } ; char**p; inti,m; m=sizeof(name)/sizeof(char*); p<name+m; p++)printf("%s\n",*p); } 7.4数组和指针运行结果:PASBASFORVCADAname01234\0SAP\0SAB\0ROF\0CV\0ADAp命令行参数
main()都使用其无参形式,实际上,main()函数可以有参数,指针数组的一个重要应用是作为main()函数的形参。main函数是由系统调用的,调用的方法是在操作系统命令状态下输入main所在的执行文件的名字(命令),也可在Windows中通过点击图标进行,但也等价于在命令状态下发出一条命令。main函数的参数跟在调用命令后,由操作系统传递给主函数,这种机制叫命令行参数。如type abc.txt命令中,abc.txt是type的参数;在VC环境
中,调试带有命令行参数的程序时,可以通过选择“过程”/“设置”/“调试”菜单中的“程序变量”选项,输入参数。
C语言如何看待命令行看作由空格分隔的若干字符串,每个字符串看作是一个命令行参数。
由第一个字符串(命令本身)开始从0编号。
程序执行时,每个参数被处理成字符串,按照规定方式使用它们。
C语言通过主函数的参数获取命令行参数。
主函数原型main
argv[]:字符指针数组,存储命令行的每个字符串,argv[0]是命令名,argv[1]是第一个参数串,argv[2]是第二个参数串,依此类推。
例21*打印命令行参数及命令本身main
(intargc,char*argv[]){inti;for(i=0;i<argc;i++)
在VC环境中:选择“过程”/“设置”/调试”菜单中的“程序变量”选项,输入“aaabbb”,再运行程序。
在DOS环境中:直接执行文件名为test.exe7.4数组和指针argvtest0aaa1bbb23运行结果:test
printf("%s%c",argv[i],i<argc-1?',':'\n'); } 设程序名为test.c例22*从命令行输入三个数
main
(intargc,char*argv[]){intd;floatf;charstr[10];if(argc<4){
printf("参数不够"); exit(0);} sscanf(argv[1],"%d",&d); sscanf(argv[2],"%f",&f); sscanf(argv[3],"%s",&str); printf("%s,%.2f,%d\n",str,f,d); } 第92页:7.5 动态存储管理
7.5 动态存储管理
在任何一个变量使用前,都必须完成关于存储方面的有关安排,包括存放位置、占据多少存储单元,这个工作叫存储分配。
存储空间的静态分配方法是根据程序提供的信息,在变量定义时即可静态计算出需要的空间,预先分配好空间。
如外部变量、局部静态变量在编译时即可决定。
局部变量的大小也是静态确定的(函数在被调用时所需的空间在编译时可确定)。
- 静态分配的好处是处理、实现方便简单,执行效率高
第93页:但存在问题是对某些问题
但存在问题是对某些问题
如数组排序程序中,定义的数组空间可以存储500个数组元素,实际问题也许只有10个元素。
对在写函数时无法预知的空间需求,如果能根据运行中的动态信息,确定实际需求空间,分配适当大小的空间,就可以提高内存空间利用率。
C语言提供了动态分配的机制,通过指针掌握对动态分配块的操作。
存储空间的动态管理包括分配、释放回收两方面的工作,由操作系统的“动态存储管理系统”完成。
C语言提供几个标准函数完成与该系统的交互工作。
- 的空间要求预估不准确,可能引起空间浪费或空间不足的情况出现。
第94页:C语言标准动态存储管理函数标准动态存
C语言标准动态存储管理函数标准动态存
储管理函数原型在标准头文件“stdlib.h”中描述。1.存储分配函数malloc()
功能分配一大小为size个字节的存储块,返回指向这个块的指针,若申请失败,返回空指针。
- 形式void*malloc(unsignedsize)
- size:无符号整数
- (void*):返回值类型,为通用指针,需要通过类型强制转化成特定的指针类型。
第95页:例23对数组进行排序时
例23对数组进行排序时
scanf("%d",&n); data=(int*)malloc(n*sizeof(int)); if(data==NULL){ … } 第96页:带初始化的存储分配函数calloc
带初始化的存储分配函数calloc
size个字节的存储块,存储块的全部内容清0,返回指向这个块的指针,如果存储申请不能满足,返回空指针。
- ()
- 形式void*calloc(unsignedsize,unsignedn)
- size:无符号整数
- n:无符号整数
- (void*):返回值类型,为通用指针,需要通过类型强制转化成特定的指针类型。
- 功能分配一块大小为n
第97页:动态存储释放函数free
动态存储释放函数free
功能释放指针p(为调用前两个函数所得到的指针)所指的存储块。如果p的值为空,什么也不做。
调用free(p)后,p的指向没有改变,但不能再使用它的值,除非p重新指向新的数据单元。
- ()
- 形式voidfree(*p)
- 注意
- 编写程序中,应养成对不再使用的存储块立刻释放的习惯,避免造成存储块丢失。
第98页:分配调整函数realloc
分配调整函数realloc
如果新的分配要求可以满足,返回新存储块的指针,内容与原来块中的一样,其余部分不进行初始化。不能再通过p指针使用原来的存储块
- ()
- 形式void*realloc(void*p,unsignedn)
- 功能更改前面做过的存储分配,指针p指向一个过去分配的存储块,n表示现在希望的存储块大小
- 如果新的要求不能满足,返回NULL,p仍指向原来的位置
第99页:C语言标准动态存储管理
C语言标准动态存储管理
的使用C语言标准动态存储管理函数的使用,是后继课程中进行算法设计的基本操作,要求掌握概念及基本程序框架,下面对使用中的注意事项做个总结。
1.一定要检查空间分配成功与否常用下面的结构:if((p=(…*)malloc(…))==NULL){……}//对分配不成功的处理2.分配空间的大小一定要用运算符sizeof来计算。
第100页:关于存储块的管理
关于存储块的管理
系统完全不进行检查。
分配成功后,程序要控制分配空间块使用的正确性,一方面不可超出实际存储块的范围,另一方面,要在使用中保持和存储块的连接关系,避免因指针误操作引起存储块丢失。
同时,已分配的存储块不再使用时,应该及时释放。
4.动态存储块的存在期从其分配成功时开始,只有用free函数释放后才能结束其存储期。
如果某个函数得到了一块动态存储空间,由一个临时指针连接,函数结束时没有进行释放,由于函数结束时临时变量没有了定义,会出现与它连接的存储块丢失的情况。
第101页:7.6 指针实例
7.6 指针实例
scanf("%s",str);或:int*pa; *pa=10;str和pa没有指向具体的存储单元就执行输入和赋值操作,结果可能非常严重。
- 程序中使用指针可能出现的问题归纳1.间接引用数组元素的指针出界。2.没有定义指针变量的初值就使用指针。例如:char*str
第102页:错误赋值错误的指针变量赋值可能引起问题
错误赋值错误的指针变量赋值可能引起问题
例如1:char*str="abcd";s[8]="12345";如果执行了str=s,指针将指向字符数组s,存储字符串"abcde"的存储空间就会丢失。
例如2:如果指针变量p指向由malloc分配的空间,执行p=NULL,则p指的空间丢失。
4.错误操作。
例如:指针变量p和q指向同一片空间,如果执行了free(p),则·q指针会变成悬空状态。
q变量的值失去了意义。
第103页:7.6 指针实例
7.6 指针实例
分析程序需要完成从整数到字符串的一个转换过程,输入是1~7内的整型数,用指针数组存储一周的英文名称,第一个元素不保存有效的数据,用来实现指针数组下标和星期几的对应。
- 例24*编写程序用户输入一周内的第几天,输出相应的英文星期几的名称。
- 程序分为三部分定义数据类型和结构、接受数字并进行转换和接受字符决定是否继续。
第104页:main(){char*week[]={
main(){char*week[]={
0,"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};intday_num;while(1){
printf("天数(1~7),退出(0),请输入:"); if(scanf("%d",&day_num)<1)day_num=-1;//退出程序if(day_num<1||day_num>7)printf("输入错误!\n"); elseprintf("星期:%s\n",week[day_num]); while(getchar()!='\n');} } 7.6指针实例可以看出,使用指针数组时,通过指针间接对元素的存取,不需进行指针的运算,这种方法效率更高。
第105页:25*编写判别回文的函数回文是顺读
25*编写判别回文的函数回文是顺读
和倒读都一样的字符串,编写函数,判断一字符串是否是回文。若是回文,函数返回1;否则返回0。
分析最直接的方法,根据回文的定义,依次判断字符串的第一个字符是否等于最后一个字符,第二个字符是否等于倒数第二个字符,……用两个指针变量分别指向待比较的一对字符。
- 函数
第106页:intpalind
intpalind
(char*s){char*p=s,c;intresult=1;while(*p)p++;p--;while(s<p)if(*s==*p){p--;s++;}else{result=0;break;}returnresult;}7.6指针实例
main(){ chars[50]; printf("输入串:"); gets(s); printf("%s",s); if(palind(s))printf("是回文!\n"); elseprintf("不是回文\n"); } 运行结果:输入串:wxyzzyxw
- wxyzzyxw是回文!输入串:abcdef
- abcdef不是回文
第107页:7.7 小结本章的内容主要
7.7 小结本章的内容主要
指针基本概念包括变量的地址和变量的值、指针变量的说明、指针变量初始化、指针的内容、指针基本运算(取变量地址、取指针内容、指针移动、指针比较)和变量与指针的关系。
指针与函数的关系指针可作为函数的参数在函数之间传递,通过指针改变调用函数中的变量,函数返回值为指针类型,指向函数的指针。
- 包括下面一些内容:
第108页:指针与数组的关系
指针与数组的关系
包括数组名与地址的关系,如何使用指针操作数组,二维数组下标与指针的关系,函数之间传递数组的指针操作,数组指针与指针数组的概念及两者的区别和main函数参数。
使用指针处理字符串包括关于字符串的基本规定、字符串的结束标记、使用指针操作字符串的基本算法和常用字符串库函数。
下载地址:{{downurl}}
{{{a}}}
{{#b}}{{{b}}}
{{/b}} {{/title}} {{#nolog}}登陆注册
{{/nolog}} {{#djsx}}点我刷新
{{/djsx}} {{#gocz}} {{/gocz}} {{#ffqr}} {{/ffqr}}