版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
七、指针7.1指针概念7.2指针变量的定义和使用7.3指针与一维数组7.4指针与函数7.5指针数组、多级指针与指向一维数组的指针7.6指针与字符串7.1指针概念
所谓指针,某种程度上就相当于地址,但要比地址的含义更加丰富
•变量的指针变量的指针指的就是该变量的首地址
•指针变量指针变量是以指针(地址)为值的一种变量
•指针指向变量如有普通变量x及指针变量p,且p=&x;,则称:指针p指向变量x
•指针变量的类型指针变量按其所指向变量类型的不同,也分成相应的多种不同类型,指针变量只允许指向相应类型的变量。例如:有定义:inta,*p;floatb,*q;
则允许:p=&a;q=&b;
不允许:p=&b;q=&a;p=q;q=p;•空指针指向地址为0的指针称为空指针,空指针用于表示指向空,记为NULL,NULL是一个指针常量,对应0地址,在头文件stdio.h中定义。7.2指针变量的定义和使用
•指针变量的定义
一般形式:数据类型*指针变量名;如:intn,*p;floatx,*p1,*p2;•取址运算符&
intn,*p;p=&n;•取值运算符*
intm,n,*p;p=&n;*p=5;m=*p;
•指针使用举例
【例7.1】输入一个整数,通过指针方式赋值给另一个变量后输出。#include<stdio.h>main(){intn,m,*p;
scanf("%d",&n);p=&n;m=*p;
printf("%d\n",m);}0x2000123412340x20000x20020x2004nmp地址内存变量
•指针变量的初始化
inti,*p=&i;char*q="abcde";把字符串首地址赋给q
int*p=NULL;0地址赋给p
(指向空)
•指针必须先赋值再使用
intn,*p;定义指针变量p*p=5;可怕的错误
p=&n;*p=5;先赋值再使用7.3指针与一维数组
7.3.1一维数组的内存安排
inta[]={10,11,12,13,14};int*p=a;0x20021112130x20040x2006a[1]a[2]pa[0]a[3]a[4]10140x20000x20080x2000p0x200a地址内存变量7.3.2指向数组的指针运算
1.指向数组的指针
•指针可以指向数组中的某个元素
intc[5],*p,*q;p=&c[0];/*与p=c;等价*/q=&c[1];•指向整型数组的指针与指向单个整型变量的指针在指针类型上是一样的,都是指向整型量的指针
intn,c[5],*p,*q=c;p=&n;2.指针的加减整数运算指针加减一个整数,该整数表示的是该指针所指向数据类型的数据的个数,指针实际的增加量或减少量是该整数乘以指针所指向数据类型的长度(字节数)。例如:p为指针变量,则p=p+1后指向了原指向的数据的后面一个数据的首地址。如果p为字符型指针变量,则其增量为1字节;如果p为整型指针变量,则其增量为2字节;如果p为实型指针变量,则其增量为4字节。3.指针和所指向值的自增自减运算
•指针可以进行自增自减运算设p为指针,则有:
p++;++p;p--;--p;•对指针所指向的值也可以进行自增自减运算,如:
(*p)++;或++(*p);相当于*p=*p+1;(*p)--;或--(*p);相当于*p=*p-1;•指针与++、--和*运算符
++、--和*运算都是单目运算符,具有同等的优先级,C语言规定单目运算符是右结合的
设有:intn,a[5]={0,1,2,3,4},*p=&a[2];
则:表达式作用和意义*++p先++p使p指向a[3],再取*p即a[3]值++*pp指向的元素值增1,即++a[2](*p)++先取*p即a[2]值,再使a[2]值增1,即a[2]++*(p++)先取*p即a[2]值,再使p增1指向a[3]
注:
*p++等价于*(p++)【例7.2】分析以下程序的运行结果。#include<stdio.h>main(){inta[]={10,11,12,13,14},*p,n,i;p=&a[0];n=*(p++);n+=*(++p);n+=(*(p+=2))++;n-=(*(--p))--;n-=*(--p-1);
printf("%d\n",n);for(i=1;i<5;i++)printf("%d",a[i]);}/*n=a[0]=10p→a[1]*//*p→a[2]n=n+a[2]=22*//*p→a[4]n=n+a[4]=36a[4]=15*//*p→a[3]n=n-a[3]=23a[3]=12
*//*p→a[2]n=n-a[1]=12
*//*p→a[0]*//*12*//*1011121215*/4.指针的比较运算
•任意两个指针可以进行相等比较,以确定它们是否指向同一个变量
•两个指针指向同一数组时,可进行比较运算(含
<、<=、>、>=、!=、==)。以确定它们在数组中的前后位置值。例:指针关系运算举例。#include"stdlib.h"#include"time.h"main(){inta[20],*p,*q,n1,n2;randomize();/*初始化随机数发生器*/n1=random(20);n2=random(20);p=a+n1;/*
p指向a[n1]
*/q=a+n2;/*
q指向a[n2]
*/if(p==q)printf("\npandqpointssameelement.");elseif(p<q)printf("\nppointsforwards.");elseprintf("\nqpointsforwards.");
printf("\np=%xq=%x",p,q);}5.指针的相减运算
只有指向同一组类型相同数据的指针之间,进行减法运算才有意义,运算结果为整数,表示两指针间相隔的数据个数。例:指针间的加减运算示例。
main(){inta[20],*p,*q;p=&a[2];q=&a[6];
printf("\nq=%x\np=%x\nq-p=%d",q,p,q-p);}/*q-p应为4。*/7.3.3下标法与指针法表示的等价性
1.数组名作为指针常量
•数组名作为一个指针,表示整个数组的首地址,它同时也是数组第一个元素的地址。设有定义:inta[5],*p;
则:p=a;与p=&a[0];等价
p=a+1;与p=&a[1];等价*(a+2)与a[2]等价
•数组名作为指针类型的常量,下列运算非法的:
a++、--a、a=…、a+=…等2.在指针中使用下标运算符
•下标运算符[]可以和指针配合使用,可将指针看成是一个指向某个数组的指针,允许使用下标法表示所指向数组中的元素
如有定义:inta[5],*p=a;
则:a[2]p[2]*(a+2)*(p+2)等价
•当指针不是指向数组的第一个元素时,同一个数组元素的下标是不同的,并允许下标取负数如有定义:inta[5],*p=a,*q=a+2;
则:q[0]与a[2]为同一个数组元素*(q-2)与q[-2]都是a[0]3.下标法表示与指针法表示的等价性
变量定义语句
inta[5],*p=a,*q=a+2;表达式含义
apq下标指针下标指针下标指针数值第1个元素
a[0]
*ap[0]
*pq[-2]
*(q-2)第3个元素a[2]
*(a+2)
p[2]
*(p+2)
q[0]*q指针指向第1个
&a[0]
a&p[0]
p&q[-2]
q-2指向第3个
&a[2]
a+2
&p[2]
p+2&q[0]q等
价
性
x[i]与*(x+i)等价
&x[i]与x+i等价
7.3.4程序举例
【例7.3】使用指针法输入5个整数,计算并输出平均值。#defineN5/*下标法*/main(){inta[N],i,s;for(i=0;i<N;i++)
scanf("%d",&a[i]);for(s=0,i=0;i<N;i++)s+=a[i];
printf("%f\n",(float)s/N);}/*指针法*/#defineN5main(){inta[N],i,s,*p;for(p=a;p<a+N;p++)
scanf("%d",p);for(s=0,p=a;p<a+N;p++)s+=*p;
printf("%f\n",(float)s/N);}例:写出下列程序的输出结果。#include"stdio.h"main(){voidfun(int*,int,int);
inti,s[]={0,1,2,3,4,5};fun(s,0,3);fun(s,2,5);for(i=0;i<6;i++)
printf("s[%d]=%d",i,s[i]);}voidfun(int*a,int
n,intm){intt;while(n<m){t=*(a+n);*(a+n)=*(a+m);*(a+m)=t;n++;m--;}}运行结果:s[0]=3s[1]=2s[2]=5s[3]=4s[4]=0s[5]=17.4指针与函数
7.4.1指针作为函数参数
1.传递单个变量指针将单个变量的指针传递给函数往往是为了让函数能通过该指针反过来修改主调函数的变量值例如:scanf("%d",&n);
主调函数将变量n的指针(&n)传递给scanf函数,
scanf函数将键盘上输入的数值通过该指针存到主调函数的变量n中。【例7.4】编写函数,使得能交换二个变量的值。voidswap(int*p1,int*p2){intt;t=*p1;*p1=*p2;*p2=t;}main(){intx,y;
scanf("%d%d",&x,&y);swap(&x,&y);
printf("x=%d,y=%d\n",x,y);}2.传递数组传递数组传递的其实是数组的首地址
【例7.5】编写函数,使用冒泡法对数组从小到大排序。voidswap(int*p1,int*p2){intt;t=*p1;*p1=*p2;*p2=t;}voidsort(inta[],intn){inti,j;for(i=0;i<n-1;i++)for(j=0;j<n-1-i;j++)if(a[j]>a[j+1])swap(&a[j],&a[j+1]);}main(){intx[10],i;for(i=0;i<10;i++)
scanf("%d",&x[i]);sort(x,10);for(i=0;i<10;i++)
printf("%d",x[i]);
printf("\n");}7.4.2指针做为函数返回类型
【例7.6】编写函数,在一个已从小到大排序的数组中查找一个指定的数,如果找到,返回指向数组中该数的指针,否则返回空指针。int*find(int*a,intn,intdata)/*数组a长度n待查数data*/{int*p=a,*q=a+n,*r;while(p<q)/*待查找区不为空时*/{r=p+(q-p)/2;/*待查找区的中点位置*/if(*r==data)returnr;/*如找到,返回该指针*/elseif(*r<data)p=r+1;/*比中点大,在后半区*/elseq=r-1;/*比中点小,在前半区*/}returnNULL;/*没找到,返回空指针*/}main(){intx[]={11,22,33,44,55,66,77,88,99,100},d,*p;
scanf("%d",&d);/*输入要查找的数*/p=find(x,10,d);/*调用查找,结果赋值给p*/if(p!=NULL)/*判断是否找到数*/
printf("Foundat%d\n",p-x);/*找到,输出下标*/else
printf("NotFound.\n");/*没找到*/}7.4.3动态内存分配与释放函数
在处理实际问题时,常会遇到数组的大小要在程序执行中才能确定的情况,合理的方法是在程序中再决定数组的大小。
C语言提供了动态存储分配函数,可在程序运行过程中,动态分配内存区供数据存储,可根据需要指定大小,以及不需时予以释放。
下面介绍动态存储分配函数中的malloc()和free(),在stdlib.h和alloc.h头文件中均含有它们的原型。•内存分配函数malloc()
原型:void*malloc(unsignedsize);
功能:内存中分配一块连续的size个字节的未初始化的存储区。返回一指向该区首址的void*
类型(称通用型或无类型)指针,须按实际需要的数据类型进行强制转换,才能赋值给相应的指针变量。如无法分配,则返回空指针•内存释放函数free()
原型:void*free(void*buffer);
功能:释放buffer所指向的由malloc()等内存分配函数所分配的内存块。【例7.7】输入n和n个整数,输出其中不重复出现的整数,要求:只要内存容量许可,不对n的上限做明显的限定。#include<stdlib.h>main(){int*p,n,i,j,ct;
scanf("%d",&n);p=(int*)malloc(n*sizeof(int));if(p==NULL){printf("Thereisnotenoughmemory.\n");return-1;}
for(i=0;i<n;i++)
scanf("%d",&p[i]);for(i=0;i<n;i++){for(ct=0,j=0;j<n;j++)if(p[i]==p[j])ct++;if(ct==1)
printf("%d\t",p[i]);}free(p);
printf("\n");}运行结果:输入:811335115544100输出:33441007.4.4函数指针
1.函数指针的定义和使用
•函数指针的概念
函数名具有类似数组名的地址特性:数组名—该数组的首地址函数名—该函数的入口地址一个函数作为一段程序,在内存中占据一片连续的存储单元,其中第一条执行指令所在的位置称为函数的入口地址,取值为函数入口地址的指针变量,称为指向函数的指针变量,简称函数指针。通过该指针可以调用并执行函数。
•函数指针的定义格式
函数值类型(*函数指针变量名)
(参数说明表);
参数说明表中可只说明形参类型,而无形参本身。
如省略参数说明表,系统不检查参数传递正确性;例如:有函数说明:int
max(int,int),abs(int);
如要定义一个用来指向max函数的指针变量,则可定义如下:
int(*p)(int,int);或int(*p)();
•函数指针的使用
给函数指针变量赋值时,只需给出函数名而不必(也不能)给出参数。如:
inta,b,c,max(int,int),(*p)();
p=max;/*p为函数指针变量,max为函数名*/
函数可通过函数名调用,也可通过函数指针调用,
如上例后,只需用(*p)代替函数名max即可。如:
c=max(a,b);/*通过函数名调用*/c=(*p)(a,b);/*通过函数指针调用*/
对函数指针变量,象p+i、p++、p--等运算无意义。2.函数指针做函数的参数
【例7.8】求三角函数sin(),cos()和tan()在10度,
20度,30度,40度和50度时的数值。#include<math.h>voidprintvalue(double(*fun)(double),intn){inti;for(i=1;i<=n;i++)
printf("%d\t%lf\n",i*10,(*fun)(3.14159*i/18));}main(){printvalue(sin,5);printvalue(cos,5);
printvalue(tan,5);}3.函数指针数组函数指针可以组成指针数组,称为函数指针数组,该数组的元素都是函数指针。定义格式:
数据类型(*函数指针数组名[常量表达式])()
其中常量表达式的值表示函数指针数组的长度。例:用循环语句for,while,do-while和if-goto编制计算的函数,并验证其正确性。要求用函数指针数组longsum1(intn){inti;longsum=0;for(i=1;i<=n;i++)sum+=i;returnsum;}longsum2(intn){inti=0;longsum=0;while(++i<=n)sum+=i;returnsum;}longsum3(intn){inti=0;longsum=0;dosum+=i;while(i++<=n);returnsum;}longsum4(intn){inti=0;longsum=0;ss:sum+=i;if(i++<=n)goto
ss;returnsum;}main(){long(*f[4])(),k;
inti,n;
printf("\ninputanumber:");
scanf("%d",&n);f[0]=sum1;f[1]=sum2;f[2]=sum3;f[3]=sum4;k=(*f[0])(n);for(i=1;i<4;i++)if(k!=(*f[i])(n)){k=-1;break;}if(k==-1)printf("Error!");elseprintf("Right.sum=%ld",k);}7.5指针数组、多级指针与
指向一维数组的指针7.5.1指针数组与多级指针1.指针的数组
•一个数组的元素的都为指针类型数据,称为指针数组
•定义格式:
数据类型*指针数组名[常量表达式]
其中常量表达式的值表示数组的元素个数。例:int*b[3];
指针数组b的每个元素相当于可以指向一般整型变量,也可以指向整型数组元素的指针变量。2.多级指针
•指针变量中可以保存另一个指针的地址,变成
“指向指针的指针”,称为多级指针。例如:有指针数组name,其元素是指向一般数据的指针。令指针变量p=name,p指向指针数组name。
则称指针变量p为二级指针。如有指针变量pp再指向p,则称pp为三级指针。
•多级指针的定义二级指针的定义形式:数据类型**指针名三级指针的定义形式:数据类型***指针名从上可知,n级指针定义时,指针名前应加n个*。3.
数据的访问如有:intx[3],y,z[2],*pa[3],**p2;pa[0]=x;pa[1]=&y;pa[2]=z;p2=pa;
则层次关系为:则有(每行等价):*(*(p2+0)+j)p2[0][j]*(pa[0]+j)pa[0][j]x[j]*(*(p2+1))
p2[1][0]*pa[1]pa[1][0]y*(*(p2+2)+j)p2[2][j]*(pa[2]+j)pa[2][j]z[j]yx[2]x[1]x[0]z[0]z[1]p2pa[1]pa[0]pa[2]例:将8个字符串按词典顺序排列。⑴用二维数组#include"string.h"#defineSIZE8main(){charname[SIZE][10]={"constant","pointer","function","variable","address","structue","union","array"};
inti,j,k;chartemp[10];
for(i=0;i<SIZE-1;i++)/*选择法排序*/ {k=i; for(j=i+1;j<SIZE;j++)
if(strcmp(name[k],name[j])>0)k=j;if(k!=i){strcpy(temp,name[k]);
strcpy(name[k],name[i]);
strcpy(name[i],temp);}}for(i=0;i<SIZE;i++)
printf("%s\n",name[i]);}⑵用指针数组#include"string.h"#defineSIZE8main(){ char*name[SIZE]={"constant","pointer","function","variable","address","structue","union","array"};
inti,j,k;char*temp;
for(i=0;i<SIZE-1;i++)/*选择法排序*/ {k=i; for(j=i+1;j<SIZE;j++)
if(strcmp(name[k],name[j])>0)k=j;if(k!=i){temp=name[k];name[k]=name[i];name[i]=temp;}}for(i=0;i<SIZE;i++)
printf("%s\n",name[i]);}⑶用二级指针#include"string.h"#defineSIZE8main(){ char*name[SIZE]={"constant","pointer","function","variable","address","structue","union","array"};
inti,j,k;char*temp,**p;
p=name;for(i=0;i<SIZE-1;i++)/*选择法排序*/ {k=i; for(j=i+1;j<SIZE;j++)
if(strcmp(*(p+k),*(p+j))>0)k=j;if(k!=i)/*原name[k],name[j]*/{temp=*(p+k);/*原name[k]*/
*(p+k)=*(p+i);/*原name[k]=name[i]*/
*(p+i)=temp;/*原name[i]*/}}for(i=0;i<SIZE;i++)
printf("%s",*(p++));}/*原name[i]*/7.5.2二维数组与
指向一维数组的指针1.二维数组的内存安排
二维数组各元按行连续存放在一块内存区域2.将二维数组看成是二重一维数组构成的数组如有定义:inta[3][4];
第一重有3个一维数组:a[0]、a[1]和a[2],每个一维数组分别包含4个元素;
第二重一维数组为数组a,它包含a[0]、a[1]和
a[2]共3个元素;第一重对应二维数组中第二维的下标第二重对应二维数组中第一维的下标3.二维数组的指针法表示a[1][0]a[0][2]a[0][1]a[0][0]a[2][0]aa[1]a[0]a[2]a[0][3]a[1][1]a[1][2]a[1][3]a[2][1]a[2][2]a[2][3]二维数据,3个一维数组,第一重虚拟的指针数组第二重虚拟的二级指针,指向一维数组的指针
•a[0]、a[1]、a[2]作为一维数组名是地址常量,有:
a[i]+j与&a[i][j]
等价*(a[i]+j)与a[i][j]等价
•二维数组a可以看成由三个元素(一维数组名)
a[0]、a[1]、a[2]组成,因而就有:
a+i与&a[i]与a[i]指向同一地址
•基于a+i与&a[i]指向同一地址,可得出:*(a+i)与a[i]等价*(a+i)+j与&a[i][j]指向同一地址*(*(a+i)+j)与a[i][j]等价综上所述,在二维数组a中:
a+i=a[i]=*(a+i)=&a[i]=&a[i][0]
(地址值相等)
a=a[0]=*(a+0)=*a=&a[0]=&a[0][0]
(地址值相等)
a[i]+j=*(a+i)+j=&a[i][j]
(地址值相等)
*(a[i]+j)=*(*(a+i)+j)=(*(a+i))[j]=a[i][j](同一元素值)4.指向一维数组的指针
•用inta[3][4];定义的二维数组名a指向一维数组
a[0]的第1个元素,a+1指向一维数组a[1]的第1个元素,…a+i指向一维数组a[i]的第1个元素,即a指向的变化是以行为单位的。这类特殊的指针称为指向一维数组的指针。
•指向一维数组的指针变量的定义格式
数据类型(*指针变量名)[常量表达式]
其中常量表达式的值等于所指向的一维数组的元素个数。例1:建立一个3×4的矩阵,使各元素的值为1~12的整数。要求使用指向一维数组的指针。main(){inti,j,k=1,a[3][4],(*pa)[4]=a;for(i=0;i<3;i++)for(j=0;j<4;j++)
*(*(pa+i)+j)=k++;/**(*(pa+i)+j)
表示
a[i][j]
*//*或
*(pa[i]+j)
或
(*(pa+i))[j]
或
pa[i][j]*/for(;pa<a+3;pa++)for(j=0;j<4;j++)
printf("%d",*(*pa+j));}例2:设有以下定义语句:
inta[3][2]={10,20,30,40,50,60},(*p)[2];p=a;
则*(*(p+2)+1)的值为______。607.5.3二维数据的构造举例
【例7.9】构造一个数据结构,它能表示一个年级所有学生的成绩(只考虑一门课程,成绩使用int类型表示),设年级共有4个班,一班50人,二班30人,三班60人,四班40人。
1.使用二维数组和指向一维数组的指针
/*二维数组,最多4个班,每班最多60个学生*/
intstu[4][60];/*指向一维数组的指针,每行60个整型数,指向二维数组*/
int(*p1stu)[60]=stu;
2.在二维数组基础上的指针数组与二级指针
/*二维数组,最多4个班,每班最多60个学生*/
intstu[4][60];/*指针数组指向二维数组的4个不同的行*/
int*pastu[4]={stu[0],stu[1],stu[2],stu[3]};/*再在指针数组的基础上构造二级指针*/
int**p2stu=pastu;3.在多个一维数组基础上的指针数组与二级指针
/*定义多个一维数组,一班有50个学生,二班有30个学生
,
三班有60个学生,四班有40个学生*/
intstu1[50],stu2[30],stu3[60],stu4[40];
/*在这4个一维数组的基础上构造指针数组*/
int*pastu[4]={stu1,stu2,stu3,stu4};/*再构造一个二级指针变量将所有有信息归结到一个单
一变量*/
int**p2stu=pastu;4.访问学生成绩访问第i个班第j个学生(i和j从0开始取值)的成绩,可以使用以下表达式:
stu[i][j]/*二维数组,下标+下标表示法*/(*(p1stu+i))[j]/*指向一维数组的指针,指针+下标*/*(pastu[i]+j)/*指针数组,下标+指针表示法*/*(*(p2stu+i)+j)/*二级指针,指针+指针表示法*/为了简化格式,避免书写的错误,可以统一使用二重下标法,如下所示:
stu[i][j]/*二维数组*/p1stu[i][j]/*指向一维数组的指针*/
pastu[i][j]/*指针数组*/p2stu[i][j]/*二级指针*/7.6指针与字符串7.6.1字符串的内存安排1.字符数组的初始化2.字符数组的输入
chara[10]="Hello!"chara[10];gets(a);'H''e''!''l''l''o''\0'0000x20000x20010x20020x20030x20040x20050x20060x20070x20080x2009地址内存变量a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]'H''e''!''l''l''o''\0'???0x20000x20010x20020x20030x20040x20050x20060x20070x20080x2009地址内存变量a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]3.字符串常量和字符指针的初始化
char*p="Hello!";'H''e''!''l''l''o''\0'?0x20100x20100x20110x20120x20130x20140x20150x20160x2017…0x2020地址内存变量pp7.6.2字符串处理程序举例
【例7.10】编程,输入一行字符,将其中以一个或多个空格分开的子串称为单词,将奇数位置的单词转换为大写,偶数位置的单词保持不变,所有单词重新组织后输出,输出时单词之间使用"---"连接,行首以"[B]"开始,行尾以"[E]"结束。例如,输入(符号
表示空格):
how
are
you?
*#@-aBc-123-$$$
则输出:[B]HOW---are---YOU?---*#@-aBc-123-$$$[E]#include<stdio.h>#include<string.h>/*字符串转换为大写函数*/char*toucase(char*str){char*p;for(p=str;*p!='\0';p++)if(*p>='a'&&*p<='z')*p=*p-'a'+'A';returnstr;}/*从字符串中取出下一个单词*/char*getnextword(char*str,char*word){char*p;for(p=str;*p=='';p++);/*过滤前导的空格*/
/*循环至单词结束*/for(;*p!=''&&*p!='\0';p++,word++)*word=*p;/*复制单词*/*word='\0';/*单词结束*/for(;*p=='';p++);/*过滤单词尾部空格*/returnp;/*返回下一个非空格的位置*/}main(){charstra[81],strb[81],word[81],*p=stra;intn=0;gets(stra);
strcpy(strb,"[B]");/*产生行首子串*/while(*p!='\0')
{p=getnextword(p,word);/*取出下一个单词*/if(n!=0)strcat(strb,"---");/*加连接子串*/if(n%2!=0)strcat(strb,word);/*直接拼接*/elsestrcat(strb,toucase(word));/*先大写再拼接*/n++;/*单词个数统计*/
}
strcat(strb,"[E]");/*拼接行尾子串*/puts(strb);}例:下面程序的输出结果是__________。charb[]="ABCD";main(){char*chp;
for(chp=b;*chp;chp+=2)
printf("%s",chp);
printf("\n");}ABCDCD7.6.3多字符串的表示与处理
多字符串实际上就是二维的字符数据,可以采用二维的字符数组,也可以采用字符的指针数组形式表示,或者二者结合。【例7.11】编程,输入一行字符,将其中的单词按逆顺序输出,例如,输入(符号
表示空格):
how
are
you?
*#@-aBc-123-$$$
则输出:*#@-aBc-123-$$$ you? are how#defineMAXN 40int
getallwords(char*str,char*pp[],int
maxn){char*p;intn;p=str;n=0;while(*p!='\0'){p=getnextword(p,pp[n]);/*分离出第n个单词*/if(pp[n][0]!='\0')n++;if(n>=maxn)break;}returnn;}main(){charstra[81],words[MAXN][81],*pa[MAXN];
inti,n;gets(stra);for(i=0;i<MAXN;i++)pa[i]=words[i];n=getallwords(stra,pa,MAXN);for(i=n-1;i>=0;i--)
printf("%s\t",words[i]);
printf("\n");}7.6.4程序举例
例1:编写函数,把字符串t接在字符串s之后,返回新字符串首地址。char*strjion(char*s,char*t){char*p;p=s;/*保存s
*/
while(*s)s++;/*找字符串s末尾*/
while(*s++=*t++);/*连接
*/returnp;
/*返回指向连接后新字符串的指针*/}例2:从键盘输入两个字符串,不使用库函数strcmp()
来比较它们的大小,若相等,则输出:“Bothequal.”,否则输出其中较大者。main(){chara[80],b[80],*p,*q;gets(a);gets(b);for(p=a,q=b;*p&&*q&&*p==*q;p++,q++);if(*p>*q)puts(a);elseif(*p<*q)puts(b);elseif(*p=='\0'&&*q=='\0')puts("Bothequal.");}
例3:编一个程序,输入一个字符串,内容依次是学号(位数不定)和姓名的汉语拼音码。经处理后,输出一个字符串,内容依次为,姓名,两个*号和学号。main()/*(1)不使用库函数*/{chara[40],b[40],*p=a,*q=b,*r;gets(a);/*定位姓名的首字符位置*/while(*p>='0'&&*p<='9')p++;r=p;/*记存姓名的首字符位置*/while(*q++=*p++);/*将姓名放入数组b*/*(q-1)='*';/*数组b中尾随姓名的'\0'
改为'*'
*/
*q++='*';/*数组b中再加一
'*'
*/*r='\0';/*使a数组的学号尾随'\0'*/p=a;while(*q++=*p++);/*将学号放入数组b的'*'
之后*/puts(b);}#include"string.h"/*(2)使用库函数*/main(){chara[40],b[40],*p;gets(a);/*定位姓名的首字符位置*/for(p=a;p>='0'&&*p<='9';p++);
strcpy(b,p);/*将姓名复制到数组b*/
strcat(b,"**");/*数组b中姓名后加两个
'*'
*/*p='\0';/*使a数组的学号尾随'\0'*/
strcat(b,a);/*将学号放入数组b中**
之后*/
puts(b)例4:编程,将字符串s中所有t子串用q子串替换后输出,s、t和q字符串从键盘输入。#include"stdio.h"#include
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年物流园区配套设施租赁合同范本3篇
- 2025年度动画设计个人聘用合同范本3篇
- 二零二五年荒山资源开发合作合同书范本3篇
- 2025年送餐服务与外卖配送智能化改造合作协议范本3篇
- 2025年度智能车展场地租赁及环保回收利用合同4篇
- 2025年新型屋顶盖瓦施工安全监管协议3篇
- 2025年物业股权抵押担保协议范本3篇
- 2025版城市绿化工程承包合同示范文本4篇
- 2025年度环保项目个人环境监测服务合同样本4篇
- 2025版美容院与美甲美睫培训机构合作协议4篇
- 桥梁监测监控实施方案
- 书籍小兵张嘎课件
- 艺术哲学:美是如何诞生的学习通超星期末考试答案章节答案2024年
- 北京海淀区2025届高三下第一次模拟语文试题含解析
- 量子医学治疗学行业投资机会分析与策略研究报告
- 多重耐药菌病人的管理-(1)课件
- (高清版)TDT 1056-2019 县级国土资源调查生产成本定额
- 环境监测对环境保护的意义
- 2023年数学竞赛AMC8试卷(含答案)
- 神经外科课件:神经外科急重症
- 2023年十天突破公务员面试
评论
0/150
提交评论