Peter_Matthew的博客

《C程序设计(第五版)谭浩强 著》课后习题(第6-10章)

2023-10-09

本文共13k字,大约需要阅读72分钟。

本文所列习题答案均不含解释说明类题目。

第7章 用函数实现模块化程序设计

  1. 写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果。两个整数由键盘输入。

非递归版。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
int gcd(int a,int b)
{
int t;
while(b!=0)
{
a%=b;
t=a;a=b;b=t;
}
return a;
}
int lcm(int a,int b)
{
return a*b/gcd(a,b);
}
int main()
{
int m,n;
scanf("%d %d",&m,&n);
printf("gcd=%d,lcm=%d\n",gcd(m,n),lcm(m,n));
return 0;
}

递归版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
int gcd(int a,int b)
{
return (!b)?a:gcd(b,a%b);
}
int lcm(int a,int b)
{
return a*b/gcd(a,b);
}
int main()
{
int m,n;
scanf("%d %d",&m,&n);
printf("gcd=%d,lcm=%d\n",gcd(m,n),lcm(m,n));
return 0;
}
  1. 求方程 $a^2+bx+c=0$ 的根,用3个函数分别求当:$b^2-4ac$ 大于0、等于0和小于0时的根并输出结果。从主函数输入 $a,b,c$ 的值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <stdio.h>
#include <math.h>
void da0(double a,double b,double d)
{
double x1,x2;
x1=(-b+sqrt(d))/2/a;
x2=(-b-sqrt(d))/2/a;
printf("x1=%f\nx2=%f\n",x1,x2);
return ;
}
void deng0(double a,double b)
{
double x;
x=-b/2/a;
printf("x1=x2=%f\n",x);
return ;
}
void xiao0(double a,double b,double d)
{
double r,i;
r=-b/2/a;
i=sqrt(-d)/2/a;
printf("无实根。\n");
printf("复数根为:x1=%f%+fi,x2=%f%+fi\n",r,i,r,-i);
return ;
}
int main()
{
double a,b,c,d;
scanf("%lf %lf %lf",&a,&b,&c);
d=b*b-4*a*c;
if(d>0)
da0(a,b,d);
else if(d==0)
deng0(a,b);
else
xiao0(a,b,d);
return 0;
}
  1. 写一个判素数的函数,在主函数输入一个整数,输出是否为素数的信息。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
int isprime(int n)
{
int i;
for(i=2;i*i<=n;i++)
{
if(n%i==0)
return 0;
}
return 1;
}
int main()
{
int n;
scanf("%d",&n);
if(isprime(n))
printf("%d is a prime number.\n",n);
else
printf("%d is not a prime number.\n",n);
return 0;
}
  1. 写一个函数,使给定的一个 $3 \times 3$ 的二维整型数组转置,即行列互换。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <stdio.h>
void transform(int a[][3])
{
int i,j,t;
for(i=0;i<3;i++)
{
for(j=0;j<i;j++)
{
t=a[i][j];
a[i][j]=a[j][i];
a[j][i]=t;
}
}
return ;
}
int main()
{
int a[3][3],i,j;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
scanf("%d",&a[i][j]);
transform(a);
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
printf("%d ",a[i][j]);
printf("\n");
}
return 0;
}
  1. 写一个函数,使输入的一个字符串按反序存放,在主函数中输入和输出字符串。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#include <string.h>
void reverse(char s[],int n)
{
int i;
char t;
for(i=0;i<n/2;i++)
{
t=s[i];
s[i]=s[n-1-i];
s[n-1-i]=t;
}
return ;
}
int main()
{
char s[100];
int n;
scanf("%s",s);
n=strlen(s);
reverse(s,n);
printf("%s\n",s);
return 0;
}
  1. 写一个函数,将两个字符串连接。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
void merge(char s1[],char s2[])
{
int i,j;
for(i=0;s1[i]!='\0';i++);
for(j=0;s2[j]!='\0';i++,j++)
s1[i]=s2[j];
s1[i]='\0';
return ;
}
int main()
{
char s1[200],s2[100];
scanf("%s",s1);
scanf("%s",s2);
merge(s1,s2);
printf("%s\n",s1);
return 0;
}
  1. 写一个函数,将一个字符串中的元音字母复制到另一字符串,然后输出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
void extract(char s1[],char s2[])
{
int i,j;
for(i=0,j=0;s1[i]!='\0';i++)
{
if(s1[i]=='A'||s1[i]=='a'||s1[i]=='E'||s1[i]=='e'||s1[i]=='I'||s1[i]=='i'||s1[i]=='O'||s1[i]=='o'||s1[i]=='U'||s1[i]=='u')
{
s2[j]=s1[i];
j++;
}
}
s2[j]='\0';
return ;
}
int main()
{
char s1[100],s2[100];
scanf("%s",s1);
extract(s1,s2);
printf("%s\n",s2);
return 0;
}
  1. 写一个数,输入一个4位数字,要求输出这4个数字字符,但每两个数字间空一空格。如输入1990,应输出“1 9 9 0”。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
void print(int n)
{
int i,j,x;
for(i=3;i>=0;i--)
{
x=n;
for(j=0;j<i;j++)
x/=10;
x%=10;
printf("%d",x);
if(i>0)
printf(" ");
}
return ;
}
int main()
{
int n;
scanf("%d",&n);
print(n);
return 0;
}
  1. 编写一个函数,由实参传来一个字符串,统计此字符串中字母、数字、空格和其他字符的个数,在主函数中输入字符串以及输出上述的结果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdio.h>
void tongji(char s[],int tj[])
{
int i;
for(i=0;s[i]!='\0';i++)
{
if(s[i]>='a'&&s[i]<='z'||s[i]>='A'&&s[i]<='Z')
tj[0]++;
else if(s[i]>='0'&&s[i]<='9')
tj[1]++;
else if(s[i]==' ')
tj[2]++;
else
tj[3]++;
}
return ;
}
int main()
{
char s[100];
int tj[4];
gets(s);
tongji(s,tj);
printf("zm=%d,sz=%d,kg=%d,qt=%d\n",tj[0],tj[1],tj[2],tj[3]);
return 0;
}
  1. 写一个函数,输入一行字符,将此字符串中最长的单词输出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdio.h>
void longest(char s[])
{
int i,l=0,max=0,maxi=0;
for(i=0;;i++)
{
if(s[i]>='a'&&s[i]<='z'||s[i]>='A'&&s[i]<='Z')
{
l++;
}
else
{
if(l>max)
{
max=l;
maxi=i-l;
l=0;
}
}
if(s[i]=='\0')
break;
}
for(i=0;i<max;i++)
printf("%c",s[maxi+i]);
printf("\n");
return ;
}
int main()
{
char s[100];
gets(s);
longest(s);
return 0;
}
  1. 写一个函数,用“起泡法”对输入的10个字符按由小到大顺序排列。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
void sort(char s[])
{
int i,j;
char t;
for(i=0;i<9;i++)
{
for(j=0;j<9-i;j++)
{
if(s[j]>s[j+1])
{
t=s[j];
s[j]=s[j+1];
s[j+1]=t;
}
}
}
return ;
}
int main()
{
char s[11];
scanf("%s",s);
sort(s);
printf("%s\n",s);
return 0;
}
  1. 用牛顿迭代法求根。方程为 $ax^3+bx^2+cx+d=0$ ,系数 $a,b,c,d$ 的值依次为1,2,3,4,由主函数输入。求在1附近的一个实根。求出根后由主函数输出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <math.h>
