# C Primer Plus 第六版 第10章 编程练习

#### 1.修改程序清单 10.7 的 rain.c 程序，用指针进行计算（仍要声明并初始化数组）。

#include <stdio.h>
#define MONTHS 12
#define YEARS   5
int main(void)
{
const float rain[YEARS][MONTHS] =
{
{4.3,4.3,4.3,3.0,2.0,1.2,0.2,0.2,0.4,2.4,3.5,6.6},
{8.5,8.2,1.2,1.6,2.4,0.0,5.2,0.9,0.3,0.9,1.4,7.3},
{9.1,8.5,6.7,4.3,2.1,0.8,0.2,0.2,1.1,2.3,6.1,8.4},
{7.2,9.9,8.4,3.3,1.2,0.8,0.4,0.0,0.6,1.7,4.3,6.2},
{7.6,5.6,3.8,2.8,3.8,0.2,0.0,0.0,0.0,1.3,2.6,5.2}
};
int year, month;
float subtot, total;

printf(" YEAR    RAINFALL  (inches)\n");
for (year = 0, total = 0; year < YEARS; year++)
{
for (month = 0, subtot = 0; month < MONTHS; month++)
subtot += *(*(rain+year)+month);
printf("%5d %15.1f\n", 2010 + year, subtot);
total += subtot;
}
printf("\nThe yearly average is %.1f inches.\n\n",
total/YEARS);
printf("MONTHLY AVERAGES:\n\n");
printf(" Jan  Feb  Mar  Apr  May  Jun  Jul  Aug  Sep ");
printf(" Oct  Nov  Dec\n");

for (month = 0; month < MONTHS; month++)
{
for (year = 0, subtot =0; year < YEARS; year++)
subtot += *(*(rain+year)+month);
printf("%4.1f ", subtot/YEARS);
}
printf("\n");

return 0;
}


#### 2.编写一个程序，初始化一个 double 类型的数组，然后把该数组的内容拷贝至 3 个其他数组中（在 main() 中声明这 4 个数组）。使用带数组表示法的函数进行第 1 份拷贝。使用带指针表示法和指针递增的函数进行第 2 份拷贝。把目标数组名和待拷贝的元素个数作为前两个函数的参数。第 3 个函数以目标数组名、源数组名和指向源数组的最后一个元素后面元素的指针。也就是说，给定以下声明，则函数调用如下所示：

copy_arr(target1, source, 5);
copy_ptr(target2, source, 5);

copy_ptrs(target3, source, source+5);

print(source,5);
print(target1,5);
print(target2,5);
print(target3,5);

#include <stdio.h>

void copy_arr(double ar[], double so[], int n);
void copy_ptr(double *ar, double *so, int n);
void copy_ptrs(double *ar, double *so, double *end);
void print(double *ar, int n);

int main(void)
{
double source[5] = {1.1,2.2,3.3,4.4,5.5};
double target1[5];
double target2[5];
double target3[5];

copy_arr(target1, source, 5);
copy_ptr(target2, source, 5);

copy_ptrs(target3, source, source+5);

print(source,5);
print(target1,5);
print(target2,5);
print(target3,5);
}

void copy_arr(double ar[], double so[], int n)
{
int i;

for (i = 0; i < n; i++)
ar[i] = so[i];
}

void copy_ptr(double *ar, double *so, int n)
{
while (--n >= 0)
*(ar++) = *(so++);
}

void copy_ptrs(double *ar, double *so, double *end)
{
while (so < end)
{
*(ar++) = *(so++);
}
}

void print(double *ar, int n)
{
int i;

for (i = 0; i < n; i++)
{
printf("%.1f ",ar[i]);
}
printf("\n");
}


#### 3.编写一个函数，返回存储在 int 类型的数组中的最大值，并在一个简单的程序中测试该函数。

#include <stdio.h>

int maxar(int ar[], int n);

int main(void)
{
int ar[10]={12,2,9,8,7,6,5,4,11,2};

printf("最大值为:%d\n",maxar(ar,10));

return 0;
}

int maxar(int ar[], int n)
{
int i;
int max = ar[0];

for (i = 1; i < n; i++)
if (max < ar[i])
max = ar[i];

return max;
}


#### 4.编写一个函数，返回存储在 double 类型数组中最大值的下标，并在一个简单的程序中测试该函数。

#include <stdio.h>

int maxar(double ar[], int n);

int main(void)
{
double ar[10]={1.1,2.2,4.4,3.3,9.9,
5.5,10.10,8.8,7.7,11.11};
printf("最大值下标为:%d\n",maxar(ar,10));

return 0;
}

int maxar(double ar[], int n)
{
int i;
int index = 0;

for (i = 1; i < n; i++)
if (ar[index] < ar[i])
index = i;

return index;
}


