2019.2.8《C Primer Plus》第十章编程练习答案

现在是凌晨01点04分,昨天起来和同学聊了会买什么钢笔好。
下午敲着代码呢,就被他叫去公园拍照了,冻死了。
去华莱士吃了两个汉堡,去他家看了流浪地球,写了一道编程题,就回家了。

10.13.1

修改程序清单10.7中的程序rain.c ,用指针进行计算(仍然需要声明并初始化数组)

/* rain.c  -- finds yearly totals, yearly average, and monthly
 average for several years of rainfall data */
#include <stdio.h>
#define MONTHS 12    // number of months in a year
#define YEARS   5    // number of years of data
int main(void)
{
    // initializing rainfall data for 2010 - 2014
    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,(*ptr)[12];
    
    ptr=rain;
    printf(" YEAR    RAINFALL  (inches)\n");
    for (year = 0, total = 0; year < YEARS; year++)
    {             // for each year, sum rainfall for each month
        for (month = 0, subtot = 0; month < MONTHS; month++)
            subtot += *(*(ptr+year)+month);
        printf("%5d %15.1f\n", 2010 + year, subtot);
        total += subtot; // total for all years
    }
    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 ");
    printf(" Nov  Dec\n");
    
    for (month = 0; month < MONTHS; month++)
    {             // for each month, sum rainfall over years
        for (year = 0, subtot =0; year < YEARS; year++)
            subtot += *(*(ptr+year)+month);
        printf("%4.1f ", subtot/YEARS);
    }
    printf("\n");
    
    return 0;
}

10.13.2

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

#include<stdio.h>
void copy_arr(double tar[],double sou[],int n);
void copy_ptr(double tar[],double sou[],int n);
void copy_ptrs(double tar[],double sou[],double *p);
int main(void)
{
	double source[5]={1.1,2.2,3.3,4.4,5.5};
	double target1[5],target2[5],target3[5];
	
	copy_arr(target1,source,5);
	copy_ptr(target2,source,5);
	copy_ptrs(target3,source,source+5);
	
	int i;
	printf("target1\t\ttarget2\t\ttarget3\n");
	for(i=0;i<5;i++)
	{
		printf("%lf\t%lf\t%lf\n",target1[i],target2[i],target3[i]);
	}
	return 0;
}
void copy_arr(double tar[],double sou[],int n)
{
	int i;
	for(i=0;i<n;i++)
		tar[i]=sou[i];
}
void copy_ptr(double tar[],double sou[],int n)
{
	int i;
	for(i=0;i<n;i++)
		*(tar+i)=*(sou+i);
}
void copy_ptrs(double tar[],double sou[],double *p)
{
	p=p-5;
	int i;
	for(i=0;i<5;i++)
		*(tar+i)=*(p+i);
}

10.13.3

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

#include<stdio.h>
int max(int arr[],int n);
int main(void)
{
	int array[15]={91,44,4,54,51,231,541,32121,22,121,02,21,215,5,456};
	printf("%d",max(array,15));
	return 0;
}

int max(int arr[],int n)
{
	int max=arr[0],i;
	for(i=0;i<n;i++){
		if(max<arr[i]){
			max=arr[i];
		}
	}
	return max;
}

10.13.4

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

#include<stdio.h>
int max(double arr[],int n);
int main(void)
{
	double array[15]={91.1,44.2,4.3,54.4,51.5,231.5,541.6,32121.7,22.8,121.9,02.1,21.2,215.3,5.4,456.5};
	printf("%d",max(array,15));
	return 0;
}

int max(double arr[],int n)
{
	double max=arr[0];
	int i,x;
	for(i=0;i<n;i++){
		if(max<arr[i]){
			max=arr[i];
			x=i;
		}
	}
	return x;
}

10.13.5

编写一个函数,返回存储在double类型数组中最大值和最小的数之间的差值,并在一个简单的程序中测试该函数

#include<stdio.h>
double max(double arr[],int n);
int main(void)
{
	double array[15]={91.1,44.2,4.3,54.4,51.5,231.5,541.6,32121.7,22.8,121.9,02.1,21.2,215.3,5.4,456.5};
	printf("%lf",max(array,15));
	return 0;
}

double max(double arr[],int n)
{
	double max=arr[0],min=arr[0];
	int i;
	for(i=0;i<n;i++){
		if(max<arr[i]){
			max=arr[i];
		}
		if(min>arr[i]){
			min=arr[i];
		}
	}
	return max-min;
}

10.13.6

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

#include<stdio.h>
void reverse(double arr[],int n);
int main(void)
{
	int i;
	double array[15]={91.1,44.2,4.3,54.4,51.5,231.5,541.6,32121.7,22.8,121.9,02.1,21.2,215.3,5.4,456.5};
	reverse(array,15);
	for(i=0;i<15;i++)
		printf("%lf\n",array[i]);
	return 0;
}

void reverse(double arr[],int n)
{
	double tem[n];
	int i;
	for(i=0;i<n;i++){
		tem[i]=arr[i];
	}
	for(i=0;i<n;i++){
		arr[i]=tem[n-i-1];
	}
}

