C Primer Plus 第十章练习

/*
1.修改程序清单10.7的rain.c程序,用指针进行计算(仍然要声明并 
初始化数组)。
分析:要定义指针分别指向第一个数组 ,然后就可以通过角标找到各个元素了 ,行就是year列就是month
用到的知识 rain[year][month] = *(*(prt+year)+month); 
*/
#include <stdio.h>
#define MONTHS 12 // 一年的月份数
#define YEARS 5 // 年数
int main(void){
 // 用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 }
	};
	const float (*prt)[MONTHS] = &rain[0];//把第一个数组地址赋值给prt指针 ,指针需要定义为const才能接收const修饰的数值 
	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];
			subtot += *(*(prt+year)+month);//*(prt+year)获取第几个数组,*(prt+year)+month获取第year 个数组的第month元素的地址 
			printf("%5d %15.1f\n", 2010 + year, subtot);
			total += subtot; // 5年的总降水量
	}
	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++)
		{ // 每个月,5年的总降水量
		for (year = 0, subtot = 0; year < YEARS; year++)
			//subtot += rain[year][month];
			subtot += *(*(prt+year)+month);//*(prt+year)获取第几个数组,*(prt+year)+month获取第year 个数组的第month元素的地址 
		printf("%4.1f ", subtot / YEARS);
	}
	printf("\n");
	return 0;
}

/*
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[],double[],int);
void copy_ptr(double[],double[],int);
void copy_ptrs(double[],double[],double[]);
int main(void){
 	double source[5] = {1.1, 2.2, 3.3, 4.4, 5.5};
 	double* sou = source;
 	double target1[5];
	double target2[5];
	double target3[5];
	
	copy_arr(target1,source,5);
		printf("target1[0]%lf\n",target1[0]);
	printf("\n");
	double* tar2  = target2;
	copy_ptr(tar2,sou,5);
	printf("\n");
	
	double* tar3 = target3;
	copy_ptrs(target3,source,sou+5);
	return 0;
}

void copy_arr(double target[],double source[],int lenght){

	for(int i = 0; i< lenght; i++){
		target[i] = source[i]; 
		printf("%.1lf ",target[i]);
	}
	

}
void copy_ptr(double target[],double source[],int lenght ){
	
	for(int i = 0;i < lenght; i++){
	
		*(target+i) = *(source+i);
		printf("%.1lf ",*(target+i));
	}

}
void copy_ptrs(double target[],double source[],double end [] ){
	
	for(int i = 0;&source[i] < end;i++){
	
		target[i] = source[i];
		printf("%.1lf ",target[i]);
		target++;		
	}

}

/*
3.编写一个函数,返回储存在int类型数组中的最大值,并在一个简
单的程序中测试该函数。
*/
#include <stdio.h>
int max(int[],int len);
int main(void){
	int arr [] = {1,3,5,7,9,10,20,80,12};
	int length = sizeof(arr)/sizeof(arr[0]);
		printf("length=%d\n",length);
	printf("最大值为%d\n",max(arr,length));


}
int max(int arr[],int len){
	
	int max = 0;
	for(int i = 0 ; i< len; i++){
		max > arr[i] ? max :  max = arr[i];
	}
	return max;

} 

/*
4.编写一个函数,返回储存在double类型数组中最大值的下标,并 
在一个简单的程序中测试该函数。
*/
#include <stdio.h>
int maxIndex(double[],int len);
int main(void){
	double arr [] = {1.1,2.2,3.3,4.4,5.5};
	int length = sizeof(arr)/sizeof(arr[0]);
		printf("length=%d\n",length);
	printf("最大值的下标为%d\n",maxIndex(arr,length));
}
int maxIndex(double arr[],int len){
	
	double max  = 0;
	int index = 0;
	for(int i = 0 ; i< len; i++){
		max > arr[i] ? max :  max = arr[i],index = i;
	}
	return index;
} 