double getx(double a,double b,double c,double d,double x0)
{
double x1=x0,f,f_;
do
{
x0=x1;
f=((a*x0+b)*x0+c)*x0+d;
f_=(3*a*x0+2*b)*x0+c;
x1=x0-f/f_;
}while(fabs(x1-x0)>=1e-5);
x0=x1;
return x0;
}
int main()
{
double a,b,c,d,x;
scanf("%lf %lf %lf %lf",&a,&b,&c,&d);
x=getx(a,b,c,d,1);
printf("%f\n",x);
return 0;
}
  1. 用递归方法求 $n$ 阶勒让德多项式的值,递归公式为
    Book-Exercises-of-PLC-5th-THQ-7-13-1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
double p(int n,double x)
{
if(n==0)return 1;
if(n==1)return x;
return ((2*n-1)*x*p(n-1,x)-(n-1)*p(n-2,x))/(double)n;
}
int main()
{
int n;
double x,ans;
scanf("%d %lf",&n,&x);
ans=p(n,x);
printf("%f\n",ans);
return 0;
}
  1. 输入10个学生5门课的成绩,分别用函数实现下列功能:
    ①计算每个学生的平均分;
    ②计算每门课的平均分;
    ③找出所有50个分数中最高的分数所对应的学生和课程;
    ④计算平均分方差:
    $\sigma = \frac{1}{n} \sum x_{i}^{2} - (\frac{\sum x_i}{n})^2$
    其中, $x_i$ 为某一学生的平均分。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <stdio.h>
double calc_stuave(int score[10][5],int n)
{
int i;
double ave=0;
for(i=0;i<5;i++)
ave+=score[n][i];
ave/=5.0;
return ave;
}
double calc_couave(int score[10][5],int n)
{
int i;
double ave=0;
for(i=0;i<10;i++)
ave+=score[i][n];
ave/=10.0;
return ave;
}
void calc_max(int score[10][5],int *max,int *maxi,int *maxj)
{
int i,j;
for(i=0;i<10;i++)
{
for(j=0;j<5;j++)
{
if(*max<score[i][j])
{
*max=score[i][j];
*maxi=i+1;
*maxj=j+1;
}
}
}
return ;
}
double calc_s(double stuave[10])
{
double s=0,s1=0,s2=0;
int i;
for(i=0;i<10;i++)
{
s1+=stuave[i]*stuave[i];
s2+=stuave[i];
}
s=s1/10.0-s2*s2/10.0/10.0;
return s;
}
int main()
{
int score[10][5];
double stuave[10],couave[5],s;
int i,j,max=0,maxi=0,maxj=0;
for(i=0;i<10;i++)
for(j=0;j<5;j++)
scanf("%d",&score[i][j]);
for(i=0;i<10;i++)
stuave[i]=calc_stuave(score,i);
for(i=0;i<5;i++)
couave[i]=calc_couave(score,i);
calc_max(score,&max,&maxi,&maxj);
s=calc_s(stuave);
for(i=0;i<10;i++)
printf("%f ",stuave[i]);
printf("\n");
for(i=0;i<5;i++)
printf("%f ",couave[i]);
printf("\n");
printf("Sudent %d \'s Course %d is max = %d\n",maxi,maxj,max);
printf("%f\n",s);
return 0;
}char t
  1. 写几个函数:
    ①输入10个职工的姓名和职工号;
    ②按职工号由小到大顺序排序,姓名顺序也随之调整;
    ③要求输入一个职工号,用折半查找法找出该职工的姓名,从主函数输入要查找的职工号,输出该职工姓名。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <stdio.h>
#include <string.h>
void input(char s[10][100],int a[10])
{
int i;
for(i=0;i<10;i++)
scanf("%s %d",s[i],&a[i]);
return ;
}
void sort(char s[10][100],int a[10])
{
char t[100];
int b,i,j;
for(i=0;i<9;i++)
{
for(j=0;j<9-i;j++)
{
if(a[j]>a[j+1])
{
b=a[j];
a[j]=a[j+1];
a[j+1]=b;
strcpy(t,s[j]);
strcpy(s[j],s[j+1]);
strcpy(s[j+1],t);
}
}
}
}
char *finds(char s[10][100],int a[10],int n)
{
int l=0,r=n-1,mid;
while(l<r)
{
mid=(l+r)/2;
if(a[mid]>a[n])
r=mid-1;
else if(a[mid]<a[n])
l=mid+1;
else
{
l=r=mid;
break;
}
}
if(a[l]==n)
return s[l];
else
return "Not Found!";
}
int main()
{
char s[10][100],*t;
int a[10],i,n;
input(s,a);
sort(s,a);
for(i=0;i<10;i++)
printf("%s %d\n",s[i],a[i]);
scanf("%d",&n);
t=finds(s,a,n);
printf("%s",t);
return 0;
}
  1. 写一个函数,输入一个十六进制数,输出相应的十进制数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
int dec(char s[])
{
int i,n=0;
for(i=0;s[i]!='\0';i++)
{
if(s[i]>='0'&&s[i]<='9')
n=n*16+s[i]-'0';
else if(s[i]>='a'&&s[i]<='z')
n=n*16+s[i]-'a'+10;
else if(s[i]>='A'&&s[i]<='Z')
n=n*16+s[i]-'A'+10;
}
return n;
}
int main()
{
int n;
char s[100];
scanf("%s",s);
n=dec(s);
printf("%d\n",n);
return 0;
}
  1. 用递归法将一个整数n转换成字符串。例如,输入483,应输出字符串“483”。n的位数不确定,可以是任意位数的整数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
int gen(int n,char s[])
{
if(!n)return 0;
int i=gen(n/10,s);
s[i]='0'+n%10;
i++;
s[i]='\0';
return i;
}
int main()
{
int n;
char s[100];
scanf("%d",&n);
gen(n,s);
printf("%s\n",s);
return 0;
}
  1. 给出年、月、日,计算该日是该年的第几天。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