#### 5.编写一个函数，返回存储在 double 类型数组中的最大值和最小值的差值，并在一个简单的程序中测试该函数。

#include <stdio.h>

double diffar(double ar[], int n);

int main(void)
{
double ar[10]={10.1,2.2,3.5,6.5,1.0,22.3,5.5,6.6,7.7,8.8};

printf("差值为:%f\n",diffar(ar,10));

return 0;
}

double diffar(double ar[], int n)
{
int i;
double max,min;
max = min = ar[0];

for (i = 0; i < n; i++)
if (min > ar[i])
min = ar[i];

for (i = 0; i < n; i++)
if (max < ar[i])
max = ar[i];

return (max-min);
}


#### 6.编写一个函数，把 double 类型数组中的数据倒序排列，并在一个简单的程序中测试该函数。

#include <stdio.h>

void revorde(double ar[], int n);
void print(double ar[], int n);

int main(void)
{
double ar[10]={10.2,45.2,111.43,22.45,99.1,223.3,
55.44,66.55,66.77,77.88};

print(ar,10);
revorde(ar,10);
print(ar,10);

return 0;
}

void revorde(double ar[], int n)
{
int i,j;
double temp;

for (j = 0; j < n-1; j++)
for (i = j+1; i < n; i++)
if (ar[j] > ar[i])
{
temp = ar[j];
ar[j] = ar[i];
ar[i] = temp;
}
}

void print(double ar[], int n)
{
int i;

for (i = 0; i < n; i++)
{
printf("%.2f  ",ar[i]);
}
putchar('\n');
}


#### 7.编写一个程序，初始化一个 double 类型的二维数组，使用编程练习 2 中的一个拷贝函数把该数组中的数据拷贝至另一个二维数组中 （因为二维数组是数组的数组，所以可以使用处理一维数组的拷贝函数来处理数组中的每个子数组）。

#include <stdio.h>

void copy(double *ar, double *so, int n);
void print(double (*ar)[5], int n);

int main(void)
{
int i;
double ar[5][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};
double so[5][5];

for (i = 0; i < 5; i++)
copy(ar[i],so[i],5);

print(so,5);

return 0;
}

void copy(double *ar, double *so, int n)
{
int i;

for (i = 0; i < 5; i++)
*(so+i) = *(ar+i);
}

void print(double (*ar)[5], int n)
{
int i,j;

for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
printf("%.1f ",*(*(ar+i)+j));
putchar('\n');
}
}


#### 8.使用编程练习 2 中的拷贝函数，把一个内含 7 个元素的数组中第 3~第 5 个元素拷贝至内含 3 个元素的数组中。该函数本身不需要修改，只需要选择合适的实际参数（实际参数不需要是数组名和数组大小，只需要是数组元素的地址和待处理元素的个数）。

#include <stdio.h>

void copy_arr(int *ar, int *so, int n);
void print(int *ar, int n);

int main(void)
{
int so[7]={1,2,3,4,5,6,7};
int ar[3];

copy_arr(ar,so+2,3);
print(ar,3);

return 0;
}

void copy_arr(int *ar, int *so, int n)
{
int i;

for (i=0;i<n;i++)
ar[i] = so[i];
}

void print(int *ar, int n)
{
int i;

for (i=0;i<n;i++)
printf("%d ",ar[i]);
printf("\n");
}


#### 9.编写一个程序，初始化一个 double 类型 3 x 5 二维数组，使用一个处理变长数组的函数将其拷贝至另一个二维数组中。还要编写一个以变长数组为形参的函数以显示两个数组的内容。这两个函数应该能处理任意 N x M 数组。

#include <stdio.h>

void copy(int n, int m, double so[n][m], double ar[n][m]);
void print(int n, int m, double ar[n][m]);

int main(void)
{
double so[5][5]={{1,2,3,4,5},
{6,7,8,9,10},
{11,12,13,14,15}};
double ar[5][5];
copy(5,5,so,ar);
print(5,5,so);
print(5,5,ar);

return 0;
}

void copy(int n, int m, double so[n][m], double ar[n][m])
{
int i,j;

for (i=0;i<n;i++)
for (j=0;j<m;j++)
ar[i][j] = so[i][j];
}

void print(int n, int m, double ar[n][m])
{
int i,j;

for (i=0;i<n;i++)
{
for (j=0;j<5;j++)
printf("%.2f ",ar[i][j]);
printf("\n");
}
}


#### 10.编写一个函数，把两个数组中相对应的元素相加，然后把结果存储在第 3 个数组中。也就是说，如果数组 1 中包含的值是 2、4、5、8，数组 2 中包含的值是 1、0、4、6，那么该函数把 3、4、9、14 赋给第 3 个数组。函数接受 3 个数组名和一个数组大小。在一个简单的程序中测试该函数。

#include <stdio.h>

void sum(int *ar1, int *ar2, int *ar3, int n);
void print(int *ar, int n);