/*
5.编写一个函数,返回储存在double类型数组中最大值和最小值的
差值,并在一个简单的程序中测试该函数。
*/
#include <stdio.h>
void max_min(double[],double*,double*,int);
int main(void){
	double arr [] = {1.1,2.2,3.3,4.4,5.5};
	double x = 0.0;
	double y = 0.0;
	double* max ;
	double* min ;
	int len = 0;
		len = sizeof(arr)/sizeof(arr[0]);
		printf("length=%d\n",len);
		max = &x;
		min = &y;
		max_min(arr,max,min,len);
		printf("main max=%lf\n",x);
		printf("main min=%lf\n",y);
	//printf("最大值的下标为%d\n",maxIndex(arr,length));
}
void  max_min(double arr [],double* max,double* min,int len){
	
	*max = arr[0];
	*min = arr[0];
	for(int i = 0; i< len; i++){
		*max > arr[i] ? *max : *max = arr[i];
		*min < arr[i] ? *min : *min = arr[i];
	}
}

/*
6.编写一个函数,把double类型数组中的数据倒序排列,并在一个
简单的程序中测试该函数。
*/
#include <stdio.h>

void sort(double[],int len); 
int main(void){
	int len = 0;
	double arr [] = {1.1,2.2,3.3,4.4,5.5,6.6};
	len = sizeof(arr)/sizeof(arr[0]);
	sort(arr,len);
	for(int i = 0;i < len; i++){
		printf("%lf ",arr[i]);
	}

}
void sort(double arr [],int len){
	double tem = 0.0;
	for(int i = 0; i < len/2;i++){
		tem = arr[i];
		arr[i] = arr[len-1-i];
		arr[len-1-i] = tem;
	}
}

/*
7.编写一个程序,初始化一个double类型的二维数组,使用编程练
习2中的一个拷贝函数把该数组中的数据拷贝至另一个二维数组中(因
为二维数组是数组的数组,所以可以使用处理一维数组的拷贝函数来
处理数组中的每个子数组)。
*/ 
#include <stdio.h>
void copy_ptr(double target[],double source[],int lenght);
int main(void){
 	double source[5] = {1.1, 2.2, 3.3, 4.4, 5.5};
 	double* sou = source;
 	double dulArr[2][5];
 	double *dul = &dulArr[0][0];
 	int len = sizeof(dulArr[0])/sizeof(dulArr[0][0]);
 	
 	copy_ptr(dul,source,len);
 	//printf("%lf\n",dulArr[0][0]);
	printf("\n");
	
	
	
	return 0;
}


void copy_ptr(double target[],double source[],int lenght ){
	
	for(int i = 0;i < lenght; i++){
	
		*(target+i) = *(source+i);
		printf("%.1lf ",*(target+i));
	}
	printf("\n");
}


/*
8.使用编程练习2中的拷贝函数,把一个内含7个元素的数组中第3
~第5个元素拷贝至内含3个元素的数组中。该函数本身不需要修改,
只需要选择合适的实际参数(实际参数不需要是数组名和数组大小,
只需要是数组元素的地址和待处理元素的个数)。
*/ 
#include <stdio.h>
void copy_ptr(double target[],double source[],int lenght);
int main(void){
 	double source[] = {1.1, 2.2, 3.3, 4.4, 5.5,6.6,7.7};
 	double* sou = source;
 	double arr[3];
 	double *dul = &arr[0];
 	
 	copy_ptr(dul,sou+2,3);
 	//printf("%lf\n",dulArr[0][0]);
	printf("\n");
	
	
	
	return 0;
}


void copy_ptr(double target[],double source[],int lenght ){
	
	for(int i = 0;i < lenght; i++){
	
		*(target+i) = *(source+i);
		printf("%.1lf ",*(target+i));
	}
	printf("\n");
}


/*
9.编写一个程序,初始化一个double类型的3×5二维数组,使用一
个处理变长数组的函数将其拷贝至另一个二维数组中。还要编写一个
以变长数组为形参的函数以显示两个数组的内容。这两个函数应该能
处理任意N×M数组(如果编译器不支持变长数组,就使用传统C函数处
理N×5的数组)。
编译器不支持变长数组故采用普通数组处理 
*/ 
#include <stdio.h>
void copy_ptr(double target[][5],double source[][5],int row);
void printfArr(double arr[][5],int row);
int main(void){
 	double arr[3][5] = 
	 	{{1.1,1.2,1.3,1.4,1.5},
		{2.1,2.2,2.3,2.4,2.5},
		{3.1,3.2,3.3,3.4,3.5}}; //创建一个多维数组
	double tar[3][5];
 	double(*a)[5] = arr;
 	double(*t)[5] = tar;
 	copy_ptr(t,a,3); 
 	//printf("ptr = %p ;ptr1 = %p \n",ptr,ptr1);
	
	printfArr(tar,3);
	
	return 0;
}