int getn(int y,int m,int d)
{
int i,n=0,days[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
if((y%4==0&&y%100!=0)||(y%100==0&&y%400==0))
days[2]=29;
for(i=1;i<m;i++)
n+=days[i];
n+=d;
return n;
}
int main()
{
int y,m,d,n;
scanf("%d %d %d",&y,&m,&d);
n=getn(y,m,d);
printf("%d\n",n);
return 0;
}

第8章 善于利用指针

本章习题均要求用指针方法处理。

  1. 输入3个整数,按由小到大的顺序输出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
int main()
{
int a1,a2,a3;
int *p1,*p2,*p3,*t;
scanf("%d %d %d",&a1,&a2,&a3);
p1=&a1;
p2=&a2;
p3=&a3;
if(*p1>*p2){t=p1;p1=p2;p2=t;}
if(*p2>*p3){t=p2;p2=p3;p3=t;}
if(*p1>*p2){t=p1;p1=p2;p2=t;}
printf("%d %d %d\n",*p1,*p2,*p3);
return 0;
}
  1. 输入3个字符串,按由小到大的顺序输出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <string.h>
int main()
{
char s1[100],s2[100],s3[100];
char *p1,*p2,*p3,*t;
scanf("%s",s1);
scanf("%s",s2);
scanf("%s",s3);
p1=s1;
p2=s2;
p3=s3;
if(strcmp(p1,p2)>0){t=p1;p1=p2;p2=t;}
if(strcmp(p2,p3)>0){t=p2;p2=p3;p3=t;}
if(strcmp(p1,p2)>0){t=p1;p1=p2;p2=t;}
printf("%s %s %s\n",p1,p2,p3);
return 0;
}
  1. 输入10个整数,将其中最小的数与第一个数对换,把最大的数与最后一个数对换。写3个函数:①输入10个数;②进行处理;③输出10个数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <stdio.h>
void input(int *a)
{
int i;
for(i=0;i<10;i++)
scanf("%d",&a[i]);
return ;
}
void cope(int *a)
{
int i;
int *max=&a[0],*min=&a[0],t;
for(i=1;i<10;i++)
{
if(*max<a[i])
max=&a[i];
if(*min>a[i])
min=&a[i];
}
t=a[0];a[0]=*min;*min=t;
t=a[9];a[9]=*max;*max=t;
return ;
}
void output(int *a)
{
int i;
for(i=0;i<10;i++)
printf("%d ",a[i]);4
printf("\n");
return ;
}
int main()
{
int a[10];
input(a);
cope(a);
output(a);
return 0;
}
  1. 有n个整数,使前面各数顺序向后移m个位置,最后m个数变成最前面m个数,见图。写一函数实现以上功能,在主函数中输入n个整数和输出调整后的n个数。
    Book-Exercises-of-PLC-5th-THQ-8-4-1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdio.h>
void move(int *a,int n,int m)
{
int i,*p;
for(i=0;i<m;i++)
{
for(p=a+n;p>a;p--)
*p=*(p-1);
*a=*(a+n);
}
*(a+n)=0;
return ;
}
int main()
{
int a[101],n,m,i;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
scanf("%d",&m);
move(a,n,m);
for(i=0;i<n;i++)
printf("%d ",a[i]);
printf("\n");
return 0;
}
  1. 有n个人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stdio.h>
int main()
{
int a[100],n,k,m,i,*p=a;
scanf("%d",&n);
for(i=0;i<n;i++)
*(p+i)=i+1;
m=n;
k=0;
p=a;
while(m>1)
{
if(*p)
{
k=(k+1)%3;
if(!k)
{
*p=0;
m--;
}
}
p++;
if(p>=a+n)
p=a;
}
for(i=0;i<n;i++)
{
if(a[i])
p=&a[i];
}
printf("%d\n",*p);
return 0;
}
  1. 写一函数,求一个字符串的长度。在main函数中输入字符串,并输出其长度。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
int getlen(char *s)
{
char *p=s;
int n=0;
while(*p!='\0')
{
n++;
p++;
}
return n;
}
int main()
{
char s[100];
int n;
scanf("%s",s);
n=getlen(s);
printf("%d\n",n);
return 0;
}
  1. 有一字符串,包含n个字符。写一函数,将此字符串中从第m个字符开始的全部字符复制成为另一个字符串。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
void cpy(char *s1,char *s2,int n,int m)
{
char *p1=s1+m-1,*p2=s2;
for(;p1<=s1+n;p1++,p2++)
*p2=*p1;
return ;
}
int main()
{
char s1[100],s2[100];
int n,m;
scanf("%s",s1);
scanf("%d %d",&n,&m);
cpy(s1,s2,n,m);
printf("%s\n",s2);
return 0;
}
  1. 输入一行文字,找出其中大写字母、小写字母、空格、数字以及其他字符各有多少。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
void count(char *s,int *dx,int *xx,int *kg,int *sz,int *qt)
{
char *p=s;
for(;*p!='\0';p++)
{
if(*p>='A'&&*p<='Z')
(*dx)++;
else if(*p>='a'&&*p<='z')
(*xx)++;
else if(*p==' ')
(*kg)++;
else if(*p>='0'&&*p<='9')
(*sz)++;
else
(*qt)++;
}
return ;
}
int main()
{
char s[100];
gets(s);
int dx,xx,kg,sz,qt;
count(s,&dx,&xx,&kg,&sz,&qt);
printf("dx=%d,xx=%d,kg=%d,sz=%d,qt=%d\n",dx,xx,kg,sz,qt);
return 0;
}
  1. 写一函数,将一个 $3 \times 3$ 的整型矩阵转置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <stdio.h>
void transform(int *a)
{
int i,j,t;
for(i=0;i<3;i++)
{
for(j=0;j<i;j++)
{
t=*(a+i*3+j);
*(a+i*3+j)=*(a+j*3+i);
*(a+j*3+i)=t;
}
}
return ;
}
int main()
{
int a[3][3],i,j;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
scanf("%d",&a[i][j]);
transform(&a[0][0]);
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
printf("%d ",a[i][j]);
printf("\n");
}
return 0;
}
  1. 将一个 $5 \times 5$ 的矩阵中最大的元素放在中心,4个角分别放4个最小的元素(顺序为从左到右,从上到下依次从小到大存放),写一函数实现之。用main函数调用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <stdio.h>
void cope(int *a)
{
int i,j,t,*max=a+12,*min1=a,*min2=a+4,*min3=a+20,*min4=a+24;
for(i=0;i<5;i++)
for(j=0;j<5;j++)
{
if(*max<*(a+i*5+j))
max=a+i*5+j;
}
t=*(a+12);*(a+12)=*max;*max=t;
for(i=0;i<5;i++)
for(j=0;j<5;j++)
{
if(*min1>*(a+i*5+j))
min1=a+i*5+j;
}
t=*a;*a=*min1;*min1=t;
for(i=0;i<5;i++)
{
for(j=0;j<5;j++)
{
if(i==0&&j==0)continue;
if(*min2>*(a+i*5+j))
min2=a+i*5+j;
}
}
t=*(a+4);*(a+4)=*min2;*min2=t;
for(i=0;i<5;i++)
{
for(j=0;j<5;j++)
{
if(i==0&&j==0)continue;
if(i==0&&j==4)continue;
if(*min3>*(a+i*5+j))
min3=a+i*5+j;
}
}
t=*(a+20);*(a+20)=*min3;*min3=t;
for(i=0;i<5;i++)
{
for(j=0;j<5;j++)
{
if(i==0&&j==0)continue;
if(i==0&&j==4)continue;
if(i==4&&j==0)continue;
if(*min4>*(a+i*5+j))
min4=a+i*5+j;
}
}
t=*(a+24);*(a+24)=*min4;*min4=t;
return ;
}
int main()
{
int a[5][5],i,j;
for(i=0;i<5;i++)
for(j=0;j<5;j++)
scanf("%d",&a[i][j]);
cope(&a[0][0]);
for(i=0;i<5;i++)
{
for(j=0;j<5;j++)
printf("%d ",a[i][j]);
printf("\n");
}
return 0;
}
  1. 在主函数中输入等长的字符串。用另一函数对它们排序。然后在主函数输出这10个已排好序的字符串。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>
