练习题8及参考答案
1. 单项选择题
(1)有以下定义和赋值语句中,正确的是 。
A. static char str[8]="Good morning"; B. char str[20];str="Good morning";
C. char *p="Good morning"; D. char *p;*p="Good morning";
【答】选项在定义字符指针变量的同时初始化为指向字符串常量的第一个字符。本题答案为C。
(2)已知变量a已定义为int型变量,以下定义并初始化指针变量p的语句中正确的是 。
A. int *p=a; B. int *p=*a; C. int p=&a; D. int *p=&a;
【答】D
(3)以下叙述正确的是 。
A. 数组名实际上是此数组的首地址,所以数组名相当于一个指针变量
B. 若定义数组 a[2][3],则a+1和*(a+1)完全相等
C. 若定义数组 a[2][3],则++a和a[1]完全等价
D. 某函数的形参为一个数组,则调用此函数时只能将数组名作为对应的实参
【答】选项A是错误的,数组名的确是数组的首地址,但它的值是一个常量,不可改变;选项B是正确的,在二维数组中,若a为数组名,则a+i和*(a+i)同样表示此数组第i行的首地址,所以完全相等,参见《C程序设计教程》的表8.1;选项C是错误的,数组名是数组的首地址,是一个常量,不能执行++运算;选项D是错误的,某函数的形参为一个数组,调用此函数时可将数组名作为对应的实参,也可以将相应的指针变量作为对应的实参。本题答案为B。
(4)有这样的定义float *p[4];则下面的叙述中正确的是 。
A. 此定义不正确,形如char *p[4];的定义才是正确的
B. 此定义正确,p是指向一维实型数组的指针变量,而不是指向单个实型变量的指针变量
C. 此定义不正确,C语言中不允许类似的定义
D. 此定义正确,定义了一个指针数组
【答】其中正确答案为D。该语句中,“[]”的优先级最高,所以p是一个数组,其次是float *,进一步表示p数组中每个元素为指向float型数的指针。
(5)若有以下定义语句:
static int a[2][3]={1,3,5,7,9,11};
int m,n;
且0≤m≤1,0≤n≤2,则 是对数组元素的正确引用。
A. a[m]+n B. *(a+5) C. *(*(a+m)+3) D. *(*(a+m)+n)
【答】*(*(a+m)+n)等价于a[m][n]。本题答案为D。
(6)有如下函数:
fun(int *p1,int *p2)
{
int *p;
*p=*p1;
*p1=*p2;
*p2=*p;
}
其功能为 。
A. 正确,但无法改变*p1和*p2的值 B. 能够成功交换*p1和*p2的值
C. 能够成功交换*p1和*p2的地址 D. 能够成功交换p1和p2的值
【答】该函数交换了*p1和*p2的值,若以fun(&a,&b);语句调用该函数,则交换了a和b的
值。本题答案为B。
(7)下面各语句行中,能正确进行字符串赋值操作的是 。
A. char st[4][5]={"ABCDE"}; B. char s[5]={'A','B','C','D','E'};
C. char *s;s="ABCDE"; D. char *s;scanf("%s",s);
【答】首先可以排除选项A,因其形式不对。也可以排除选项B,因为字符数组的长度不够,没有考虑字符串结束符。选项D也是错误的,其错误的原因是:在这两条语句中,只确定了指针变量p本身在内存中的地址,但p所指的值没有确定。所以,只有选项C是正确的,C语言中规定可以给字符指针单独赋值。本题答案为C。
(8)执行以下程序段后,m的值为 。
static int a[2][3]={1,2,3,4,5,6};
int m,*ptr=&a[0][0];
m=(*ptr)*(*ptr+2)*(*ptr+4);
A. 15 B. 48 C. 24 D. 无定值
【答】*ptr=1,*ptr+2=3,*ptr+4=5,m=1*3*5=15。本题答案为A。
(9)设有定义:
static a[4][3]={1,2,3,4,5,6,7,8,9,10,11,12};
int (*prt)[3]=a,*p=a[0];
则以下能够正确表示数组元素a[1][2]的表达式是 。
A. *((*prt+1)[2]) B. (2)*(*(p+5)) C. (*prt+1)+2 D. *(*(a+1)+2)
【答】a是一个二维数组。int (*prt)[3]=a定义中,由于有括号,“*”优先级高,即prt是一个指针,后面有“[3]”,表示prt是一个包含三个元素的数组的指针。int *p=a[0]的初始化中,表示p是一个整数指针变量,指向a数组的第一行的第一个元素即a[0][0]。
用prt表示a[1][2]的各种方式如下:
*(prt[1]+2)
*(*(prt+1)+2)
(*(prt+1))[2]
prt[1][2]
再看以上各种表达式:
选项A、C显然是错误的;选项B中,p+5指向a[0][5],执行两次“*”肯定是错误的;选项D是正确的,因为a是常量,是数组的首地址,*(a+1)指向第二行, *(*(a+1)+2)表示第二行的第三个元素,即a[1][2]。本题答案为D。
(10)若有定义char s[3][4];以下对数组元素s[i][j]的各种引用形式中正确的是 。
A.*(s+i)[j] B.*(&s[0][0]+4*i+j) C.*((s+i)+j) D.*(*(s+i)[j])
【答】选项A是错误的,*(s+i)[j]表达式中,运算符[]的优先级最高,故此表达式相当于*(*(s+i+j)),显然这是此数组第i+ j行的第 0个元素的值,而不是s[i][j];选项B是正确的,*(&s[0][0]+4*i+j)是直接使用偏移量法来引用数组元素,根据二维数组在内存中的行优先顺序存放规则,*(&s[0][0]+4*i+j)等价于s[i][j];选项C是错误的,*((s+i)+j)等价于*(s+i+j),是数组第i+j行首地址;选项D是错误的,*(*(s+i)[j])等价于***(s+i+j),是错误的表达方式。本题答案为B。
(11)有如下程序:
#include
main()
{
static int a[3][4]={1,2,3,4,5,6,7,8};
int (*p)[4]=a;
printf("%d\n",*(p+1)[1]);
}
则下列说法中正确的是 。
A. 输出结果为:0
B. 输出结果为:6
C. 输出结果为:0,6
D. 将输出数据元素的地址而不是数据元素的值
【答】程序中先给静态数组a的前两行元素赋了初值,第三行元素取默认值0。在语句int (*p)[4]=a;中,定义了一个二维数组指针,并将a的首地址赋给它。在表达式*(p+1)[1]中,[]的优先级最高,*(p+1)[1]等价于*(*(p+1+1))=*(*(p+2)),即为a数组第三行的第一个元素。所以输出为0。因此,只有A是正确的。
(12)以下程序的运行结果是 。
#include
main()
{
static int a[]={5,3,7,2,1,5,4,10};
int s=0,k;
for (k=0;k<8;k+=2)
s+=*(a+k);
printf("%d\n",s);
}
A. 17 B. 27 C. 13 D. 无定值
【答】A
(13)以下程序的运行结果是 。
#include
main()
{
int a[]={1,2,3,4,5,6};
int x,y,*p;
p=&a[0];
x=*(p+2);
y=*(p+4);
printf("%d,%d,%d\n",*p,x,y);
}
A. 1,3,5 B. 2,4,6 C. 1,1,1 D. 3,3,3
【答】A
(14)以下程序的运行结果是 。
#include
main()
{
int a[]={1,2,3,4,5,6};
int *p=a;
printf("%d,",*p);
printf("%d,",*(++p));
printf("%d,",*++p);
printf("%d,",*(p--));
p+=3;
printf("%d,%d\n",*p,*(a+3));
}
A. 1,2,3,3,2,1 B. 1,2,3,3,5,4 C. 1,3,5,3,3,3 D. 1,3,5,5,3,1
【答】B
(15)以下程序的运行结果是 。
#include
main()
{
char str[2][5]={"7045","9265"},*a[2];
int i,j,s=0;
for (i=0;i<2;i++)
a[i]=str[i];
for (i=0;i<2;i++)
for (j=0;a[i][j]>'0' && a[i][j]<='9';j+=2)
s=10*s+a[i][j]-'0';
printf("%d\n",s);
}
A. 7496 B. 70936 C. 74936 D. 704936
【答】A
(16)以下程序的运行结果是 。
#include
main()
{
static char c[]="china";
char *p=c;
while (*p)
printf("%c",*p++-32);
printf("\n");
}
A. china B. CHINA C. ch D. 陷入死循环
【答】B
(17)以下程序的运行结果是 。
#include
main()
{
char *pp[2][3]={"abc","defgh","ijkl","mnopqr","stuvw","xyz"};
printf("%c",***(pp+1));
printf("%c",**pp[0]);
printf("%c",(*(*(pp+1)+1))[4]);
printf("%c",*(pp[1][2]+2));
printf(",%s\n",**(pp+1));
}
A. mawz,defgh B. mawz,mnopqr C. adim,defgh D. adim,mnopqr
【答】B
(18)以下
程序的运行结果是 。
#include
int fun(int x,int y)
{
return(y-x);
}
main()
{
int a=5,b=6,c=2;
int (*g)(int,int);
g=fun;
c=(*g)(a,b);
printf("%d\n",c);
}
A. 1 B. 2 C. 3 D. 以上都不对
【答】A
2. 填空题
(1)有以下定义:
char s[3]="AB";
char *p;
在执行了语句p=s;之后,*(p+2)的值是 。
【答】字符数组s长度为2,但在内存中占有3个字节,第3个字节是字符串结束符'\0',所以*(p+2)的值是'\0'。
(2)以下程序的运行结果是 。
#include
main()
{
int a[4]={0,1,2,3},*p;
p=&a[2];
printf("%d\n",*--p);
}
【答】p指向a[2],对于表达式*--p,先计算--p,返回a[1]的指针,再计算*运行,返回a[1]。本题答案为:1。
(3)以下程序的运行结果是 。
#include
main()
{
static char s[]={"abcdef"};
char *p=s;
*(p+2)+=3;
printf("%c,%c\n",*p,*(p+2));
}
【答】执行语句char *p=s;后,指针p将指向数组s的起始地址;再执行*(p+2)+=3;,将数组元素s[2]的值增加 3,s[2]的值由'c'变为'f',指针 p自身的值并未改变,依然指向数组s的始址,此时执行printf("%c,%c\n",*p,*(p+2));将输出字符s[0]和s[2],即'a'和'f'。本题答案为:a,f
(4)以下程序的运行结果是 。
#include
main()
{
static int a[]={1,3,4,5,7,8};
int y,x,*ptr;
y=1;
ptr=&a[1];
for (x=0;x<3;x++)
y*=*(ptr+x);
printf("%d\n",y);
}
【答】整型指针变量ptr指向整型数组a第2个元素存放的地址位置,即*ptr=3,执行循环y的值即为3*4*5=60。本题答案为:60。
(5)以下程序的运行结果是 。
#include
main()
{
static char s[]="Program",*ptr;
for (ptr=s;ptr
putchar(*ptr);
putchar('\n');
}
【答】Porm
(6)以下程序的运行结果是 。
#include
main()
{
char *p="abcdefghijklmnopq";
while (*p++!='e')
printf("%c",*p);
printf("\n");
}
【答】bcde
(7)以下程序的运行结果是 。
#include
main()
{
int m[12],k;
int *p[3],sum=0;
for (k=0;k<12;k++)
{
m[k]=2*k;
if (k<3)
p[k]=m+2*k*k;
}
for (k=0;k<3;k++)
sum+=(*(p+k))[4-k];
printf("sum=%d\n",sum);
}
【答】数组p为一个指针数组,在使用第一个for循环进行赋值以后,p中各指针的指向分别是:p[0]指向m[0],p[1]指向m[2],p[2]指向m[8]。表达式(*(p+k))[4-k]等价于p[k][4-k],当k=0时,即为m[4],k=1时,即为m[5],k=2时,即为 m[10]。
本题答案为:sum=38。
(8)以下程序的运行结果是 。
#include
main()
{
int **k,*j,i=100;
j=&i;
k=&j;
printf("%d\n",**k);
}
【答】本程序中,执行语句j=&i;k=&j;之后,j的值是i的地址,k的值是j的地址,经过两次取内容操作,**k的值就是变量i的值0。本题答案为:100。
(9)以下程序的运行结果是 。
#include
void g(int **p);
main()
{ int line[100],i;
int *p=line;
for (i=0;i<100;i++)
{ *p=i;
g(&p);
}
for (i=0;i<100;i++)
printf("%d ",line[i]);
printf("\n");
}
void g(int **p)
{
(*(*p))++;
(*p)++;
}
【答】在本程序中添加相应的注释,用于说明程序设计思路。
main()
{
int line[100],i;
int *p=line; /*p是line数组的指针,此时p=line的首地址*/
for (i=0;i<100;i++)
{
*p=i; /*p所指向的值设为i,即line[0]=0,…*/
g(&p); /*p为line数组指针的指针,即line[i]指针的地址*/
}
for (i=0;i<100;i++)
printf("%d ",line[i]);
printf("\n");
}
void g(int **p) /*p为二级指针,调用时p为line[i]指针的地址*/
{
(*(*p))++; /*p所指的变量值增1,即将line[i]之值增1*/
(*p)++; /*p为line[i+1]指针的地址,对执行结果无影响*/
}
本程序的运行结果是:1 2 3 … 100。
(10)以下程序的运行结果是 。
#include
main()
{
static int a[]={1,3,5,7};
int *p[3]={a+2,a+1,a};
int **q=p;
printf("%d\n",*(p[0]+1)+**(q+2));
}
【答】指针数组p有3个元素,分别指向数组a的第3、2、1个元素。二级指针q指向指针数组p,则p[0]指向a[2],p[0]+1指向a[3],*(p[0]+1)=7;q指向p,q+2指向p[2],*(p[2])指向a[0],**(p[2])=1。本题答案为:8。
(11)以下程序的运行结果是 。
#include
main()
{
int a[3][2]={1,2,3,4,5,6},(*p)[2];
p=a;
printf("%d,%d,%d,%d\n",*(p[2]+1),*(*(p+2)+1),(*(p+2))[1],
p[2][1]);
}
【答】*(p[2]+1),*(*(p+2)+1),(*(p+2))[1],p[2][1]都对应a[2][3]即6。本题答案为:6,6,6,6。
(12)以下程序的运行结果是 。
#include
main()
{
int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
int (*p)[4]=a,i,j,k=0;
for (i=0;i<3;i++)
for (j=0;j<2;j++)
k+=*(*(p+i)+j);
printf("%d\n",k);
}
【答】*(*(p+i)+j)等价于a[i][j],k=1+3+9+11+17+19=60。本题答案为:60。
(13)以下程序的运行结果是 。
#include
int a[5]={0,1,2,3,4};
int *p[5]={a,a+1,a+2,a+3,a+4};
int **pp=p;
main()
{ pp++;
printf("%d,%d,%d\n",pp-p,*pp-a,**pp);
*pp++;
printf("%d,%d,%d\n",pp-p,*pp-a,
**pp);
*++pp;
printf("%d,%d,%d\n",pp-p,*pp-a,**pp);
++*pp;
printf("%d,%d,%d\n",pp-p,*pp-a,**pp);
pp=p;
printf("%d,%d,%d\n",pp-p,*pp-a,**pp);
**pp++;
printf("%d,%d,%d\n",pp-p,*pp-a,**pp);
*++*pp;
printf("%d,%d,%d\n",pp-p,*pp-a,**pp);
++**pp;
printf("%d,%d,%d\n",pp-p,*pp-a,**pp);
}
【答】pp先指向p[0],pp++之后pp指向p[1],故pp-p=1,*pp-a=(a+1)-a=1,**pp=*p[1]=*(a+1)=1;对于*pp++,先执行pp++,此后pp指向p[2],故pp-p=2,*pp-a=(a+2)-a=2,**pp=*p[2]=*(a+2)=2;对于*++pp,先执行++pp,此后pp指向p[3],故pp-p=3,*pp-a=(a+3)-a=3,**pp=*p[3]=*(a+3)=3;对于++*pp,先执行*pp返回p[3],再执行++,则使得p[3]由原来指向a[3]增1变为指向a[4],故pp-p=3,*pp-a=(a+4)-a=4,**pp=*p[4]=*(a+4)=4;pp=p之后,pp重新指向p,故pp-p=0,*pp-a=a-a=0,**pp=*p[0]=*a=0;对于**pp++,先执行pp++,pp指向p[1],故pp-p=1,*pp-a=(a+1)-a=1,**pp=*p[1]=*(a+1)=1;对于*++*pp,先执行*pp,返回p[1],再执行++,则使p[1]由原来指向a[1]增1变为指向a[2], 故pp-p=1,*pp-a=(a+2)-a=2,**pp=*p[1]=*(a+2)=2;对于++**pp,先执行*pp返回p[1],再执行*,返回a[1],再执行++,则a[1]=3,故pp-p=1,*pp-a=(a+2)-a=2,**pp=*p[1]=*(a+2)=3;本题答案为:
1 1 1
2 2 2
3 3 3
3 4 4
0 0 0
1 1 1
1 2 2
1 2 3
(14)以下程序的运行结果是 。
#include
main()
{
char *c[]={"ENTER","NEW","POINT","FIRST"};
char **cp[]={c+3,c+2,c+1,c};
char ***cpp=cp;
printf("%s\n",**++cpp);
printf("%s\n",*--*++cpp+3);
printf("%s\n",*cpp[-2]+3);
printf("%s\n",cpp[-1][-1]+1);
}
【答】cpp指向cp,cp的各元素指向c的各元素。对于**++cpp,先执行++cpp使cpp指向cp[1],并返回cp[1],再执行**,则返回"POINT";对于*--*++cpp+3,先执行++cpp使cpp指向cp[2],并返回cp[2],再执行*,返回c+1,即指向c[1],再执行--,指向c[0],再+3,指向字符E,最后执行*,返回"ER";对于*cpp[-2]+3,*cpp[-2]返回cp[0],即指向c[3],再执行+3,返回"ST";对于cpp[-1][ -1]+1,当前cpp指向cp[2],cpp[-1]返回cp[1]即c[2],再执行[-1],则指向c[1],最后加1,返回"EW"。本题答案为:
POINT
ER
ST
EW
3. 编程题
(1)编写一个程序,输入一个整数,利用指针变量返回该数的绝对值。
【解】设计一个函数iabs,其参数为整数指针,返回绝对值的指针。程序如下:
/*文件名:exci8_1.cpp*/ VC++6.0
#include
int *iabs(int *p)
{
if (*p<0)
*p=-*p;
return p;
}
main()
{
int a;
printf("输入一整数:");
scanf("%d",&a);
printf("绝对值为:%d\n",*iabs(&a));
/* 调用iabs()函数后,由于是传地址调用,所以a的值变成绝对值 */
}
(2)编写一个函数,计算数
组中的最大元素及其下标,数组以指针方式传递。
【解】设计一个findmax()函数,返回数组最大值的指针,通过一个参数t返回最大值的下标。函数如下:
/*文件名:exci8_2.cpp*/ VC++6.0
int *findmax(int *p,int n,int *t)
{
int i,max;
max=*p;*t=0;
for (i=1;i
if (max<*(p+i))
{
max=*(p+i);
*t=i;
}
return (&max);
}
(3)编写一个程序,将用科学计数法输入的一个数(字符串)转换成对应的实数。
【解】科学计数法是用e指数表示的一个实数,比如1.345e-2,程序要将其转换成0.01345。转换过程是:先跳过其前的空格,考虑其符号,正数用sign=1表示,负数用sign=0表示;然后考虑整数和小数部分,产生一个实数val;跳过e或E,对于正指数,val乘以相应个数的10,对于正指数,val除以相应个数的10。最后返回val*sign。程序如下:
/*文件名:exci8_3.cpp*/ VC++6.0
#include
#include
#define MaxLen 100
double atoe(char *s);
main()
{
char *s;
s=(char *)malloc(MaxLen);
printf("输入一个数:");
gets(s);
printf("对应的数:%lf\n\n",atoe(s));
}
double atoe(char *s)
{
double val,power;
int sign,e,i;
char c;
for (;*s==' '|| *s=='\n' || *s=='\t';s++); /*跳过空格*/
sign=1;
if (*s=='+'|| *s=='-') /*数的符号处理*/
sign=(*s++=='+')?1:-1;
for (val=0;*s>='0' && *s<='9';s++) /*数字字符转换*/
val=val*10+(*s-'0');
if (*s=='.')
{ /*考虑小数部分*/
s++;
for (power=1;*s>='0'&& *s<='9';s++)
{
val=val*10+*s-'0';
power*=10;
}
val=val/power;
}
if (*s=='e'|| *s=='E') /*考虑指数部分*/
{
s++;
if (*s=='+'|| *s=='-')
c=*s++;
else
c='+';
for (e=0;*s>='0'&& *s<='9';s++)
e=e*10+(*s-'0');
if (c=='+')
for (i=e;i>0;i--)
val*=10;
else
for (i=e;i>0;i--)
val/=10;
}
return val*sign;
}
程序运行结果:
输入一个数: 123.45e-2↙
对应的数:1.234500
(5)编写一个程序,求出两个字符串:
s[]="This is C programming text"
t[]="This is a text for C programming"
包含的最长的相同单词(同一字母的大小写视为不同的字符)。规定单词全由英文字母组成,单词之间由一个或多个空格符分隔。
【解】自左向右顺序扫描字符串s,逐个找出单词(单词开始位置和单词长度),当该单
词的长度比已找到的单词更长时,就从头到尾扫描字符串t。在从t字符串中找出与该字符串长度相等、字符相同的单词后,记录下该单词的和的长度,并回到s,在其中找出下一个更长的单词。上述寻找过程直到字符串s扫描结束,最后输出找到的单词。程序如下:
/*文件名:exci8_5.cpp*/ VC++6.0
#include
#include
void maxword(char *s,char *t)
{
char *res,*temp,chs,cht;
int i,j,found,maxlen=0;
while (*s!='\0')
{
while (*s==' ') s++; /*删除s开头的空格*/
for (i=0;s[i]!=' ' && s[i]!='\0';i++); /*求s的一个单词长度*/
if (i>maxlen) /*maxlen为最大相同单词长度*/
{
chs=s[i]; /*i存储s中单词的长度*/
s[i]='\0';
temp=t;
found=0; /*若找到与当前s中单词匹配者,found为1*/
while (*temp!='\0' && !found)
{
while (*temp==' ') temp++;
for (j=0;temp[j]!=' ' && temp[j]!='\0';j++);
/*j存储t中单词的长度*/
if (j==i) /*找到了相同长度的单词*/
{
cht=temp[j];
temp[j]='\0';
if (strcmp(s,temp)==0) /*判定是否相同*/
{
maxlen=i;
res=s;
found=1;
}
temp[j]=cht; /*恢复原值*/
}
temp=&temp[j]; /*取下一个单词*/
}
s[i]=chs; /*恢复原值*/
}
s=&s[i]; /*取下一个单词*/
}
if (maxlen==0)
printf("没有相同的单词.\n");
else
{
chs=res[maxlen];
res[maxlen]='\0';
printf("%s\n",res);
res[maxlen]=chs;
}
}
main()
{
static char s[]="This is C programming text";
static char t[]="This is a text for C programming";
maxword(s,t);
}
程序运行结果:
programming
(6)编写一个程序,输入若干个字符串,采用冒泡排序法对这些字符串按词典顺序进行排序并输出。
【解】用一个指针数组pa存放字符串。然后采用冒泡排序法对这些字符串按词典顺序进行排序,对应的函数为sort。最后输出结果。程序如下:
/*文件名:exci8_6.cpp*/ VC++6.0
#include
#include
#include
#define Max 100
void sort(char *pa[],int n)
{
int i,j,exchange;
char *temp=(char *)malloc(20);
for (i=1;i<=n
-1;i++)
{
exchange=0;
for (j=n-1;j>=i;j--)
if (strcmp(pa[j],pa[j-1])<0) /*交换元素*/
{
temp=pa[j];
pa[j]=pa[j-1];
pa[j-1]=temp;
exchange=1;
}
if (!exchange)
return;
}
}
main()
{
char *pa[Max];
int n,i;
printf("串个数:");
scanf("%d",&n);
for (i=0;i
{
pa[i]=(char *)malloc(20);
printf("第%d个串:",i+1);
scanf("%s",pa[i]);
}
printf("排序前:");
for (i=0;i
printf("%s ",pa[i]);
printf("\n");
sort(pa,n);
printf("排序后:");
for (i=0;i
printf("%s ",pa[i]);
printf("\n");
}
(7)编写一个程序,在一个已排序列的字符串数组中,插入输入的一个字符串,使该数组的元素仍然有序。
【解】用指针数组pa存放字符串(与字符串数组相比其优点是可以动态分配内存空间),对于用户输入的一个字符串temp,采用二分查找法在pa中找到合适的位置i,然后将temp插入到pa的位置i即可。程序中的binary函数用于实现二分查找过程;insert函数用于实现字符串的插入过程。程序如下:
/*文件名:exci8_7.cpp*/ VC++6.0
#include
#include
#include
#define Max 20
int binary(char *pa[],char *str,int n)
{
int high=n-1,low=0,mid;
if (strcmp(str,pa[0])<0) /*若插入串比第0个串小,则插入位置为0*/
return 0;
if (strcmp(str,pa[high])>0) /*若插入串比最后串大,则插入位置为n*/
return n;
while (low<=high)
{
mid=(low+high)/2;
if (strcmp(str,pa[mid])<0)
high=mid-1;
else if (strcmp(str,pa[mid])>0)
low=mid+1;
else
return mid; /*插入串与某个串相同*/
}
return low; /*插入的位置在字符串数组中间*/
}
void insert(char *pa[],char *str,int n,int i)
/*将str插入到pa位置i处*/
{
int j;
for (j=n;j>i;j--) /*位置i后的字符串后移*/
pa[j]=pa[j-1];
pa[i]=str;
}
main()
{
char *temp,*pa[Max]={"do","else","for","if","switch","while"};
int i,j,n=6;
printf("原序列:");
for (i=0;i
printf("%s ",pa[i]);
printf("\n");
printf("插入串:");
temp=(char *)malloc(20*sizeof(char));
gets(temp);
pa[n]=(char *)malloc(20*sizeof(char)); /*预留空间*/
j=binary(pa,temp,n);
insert(pa,temp,n,j);
printf("新序列:");
for (i=0;i
printf("%s ",pa[i]);
printf("
\n");
}
(8)设计一个程序,使输入的句子按如下方式改造后输出:
① 单词之间只留一个空格作间隔;
② 句子结束后必须紧跟句号;
③ 如果把句子的单词从左到右依次编号为1,2,3,…,则对于第奇数个单词,只要直接复制就行了,而对于第偶数个单词,应按反序打印。
【解】①②小题的功能由函数func1()实现。先将str开头的空格过滤,然后扫描串,将非空格字符直接复制到nstr,若遇到空格,如果是第一个空格,也复制到nstr,否则不复制。扫描完后,nstr最后若为空格,则添加‘.’。③小题的功能由函数func2()实现。先找出一个单词,由p指向该单词开头,q指向其结尾。若是奇数个单词,则按p->q的顺序复制到nstr中;否则按q->p的顺序复制到nstr中。程序如下:
/*文件名:exci8_8.cpp*/ VC++6.0
#include
#include
#include
#define Max 100
char *func1(char *str)
{
char *nstr=(char *)malloc(sizeof(str)+1);
char *p=nstr;
int first=1; /*标识是否为一串空格的第一个空格*/
while (*str!='\0' && *str==' ') str++; /*除掉开头的空格*/
while (*str!='\0') /*扫描串*/
if (*str!=' ')
{
*nstr++=*str++;
first=1;
}
else
{
if (first==1)
{
*nstr++=*str++;
first=0;
}
else str++;
}
nstr--;
if (*nstr==' ') /*最后为空字符,则添加'.'*/
*nstr='.';
else if (*nstr!='.') /*最后不为'.',则添加'.'*/
*(++nstr)='.';
*(++nstr)='\0'; /*添加结束标志*/
return p;
}
char *func2(char *str)
{
int count=0;
char *nstr=(char *)malloc(strlen(str)),*p,*q,*s,*np=nstr;
p=q=str;
while (*q!='.')
{
while (*q!='.' && *q!=' ') q++; /*找出一个单词*/
count++;
if (count%2==1) /*奇数个单词*/
for (;p<=q;p++)
*nstr++=*p;
else /*偶数个单词*/
{
s=q-1;
for (;s>=p;s--) /*将当前单词逆序复制到nstr中*/
*nstr++=*s;
*nstr++=*q;
}
if (*q!='.') q++;
p=q;
}
*nstr='\0'; /*添加结束标志*/
return np;
}
main()
{
char *str;
str=(char *)malloc(Max);
printf("输入句子:");
gets(str);
str=func1(str);
printf("(1)(2)后:%s\n",str);
str=func2(str);
printf(" (3)步后:%s\n
",str);
}
程序运行结果:
输入句子:while switch do-while for↙
(1)(2)后:while switch do-while for.
(3)步后:while hctiws do-while rof.
(10)编写一个程序,实现一个整数、长整数、浮点数和双精度数除2的计算,要求所有类型的数除2只使用一个函数。
【解】编写一个half(void *x,char type)函数,其中x参数是一个地址,type参数指出该地址存储的数的类型,不同类型的数的运算是不同的,例如:
*((int *)x)/=2;
表示将x地址的数转换成整数后除2,再存储在该地址中,相当于以下一段代码:
int a;
a=(int *)x;
a=a/2;
*x=a;
这段代码并不能替换原代码,这是因为half()的参数为void类型,没有包括错误检查,但这段代码中有*x=a;赋值,会出现类型不匹配。程序如下:
/*文件名:exci8_10.cpp*/ VC++6.0
#include
void half(void *x,char type);
main()
{
int i=10;
long l=500000;
float f=24.8;
double d=123.456789;
printf("%d\t%ld\t%f\t%lf\n",i,l,f,d);
half(&i,'i');
half(&l,'l');
half(&f,'f');
half(&d,'d');
printf("%d\t%ld\t%f\t%lf\n",i,l,f,d);
}
void half(void *x,char type)
{
switch(type)
{
case 'i':*((int *)x)/=2;
break;
case 'l':*((long *)x)/=2;
break;
case 'f':*((float *)x)/=2;
break;
case 'd':*((double *)x)/=2;
break;
}
}
(11)编写一个程序,采用第6章中介绍的三种排序法将如下10种语言名称(用字符指针数组language存放这10种语言名称)按词典顺序排序:
English,Chinese,Russian,Japanese,Spanish,Italian,French,Finnish,Danish,Greek
【解】采用冒泡排序法排序的程序如下:
/*文件名:exci8_11_1.cpp*/ VC++6.0
#include
#include
#define N 10
void bubblesort(char *p[],int n);
main()
{
char *language[]={"English","Chinese","Russian","Japanese",
"Spanish","Italian","French","Finnish","Danish","Greek"};
char **p=language;
int i;
printf("排序前:\n");
for (i=0;i
{
printf("%12s ",*p++);
if (i==4)
printf("\n");
}
printf("\n");
bubblesort(language,N);
printf("排序后:\n");
p=language;
for (i=0;i
{
printf("%12s ",*p++);
if (i==4)
printf("\n");
}
printf("\n");
}
void bubblesort(char *p[],int n)
{
int i,j,exchange;
char *tmp;
for (i=0;i
{
exchange=0;
for (j=n-2;j>=i;j--)
if (strcmp(p[j+1],p[j])<0)
{
tmp=p[j+1];
p[j+1]=p[j];
p[j]=tmp
;
exchange=1;
}
if (!exchange) /*本趟未发生交换,排序完成,退出for循环*/
break;
}
}
采用直接插入排序法排序的程序如下:
/*文件名:exci8_11_2.cpp*/ VC++6.0
#include
#include
#define N 10
void insertsort(char *p[],int n);
main()
{
char *language[]={"English","Chinese","Russian","Japanese",
"Spanish","Italian","French","Finnish","Danish","Greek"};
char **p=language;
int i;
printf("排序前:\n");
for (i=0;i
{
printf("%12s ",*p++);
if (i==4)
printf("\n");
}
printf("\n");
insertsort(language,N);
printf("排序后:\n");
p=language;
for (i=0;i
{
printf("%12s ",*p++);
if (i==4)
printf("\n");
}
printf("\n");
}
void insertsort(char *p[],int n)
{
int i,j;
char *tmp;
for (i=1;i
if (strcmp(p[i],p[i-1])<0)
{
tmp=p[i];j=i-1;
do
{
p[j+1]=p[j];
j--;
} while (strcmp(tmp,p[j])<0 && j>=0);
p[j+1]=tmp;
}
}
采用直接选择排序法排序的程序如下:
/*文件名:exci8_11_3.cpp*/ VC++6.0
#include
#include
#define N 10
void selectsort(char *p[],int n);
main()
{
char *language[]={"English","Chinese","Russian","Japanese",
"Spanish","Italian","French","Finnish","Danish","Greek"};
char **p=language;
int i;
printf("排序前:\n");
for (i=0;i
{
printf("%12s ",*p++);
if (i==4)
printf("\n");
}
printf("\n");
selectsort(language,N);
printf("排序后:\n");
p=language;
for (i=0;i
{
printf("%12s ",*p++);
if (i==4)
printf("\n");
}
printf("\n");
}
void selectsort(char *p[],int n)
{
int i,j,k;
char *tmp;
for (i=0;i
{
k=i;
for (j=i+1;j
if (strcmp(p[j],p[k])<0)
k=j;
if (k!=i)
{
tmp=p[i];p[i]=p[k];p[k]=tmp;
}
}
}
v
发布时间: 2007/11/23 8:14:04