void copy_ptr(double target[][5],double source[][5],int row ){
	
	for(int i = 0;i < row; i++){
		
		for(int j = 0; j < 5; j++){
				*(target[i]+j) = *(source[i]+j);
				printf("%.1lf ",*(target[i]+j));
		}
		printf("\n");
	
	}
	printf("\n");
}
void printfArr(double arr[][5],int row){
	
	for(int i = 0;i < row; i++){
		
		for(int j = 0; j < 5; j++){
				printf("%.1lf  ",arr[i][j]);
		}
			printf("\n");
	
	}
	printf("\n");
}

/*
10.编写一个函数,把两个数组中相对应的元素相加,然后把结果
储存到第 3 个数组中。也就是说,如果数组1中包含的值是2、4、5、
8,数组2中包含的值是1、0、4、6,那么该函数把3、4、9、14赋给第
3个数组。函数接受3个数组名和一个数组大小。在一个简单的程序中
测试该函数。
*/ 
#include <stdio.h>
void arrAdd(int a[],int b [],int c[],int len);
int main(void){
	int a[] = {2,4,5,8};
	int b[] = {1,0,4,6};
	int c[4];
	arrAdd(a,b,c,4);
	return 0;
}
void arrAdd(int a[],int b [],int c[],int len){
	
	 for(int i = 0; i < len; i++){
	 	*(c+i) = *(a+i) + *(b+i);
	 	printf("c数值第%d位:%d\n",(i+1),*(c+i));
	 } 
	 
}




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

void printArr(int[][5],int len); 
void doubleArr(int[][5],int len);
int main(void){
	
	int arr [3][5] = {	{1,2,3,4,5},
						{6,7,8,9,10},
	 					{11,12,13,14,15}};
	//int (*prt)[3][5] = arr = >&arr[0]; 
	printArr(arr,3);
	doubleArr(arr,3);
	printArr(arr,3);
}

void printArr(int arr[][5],int len){
	int size = sizeof(arr[0])/sizeof(arr[0][0]);
	for(int i = 0; i < len; i++){
			printf(" { ");
		for(int j = 0; j < size;j++){
			printf("%d ",arr[i][j]);
		}
			printf("} \n");
	}

}
void doubleArr(int arr[][5],int len){
	int size = sizeof(arr[0])/sizeof(arr[0][0]);
	for(int i = 0; i < len; i++){
			arr+i;//&arr[0]+i
		for(int j = 0; j < size;j++){
			*(arr[i]+j) *=2; //*(&arr[i][0]+j) = 2*(&arr[i][0]+j)
		}
			printf("\n");
	}

}

/*
12.重写程序清单10.7的rain.c程序,把main()中的主要任务都改成
用函数来完成。
分析:主要编写函数
	  一.5年的总降水量
	  二.每个月,5年的总降水量		 
*/
#include <stdio.h>
#define MONTHS 12   // 一年的月份数
#define YEARS  5    // 年数
void rainSum(const float rain[][MONTHS],float * to) ;
void rainMonthSum(const float rain[][MONTHS]) ;
int main(void)
{
// 用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 = 0;
	float *to = &total;
	rainSum(rain,to);
	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");
	rainMonthSum(rain);
	return 0;
}
void rainSum(const float rain[][MONTHS],float *to){

	float sum;

	
	for (int year = 0; year < YEARS; year++)
	{             // 每一年,各月的降水量总和
		float subtot = 0;
		for (int month = 0 ; month < MONTHS; month++){
			subtot += rain[year][month];
		}
			
		printf("%5d %15.1f\n", 2010 + year, subtot);
		sum += subtot;  // 5年的总降水量
	}
		*to = sum;
		printf("5年的总降水量 %15.1f\n", sum);
}
void rainMonthSum(const float rain[][MONTHS]){
	float subtot = 0;
	for (int month = 0; month < MONTHS; month++)
	{             // 每个月,5年的总降水量
		subtot = 0;
		for (int year = 0; year < YEARS; year++)
		subtot += rain[year][month];
	printf("%4.1f ", subtot / YEARS);
	}
	printf("\n");
}