#include <string.h>
void sort(char (*p)[100])
{
int i,j;
char t[100];
for(i=0;i<9;i++)
{
for(j=0;j<9-i;j++)
{
if(strcmp(*(p+j),*(p+j+1))>0)
{
strcpy(t,*(p+j));
strcpy(*(p+j),*(p+j+1));
strcpy(*(p+j+1),t);
}
}
}
return ;
}
int main()
{
int i;
char s[10][100],(*p)[100];
for(i=0;i<10;i++)
scanf("%s",s[i]);
p=s;
sort(p);
for(i=0;i<10;i++)
printf("%s\n",s[i]);
return 0;
}
  1. 用指针数组处理上一题目,字符串不等长。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdio.h>
#include <string.h>
void sort(char *p[])
{
int i,j;
char *t;
for(i=0;i<9;i++)
{
for(j=0;j<9-i;j++)
{
if(strcmp(p[j],p[j+1])>0)
{
t=p[j];
p[j]=p[j+1];
p[j+1]=t;
}
}
}
return ;
}
int main()
{
int i;
char s[10][100],*p[10];
for(i=0;i<10;i++)
{
scanf("%s",s[i]);
p[i]=s[i];
}
sort(p);
for(i=0;i<10;i++)
printf("%s\n",p[i]);
return 0;
}
  1. 写一个用矩形法求定积分的通用函数,分别求
    $\int_{0}^{1} \sin{x}\mathrm{d}x$ , $\int_{-1}^{1} \cos{x}\mathrm{d}x$ , $\int_{0}^{2} \mathrm{e}^x\mathrm{d}x$
    说明: sin,cos,exp函数已在系统的数学函数库中,程序开头要用 #include <math.h>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdio.h>
#include <math.h>
double integral(double (*f)(double),double a,double b,int n)
{
int i;
double s=0,h,dx=(b-a)/(double)n,x=a;
for(i=0;i<n;i++)
{
h=(*f)(x);
s+=h*dx;
x+=dx;
}
return s;
}
int main()
{
int n=100000;
double I1,I2,I3;
I1=integral(sin,0,1,n);
I2=integral(cos,-1,1,n);
I3=integral(exp,0,2,n);
printf("Integral from 0 to 1 of sin(x) is %f\n",I1);
printf("Integral from -1 to 1 of cos(x) is %f\n",I2);
printf("Integral from 0 to 2 of exp(x) is %f\n",I3);
return 0;
}
  1. 将n个数按输入时顺序的逆序排列,用函数实现。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
void reverse(int *a,int n)
{
int i,t;
for(i=0;i<n/2;i++)
{
t=*(a+i);
*(a+i)=*(a+n-1-i);
*(a+n-1-i)=t;
}
return ;
}
int main()
{
int a[100],i,n;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
reverse(a,n);
for(i=0;i<n;i++)
printf("%d ",a[i]);
printf("\n");
return 0;
}
  1. 有一个班4个学生,5 门课程。①求第1门课程的平均分;②找出有两门以上课程不及格的学生,输出他们的学号和全部课程成绩及平均成绩;③找出平均成绩在90分以上或全部课程成绩在85分以上的学生。分别编3个函数实现以上3个要求。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <stdio.h>
double cou1ave(int (*a)[5])
{
double s=0;
int i;
for(i=0;i<4;i++)
s+=(*(a+i))[0];
s/=4;
return s;
}
void flunk(int *n,int (*a)[5],double *ave)
{
int i,j,num;
for(i=0;i<4;i++)
{
*(ave+i)=0;
num=0;
for(j=0;j<5;j++)
{
if((*(a+i))[j]<60)
num++;
*(ave+i)+=(*(a+i))[j];
}
*(ave+i)/=5.0;
if(num>=2)
{
printf("%d ",*(n+i));
for(j=0;j<5;j++)
printf("%d ",(*(a+i))[j]);
printf("%f\n",*(ave+i));
}
}
return ;
}
void find(int *n,int (*a)[5],double *ave)
{
int i,j,num;
for(i=0;i<4;i++)
{
num=0;
for(j=0;j<5;j++)
{
if((*(a+i))[j]>=85)
num++;
}
if(num==5||*(ave+i)>=90)
{
printf("%d ",*(n+i));
for(j=0;j<5;j++)
printf("%d ",(*(a+i))[j]);
printf("%f\n",*(ave+i));
}
}
return ;
}
int main()
{
int n[4],a[4][5],i,j;
double c1ave,ave[4];
for(i=0;i<4;i++)
{
scanf("%d",&n[i]);
for(j=0;j<5;j++)
scanf("%d",&a[i][j]);
}
c1ave=cou1ave(a);
printf("%f\n",c1ave);
flunk(n,a,ave);
find(n,a,ave);
return 0;
}
  1. 输入一个字符串,内有数字和非数字字符,例如:
    1
    A123x456 17960? 302tab5876
    将其中连续的数字作为一个整数,依次存放到一数组a中。例如,123放在a[0],456放在a[1]……统计共有多少个整数,并输出这些数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <stdio.h>
void cope(char *p,int *a,int *n)
{
int num=0,flag=0;
for(;*p!='\0';p++)
{
if(*p>='0'&&*p<='9')
{
flag=1;
num=num*10+*p-'0';
}
else
{
if(flag)
{
flag=0;
*(a+*n)=num;
num=0;
(*n)++;
}
}
}
if(flag)
{
flag=0;
*(a+*n)=num;
num=0;
(*n)++;
}
return ;
}
int main()
{
char s[100];
int a[100],n=0,i;
gets(s);
cope(s,a,&n);
printf("%d\n",n);
for(i=0;i<n;i++)
printf("%d ",a[i]);
printf("\n");
return 0;
}
  1. 写一函数,实现两个字符串的比较。即自己写一个strcmp函数,函数原型为
    1
    int strcmp(char * p1,char * p2);
    设p1指向字符串s1,p2指向字符串s2。要求当s1 $=$ s2时,返回值为0;若 s1 $\neq$ s2,返回它们二者第1个不同字符的ASCII码差值(如”BOY与”BAD”,第2个字母不同,O与A之差为79-65=14)。如果s1>s2,则输出正值;如果s1<s2,则输出负值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
int strcmp(char *p1,char *p2)
{
for(;*p1!='\0'||*p2!='\0';p1++,p2++)
if(*p1!=*p2)
return *p1-*p2;
return 0;
}
int main()
{
char s1[100],s2[100];
scanf("%s",s1);
scanf("%s",s2);
printf("%d\n",strcmp(s1,s2));
return 0;
}
  1. 编一程序,输入月份号,输出该月的英文月名。例如,输入3,则输出”March”,要求用指针数组处理。
1
2
3
4
5
6
7
8
9
#include <stdio.h>
int main()
{
int n;
char *p[13]={"Non-existent","January","February","March","April","May","June","July","August","September","October","November","December"};
scanf("%d",&n);
printf("%s\n",p[n]);
return 0;
}
  1. (1)编写一个函数new,对n个字符开辟连续的存储空间,此函数应返回一个指针(地址),指向字符串开始的空间。new(n)表示分配n个字节的内存空间。
    (2)写一函数free,将前面用new函数占用的空间释放。free(p)表示将p(地址)指向的单元以后的内存段释放。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stdio.h>
