## C Primer Plus 第10章 数组和指针 编程练习答案 顶原

idreamo

1、修改程序清单10.7中的程序rain，使它不使用数组下标，而是使用指针进行计算（程序中仍然需要声明并初始化数组）。

``````#include <stdio.h>
#define MONTHS 12
#define YEARS 5
int main (void)
{
//把数组初始化为2000年到2004年的降水量数据
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.lf\n",2000+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 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个数组都需要在主程序中声明）。制作第一份拷贝的函数使用数组符号。制作第二份拷贝的函数使用指针符号，并使用指针的增量操作。把目标数组名和要复制的元素数目做为参数传递给函数。也就是说，如果给定了下列声明，函数调用应该如下面所示：

``````double source[5] = {1.1,2.2,3.3,4.4,5.5};
double target1[5];
double target2[5];
copy_arr(source,target1,5);
copy_ptr(source,target2,5);``````
``````#include <stdio.h>
void copy_arr(double source[],double target1[],int n);
void copy_ptr(double *source,double *target2,int n);
int main(void)
{
double source[] = {1.1, 2.2, 3.3, 4.4, 5.5};
double target1[5] = {0};
double target2[5] = {0};
printf("Before operation:\n");
printf("source :\t%g\t%g\t%g\t%g\t%g\n",source[0],source[1],source[2],source[3],source[4]);
printf("target1:\t%g\t%g\t%g\t%g\t%g\n",target1[0],target1[1],target1[2],target1[3],target1[4]);
printf("target2:\t%g\t%g\t%g\t%g\t%g\n",target2[0],target2[1],target2[2],target2[3],target2[4]);
copy_arr(source, target1, 5);
copy_ptr(source, target2, 5);
printf("After operation:\n");
printf("source :\t%g\t%g\t%g\t%g\t%g\n",source[0],source[1],source[2],source[3],source[4]);
printf("target1:\t%g\t%g\t%g\t%g\t%g\n",target1[0],target1[1],target1[2],target1[3],target1[4]);
printf("target2:\t%g\t%g\t%g\t%g\t%g\n",target2[0],target2[1],target2[2],target2[3],target2[4]);

return 0;
}
void copy_arr(double source[],double target1[],int n)
{
int i;
for(i=0;i<n;i++)
target1[i]=source[i];
return 0;
}
void copy_ptr(double *source,double *target2,int n)
{
int i=0;
while(i++<n)
*(target2++) = *(source++);
return 0;
}
``````

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

``````#include<stdio.h>
#define WIDTH 6
int max(int ar[WIDTH],int n);
int main(void)
{
int ar[WIDTH]={4,3,6,2,8,6};

printf("The max is %d\n",max(ar,WIDTH));
return 0;
}
int max(int ar[WIDTH],int n)
{
int i,max;
for(i=1,max=ar[0];i<n;i++)
{
if(max < ar[i])
max=ar[i];
}
return max;
}
``````

4、编写一个函数，返回一个double数组中存储的最大值的索引，并在一个简单的程序中测试这个函数。

``````#include<stdio.h>
#define WIDTH 6
int max(float ar[WIDTH],int n);
int main(void)
{
float ar[WIDTH]={4.4,3.3,6.6,2.2,8.8,9.9};

printf("The max number's index is %d\n",max(ar,WIDTH));
return 0;
}
int max(float ar[WIDTH],int n)
{
int i,max;
for(i=1,max=0;i<n;i++)
{
if(ar[max] < ar[i])
max=i;
}
return max;
}
``````

5、 编写一个函数，返回一个double数组中最大值和最小值之间的差值，并在一个简单的程序中测试这个函数。

``````#define WIDTH 6
float gap(float ar[WIDTH],int n);
int main(void)
{
float ar[WIDTH]={4.4,3.3,6.6,2.2,8.8,9.9};

printf("The gap between max and min is %.2f\n",gap(ar,WIDTH));
return 0;
}
float gap(float ar[WIDTH],int n)
{
int i;
float min,max;
for(i=1,max=ar[0],min=ar[0];i<n;i++)
{
if(max< ar[i]) max=ar[i];
if(min> ar[i]) min=ar[i];
}
return (max-min);
}
``````

6、编写一个程序，初始化一个二维数组，并利用练习2中的任一函数来把这个二维数组复制到另一个二维数组（因为二维数组是数组的数组，所以可以使用处理一维数组的函数来复制数组的每个子数组）。

``````#include <stdio.h>
#define ROWS 2
#define COLS 3
void copy_2d(double source[][COLS], double target[][COLS], int );
void copy_1d(double a1[], double a2[], int n);

int main(void)
{
int i,j;
double source[ROWS][COLS] = {1, 2, 3, 4, 5, 6};
double target[ROWS][COLS] = {0};
copy_2d(source, target, ROWS);
for (i=0; i<ROWS; i++)
{
for (j=0; j<COLS; j++)
printf("%g\t",target[i][j]);
printf("\n");
}

return 0;
}

void copy_2d(double ( *source )[COLS], double target[][COLS], int n)
{
int i;
for(i=0;i<n;i++)
copy_1d( *(source+i),target[i],COLS);
}

void copy_1d(double a1[], double *a2, int n)
{
int i;
for (i=0; i<n; i++)
a2[i] = a1[i];
}
``````

7、利用练习2中的复制函数，把一个包含7个元素的数组内第3到第5元素复制到 一个包含3个元素的数组中。函数本身不需要修改，只需要选择合适的实际参数（实际参数不需要是数组名和数组大小，而只须是数组元素的地址和需要复制的元素数目）。

``````#include <stdio.h>
void copy_arr(double source[],double target1[],int n);
void copy_ptr(double *source,double *target2,int n);
int main(void)
{
double source[] = {1.1, 2.2, 3.3, 4.4, 5.5};
double target1[3] = {0};
double target2[5] = {0};
printf("Before operation:\n");
printf("source :\t%g\t%g\t%g\t%g\t%g\n",source[0],source[1],source[2],source[3],source[4]);
printf("target1:\t%g\t%g\t%g\n",target1[0],target1[1],target1[2]);
printf("target2:\t%g\t%g\t%g\t%g\t%g\n",target2[0],target2[1],target2[2],target2[3],target2[4]);
copy_arr(&source[2], target1, 3);
copy_ptr(source, target2, 5);
printf("After operation:\n");
printf("source :\t%g\t%g\t%g\t%g\t%g\n",source[0],source[1],source[2],source[3],source[4]);
printf("target1:\t%g\t%g\t%g\n",target1[0],target1[1],target1[2]);
printf("target2:\t%g\t%g\t%g\t%g\t%g\n",target2[0],target2[1],target2[2],target2[3],target2[4]);

return 0;
}
void copy_arr(double source[],double target1[],int n)
{
int i;
for(i=0;i<n;i++)
target1[i]=source[i];
return 0;
}
void copy_ptr(double *source,double *target2,int n)
{
int i=0;
while(i++<n)
*(target2++) = *(source++);
return 0;
}
``````

8、编写一个程序，初始化一个3x5的二维double数组，并利用一个基于变长数组的函数把该数组复制到另一个二维数组。还要编写一个基于变长数组的函数来显示两个数组的内容。这两个函数应该能够处理任意的NXM数组。

``````#include <stdio.h>
#define ROWS 3
#define COLS 5
void copy_2d(int n,int m,double source[n][m], double target[n][m]);
void copy_1d(double a1[], double a2[], int n);
void show_arr(int n,int m,double ar[n][m]);

int main(void)
{
int i,j;
double source[ROWS][COLS] = {{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15}};
double target[ROWS][COLS] = {0};
printf("Before operation :\n");
show_arr(ROWS,COLS,source);
copy_2d(ROWS,COLS,source,target);
printf("After operation :\n");
show_arr(ROWS,COLS,target);

return 0;
}

void copy_2d(int n,int m,double source[n][m], double target[n][m])
{
int i;
for(i=0;i<n;i++)
copy_1d( *(source+i),target[i],COLS);
}

void copy_1d(double a1[], double *a2, int n)
{
int i;
for (i=0; i<n; i++)
a2[i] = a1[i];
}

void show_arr(int n,int m,double ar[n][m])
{
int i,j;
for (i=0; i<ROWS; i++)
{
for (j=0; j<COLS; j++)
printf("%g\t",ar[i][j]);
printf("\n");
}
}
``````

9、编写一个程序，把两个数组内的相应元素相加，结果存储到第三个数组内。函数的数组名包含3个数组名和数组大小，并在一个简单的程序中测试这个函数。

``````#include<stdio.h>
#define COLS 4
void sum(int a1[],int a2[],int target[],int n);
int main(void)
{
int a1[COLS]={2,4,5,8};
int a2[COLS]={1,0,4,6};
int target[COLS]={0};

sum(a1,a2,target,COLS);
printf("a1[0]=%d\t a1[1]=%d\t a1[2]=%d\t a1[3]=%d\n",a1[0],a1[1],a1[2],a1[3]);
printf("a2[0]=%d\t a2[1]=%d\t a2[2]=%d\t a2[3]=%d\n",a2[0],a2[1],a2[2],a2[3]);
printf("target[0]=%d\t target[1]=%d\t target[2]=%d\t target[3]=%d\n",target[0],target[1],target[2],target[3]);
return 0;
}
void sum(int a1[],int a2[],int target[],int n)
{
int i;
for(i=0;i<COLS;i++)
target[i]=a1[i]+a2[i];
return 0;
}
``````

10、编写一个程序，声明一个3x5的数组并初始化，具体数值可以随意。程序打印出数值，然后数值翻一番，接着再次打印出新值。编写一个函数来显示数组的内容，再编写另一个函数执行翻倍功能。数组名和数组行数作为参数由程序传递给函数。

``````#include<stdio.h>
#define ROWS 3
#define COLS 5
void show_arr(int ar[][COLS],int n);
void twice(int (*pt)[COLS],int n);
int main(void)
{
int ar[ROWS][COLS] = {{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15}};
printf("Before:\n");
show_arr(ar,ROWS);
twice(ar,ROWS);
printf("After:\n");
show_arr(ar,ROWS);
return 0;
}
void show_arr(int ar[][COLS],int n)
{
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<COLS;j++)
printf("%d\t",ar[i][j]);
printf("\n");
}
return 0;
}
void twice(int (*pt)[COLS],int n)
{
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<COLS;j++)
*(*(pt+i)+j)=2*(*(*(pt+i)+j));
}
return 0;

}
``````