int main(void)
{
int ar1[4]={1,3,5,7};
int ar2[4]={2,4,6,8};
int ar3[4];

sum(ar1,ar2,ar3,4);

print(ar1,4);
print(ar2,4);
print(ar3,4);

return 0;
}

void sum(int *ar1, int *ar2, int *ar3, int n)
{
int i;

for (i = 0; i < n; i++)
*(ar3+i) = *(ar1+i) + *(ar2+i);
}

void print(int *ar, int n)
{
int i;
for (i = 0; i < n; i++)
printf("%5d",ar[i]);
printf("\n");
}


#### 11.编写一个程序，声明一个 int 类型的 3 x 5 二维数组，并用合适的值初始化它。该程序打印数组中的值，然后个值翻倍（即是原值的 2 倍），并显示出各元素的新值。编写一个函数显示数组的内容，在编写一个函数把各元素的值翻倍。这两个函数都以函数名和行数作为参数。

#include <stdio.h>

void print(int (*ar)[5], int n);
void dou(int (*ar)[5], int n);

int main(void)
{
int ar[3][5]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

print(ar,3);
dou(ar,3);
print(ar,3);

return 0;
}

void print(int ar[][5], int n)
{
int i,j;
for (i=0;i<n;i++)
{
for (j=0;j<5;j++)
printf("%5d",ar[i][j]);
printf("\n");
}
}

void dou(int (*ar)[5], int n)
{
int i,j;
for (i=0;i<n;i++)
for (j=0;j<5;j++)
ar[i][j] *= 2;
}


#### 12.重写程序清单 10.7 的 rain.c 程序，把 main() 中的主要任务都改成用函数来完成。

#include <stdio.h>
#define MONTHS 12
#define YEARS  5

float year(const float (*ar)[MONTHS], int n);
void month(const float (*ar)[MONTHS], int n);
int main(void)
{
float sum;
const float rain[YEARS][MONTHS] =
{
{4.3,4.3,4.3,3.0,2.0,1.2,0.2,0.2,0.4,2.4,3.5,6.6},
{8.5,8.2,1.2,1.6,2.4,0.0,5.2,0.9,0.3,0.9,1.4,7.3},
{9.1,8.5,6.7,4.3,2.1,0.8,0.2,0.2,1.1,2.3,6.1,8.4},
{7.2,9.9,8.4,3.3,1.2,0.8,0.4,0.0,0.6,1.7,4.3,6.2},
{7.6,5.6,3.8,2.8,3.8,0.2,0.0,0.0,0.0,1.3,2.6,5.2}
};

printf(" YEAR   RAINFALL  (inches)\n");
sum=year(rain,YEARS);
printf("\nThe yearly average is %.1f inches.\n\n",
sum / YEARS);
printf("MONTHLY AVERAGES:\n\n");
printf(" Jan  Feb  Mar  Apr  May  Jun  Jul  Aug  Sep ");
printf(" Oct  Nov  Dec\n");
month(rain,MONTHS);

return 0;
}

float year(const float (*ar)[MONTHS], int n)
{
int i,j;
float total = 0;
float sum = 0;

for (i = 0; i < n; i++)
{
for (j = 0, total = 0; j < MONTHS; j++)
total += ar[i][j];
printf("%5d %15.1f \n", 2010+i,total);
sum += total;
}
return sum;
}

void month(const float (*ar)[MONTHS], int n)
{
int i,j;
float total = 0;

for (i = 0; i < n; i++)
{
for (j = 0, total = 0; j < YEARS; j++)
total += ar[j][i];
printf("%4.1f ", total/YEARS);
}
printf("\n");
}


#### 13.编写一个程序，提示用户输入 3 组数，每组数包含 5 个 double 类型的数（假定用户都正确地响应，不会输入非数值数据）。改程序完成以下任务。

a.把用户输入的数据存储在 3 x 5 的数组中
b.计算每组（5 个）数据的平均值
c.计算所有数据的平均值
d.找出这 15 个数据中的最大值
e.打印结果

#include <stdio.h>

#define N 3
#define M 5

void input(double (*ar)[M]);
void mean(double (*ar)[M], double *sum);
void means(double (*ar)[M], double *sums);
void sort(double (*ar)[M], double *max);
void print(double (*ar)[M],double *sum, double *sums, double *max);

int main(void)
{
int ch;
double ar[N][M];
double sum[M],sums,max;

while ((ch = menu()) != 0)
{
switch (ch)
{
case 1 : input(ar);break;
case 2 : mean(ar,sum);break;
case 3 : means(ar,&sums);break;
case 4 : sort(ar,&max);break;
case 5 : print(ar,sum,&sums,&max);break;
}
}
return 0;
}