#define MAXSIZE 1000
char buf[MAXSIZE],*nowp=buf;
char *new(int size)
{
if(nowp+size<=buf+MAXSIZE)
{
nowp+=size;
return nowp-size;
}
else
return NULL;
}
void free(char *p)
{
if(p>=buf+MAXSIZE)
return ;
nowp=p;
while(p<buf+MAXSIZE)
{
*p='\0';
p++;
}
return ;
}
int main()
{
char *p=new(10);
scanf("%s",p);
printf("%s\n",p);
free(p);
return 0;
}
  1. 用指向指针的指针的方法对5个字符串排序并输出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <stdio.h>
#include <string.h>
void sort(char **P)
{
int i,j;
char *t;
for(i=0;i<4;i++)
{
for(j=0;j<4-i;j++)
{
if(strcmp(*(P+j),*(P+j+1))>0)
{
t=*(P+j);
*(P+j)=*(P+j+1);
*(P+j+1)=t;
}
}
}
return ;
}
int main()
{
char s[5][100],*p[5],**P;
int i;
for(i=0;i<5;i++)
{
scanf("%s",s[i]);
p[i]=s[i];
}
P=p;
sort(P);
for(i=0;i<5;i++)
printf("%s\n",p[i]);
return 0;
}
  1. 用指向指针的指针的方法对n个整数排序并输出。要求将排序单独写成一个函数。n个整数在主函数中输入,最后在主函数中输出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <stdio.h>
#include <string.h>
void sort(int **P,int n)
{
int i,j;
int *t;
for(i=0;i<n-1;i++)
{
for(j=0;j<n-1-i;j++)
{
if(**(P+j)-**(P+j+1)>0)
{
t=*(P+j);
*(P+j)=*(P+j+1);
*(P+j+1)=t;
}
}
}
return ;
}
int main()
{
int a[100],*p[100],**P;
int n,i;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
p[i]=&a[i];
}
P=p;
sort(P,n);
for(i=0;i<n;i++)
printf("%d ",*p[i]);
printf("\n");
return 0;
}

第9章 用户自己建立数据类型

  1. 定义一个结构体变量(包括年、月、日)。计算该日在本年中是第几天,注意闰年问题。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