10.13.7

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

#include<stdio.h>
void copy(double arr[][5],double tar[][5],int n);
void copy_ptr(double sou[],double tar[],int n);
int main(void)
{
	int i,j;
	double array[4][5]=
	{
		{1.2,2.3,3.4,4.5,5.6},
		{1.1,1.2,1.3,1.4,1.5},
		{3.2,2.1,1.0,3.9,3.8},
		{4.1,4.2,4.3,4.4,4.5}
	},target[4][5];
	copy(array,target,4);
	for(i=0;i<4;i++){
		for(j=0;j<5;j++)
			printf("%.1lf ",target[i][j]);
		printf("\n");
	}
	return 0;
}
void copy(double arr[][5],double tar[][5],int n)
{
	int i;
	for(i=0;i<n;i++)
		copy_ptr(arr[i],tar[i],5);
}
void copy_ptr(double sou[],double tar[],int n)
{
	int i;
	for(i=0;i<n;i++)
		*(tar+i)=*(sou+i);
}

10.13.8

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

#include<stdio.h>
void copy(double *former,double *tar,int n);
int main(void)
{
	double array[7]={1.1,2.2,3.3,4.4,5.5,6.6,7.7},target[3];
	copy(&array[2],&target[0],3);
	int i;
	for(i=0;i<3;i++)
		printf("%lf\n",target[i]);
	return 0;
}

void copy(double *former,double *tar,int n)
{
	int i;
	for(i=0;i<n;i++)
		*(tar+i)=*(former+i);
}

10.13.9

编写一个程序,初始化一个double类型的3*5二维数组,使用一个处理变长数组元素的函数将其拷贝至另一个二维数组中。还要编写一个以变长数组为形参的函数以显示两个数组的内容。这两个函数应该能处理任意N M数组(如果编译器不支持变长数组,就使用传统C函数处理N5 的数组)。

#include<stdio.h>
void copy(int row,int col,double arr[row][col],double tar[row][col]);
void show(int row,int col,double arr[row][col]);
int main(void)
{
	double array[3][5]={
	{1.1,2.2,3.3,4.4,5.5},
	{2.1,2.2,3.2,4.6,8.2},
	{9.9,8.8,7.7,6.6,5.5}
	},target[3][5];
	copy(3,5,array,target);
	show(3,5,array);
	printf("\n");
	show(3,5,target);
	
	return 0;
	
}
void copy(int row,int col,double arr[row][col],double tar[row][col])
{
	int i,j;
	for(i=0;i<row;i++){
		for(j=0;j<col;j++)
			tar[i][j]=arr[i][j];
	}
}
void show(int row,int col,double arr[row][col])
{
	int i,j;
	for(i=0;i<row;i++){
		for(j=0;j<col;j++)
			printf("%.1lf\t",arr[i][j]);
		printf("\n");
	}
}

10.13.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);
int main(void)
{
	int arr1[5]={2,4,5,8,10},arr2[5]={1,0,4,6,9},arr3[5],i;
	sum(arr1,arr2,arr3,5);
	for(i=0;i<5;i++)
		printf("%d\t",arr3[i]);
	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];
}

10.13.11

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

#include<stdio.h>
void show(int ar[][5],int n);
void doubling(int ar[][5],int n);
int main(void)
{
	int arr[3][5]={
	{1,2,3,4,5},
	{2,4,6,8,10},
	{3,5,7,9,11}
	};
	
	show(arr,3);
	doubling(arr,3);
	show(arr,3);
	
	return 0;
}
void show(int ar[][5],int n)
{
	int i,j;
	for(i=0;i<n;i++)
		for(j=0;j<5;j++)
			printf("%.1d\t",ar[i][j]);
	printf("\n");
}
void doubling(int ar[][5],int n)
{
	int i,j;
	for(i=0;i<n;i++)
		for(j=0;j<5;j++)
			ar[i][j]=ar[i][j]*2;
}

10.13.12

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

/* rain.c  -- finds yearly totals, yearly average, and monthly
 average for several years of rainfall data */
#include <stdio.h>
#define MONTHS 12    // number of months in a year
#define YEARS 5    // number of years of data
float sum(int years,int months,float rain[years][months]);
void monthly(int years,int months,float rain[years][months]);
int main(void)
{
    // initializing rainfall data for 2010 - 2014
    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}
    };
    float total;
    
    total=sum(YEARS,MONTHS,rain);
    printf("\nThe yearly average is %.1f inches.\n\n",total/YEARS);
	monthly(YEARS,MONTHS,rain);
    
    return 0;
}
float sum(int years,int months,float rain[years][months])
{
	int year, month;
	float subtot, total;
	printf(" YEAR    RAINFALL  (inches)\n");
    for (year = 0, total = 0; year < years; year++)
    {             // for each year, sum rainfall for each month
        for (month = 0, subtot = 0; month < months; month++)
            subtot += rain[year][month];
        printf("%5d %15.1f\n", 2010 + year, subtot);
        total += subtot; // total for all years
    }
    return total;
}
void monthly(int years,int months,float rain[years][months])
{
	int year, month;
	float subtot;
	printf("MONTHLY AVERAGES:\n\n");
    printf(" Jan  Feb  Mar  Apr  May  Jun  Jul  Aug  Sep  Oct ");
    printf(" Nov  Dec\n");
    
    for (month = 0; month < months; month++)
    {             // for each month, sum rainfall over years
        for (year = 0, subtot =0; year < years; year++)
            subtot += rain[year][month];
        printf("%4.1f ", subtot/years);
    }
    printf("\n");
}

