/*
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]);