struct date
{
int year,month,day;
}d;
int main()
{
int i,n=0,days[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
if((d.year%4==0&&d.year%100!=0)||(d.year%100==0&&d.year%400==0))
days[2]=29;
scanf("%d %d %d",&d.year,&d.month,&d.day);
for(i=1;i<d.month;i++)
n+=days[i];
n+=d.day;
printf("%d\n",n);
return 0;
}
  1. 写一个函数days,实现第1题的计算。由主函数将年、月、日传递给days函数,计算后将日子数传回主函数输出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
struct date
{
int year,month,day;
}d;
int days(struct date d)
{
int i,n=0,days[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
if((d.year%4==0&&d.year%100!=0)||(d.year%100==0&&d.year%400==0))
days[2]=29;
for(i=1;i<d.month;i++)
n+=days[i];
n+=d.day;
return n;
}
int main()
{
int n;
scanf("%d %d %d",&d.year,&d.month,&d.day);
n=days(d);
printf("%d\n",n);
return 0;
}
  1. 编写一个函数print,打印一个学生的成绩数组,该数组中有5个学生的数据记录,每个记录包括num,name,score[3],用主函数输入这些记录,用print函数输出这些记录。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stdio.h>
#define STU struct student
STU
{
int num,score[3];
char name[10];
}a[5];
void print(STU a[])
{
int i,j;
for(i=0;i<5;i++)
{
printf("%d ",a[i].num);
printf("%s ",a[i].name);
for(j=0;j<3;j++)
printf("%d ",a[i].score[j]);
printf("\n");
}
return ;
}
int main()
{
int i,j;
for(i=0;i<5;i++)
{
scanf("%d",&a[i].num);
scanf("%s",a[i].name);
for(j=0;j<3;j++)
scanf("%d",&a[i].score[j]);
}
print(a);
return 0;
}
  1. 在第3题的基础上,编写一个函数input,用来输入5个学生的数据记录。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stdio.h>
#define STU struct student
STU
{
int num,score[3];
char name[10];
}a[5];
void input(STU a[])
{
int i,j;
for(i=0;i<5;i++)
{
scanf("%d",&a[i].num);
scanf("%s",a[i].name);
for(j=0;j<3;j++)
scanf("%d",&a[i].score[j]);
}
return ;
}
void print(STU a[])
{
int i,j;
for(i=0;i<5;i++)
{
printf("%d ",a[i].num);
printf("%s ",a[i].name);
for(j=0;j<3;j++)
printf("%d ",a[i].score[j]);
printf("\n");
}
return ;
}
int main()
{
input(a);
print(a);
return 0;
}
  1. 有10个学生,每个学生的数据包括学号、姓名、3门课程的成绩,从键盘输入10个学生数据,要求输出3门课程总平均成绩,以及最高分的学生的数据(包括学号、姓名、3门课程成绩、平均分数)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <stdio.h>
#define STU struct student
STU
{
int num,score[3];
char name[10];
double aver;
}a[10];
void input(STU a[])
{
int i,j;
for(i=0;i<10;i++)
{
scanf("%d",&a[i].num);
scanf("%s",a[i].name);
for(j=0;j<3;j++)
scanf("%d",&a[i].score[j]);
}
return ;
}
void print(STU a)
{
int i;
printf("%d ",a.num);
printf("%s ",a.name);
for(i=0;i<3;i++)
printf("%d ",a.score[i]);
printf("\n");
printf("%f\n",a.aver);
return ;
}
int main()
{
int i,j,max=0;
input(a);
for(i=0;i<10;i++)
{
a[i].aver=0;
for(j=0;j<3;j++)
a[i].aver+=a[i].score[j];
a[i].aver/=3.0;
if(a[max].aver<a[i].aver)
max=i;
}
for(i=0;i<10;i++)
printf("%f ",a[i].aver);
printf("\n");
print(a[max]);
return 0;
}
  1. 13个人围成一圈,从第1个人开始顺序报号1,2,3。凡报到3者退出圈子。找出最后留在圈子中的人原来的序号。要求用链表实现。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>
struct person
{
int num;
struct person *next;
}a[13];

int main()
{
int i,k=0,m=13;
for(i=0;i<13;i++)
a[i].num=i+1;
for(i=0;i<12;i++)
a[i].next=&a[i+1];
a[12].next=&a[0];
struct person *now=&a[0];
while(m>1)
{
while(!now->num)now=now->next;
k=(k+1)%3;
if(!k)
{
now->num=0;
m--;
}
now=now->next;
}
for(i=0;i<13;i++)
if(a[i].num)
printf("%d\n",a[i].num);
return 0;
}
  1. 在第9章例9.9例9.10的基础上,写一个函数del,用来删除动态链表中指定的结点。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <stdio.h>
#include <stdlib.h>
#define STU struct student
STU
{
int num;
double score;
STU *next;
};
STU *creat(void)
{
STU *head,*p,*t;
int num;
double score;
head=p=(STU *)malloc(sizeof(STU));
t=NULL;
scanf("%d,%lf",&num,&score);
while(num!=0)
{
if(t!=NULL)p=t;
p->num=num;
p->score=score;
t=p->next=(STU *)malloc(sizeof(STU));
scanf("%d,%lf",&num,&score);
}
p->next=NULL;
return head;
}
void print(STU *head)
{
STU *p=head;
while(p!=NULL)
{
printf("%d %f\n",p->num,p->score);
p=p->next;
}
return ;
}
STU *del(STU *head,int num)
{
STU *p=head,*last;
while(p!=NULL)
{
if(p->num==num)
break;
last=p;
p=p->next;
}
if(p==NULL)
{
printf("Not in this link list.\n");
}
else if(p==head)
{
head=p->next;
printf("Deleted.\n");
}
else
{
last->next=p->next;
printf("Deleted.\n");
}
return head;
}
int main()
{
STU *head;
head=creat();
int num;
scanf("%d",&num);
head=del(head,num);
print(head);
return 0;
}
  1. 写一个函数insert,用来向一个动态链表插入结点。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <stdio.h>
#include <stdlib.h>
#define STU struct student
STU
{
int num;
double score;
STU *next;
};
STU *creat(void)
{
STU *head,*p,*t;
int num;
double score;
head=p=(STU *)malloc(sizeof(STU));
t=NULL;
scanf("%d,%lf",&num,&score);
while(num!=0)
{
if(t!=NULL)p=t;
p->num=num;
p->score=score;
t=p->next=(STU *)malloc(sizeof(STU));
scanf("%d,%lf",&num,&score);
}
p->next=NULL;
return head;
}
void print(STU *head)
{
STU *p=head;
while(p!=NULL)
{
printf("%d %f\n",p->num,p->score);
p=p->next;
}
return ;
}
STU *insert(STU *head,STU *stud)
{
STU *p=head,*last;
while(p!=NULL)
{
if(p->num>stud->num)
break;
last=p;
p=p->next;
}
if(p==head)
{
stud->next=p;
head=stud;
}
else if(p==NULL)
{
stud->next=NULL;
last->next=stud;
}
else
{
stud->next=p;
last->next=stud;
}
return head;
}
int main()
{
STU *head,*stud;
head=creat();
int num;
scanf("%d",&num);
head=del(head,num);
stud=(STU *)malloc(sizeof(STU));
scanf("%d,%lf",&stud->num,&stud->score);
head=insert(head,stud);
print(head);
return 0;
}
  1. 综合本章例9.9(建立链表的函数creat)、例9.10(输出链表的函数print)本章习题第7题(除链表中结点的函数del)、第8题(插入结点的函数insert),再编写一个主函数,先后调用这些函数。用以上5个函数组成一个程序,实现链表的建立、输出、删除和插入,在主函数中指定需要删除和插入的结点的数据。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include <stdio.h>
#include <stdlib.h>
#define STU struct student
STU
{
int num;
double score;
STU *next;
};
STU *creat(void)
{
STU *head,*p,*t;
int num;
double score;
head=p=(STU *)malloc(sizeof(STU));
t=NULL;
scanf("%d,%lf",&num,&score);
while(num!=0)
{
if(t!=NULL)p=t;
p->num=num;
p->score=score;
t=p->next=(STU *)malloc(sizeof(STU));
scanf("%d,%lf",&num,&score);
}
p->next=NULL;
return head;
}
void print(STU *head)
{
STU *p=head;
while(p!=NULL)
{
printf("%d %f\n",p->num,p->score);
p=p->next;
}
return ;
}
STU *del(STU *head,int num)
{
STU *p=head,*last;
while(p!=NULL)
{
if(p->num==num)
break;
last=p;
p=p->next;
}
if(p==NULL)
{
printf("Not in this link list.\n");
}
else if(p==head)
{
head=p->next;
printf("Deleted.\n");
}
else
{
last->next=p->next;
printf("Deleted.\n");
}
return head;
}
STU *insert(STU *head,STU *stud)
{
STU *p=head,*last;
while(p!=NULL)
{
if(p->num>stud->num)
break;
last=p;
p=p->next;
}
if(p==head)
{
stud->next=p;
head=stud;
}
else if(p==NULL)
{
stud->next=NULL;
last->next=stud;
}
else
{
stud->next=p;
last->next=stud;
}
return head;
}
int main()
{
STU *head,*stud;
head=creat();
int num;
scanf("%d",&num);
head=del(head,num);
stud=(STU *)malloc(sizeof(STU));
scanf("%d,%lf",&stud->num,&stud->score);
head=insert(head,stud);
print(head);
return 0;
}
  1. 已有a,b两个链表,每个链表中的结点包括学号、成绩。要求把两个链表合并,按学号升序排列。

调用已有函数版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <stdio.h>
#include <stdlib.h>
#define STU struct student
STU
{
int num;
double score;
STU *next;
};
STU *creat(void)
{
STU *head,*p,*t;
int num;
double score;
head=p=(STU *)malloc(sizeof(STU));
t=NULL;
scanf("%d,%lf",&num,&score);
while(num!=0)
{
if(t!=NULL)p=t;
p->num=num;
p->score=score;
t=p->next=(STU *)malloc(sizeof(STU));
scanf("%d,%lf",&num,&score);
}
p->next=NULL;
return head;
}
void print(STU *head)
{
STU *p=head;
while(p!=NULL)
{
printf("%d %f\n",p->num,p->score);
p=p->next;
}
return ;
}
STU *insert(STU *head,STU *stud)
{
STU *p=head,*last;
while(p!=NULL)
{
if(p->num>stud->num)
break;
last=p;
p=p->next;
}
if(p==head)
{
stud->next=p;
head=stud;
}
else if(p==NULL)
{
stud->next=NULL;
last->next=stud;
}
else
{
stud->next=p;
last->next=stud;
}
return head;
}
STU *merge(STU *heada,STU *headb)
{
STU *pb=headb;
while(headb!=NULL)
{
headb=headb->next;
heada=insert(heada,pb);
pb=headb;
}
return heada;
}
int main()
{
STU *heada,*headb;
heada=creat();
headb=creat();
heada=merge(heada,headb);
print(heada);
return 0;
}

单独函数版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <stdio.h>
#include <stdlib.h>
#define STU struct student
STU
{
int num;
double score;
STU *next;
};
STU *creat(void)
{
STU *head,*p,*t;
int num;
double score;
head=p=(STU *)malloc(sizeof(STU));
t=NULL;
scanf("%d,%lf",&num,&score);
while(num!=0)
{
if(t!=NULL)p=t;
p->num=num;
p->score=score;
t=p->next=(STU *)malloc(sizeof(STU));
scanf("%d,%lf",&num,&score);
}
p->next=NULL;
return head;
}
void print(STU *head)
{
STU *p=head;
while(p!=NULL)
{
printf("%d %f\n",p->num,p->score);
p=p->next;
}
return ;
}
STU *merge(STU *heada,STU *headb)
{
STU *pa=heada,*pb=headb,*last;
while(headb!=NULL)
{
while(pa!=NULL)
{
if(pa->num>headb->num)
break;
last=pa;
pa=pa->next;
}
if(pa==heada)
{
headb=headb->next;
pb->next=pa;
heada=pb;
pb=headb;
}
else if(pa==NULL)
{
last->next=headb;
headb=pb=NULL;
break;
}
else
{
last->next=headb;
headb=headb->next;
pb->next=pa;
pb=headb;
}
}
return heada;
}
int main()
{
STU *heada,*headb;
heada=creat();
headb=creat();
heada=merge(heada,headb);
print(heada);
return 0;
}
  1. 有两个链表a和 b,设结点中包含学号、姓名。从a链表中删去与b链表中有相同学号的那些结点。

调用已有函数版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <stdio.h>
#include <stdlib.h>
#define STU struct student
STU
{
int num;
double score;
STU *next;
};
STU *creat(void)
{
STU *head,*p,*t;
int num;
double score;
head=p=(STU *)malloc(sizeof(STU));
t=NULL;
scanf("%d,%lf",&num,&score);
while(num!=0)
{
if(t!=NULL)p=t;
p->num=num;
p->score=score;
t=p->next=(STU *)malloc(sizeof(STU));
scanf("%d,%lf",&num,&score);
}
p->next=NULL;
return head;
}
void print(STU *head)
{
STU *p=head;
while(p!=NULL)
{
printf("%d %f\n",p->num,p->score);
p=p->next;
}
return ;
}
STU *del(STU *head,int num)
{
STU *p=head,*last;
while(p!=NULL)
{
if(p->num==num)
break;
last=p;
p=p->next;
}
if(p==NULL)
{
printf("Not in this link list.\n");
}
else if(p==head)
{
head=p->next;
printf("Deleted.\n");
}
else
{
last->next=p->next;
printf("Deleted.\n");
}
return head;
}
STU *unique(STU *heada,STU *headb)
{
STU *pb=headb;
while(pb!=NULL)
{
heada=del(heada,pb->num);
pb=pb->next;
}
return heada;
}
int main()
{
STU *heada,*headb;
heada=creat();
headb=creat();
heada=unique(heada,headb);
print(heada);
return 0;
}

单独函数版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <stdio.h>
#include <stdlib.h>
#define STU struct student
STU
{
int num;
double score;
STU *next;
};
STU *creat(void)
{
STU *head,*p,*t;
int num;
double score;
head=p=(STU *)malloc(sizeof(STU));
t=NULL;
scanf("%d,%lf",&num,&score);
while(num!=0)
{
if(t!=NULL)p=t;
p->num=num;
p->score=score;
t=p->next=(STU *)malloc(sizeof(STU));
scanf("%d,%lf",&num,&score);
}
p->next=NULL;
return head;
}
void print(STU *head)
{
STU *p=head;
while(p!=NULL)
{
printf("%d %f\n",p->num,p->score);
p=p->next;
}
return ;
}
STU *unique(STU *heada,STU *headb)
{
STU *pa=heada,*pb=headb,*last;
while(pa!=NULL)
{
while(pa->num>pb->num)
pb=pb->next;
if(pa->num==pb->num)
{
if(pa==heada)
{
heada=heada->next;
pa=heada;
}
else
{
last->next=pa->next;
pa=pa->next;
}
}
else
{
last=pa;
pa=pa->next;
}
}
return heada;
}
int main()
{
STU *heada,*headb;
heada=creat();
headb=creat();
heada=unique(heada,headb);
print(heada);
return 0;
}
  1. 建立一个链表,每个结点包括:学号、姓名、性别、年龄。输入一个年龄,如果链表中的结点所包含的年龄等于此年龄,则将此结点删去。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STU struct student
STU
{
int num,age;
char name[10],sex;
STU *next;
};
STU *creat(void)
{
STU *head,*p,*t;
int num,age;
char name[10],sex;
head=p=(STU *)malloc(sizeof(STU));
t=NULL;
scanf("%d %s %c %d",&num,name,&sex,&age);
while(num!=0)
{
if(t!=NULL)p=t;
p->num=num;
strcpy(p->name,name);
p->sex=sex;
p->age=age;
t=p->next=(STU *)malloc(sizeof(STU));
scanf("%d %s %c %d",&num,name,&sex,&age);
}
p->next=NULL;
return head;
}
void print(STU *head)
{
STU *p=head;
while(p!=NULL)
{
printf("%d %s %c %d\n",p->num,p->name,p->sex,p->age);
p=p->next;
}
return ;
}
STU *del(STU *head,int age)
{
STU *p=head,*last;
while(p!=NULL)
{
while(p!=NULL)
{
if(p->age==age)
break;
last=p;
p=p->next;
}
if(p==NULL)
{
printf("Not in this link list.\n");
}
else if(p==head)
{
head=p->next;
p=head;
printf("Deleted.\n");
}
else
{
last->next=p->next;
p=last->next;
printf("Deleted.\n");
}
}
return head;
}
int main()
{
STU *head;
int age;
head=creat();
scanf("%d",&age);
head=del(head,age);
print(head);
return 0;
}

第10章 对文件的输入输出

  1. 什么是文件型指针?通过文件指针访问文件有什么好处?

  2. 对文件的打开与关闭的含义是什么?为什么要打开和关闭文件?

  3. 从键盘输入一个字符串,将其中的小写字母全部转换成大写字母,然后输出到一个磁盘文件test中保存,输入的字符串以“!”结束。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp;
char s[100];
int i;
gets(s);
for(i=0;s[i]!='!';i++)
{
if(s[i]>='a'&&s[i]<='z')
s[i]-=32;
}
if((fp=fopen("test","w"))==NULL)
{
printf("Can not open file \"test\" !\n");
exit(0);
}
for(i=0;s[i]!='!';i++)
{
fputc(s[i],fp);
}
fclose(fp);
return 0;
}
  1. 有两个磁盘文件A和B,各存放一行字母,今要求把这两个文件中的信息合并(按字母顺序排列),输出到一个新文件C中去。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp;
char s[100],c,t;
int i,j,n;
if((fp=fopen("A","r"))==NULL)
{
printf("Can not open file \"A\" !\n");
exit(0);
}
for(i=0;(c=fgetc(fp))!=EOF;i++)
s[i]=c;
fclose(fp);
if((fp=fopen("B","r"))==NULL)
{
printf("Can not open file \"B\" !\n");
exit(0);
}
for(;(c=fgetc(fp))!=EOF;i++)
s[i]=c;
fclose(fp);
n=i;
s[n]='\0';
for(i=0;i<n-1;i++)
{
for(j=0;j<n-1-i;j++)
{
if(s[j]>s[j+1])
{
t=s[j];
s[j]=s[j+1];
s[j+1]=t;
}
}
}
if((fp=fopen("C","w"))==NULL)
{
printf("Can not open file \"C\" !\n");
exit(0);
}
fputs(s,fp);
fclose(fp);
return 0;
}
  1. 有5个学生,每个学生有3门课程的成绩,从键盘输入学生数据(包括学号,姓名,3门课程成绩),计算出平均成绩,将原有数据和计算出的平均分数存放在磁盘文件stud中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>