10.13.13

编写一个程序,提示用户输入3组数,每组数包含5个double类型的数(假设用户都正确的响应,不会输入非法数据)。程序应该完成下列任务。
a.把用户输入的数据储存再3*5的数组中。
b.计算每组(5个)数据的平均值。
c.计算所有数据的平均值。
d.找出这15个数据中的最大值
e.打印结果
每个任务都要用单独的函数来完成(使用传统C处理数组的方式)。完成任务b,要编写一个计算并返回一维数组平均值的函数,利用循环调用该函数3次。对于处理其他任务的函数,应该把整个数组作为参数,完成任务 c 和任务 d 的函数应该把结果返回主调函数。

#include<stdio.h>
void enter(double ar[][5],int n);
void aver(double ar[],int n);
double aver_all(double ar[][5],int row);
double biggest(double ar[][5],int row);
void show(double ar[][5],int row);
int main(void)
{
	double array[3][5];
	enter(array,3);
	aver(array[0],5);
	aver(array[1],5);
	aver(array[2],5);
	aver_all(array,3);
	printf("所有数据平均值%lf\n",aver_all(array,3));
	printf("最大值%lf\n",biggest(array,3));
	show(array,3);
	return 0;
}
void enter(double ar[][5],int n)
{
	int i,j;
	for(i=0;i<n;i++)
	{
		printf("请输入五个double类型的数\n");
		for(j=0;j<5;j++)
			scanf("%lf",&ar[i][j]);
	}
}
void aver(double ar[],int n)
{
	double sum=0;
	int i;
	for(i=0;i<n;i++)
		sum+=ar[i];
	printf("平均值为%lf\n",sum/n);
}
double aver_all(double ar[][5],int row)
{
	double sum=0;
	int i,j;
	for(i=0;i<row;i++)
		for(j=0;j<5;j++)
			sum+=ar[i][j];
	return sum/(row*5);
}
double biggest(double ar[][5],int row)
{
	double big;
	int i,j;
	big=ar[0][0];
	for(i=0;i<row;i++)
		for(j=0;j<5;j++)
			if(big<ar[i][j])
				big=ar[i][j];
	return big;
}
void show(double ar[][5],int row)
{
	int i,j;
	for(i=0;i<row;i++){
		for(j=0;j<5;j++)
			printf("%lf\t",ar[i][j]);
		printf("\n");
	}
}

10.13.14

以变长数组作为函数形参,完成编程练习13。

#include<stdio.h>
void enter(int n,int col,double ar[n][col]);
void aver(int n,double ar[]);
double aver_all(int row,int col,double ar[row][col]);
double biggest(int row,int col,double ar[row][col]);
void show(int row,int col,double ar[row][col]);
int main(void)
{
	double array[3][5];
	enter(3,5,array);
	aver(5,array[0]);
	aver(5,array[1]);
	aver(5,array[2]);
	printf("所有数据平均值%lf\n",aver_all(3,5,array));
	printf("最大值%lf\n",biggest(3,5,array));
	show(3,5,array);
	return 0;
}
void enter(int n,int col,double ar[n][col])
{
	int i,j;
	for(i=0;i<n;i++)
	{
		printf("请输入五个double类型的数\n");
		for(j=0;j<col;j++)
			scanf("%lf",&ar[i][j]);
	}
}
void aver(int n,double ar[])
{
	double sum=0;
	int i;
	for(i=0;i<n;i++)
		sum+=ar[i];
	printf("平均值为%lf\n",sum/n);
}
double aver_all(int row,int col,double ar[row][col])
{
	double sum=0;
	int i,j;
	for(i=0;i<row;i++)
		for(j=0;j<col;j++)
			sum+=ar[i][j];
	return sum/(row*col);
}
double biggest(int row,int col,double ar[row][col])
{
	double big;
	int i,j;
	big=ar[0][0];
	for(i=0;i<row;i++)
		for(j=0;j<col;j++)
			if(big<ar[i][j])
				big=ar[i][j];
	return big;
}
void show(int row,int col,double ar[row][col])
{
	int i,j;
	for(i=0;i<row;i++){
		for(j=0;j<col;j++)
			printf("%lf\t",ar[i][j]);
		printf("\n");
	}
}

第九章和第十章知识很难理解掌握,但是题还是不难做的……
明天起来看看别人是怎么写的代码……
总感觉自己写代码稀里糊涂的,要试好几遍才能写对。

2019年2月8日01点18分

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值