/*
用时:35分钟
13.编写一个程序,提示用户输入3组数,每组数包含5个double类
型的数(假设用户都正确地响应,不会输入非数值数据)。该程序应
完成下列任务。
a.把用户输入的数据储存在3×5的数组中
b.计算每组(5个)数据的平均值
c.计算所有数据的平均值
d.找出这15个数据中的最大值
e.打印结果
每个任务都要用单独的函数来完成(使用传统C处理数组的方
式)。完成任务b,要编写一个计算并返回一维数组平均值的函数,利
用循环调用该函数3次。对于处理其他任务的函数,应该把整个数组作
为参数,完成任务c和d的函数应把结果返回主调函数。
分析:
	a用两个for循环来提示用户输入,并给数组赋值 
	b计算数组平均值的函数,返回结果 
	c计算所有值的平均函数
	d找出最大值
	e 每个函数的结果都要打印 
*/
#include <stdio.h>
#define  COL 5
#define	 ROW 3
//用两个for循环来提示用户输入,并给数组赋值 
void inputArr(double arr [][COL],int row); 
//计算单个数组平均值
double ave(double arr[],int len); 
//计算所有值的平均函数
double aveAll(double arr[][COL],int row);
//	d找出最大值
double max(double arr[][COL]);
int main(void)
{
	double arr[ROW][COL];
	inputArr(arr,ROW);
	for(int i = 0; i< ROW; i++){
		printf("第%d数组的平均值为:%.2lf\n",i+1,ave(arr[i],COL));
	}
	printf("所有值的平均值为:%.2lf\n",aveAll(arr,ROW));
	printf("最大值为%.2lf\n",max(arr));
	return 0;
}
double max(double arr[][COL]){
	double max = arr[0][0];
	for(int i = 0;i < ROW;i++){
		for(int j = 0; j < COL; j++){
			max > arr[i][j]? max : max = arr[i][j];
		}
	}
	return max;
}
double aveAll(double arr[][COL],int row){
	double sum = 0;
	for(int i = 0;i < row;i++){
		for(int j = 0; j < COL; j++){
			sum+=arr[i][j];
		}
	}

	return sum/(COL*row);
}
double ave(double arr[],int len){
	double sum = 0;
	for(int i = 0;i < len;i++){
		sum+= arr[i];
	}

	return sum/len;
}
void inputArr(double arr [][COL],int row){
	for(int i = 0; i < row;i++){
		printf("请输入第%d double类型数组:\n",i+1);
		for(int j = 0; j< COL; j++){
		printf("第%d个数的值",j+1);
		scanf("%lf",&arr[i][j]);
		printf("\n");
		}
	}
}

14.以变长数组作为函数形参,完成编程练习13。编译器不支持故不写了~

可变函数定义 double max(int,int,double arr[*][*]);

也可以写成double max(int rows,int cols,double arr [rows][cols]);

相关推荐
今天也想MK代码1 小时前
rust编程实战:实现3d粒子渲染wasm
开发语言·rust·wasm
结衣结衣.1 小时前
【Qt】自定义信号和槽函数
开发语言·c++·qt·c++11
尘鹄2 小时前
一文讲懂Go语言如何使用配置文件连接数据库
开发语言·数据库·后端·golang
qq_433554542 小时前
C++ 二叉搜索树代码
开发语言·c++·算法
好看资源平台2 小时前
手写识别革命:Manus AI如何攻克多语言混合识别难题(二)
开发语言·人工智能·php
Hopebearer_2 小时前
vue3中ref和reactive的区别
开发语言·前端·javascript·vue.js·前端框架·ecmascript
lly2024062 小时前
CentOS Docker 安装指南
开发语言
我命由我123452 小时前
Java Maven 项目问题:com.diogonunes:JColor:jar:5.5.1 was not found in...
java·开发语言·java-ee·maven·intellij-idea·jar·intellij idea
烂蜻蜓3 小时前
深入理解 HTML 元素:构建网页的基础
开发语言·前端·css·html·html5
森焱森4 小时前
出现“ping不通但可以远程连接”的情况可能由以下原因导致
linux·c语言·网络·c++