#include <stdlib.h>
#define STU struct student
STU
{
int num,score[3];
char name[10];
double ave;
}stu[5];
int main()
{
FILE *fp;
int i,j;
for(i=0;i<5;i++)
{
scanf("%d",&stu[i].num);
scanf("%s",stu[i].name);
for(j=0;j<3;j++)
scanf("%d",&stu[i].score[j]);
}
for(i=0;i<5;i++)
{
stu[i].ave=0;
for(j=0;j<3;j++)
stu[i].ave+=stu[i].score[j];
stu[i].ave/=3.0;
}
if((fp=fopen("stud","w"))==NULL)
{
printf("Can not open file \"stud\" !\n");
exit(0);
}
for(i=0;i<5;i++)
{
if(fwrite(&stu[i],sizeof(STU),1,fp)!=1)
{
printf("Write Error!\n");
}
}
fclose(fp);
return 0;
}
  1. 将第5题stud文件中的学生数据,按平均分进行排序处理,将已排序的学生数据存入一个新文件stu_sort中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <stdio.h>
#include <stdlib.h>
#define STU struct student
STU
{
int num,score[3];
char name[10];
double ave;
}stu[5],t;
int main()
{
FILE *fp;
int i,j,n;
if((fp=fopen("stud","r"))==NULL)
{
printf("Can not open file \"stud\" !\n");
exit(0);
}
for(i=0;fread(&stu[i],sizeof(STU),1,fp)!=0;i++);
n=i;
fclose(fp);
for(i=0;i<n-1;i++)
{
for(j=0;j<n-1-i;j++)
{
if(stu[j].ave<stu[j+1].ave)
{
t=stu[j];
stu[j]=stu[j+1];
stu[j+1]=t;
}
}
}
if((fp=fopen("stu_sort","w"))==NULL)
{
printf("Can not open file \"stu_sort\" !\n");
exit(0);
}
for(i=0;i<n;i++)
{
if(fwrite(&stu[i],sizeof(STU),1,fp)!=1)
{
printf("Write Error!\n");
}
}
fclose(fp);
return 0;
}
  1. 将第6题已排序的学生成绩文件进行插入处理。插入一个学生的3门课程成绩,程序先计算新插入学生的平均成绩,然后将它按成绩高低顺序插入,插入后建立一个新文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <stdio.h>
