1
实验五 指 针
5-1 通过程序S5-1.C理解指针与数组的关系。
源程序S5-1.C
main()
{ int a[5],*p,i;
for(i=0;i<5;i++)
a[i]=i+1;
p=a;
for(i=0;i<5;i++)
{ printf("*[p+%d]=%d\t",i,*(p+i));
printf("a[%d]=%d\n",i,a[i]);
}
}
写出程序运行的结果,并通过输出结果理解指针与数组的关系。
〖指导〗
通过该程序的输出结果,可以进一步理解用指针法和下标法表示数组元素的
两种不同表示形式:*(p+i)和a[i]是等价的。
5-2 完善程序S5-2.C,使程序能从第一个字符串中删去任何在第二个字符串中
出现的字符。输入abcdefg给s1,cde给s2,会输出什么结果?
源程序S5-2.C
main()
{ char s1[20],s2[20],*p1,*p2;
int i;
scanf("%s%s",s1,s2);
printf("\n");
for(i=0;*(p1+i)!= '\0';i++)
{ for(p2=s2;*(p2)!= ‘\0’;p2++)
strcpy(&s1[i],&s1[i+1]);
}
printf ("%s",s1);
}
〖指导〗
(1) p1在使用前必须要有明确的指向。
(2) strcpy(&s1[i],&s1[i+1])是将s1中下标为i+1开始的字符串复制到下标为i
2
的位置,即删除下标为i处的字符。
5-3 通过指针数组p和一维数组a构成一个3×2的二维数组,并为数组赋初值,
要求先按行的顺序输出二维数组,再按列的顺序输出二维数组。试完善程
序S5-3.C。
源程序S5-3.C
main()
{ int i,j,a[]={2,4,6,8,10,12},*p[3];
for(i=0;i<3;i++)
p[i]=&a[2*i];
for(i=0;i<3;i++) /* 按行的顺序输出二维数组 */
{ for(j=0;j<2;j++)
printf("%4d",p[i][j]);
printf("\n");
}
}
〖指导〗
程序S5-3.C中按行的顺序输出二维数组的结果为:
2 4
6 8
10 12
要求完善的程序是按列的顺序输出二维数组,其输出结果为:
2 6 10
4 8 12
5-4 完善程序S5-4.C。从键盘上输入10个数据到一维数组x中,然后找出数组
中的最大值和该值所在数组元素的下标。
源程序S5-4.C
main()
{ int x[10],*p1,*p2,i;
for(i=0;i<10;i++)
scanf("%d",x+i);
for(p1=x,p2=x;p1-x<10;p1++)
if(*p1>*p2) p2= ;
printf("MAX=%d,INDEX=%d\n",*p2, );
}
〖指导〗
程序S5-4.C中*p2记录的是数组中的最大值;第2个空是最大值所在元素
的下标。
3
5-5 有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡
报到3的人,退出圈子,问最后留下的是原来第几号的那位。试编程S5-5.C,
并写出运行过程和结果。
〖指导〗
(1) 要解决上面的问题,需要定义如下变量或数组:
①一个一维数组num,和一个指针变量p,将p指向num;
②定义一个循环计数变量i=0,当i=n时,所有人都报了数,一轮报数结束,
第2轮报数开始,这时将i重新赋值为0;
③在循环报数过程中,需要定义一个变量k=0,作为按1,2,3报数时的计
数变量,把报到3的人所在的数组元素赋值为0;
④定义一个用于记录退出人数的变量m=0,直到只有1个非0元素为止。
(2) 算法步骤
①输入人数n;
②以1至n为序号给每个人编号,即
for(i=0;i<n;i++)
*(p+i)=i+1; /* 以1至n为序号给每个人编号 */
③判断,如果*(p+i)!=0,则k++;
④判断,如果k=3,则*(p+i)=0,即对退出圈子的人的编号置0;同时将k
重新置0,退出的人数加1,即m++;否则,执行⑤;
⑤计数变量i加1,如果i=n,则将i赋值为0,即报数到末尾后(一圈报数
结束)i恢复为0;
⑥如果m<n-1,继续执行③,否则执行⑦;
⑦如果*p=0,则p++,继续执行⑦,否则执行⑧;
⑧输出n个人中最后留下的是第几号。
5-6 完善程序S5-6.C,使其能按字典顺序对多个字符串排序。
源程序S5-6.C
#include <stdio.h>
#include <string.h>
main()
{ char *t;
int i,j,n;
char *s[ ]={"pascal", "basic","fortran","turbo C"};
scanf ("%d",&n); /* 输入字符串的个数n */
for(i=0;i<n-1;i++) /* 用冒泡法排序 */
}
〖指导〗
字符串的比较不能用相等运算符“==”,只能用字符串比较函数strcmp();函
4
数strcmp()的两个参数是两个地址值,因此可以用strcmp(s[i],s[j])进行比较。
5-7 调试程序S5-7.C。该程序的功能是将数组x的元素倒序输出。例如,输入1
2 3 4 5,则输出为5 4 3 2 1。改正错误,但不能改变程序的结构和删除整行。
源程序S5-7.C
#include<stdio.h>
#define M 20
main()
{
int i,x[M],n, m, *p,*k,*j;
printf("\nEnter n:");
scanf("%d",n);
printf("\nEnter array x[i](i=0~n):\n");
for(i=0;i<n;i++)
scanf("%d",x+i);
printf("\n");
m=n/2;
k=x;
j=x+n;
p=x+m;
for(;k<=p;k++,j--)
{ int t=*k;
k=j;*j=t;
}
printf("\nThe array inverted:\n");
for(i=0;i<n;i++)
printf("%d ",x[i]);
getch();
}
〖指导〗
(1) 注意边界元素的下标。
(2) 注意数据的正确交换。
(3) 注意由错误的结果分析错误可能发生的地方。
5-8 程序S5-8.C的功能是输入一个英文字符串,将其中每个单词的最后一个字
母改成大写,然后输出该字符串。例如,输入I am a student 则输出 I aM
A studenT。调试该程序,使其得到正确的结果。注意:不得增加或删除
程序行,也不能更改程序结构。
源程序S5-8.C
#include<stdio.h>
5
#include<ctype.h>
main()
{ char ch[80],*c;
int d,k=0;
printf("\nPlease input a string:");
gets(ch);
c=ch;
for(;*c;c++)
if(k)
{ if(c=' ')
{ k=0;
*c=toupper(*(c-1));
}
}
else
k=1;
printf("\nResult is: %s",ch);
getch();
}
〖指导〗
(1) 注意“=”与“==”的区别和正确使用。
(2) 注意哪些位置上的字母应该转换为大写字母,转换后应该放在什么位置
上。
(3) 输入时要注意,在最后一个单词后面要输入一个空格,否则最后一个单
词的最后一个字符不会改变为大写字母。
*5-9 编写程序S5-9.C,模拟用户注册和登录的过程。将S4-11.C改为用指
针实现。