第十章 指针
1. 单项选择题
(1)【答】A
(2)【答】A
(3)【答】D
(4)【答】C
(5)【答】B
(6)【答】C
(7)【答】C
(8)【答】A
(9)【答】B
(10)【答】D
(11)【答】A
(12)【答】B 此题题目有错,应该改为“则对a数组元素的不正确引用是”
(13)【答】C
(14)【答】B
(15)【答】C
(16)【答】C 此题题目有错,应该改为“
char s[]="\n123\\" ”
(17)【答】C
(18)【答】C
(19)【答】B 此题答案有错,应该改为“ B) *p=*&j
”
(20)【答】D
(21)【答】A
(22)【答】B
(23)【答】D
2. 填空题
(1)【答】
1 2
3
0 5
6
0 0
9
(2)【答】s[i]<'0' ||
s[i]>'9'
'\0'
(3)【答】findbig
(4)【答】void(*p)(int,int)
(5)【答】0
(6)【答】10
(7)【答】0
7
(8)【答】i
*(a+9-i)
(9)【答】
9876
876
(10)【答】efgh
(11)【答】abc
(12)【答】7
(13)【答】'\0'
i
(14)【答】&n
*k
(15)【答】max<a[row][col]
max<m+n
(16)【答】*t
*s-*t
(17)【答】字符串"JAVA"的存储地址
(18)【答】有4个元素的一维数组
(19)【答】c
(20)【答】3
(21)【答】2
(22)【答】12
12
3. 编程题
(1)编写一个程序,输入一个整数,利用指针变量返回该数的绝对值。
【解】设计一个函数iabs,其参数为整数指针,返回绝对值的指针。程序如下:
#include
<stdio.h>
int *iabs(int
*p)
{
if
(*p<0)
*p=-*p;
return
p;
}
main()
{
int
a;
printf("输入一整数:");
scanf("%d",&a);
printf("绝对值为:%d\n",*iabs(&a));
}
(2)编写一个函数,计算数组中的最大元素及其下标,数组以指针方式传递。
【解】设计一个findmax()函数,返回数组最大值的指针,通过一个参数t返回最大值的下标。函数如下:
int *findmax(int
*p,int n,int *t)
{
int
i,max;
max=*p;*t=0;
for
(i=1;i<n;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。程序如下:
#include
<stdio.h>
#include
<malloc.h>
#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
(4)输入一个字符串,内有数字和非数字字符,如:
a123x456?17960?302tab5876
将其中连续的数字作为一个整数,依次存放到一数组a中。例如,123放在a[0]中,456放在a[1]中,…,统计共有多少个整数,并输出这些数。
【解】用一个字符串指针变量s指向输入的字符串,扫描整个字符串,先跳过非数字字符,读出数字字符,并转换成整数后存放在数组元素中。程序如下:
#include
<stdio.h>
#include
<malloc.h>
#define MaxLen
100
#define Max
10
int trans(char
*s,int a[])
{
int
n=0,d;
while
(*s!='\0')
{
while (*s>'9' || *s<'0')
s++;
d=0;
while (*s>='0' &&
*s<='9')
{
d=10*d+(*s-'0');
s++;
}
a[n]=d;
n++;
}
return
n;
}
main()
{
char
*s;
int
a[Max],n,i;
s=(char
*)malloc(MaxLen);
printf("输入一个串:");
gets(s);
n=trans(s,a);
printf("整数个数:%d\n",n);
printf("输出数:");
for
(i=0;i<n;i++)
printf("%d ",a[i]);
printf("\n");
}
程序运行结果:
输入一个串:a123x456 17960?302tab5876↙
整数个数:5
输出数:123 456 17960 302 5876
(5)编写一个程序,求出两个字符串:
s[]="This is C
programming text"
t[]="This is a
text for C programming"
包含的最长的相同单词(同一字母的大小写视为不同的字符)。规定单词全由英文字母组成,单词之间由一个或多个空格符分隔。
【解】自左向右顺序扫描字符串s,逐个找出单词(单词开始位置和单词长度),当该单词的长度比已找到的单词更长时,就从头到尾扫描字符串t。在从t字符串中找出与该字符串长度相等、字符相同的单词后,记录下该单词的和的长度,并回到s,在其中找出下一个更长的单词。上述寻找过程直到字符串s扫描结束,最后输出找到的单词。程序如下:
#include
<stdio.h>
#include
<string.h>
void
maxword(char *s,char *t)
{
char
*res,*temp,chs,cht;
int
i,j,found,maxlen=0;
while
(*s!='\0')
{
while (*s==' ')
s++;
for (i=0;s[i]!=' ' &&
s[i]!='\0';i++);
if
(i>maxlen)
{
chs=s[i];
s[i]='\0';
temp=t;
found=0;
while (*temp!='\0' &&
!found)
{
while (*temp==' ') temp++;
for (j=0;temp[j]!=' ' &&
temp[j]!='\0';j++);
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。最后输出结果。程序如下:
#include
<stdio.h>
#include
<malloc.h>
#include
<string.h>
#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<n;i++)
{
pa[i]=(char *)malloc(20);
printf("第%d个串:",i+1);
scanf("%s",pa[i]);
}
printf("排序前:");
for
(i=0;i<n;i++)
printf("%s ",pa[i]);
printf("\n");
sort(pa,n);
printf("排序后:");
for
(i=0;i<n;i++)
printf("%s ",pa[i]);
printf("\n");
}
(7)编写一个程序,在一个已排序列的字符串数组中,插入输入的一个字符串,使该数组的元素仍然有序。
【解】用指针数组pa存放字符串(与字符串数组相比其优点是可以动态分配内存空间),对于用户输入的一个字符串temp,采用二分查找法在pa中找到合适的位置i,然后将temp插入到pa的位置i即可。程序中的binary函数用于实现二分查找过程;insert函数用于实现字符串的插入过程。程序如下:
#include
<stdio.h>
#include
<malloc.h>
#include
<string.h>
#define Max
20
int binary(char
*pa[],char *str,int n)
{
int
high=n-1,low=0,mid;
if
(strcmp(str,pa[0])<0)
return 0;
if
(strcmp(str,pa[high])>0)
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)
{
int
j;
for
(j=n;j>i;j--)
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<n;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<n+1;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中。程序如下:
#include
<stdio.h>
#include
<malloc.h>
#include
<string.h>
#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++=*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.
(9)使用指针数组对输入的三个整数序列(每个序列5个整数),分别从小到大进行排序,排序方法不限。
【解】使用一个二维数组a,用于接收用户输入的三个整数数序,并使用指针数组p分别指向三个待排序的整数序列。可以建立一个循环,每次进入循环改变所使用的指针,也就改变了操作的整数序列,这样循环体每执行一次就排好一个整数序列。程序如下:
#include
<stdio.h>
main()
{
int
a[3][5],*p[3];
int
i,j,k,min,code;
p[0]=*a;
p[1]=*(a+1);
p[2]=*(a+2);
for
(i=0;i<3;i++)
{
printf("输入第%d个数序的5个整数:",i+1);
for (j=0;j<5;j++)
scanf("%d",p[i]+j);
}
for
(i=0;i<3;i++)
{
for
(j=0;j<4;j++)
{
for (k=j;k<5;k++)
if (k==j || *(p[i]+k)<min)
{
min=*(p[i]+k);
code=k;
}
if (code!=j)
{
*(p[i]+code)=*(p[i]+j);
*(p[i]+j)=min;
}
}
}
printf("输出结果如下:\n");
for
(i=0;i<3;i++) {
printf(" 数序%d:",i+1);
for (j=0;j<5;j++)
printf("%d ",*(p[i]+j));
printf("\n");
}
}
(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;赋值,会出现类型不匹配。程序如下:
#include
<stdio.h>
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
【解】采用冒泡排序法排序的程序如下:
#include
<stdio.h>
#include
<string.h>
#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<N;i++)
{
printf("s ",*p++);
if (i==4)
printf("\n");
}
printf("\n");
bubblesort(language,N);
printf("排序后:\n");
p=language;
for
(i=0;i<N;i++)
{
printf("s ",*p++);
if (i==4)
printf("\n");
}
printf("\n");
}
void
bubblesort(char *p[],int n)
{
int
i,j,exchange;
char
*tmp;
for
(i=0;i<n-1;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)
break;
}
}
采用直接插入排序法排序的程序如下:
#include
<stdio.h>
#include
<string.h>
#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<N;i++)
{
printf("s ",*p++);
if (i==4)
printf("\n");
}
printf("\n");
insertsort(language,N);
printf("排序后:\n");
p=language;
for
(i=0;i<N;i++)
{
printf("s ",*p++);
if
(i==4)
printf("\n");
}
printf("\n");
}
void
insertsort(char *p[],int n)
{
int
i,j;
char
*tmp;
for
(i=1;i<n;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;
}
}
采用直接选择排序法排序的程序如下:
#include
<stdio.h>
#include
<string.h>
#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<N;i++)
{
printf("s ",*p++);
if (i==4)
printf("\n");
}
printf("\n");
selectsort(language,N);
printf("排序后:\n");
p=language;
for
(i=0;i<N;i++)
{
printf("s ",*p++);
if (i==4)
printf("\n");
}
printf("\n");
}
void
selectsort(char *p[],int n)
{
int
i,j,k;
char
*tmp;
for
(i=0;i<n-1;i++)
{
k=i;
for (j=i+1;j<n;j++)
if (strcmp(p[j],p[k])<0)
k=j;
if (k!=i)
{
tmp=p[i];p[i]=p[k];p[k]=tmp;
}
}
}
|