#include <stdlib.h>
#define STU struct student
STU
{
int num,score[3];
char name[10];
double ave;
}stu[6],t;
int main()
{
FILE *fp;
int i,j,n;
if((fp=fopen("stu_sort","r"))==NULL)
{
printf("Can not open file \"stu_sort\" !\n");
exit(0);
}
for(i=0;fread(&stu[i],sizeof(STU),1,fp)!=0;i++);
n=i;
fclose(fp);
scanf("%d",&t.num);
scanf("%s",t.name);
for(i=0;i<3;i++)
scanf("%d",&t.score[i]);
t.ave=0;
for(i=0;i<3;i++)
t.ave+=t.score[i];
t.ave/=3.0;
for(i=0;i<n;i++)
{
if(t.ave>stu[i].ave)
break;
}
for(j=n;j>i;j--)
stu[j]=stu[j-1];
stu[i]=t;
n++;
if((fp=fopen("stu_new","w"))==NULL)
{
printf("Can not open file \"stu_new\" !\n");
exit(0);
}
for(i=0;i<n;i++)
{
if(fwrite(&stu[i],sizeof(STU),1,fp)!=1)
{
printf("Write Error!\n");
}
}
fclose(fp);
return 0;
}
  1. 将第7题结果仍存入原有的stu_sort文件而不另建立新文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <stdio.h>
#include <stdlib.h>
#define STU struct student
STU
{
int num,score[3];
char name[10];
double ave;
}stu[6],t;
int main()
{
FILE *fp;
int i,j,n;
if((fp=fopen("stu_sort","r"))==NULL)
{
printf("Can not open file \"stu_sort\" !\n");
exit(0);
}
for(i=0;fread(&stu[i],sizeof(STU),1,fp)!=0;i++);
n=i;
fclose(fp);
scanf("%d",&t.num);
scanf("%s",t.name);
for(i=0;i<3;i++)
scanf("%d",&t.score[i]);
t.ave=0;
for(i=0;i<3;i++)
t.ave+=t.score[i];
t.ave/=3.0;
for(i=0;i<n;i++)
{
if(t.ave>stu[i].ave)
break;
}
for(j=n;j>i;j--)
stu[j]=stu[j-1];
stu[i]=t;
n++;
if((fp=fopen("stu_sort","w"))==NULL)
{
printf("Can not open file \"stu_sort\" !\n");
exit(0);
}
for(i=0;i<n;i++)
{
if(fwrite(&stu[i],sizeof(STU),1,fp)!=1)
{
printf("Write Error!\n");
}
}
fclose(fp);
return 0;
}
  1. 有一磁盘文件employee,内存放职工的数据。每个职工的数据包括职工姓名、职工号、性别、年龄、住址、工资、健康状况、文化程度。今要求将职工名、工资的信息单独抽出来另建一个简明的职工工资文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define EMP1 struct employee1
#define EMP2 struct employee2
EMP1
{
int num,age,salary;
char name[10],sex,addr[20],health[10],degree[10];
}emp1[10];
EMP2
{
int salary;
char name[10];
}emp2[10];
int main()
{
FILE *fp;
int i,n;
if((fp=fopen("employee","r"))==NULL)
{
printf("Can not open file \"employee\" !\n");
exit(0);
}
for(i=0;fread(&emp1[i],sizeof(EMP1),1,fp)!=0;i++)
{
strcpy(emp2[i].name,emp1[i].name);
emp2[i].salary=emp1[i].salary;
}
n=i;
fclose(fp);
if((fp=fopen("salary","w"))==NULL)
{
printf("Can not open file \"salary\" !\n");
exit(0);
}
for(i=0;i<n;i++)
{
if(fwrite(&emp2[i],sizeof(EMP2),1,fp)!=1)
{
printf("Write Error!\n");
}
}
fclose(fp);
return 0;
}
  1. 从第9题的“职工工资文件”中删去一个职工的数据,再存回原文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define EMP2 struct employee2
EMP2
{
int salary;
char name[10];
}emp2[10];
int main()
{
FILE *fp;
int i,n;
char name[10];
if((fp=fopen("salary","r"))==NULL)
{
printf("Can not open file \"salary\" !\n");
exit(0);
}
for(i=0;fread(&emp2[i],sizeof(EMP2),1,fp)!=0;i++);
n=i;
fclose(fp);
scanf("%s",name);
for(i=0;i<n;i++)
{
if(strcmp(emp2[i].name,name)==0)
break;
}
if(i==n)
{
printf("Not in this file!\n");
}
else
{
for(;i<n-1;i++)
emp2[i]=emp2[i+1];
n--;
printf("Deleted!\n");
}
if((fp=fopen("salary","w"))==NULL)
{
printf("Can not open file \"salary\" !\n");
exit(0);
}
for(i=0;i<n;i++)
{
if(fwrite(&emp2[i],sizeof(EMP2),1,fp)!=1)
{
printf("Write Error!\n");
}
}
fclose(fp);
return 0;
}
  1. 从键盘输入若干行字符(每行长度不等),输入后把它们存储到一磁盘文件中。再从该文件中读入这些数据,将其中小写字母转换成大写字母后在显示屏上输出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp;
char s[100],c='Y';
int i;
if((fp=fopen("file","w"))==NULL)
{
printf("Can not open file \"file\" !\n");
exit(0);
}
while(c!='N'&&c!='n')
{
gets(s);
fputs(s,fp);
printf("Continue?(Y,y or N,n)");
c=getchar();getchar();
}
fclose(fp);
if((fp=fopen("file","r"))==NULL)
{
printf("Can not open file \"file\" !\n");
exit(0);
}
while(fgets(s,99,fp)!=NULL)
{
for(i=0;s[i]!='\0';i++)
{
if(s[i]>='a'&&s[i]<='z')
s[i]-=32;
}
puts(s);
}
fclose(fp);
return 0;
}

知识共享许可协议

知识共享许可协议

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