11、重写程序清单10.7的程序rain，main()中的主要功能改为由函数来执行。

``````/*rain.c 针对若干年的降水量数据，计算年降水总量、年降水平均量、以及月降水平均量*/
#include <stdio.h>
#define MONTHS 12
#define YEARS 5
void display(float arr[][MONTHS],int years);
int main (void)
{
//把数组初始化为2000年到2004年的降水量数据
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}
};
display(rain,YEARS);
return 0;
}
void display(float arr[][MONTHS],int years)
{
int year,month;
float subtot,total;

printf("YEAR  RAINALL(inches) \n");
for(year=0,total=0;year<years;year++)
{
for(month=0,subtot=0;month<MONTHS;month++)
subtot+=arr[year][month];
printf("%5d %15.1f\n",2000+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  Oct  Nov  Dec\n");

for(month=0;month<MONTHS;month++)
{    //每个月，各年该月份的总降水量
for(year=0,subtot=0;year<years;year++)
subtot+=arr[year][month];
printf("%4.1f ",subtot/years);
}
printf("\n");
return 0;
}
``````

12、编写一个程序，提示用户输入3个数集，每个数集包括5个double值。程序应当实现下列所有功能：

a.把输入信息存储到一个3*5的数组中；

b.计算出每个数集（包含5个数值）的平均值；

c.计算所有数值的平均值；

d.找出这15个数的最大值；

e.打印结果

``````#include <stdio.h>
#define ROWS 3
#define COLS 5
void store(double ar[][COLS],int rows);
double average_row(double ar[COLS]);
double average_tot(double ar[][COLS],int rows);
double f_max(double ar[][COLS],int rows);
void display(double ar[][COLS],int rows,double average0,double average1,double average2,double average_total,
double max);
int main(void)
{
double array[ROWS][COLS];
double average0,average1,average2,average_total,max;
store(array,ROWS);
average0=average_row(&array[0]);
average1=average_row(&array[1]);
average2=average_row(&array[2]);
average_total=average_tot(array,ROWS);
max = f_max(array,ROWS);
display(array,ROWS,average0,average1,average2,average_total,max);
return 0;
}
void store(double ar[][COLS],int rows)
{
int i,j;
printf("Please input 3 array of 5 numbers:");
for(i=0;i<rows;i++)
{
for(j=0;j<COLS;j++)
scanf("%lf",&ar[i][j]);
}
}
double average_row(double ar[COLS])
{
int i;
double sum=0;
for(i=0;i<COLS;i++)
sum += ar[i];
return sum/COLS;
}
double average_tot(double ar[][COLS],int rows)
{
int i,j;
double sum=0;
for(i=0;i<rows;i++)
{
for(j=0;j<COLS;j++)
sum+=ar[i][j];
}
return sum/(ROWS*COLS);
}
double f_max(double ar[][COLS],int rows)
{
int i,j;
double max = ar[0][0];
for(i=0;i<rows;i++)
for(j=0;j<=COLS;j++)
if (max < ar[i][j])
max=ar[i][j];

return max;
}
void display(double ar[][COLS],int rows,double average0,double average1,double average2,double average_total,
double max)
{
int i,j;
printf("a.\narray = \n");
for(i=0;i<rows;i++)
{
for(j=0;j<COLS;j++)
printf("%g\t",ar[i][j]);
printf("\n");
}
printf("b.\n");
printf("average0 = %g\n",average0);
printf("average1 = %g\n",average1);
printf("average2 = %g\n",average2);

printf("c.\n");
printf("total average = %g\n",average_total);

printf("d.\n");
printf("max = %g\n",max);
}
``````

### 评论(0)

C Primer Plus第6版_源代码+练习答案

osc_d9817zy2
2018/07/06
8
0
C++ Primer 第 5 版 习题参考答案

osc_2o4gyq0o
2019/08/16
4
0

03/31
0
0

C是编译型语言。如果之前使用过编译型语言（如，Pascal或FORTRAN），就会很熟悉组建C程序的几个基本步骤。但是，如果以前使用的是解释型语言（如，BASIC）或面向图形界面语言（如，Visual Ba...

04/06
0
0
C++Primer第五版——习题答案详解（三）

osc_h5z5wotn
2019/03/07
4
0

PDF如何添加下划线？迅捷PDF编辑器一键添加

“在PDF文件中如何添加下划线？”最近，很多办公室小伙伴都向小编咨询这样一个问题。我们常常需要接触、使用到PDF文件，通过查看、阅读、编辑PDF文件以处理各种各样的学习、工作任务。当我们...

dawda
56分钟前
52
0
go中gin框架+realize实现边写代码边编译，热更新

osc_ho8dcqsx
56分钟前
43
0
CAP理论的理解

osc_5rgbamh9
57分钟前
43
0

蠢蠢的我=》 select t1.name from ( select name,count(*) as num from table t where fenshu>80 group by name) t1join( select name,count(kecheng) as num from table group ......

osc_gk4myeyk
58分钟前
36
0
Memcache（1.1）Memcache 基本概述与架构概述

【1】基本概念介绍 官网：https://memcached.org/ 【1.1】memcache与memcached memcache：是早期使用的，与php结合的，是Php中常用的一个原生插件，完全在php框架内开发的 memcached：是建立...

osc_7ie26pzn

24
0