10.1
//rain.c -- 计算每年的总降水量、年平均降水量、5年中每月平均降水量
#include <stdio.h>
#include <Windows.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 }
};
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("MONTHSLY AVERAGES:\n\n");
printf(" Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec\n");
for (month = 0; month < MONTHS; month++)
{ //每个月,5年的总降水量
for (year = 0, subtot = 0; year < YEARS; year++)
subtot += rain[year][month];
printf("%5.1f", subtot / YEARS);
}
printf("\n");
system("pause");
return 0;
}
修改以上代码,用指针进行计算
#include <stdio.h>
#include <Windows.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 }
};
float(*pr)[MONTHS] = &rain; //改动处---------------------------------
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 += *(*(pr + year) + month); //改动处------------------
printf("%5d %15.1f\n", 2010 + year, subtot);
total += subtot;
}
printf("\nThe yearly average is %.1f inches.\n\n", total / YEARS);
printf("MONTHSLY 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 += *(*(pr + year) + month); //改动处------------------
printf("%5.1f", subtot / YEARS);
}
printf("\n");
system("pause");
return 0;
}
10.2
编写一个程序,初始化一个double类型的数组,然后把该数组的内容拷贝至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 arr[], double source[], int i)
{
while (i-- > 0)
arr[i] = source[i];
}
void copy_ptr(double* arr, double* source, int i)
{
while (i-- > 0)
*(arr++) = *(source++);
}
void copy_ptrs(double* arr, double* source, double* end)
{
while (source < end)
*(arr++) = *(source++);
}
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);
return 0;
}
10.3
编写一个函数,返回存储在int类型数组中的最大值,并在一个简单的程序中测试该函数
#include <stdio.h>
#include <Windows.h>
int MAX(int arr[], int i)
{
for (int j = 0; j < i; j++)
arr[0] = (arr[0] < arr[j] ? arr[j] : arr[0]);
return arr[0];
}
int main(void)
{
int arr[5] = { 5,3,7,8,1 };
printf("%d\n", MAX(arr, 5));
system("pause");
return 0;
}
10.4
编写一个函数,返回存储在double类型数组中最大值的下标,并在一个简单的程序中测试该函数
#include <stdio.h>
#include <Windows.h>
int MAX(double arr[], int i)
{
int m = 0;
for (int j = 0; j < i; j++)
{
if (arr[m] < arr[j])
m = j;
}
return m;
}
int main(void)
{
double arr[] = { 1,9,2,8,55,12,74,0,3,14 };
printf("%d\n", MAX(arr, 10));
system("pause");
return 0;
}
10.5
编写一个函数,返回存储在double类型数组中最大值与最小值的差值,并在一个简单的程序中测试该函数
#include <stdio.h>
#include <Windows.h>
int MAX(double arr[], int i)
{
double max, min;
int m = 0;
for (int j = 0; j < i; j++)
{
if (arr[m] < arr[j])
m = j;
}
max = arr[m];
m = 0;
for (int j = 0; j < i; j++)
{
if (arr[m] > arr[j])
m = j;
}
min = arr[m];
return max - min;
}
int main(void)
{
double arr[] = { 1,9,2,8,55,12,74,2,3,14 };
printf("%d\n", MAX(arr, 10));
system("pause");
return 0;
}
10.6
编写一个函数,把double类型数组中的数据倒序排列,并在一个简单程序中测试
#include <stdio.h>
void sort(double arr[], int i)
{
double m = 0;
int j = 0, k = 0;
for (j = 0; j < i - 1; j++)
{ //使用的是冒泡排序
for (k = 0; k < i - 1 - j; k++)
{
if (arr[k] < arr[k + 1])
{
m = arr[k];
arr[k] = arr[k + 1];
arr[k + 1] = m;
}
}
}
}
int main(void)
{
double arr[] = { 1,9,2,8,55,12,74,2,3,14 };
sort(arr, 10);
return 0;
}
10.7
编写一个函数,把double类型的二维数组,使用10.2中的一个拷贝函数把该数组中的数据拷贝到另一个二维数组中
#include <stdio.h>
void copy_arr(double arr[], double source[], int i)
{
while (i-- > 0)
arr[i] = source[i];
}
void copy_ptr(double* arr, double* source, int i)
{
while (i-- > 0)
*(arr++) = *(source++);
}
void copy_ptrs(double* arr, double* source, double* end)
{
while (source < end)
*(arr++) = *(source++);
}
int main(void)
{
double source[2][3] =
{
{ 0,1,2 },
{ 3,4,5 }
};
double arr[2][3] = { 0 };
for (int i = 0; i < 2; i++)
copy_arr(arr[i], source[i], 3);
//for (int i = 0; i < 2; i++)
//copy_ptr(arr[i], source[i], 3);
//for (int i = 0; i < 2; i++)
//copy_ptrs(arr[i], source[i], source[i] + 3);
return 0;
}
10.8
使用10.2中的拷贝函数,把一个含有7个元素的数组中第3~第5个元素拷贝至内含3个元素的数组中,该函数本身不需要修改,只需要选择合适的实际参数(实际参数只需要数组元素的地址和待处理元素的个数)
#include <stdio.h>
#include <Windows.h>
void copy_ptr(int* arr, int* source, int i)
{
while (i-- > 0)
*(arr++) = *(source++);
}
int main(void)
{
int source[5] = { 2,6,4,8,3 };
int arr[3] = { 0 };
copy_ptr(arr, source + 2, 3);
for (int i = 0; i < 3; i++)
printf("%d ", arr[i]);
system("pause");
return 0;
}
10.9
编写一个程序,初始化一个double类型的35二维数组,使用一个处理变长数组的函数将其拷贝至另一个二维数组中。还要编写一个以变长数组为形参的函数以显示两个数组的内容。这两个函数应该能处理任意NM的二维数组
#include <stdio.h>
#include <Windows.h>
void copy(int n, int m, double arr[n][m], double source[n][m])
{
int i, j;
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
arr[i][j] = source[i][j];
}
}
void print(int n, int m, double arr[n][m])
{
int i, j;
for (i = 0; i < n; i++)
{
for (j = 0; j < 5; j++)
printf("%lf ", arr[i][j]);
printf("\n");
}
}
int main(void)
{
double source[5][5] =
{
{ 0,1,2,3,4 },
{ 5,6,7,8,9 },
{ 10,11,12,13,14 }
};
double arr[5][5];
copy(5, 5, arr, source);
print(5, 5, source);
print(5, 5, arr);
system("pause");
return 0;
}
10.10
编写一个函数,把两个数组中相对应的元素相加,然后把结果存储到第三个数组中,函数接受3个数组名和一个数组大小,在一个简单的程序中测试
#include <stdio.h>
#include <Windows.h>
void copy_add(int* arr1, int* arr2, int* arr3, int i)
{
for (int j = 0; j < i; j++)
*(arr3 + j) = *(arr1 + j) + *(arr2 + j);
}
int main(void)
{
int arr1[4] = { 2,4,5,8 };
int arr2[4] = { 1,0,4,6 };
int arr3[4] = { 0 };
copy_add(arr1, arr2, arr3, 4);
for (int i = 0; i < 4; i++)
printf("%d ", arr3[i]);
system("pause");
return 0;
}
10.11
编写一个程序,声明一个int类型的3*5二维数组,并用合适的值初始化它,该程序打印数组中的值,然后各值翻倍,并显示出各元素的新值。编写一个函数显示数组的内容,再编写一个函数把各元素的值翻倍。这两个函数都以函数名和行数作为参数
#include <stdio.h>
#include <Windows.h>
void print(int(*arr)[5], int i)
{
int j, k;
for (j = 0; j < i; j++)
{
for (k = 0; k < 5; k++)
printf("%d ", arr[j][k]);
printf("\n");
}
}
void print2(int(*arr)[5], int i)
{
int j, k;
for (j = 0; j < i; j++)
{
for (k = 0; k < 5; k++)
printf("%d ", arr[j][k] * 2);
printf("\n");
}
}
int main(void)
{
int arr[3][5] =
{
{ 0,1,2,3,4 },
{ 5,6,7,8,9 },
{ 10,11,12,13,14 }
};
print(arr, 3);
print2(arr, 3);
system("pause");
return 0;
}
10.12
重写10.1中的rain.c程序,把**main()**中的主要任务都改用函数来完成
#include <stdio.h>
#include <Windows.h>
#define MONTHS 12
#define YEARS 5
void year(const float(*arr)[MONTHS], int n)
{
int i, j;
float total;
float subtot = 0;
printf(" YEAR RAINFALL (inches)\n");
for (i = 0; i < n; i++)
{
for (j = 0, total = 0; j < MONTHS; j++)
total += arr[i][j];
printf("%5d %15.1f \n", 2010 + i, total);
subtot += total;
}
printf("\nThe yearly average is %.1f inches.\n\n", subtot / YEARS);
}
void month(const float(*arr)[MONTHS], int n)
{
int i, j;
float total = 0;
printf("MONTHLY AVERAGES:\n\n");
printf(" Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec\n");
for (i = 0; i < n; i++)
{
for (j = 0, total = 0; j < YEARS; j++)
total += arr[j][i];
printf("%4.1f ", total / YEARS);
}
printf("\n");
}
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 }
};
year(rain, YEARS);
month(rain, MONTHS);
system("pause");
return 0;
}
10.13
编写一个程序,提示用户输入3组数,每组数包含5个double类型的数。改程序完成以下任务:
a.把用户输入的数据存储在 3*5 的数组中
b.计算每组(5 个)数据的平均值
c.计算所有数据的平均值
d.找出这 15 个数据中的最大值
e.打印结果
每个任务都要用单独的函数来完成(使用传统 C 处理数组的方式)。完成任务 b ,要编写一个计算并返回一维数组平均值的函数,利用循环调用该函数 3 次。对于处理其他任务的函数,应该把整个数组作为参数,完成任务 c 和 d 的函数应该把结果返回主调函数
#include <stdio.h>
#include <Windows.h>
void input(double(*arr)[5], int i)
{
for (int j = 0; j < i; j++)
{
printf("请输入第%d组数据%d个:\n", j + 1, 5);
for (int k = 0; k < 5; k++)
scanf_s("%lf", &arr[j][k]);
}
}
void average(double(*arr)[5], double* aver, int i)
{
int total = 0, k;
for (int j = 0; j < i; j++)
{
for (k = 0, total = 0; k < 5; k++)
total += arr[j][k];
aver[j] = total / 5;
}
}
double averal(double(*arr)[5], int i)
{
int total = 0, sum = 0, k;
for (int j = 0; j < i; j++)
{
for (k = 0, total = 0; k < 5; k++)
total += arr[j][k];
sum += total;
}
return sum / 15;
}
double MAX(double(*arr)[5], int i)
{
double max = 0;
for (int j = 0; j < i; j++)
{
for (int k = 0; k < 5; k++)
{
if (max < arr[j][k])
max = arr[j][k];
}
}
return max;
}
void print(double(*arr)[5], double* aver, int i, double ave, double max)
{
printf("\n");
printf("b:\n");
for (int j = 0; j < i; j++)
printf(" %2f ", aver[j]);
printf("\n");
printf("c:\n %2f\n", ave);
printf("d:\n %2f\n", max);
}
int main(void)
{
double ave, max;
double arr[3][5] = { 0 };
double aver[3] = { 0 };
input(arr, 3);
average(arr, aver, 3);
ave = averal(arr, 3);
max = MAX(arr, 3);
print(arr, aver, 3, ave, max);
system("pause");
return 0;
}
10.14
略