{
int ch;
puts("======================");
puts("1) 输入3x5的数据     |");
puts("2) 每组数据的平均值  |");
puts("3) 所有数据的平均值  |");
puts("4) 数据中的最大值    |");
puts("5) 打印结果          |");
puts("0) 退出              |");
while (scanf("%d",&ch) != 1)
{
while (getchar() != '\n');
puts("请输入<0-5>:");
}
while (getchar() != '\n');

return ch;
}

void input(double (*ar)[M])
{
int i,j;

for (i = 0; i < N; i++)
{
printf("请输入第%d组数据%d个:\n",i+1,M);
for (j = 0; j < M; j++)
scanf("%lf",&ar[i][j]);
}
}

void mean(double (*ar)[M], double *sum)
{
int i,j;
double total=0;

for (i = 0; i < N; i++)
{
for (j = 0, total = 0; j < M; j++)
{
total += ar[i][j];
}
sum[i] = total / M;
}
}

void means(double (*ar)[M], double *sums)
{
int i,j;
double total=0;

for (i = 0; i < N; i++)
{
for (j = 0; j < M; j++)
{
total += ar[i][j];
}
}
*sums = total / (N * M);
}

void sort(double (*ar)[M], double *max)
{
int i,j;
*max = ar[0][0];

for (i = 0; i < N; i++)
for (j = 0; j < M; j++)
if (*max < ar[i][j])
*max = ar[i][j];
}

void print(double (*ar)[M],double *sum, double *sums, double *max)
{
int i,j;

for (i = 0; i < N; i++)
{
printf("第%d组数据为：\n",i+1);
for (j = 0; j < M; j++)
printf("%6.1lf ",ar[i][j]);
putchar('\n');
}

for (i = 0; i < N; i ++)
{
printf("第%d组数据的平均值为:%lf\n",i+1,sum[i]);
}
printf("数据的最大值为:%lf\n",*max);
}


#### 14.以变长数组作为函数形参，完成编程练习 13。

#include <stdio.h>

#define N 3
#define M 5

void input(int n, int m, double ar[n][m]);
void mean(int n, int m, double ar[n][m]);
void means(int n, int m, double ar[n][m]);
void sort(int n, int m, double ar[n][m]);

int main(void)
{
int ch;
double ar[N][M];

while ((ch = menu()) != 0)
{
switch (ch)
{
case 1 : input(N,M,ar);break;
case 2 : mean(N,M,ar);break;
case 3 : means(N,M,ar);break;
case 4 : sort(N,M,ar);break;
}
}
return 0;
}

{
int ch;
puts("======================");
puts("1) 输入3x5的数据     |");
puts("2) 每组数据的平均值  |");
puts("3) 所有数据的平均值  |");
puts("4) 数据中的最大值    |");
puts("0) 退出              |");
while (scanf("%d",&ch) != 1)
{
while (getchar() != '\n');
puts("请输入<0-4>:");
}
while (getchar() != '\n');

return ch;
}

void input(int n, int m, double ar[n][m])
{
int i,j;

for (i = 0; i < n; i++)
{
printf("请输入第%d组数据%d个:\n",i+1,m);
for (j = 0; j < m; j++)
scanf("%lf",&ar[i][j]);
}

for (i = 0; i < n; i++)
{
printf("第%d组数据为：\n",i+1);
for (j = 0; j < m; j++)
printf("%6.1lf ",ar[i][j]);
putchar('\n');
}
}

void mean(int n, int m, double ar[n][m])
{
int i,j;
double total=0;
double sum[m];

for (i = 0; i < n; i++)
{
for (j = 0, total = 0; j < m; j++)
{
total += ar[i][j];
}
sum[i] = total / m;
}

for (i = 0; i < n; i ++)
{
printf("第%d组数据的平均值为:%lf\n",i+1,sum[i]);
}
}

void means(int n, int m, double ar[n][m])
{
int i,j;
double sums;
double total=0;

for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
total += ar[i][j];
}
}
sums = total / (n * m);

printf("所有数据的平均值为:%4.1lf\n",sums);
}

void sort(int n, int m, double ar[n][m])
{
int i,j;
double max;
max = ar[0][0];

for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
if (max < ar[i][j])
max = ar[i][j];

printf("数据最大值为:%4.1lf\n",max);
}


03-12 12万+

11-29 4664

11-01 10万+

11-01 4万+

08-09 876

01-15 1838

03-04 2598

05-29 53

04-23 938

10-02 4002

05-11 394

03-13 1万+

04-25 7万+

03-04 14万+

03-10 13万+

03-05 6万+

03-13 12万+

03-08 5万+

05-28 13

03-10 19万+

04-14 60万+

03-13 15万+

02-19 18万+

03-01 14万+

03-06 4226

03-08 7万+

03-16 3340

03-18 1万+

#### 优雅的替换if-else语句

©️2019 CSDN 皮肤主题: 1024 设计师: 上身试试