1.修改程序清单10.7的rain.c程序,用指针进行计算(仍然要声明并初始化数组)。
#include <stdio.h>
#define MONTHS 12
#define YEARS 5
int main(void)
{
int year, month;
float subtot, total;
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}
};
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("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 (year = 0, subtot = 0; year < YEARS; year++)
{
subtot += *(*(rain + year) + month);
}
printf("%4.1f ", subtot / YEARS);
}
printf("\n");
return 0;
}
2.编写一个程序,初始化一个double类型的数组,然后把该数组的内容拷贝至3个其他数组中(在main ()中声明这4个数组)。使用带数组表示法的函数进行第Ⅰ份拷贝。使用带指针表示法和指针递增的函数进行第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>
#define LEN 5
void copy_arr(double x[], const double source[], int n);
void copy_ptr(double *x, const double *source, int n);
void copy_ptrs(double *x, const double *source, const double *end);
void show_arr(const double x[], int n);
int main(void)
{
double source[LEN] = {1.1, 2.2, 3.3, 4.4, 5.5};
double target1[LEN];
double target2[LEN];
double target3[LEN];
printf("原数组是:\n");
show_arr(source, LEN);
copy_arr(target1, source, LEN);
printf("第一次拷贝完后结果是:\n");
show_arr(target1, LEN);
copy_ptr(target2, source, LEN);
printf("第二次拷贝完后结果是:\n");
show_arr(target2, LEN);
copy_ptrs(target3, source, source + LEN);
printf("第三次拷贝完后结果是:\n");
show_arr(target3, LEN);
printf("本程序完成!\n");
return 0;
}
void show_arr(const double x[], int n)
{
int i;
for (i = 0; i < n; i++)
{
printf("%-5g", x[i]);
}
putchar('\n');
return;
}
void copy_arr(double x[], const double source[], int n)
{
int i;
for (i = 0; i < n; i++)
{
x[i] = source[i];
}
return;
}
void copy_ptr(double *x, const double *source, int n)
{
int i;
for (i = 0; i < n; i++)
{
*(x + i) = *(source + i);
}
return;
}
void copy_ptrs(double *x, const double *source, const double *end)
{
int i;
for (i = 0; i < end - source; i++)
{
*(x + i) = *(source + i);
}
return;
}
3.编写一个函数,返回储存在int类型数组中的最大值,并在一个简单的程序中测试该函数。
#include <stdio.h>
#define N 5
int find_max(const int a[], int n);
void show_array(const int a[], int n);
int main(void)
{
int max;
int array[N] = {1, 4, 3, 2, 5};
printf("array数组是:\n");
show_array(array, N);
max = find_max(array, N);
printf("array数组中最大值是:%d\n", max);
return 0;
}
int find_max(const int a[], int n)
{
int i;
int max = a[0];
for (i = 1; i < n; i++)
{
max = max < a[i] ? a[i] : max;
}
return max;
}
void show_array(const int a[], int n)
{
int i;
for (i = 0; i < n; i++)
{
printf("%-3d", a[i]);
}
putchar('\n');
return;
}
4.编写一个函数,返回储存在 double类型数组中最大值的下标,并在一个简单的程序中测试该函数。
#include <stdio.h>
#define N 5
int find_max_index(const double a[], int n, double *k);
void show_array(const double a[], int n);
int main(void)
{
double t;
int max_index;
double array[N] = {1.0, 4.0, 3.0, 2.0, 5.0};
printf("array数组是:\n");
show_array(array, N);
max_index = find_max_index(array, N, &t);
printf("array数组中最大值%g的下标是:%d\n", t, max_index);
return 0;
}
int find_max_index(const double a[], int n, double *k)
{
int j, index;
double max = a[0];
for (j = 1; j < n; j++)
{
if (max < a[j])
{
max = a[j];
index = j;
}
}
*k = max;
return index;
}
void show_array(const double a[], int n)
{
int i;
for (i = 0; i < n; i++)
{
printf("%-5g", a[i]);
}
putchar('\n');
return;
}
5.编写一个函数,返回储存在double类型数组中最大值和最小值的差值,并在一个简单的程序中测试该函数。
#include <stdio.h>
#define N 5
int d_value(const double a[], int t, double *m, double *n);
void show_array(const double a[], int n);
int main(void)
{
double m, n, v;
double array[N] = {1.0, 4.0, 3.0, 2.0, 5.0};
printf("array数组是:\n");
show_array(array, N);
v = d_value(array, N, &m, &n);
printf("array数组中最大值%g和最小值%g之差是:%g\n", m, n, v);
return 0;
}
int d_value(const double a[], int t, double *m, double *n)
{
int i, val;
double max = a[0];
double min = a[0];
for (i = 1; i < t; i++)
{
max = max < a[i] ? a[i] : max;
min = min > a[i] ? a[i] : min;
}
*m = max;
*n = min;
val = max - min;
return val;
}
void show_array(const double a[], int n)
{
int i;
for (i = 0; i < n; i++)
{
printf("%-5g", a[i]);
}
putchar('\n');
return;
}
6.编写一个函数,把 double类型数组中的数据倒序排列,并在一个简单的程序中测试该函数。
#include <stdio.h>
#define N 5
void reverse(double a[], int n);
void show_array(const double a[], int n);
int main(void)
{
double array[N] = {1.0, 4.0, 3.0, 2.0, 5.0};
printf("array数组最初是:\n");
show_array(array, N);
reverse(array, N);
printf("array数组倒序排列后是:\n");
show_array(array, N);
return 0;
}
void reverse(double a[], int n)
{
int i, t;
for (i = 0; i < n / 2; i++)
{
t = a[i];
a[i] = a[n - 1 - i];
a[n - 1 - i] = t;
}
return;
}
void show_array(const double a[], int n)
{
int i;
for (i = 0; i < n; i++)
{
printf("%-5g", a[i]);
}
putchar('\n');
return;
}
7.编写一个程序,初始化一个double类型的二维数组,使用编程练习2中的一个拷贝函数把该数组中的数据拷贝至另一个二维数组中(因为二维数组是数组的数组,所以可以使用处理一维数组的拷贝函数来处理数组中的每个子数组)。
#include <stdio.h>
#define N 2
#define M 3
void copy_arr(const double a[], double b[], int n);
void show_array(const double (*x)[M], int n);
int main(void)
{
const double a[N][M] =
{
{1.0, 2.0, 3.0},
{4.0, 5.0, 6.0}
};
double b[N][M] = {0.0};
printf("a数组是:\n");
show_array(a, N);
printf("原b数组是:\n");
show_array(b, N);
//↑GCC4版本中会有警告;
//↑可以强制类型转换;
//↑(const double(*)[M]);
copy_arr(*a, *b, N * M);
printf("b数组拷贝a数组后是:\n");
show_array(b, N);
return 0;
}
void copy_arr(const double a[], double b[], int n)
{
int i;
for (i = 0; i < n; i++)
{
b[i] = a[i];
}
return;
}
void show_array(const double (*x)[M], int n)
{
int i, j;
for (i = 0; i < n; i++)
{
for (j = 0; j < M; j++)
{
printf("%-5g", x[i][j]);
}
putchar('\n');
}
return;
}
8.使用编程练习2中的拷贝函数,把一个内含7个元素的数组中第3~第5个元素拷贝至内含3个元素的数组中。该函数本身不需要修改,只需要选择合适的实际参数(实际参数不需要是数组名和数组大小,只需要是数组元素的地址和待处理元素的个数)。
#include <stdio.h>
#define LEN1 7
#define LEN2 3
void copy_arr(double ar1[], const double ar2[], int n);
void show_arr(const double ar[], int n);
int main(void)
{
double orig[LEN1] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0};
double copy[LEN2];
printf("7元素数组是:\n");
show_arr(orig, LEN1);
printf("拷贝上面第3到第5个的元素数组是:\n");
copy_arr(copy, orig + 2, LEN2);
show_arr(copy, LEN2);
return 0;
}
void copy_arr(double ar1[], const double ar2[], int n)
{
int i;
for (i = 0; i < n; i++)
{
ar1[i] = ar2[i];
}
return;
}
void show_arr(const double ar[], int n)
{
int i;
for (i = 0; i < n; i++)
{
printf("%-5g", ar[i]);
}
putchar('\n');
return;
}
9.编写一个程序,初始化一个double类型的3×5二维数组,使用一个处理变长数组的函数将其拷贝至另一个二维数组中。还要编写一个以变长数组为形参的函数以显示两个数组的内容。这两个函数应该能处理任意NXM数组(如果编译器不支持变长数组,就使用传统C函数处理NX5的数组)。
#include <stdio.h>
#define N 3
#define M 5
void show_array(int n, int m, const double x[n][m]);
void copy_array(int n, int m, const double a[n][m], double b[n][m]);
int main(void)
{
const double a[N][M] =
{
{1.0,2.0,3.0,4.0,5.0},
{6.0,7.0,8.0,9.0,10.0},
{11.0,12.0,13.0,14.0,15.0}
};
double b[N][M] = {0.0};
printf("a数组是:\n");
show_array(N, M, a);
printf("原b数组是:\n");
show_array(N, M, b);
//↑GCC4版本中会有警告;
//↑可以强制类型转换;
//↑(const double(*)[M]);
copy_array(N, M, a, b);
printf("b数组拷贝a数组后是:\n");
show_array(N, M, b);
return 0;
}
void show_array(int n, int m, const double x[n][m])
{
int i, j;
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
printf("%-5g", x[i][j]);
}
putchar('\n');
}
return;
}
void copy_array(int n, int m, const double a[n][m], double b[n][m])
{
int i, j;
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
b[i][j] = a[i][j];
}
}
return;
}
10.编写一个函数,把两个数组中相对应的元素相加,然后把结果储存到第3个数组中。也就是说,如果数组1中包含的值是2、4、5、8,数组2中包含的值是1、0、4、6,那么该函数把3、4、9、14赋给第3个数组。函数接受3个数组名和一个数组大小。在一个简单的程序中测试该函数。
#include <stdio.h>
#define N 4
void add_array(const int a[], const int b[], int c[], int n);
void show_array(const int x[], int n);
int main(void)
{
int a[N] = {2, 4, 5, 8};
int b[N] = {1, 0, 4, 6};
int c[N] = {0};
printf("a数组是:\n");
show_array(a, N);
printf("b数组是:\n");
show_array(b, N);
printf("原c数组是:\n");
show_array(c, N);
add_array(a, b, c, N);
printf("a数组与b数组之和拷贝至c数组后结果是:\n");
show_array(c, N);
return 0;
}
void add_array(const int a[], const int b[], int c[], int n)
{
int i;
for (i = 0; i < n; i++)
{
c[i] = a[i] + b[i];
}
return;
}
void show_array(const int x[], int n)
{
int i;
for (i = 0; i < n; i++)
{
printf("%-3d", x[i]);
}
putchar('\n');
return;
}
11.编写一个程序,声明一个int类型的3×5二维数组,并用合适的值初始化它。该程序打印数组中的值,然后各值翻倍(即是原值的2倍),并显示出各元素的新值。编写一个函数显示数组的内容,再编写一个函数把各元素的值翻倍。这两个函数都以函数名和行数作为参数。
#include <stdio.h>
#define N 3
#define M 5
void show(const int (*a)[M], int n);
void two_times(int (*a)[M], int n);
int main(void)
{
int a[N][M] =
{
{1, 2, 3, 4, 5},
{6, 7, 8, 9, 10},
{11, 12, 13, 14, 15}
};
printf("原数组是:\n");
show(a, N);
//↑若有编译警告;
//↑可以使用强制类型转换;
//↑(const int (*)[M]);
two_times(a, N);
printf("原数组翻倍后是:\n");
show(a, N);
return 0;
}
void show(const int (*a)[M], int n)
{
int i, j;
for (i = 0; i < n; i++)
{
for (j = 0; j < M; j++)
{
printf("%-5d", a[i][j]);
}
putchar('\n');
}
return;
}
void two_times(int (*a)[M], int n)
{
int i, j;
for (i = 0; i < n; i++)
{
for (j = 0; j < M; j++)
{
a[i][j] *= 2;
}
}
return;
}
12.重写程序清单10.7的rain.c程序,把 main ( )中的主要任务都改成用函数来完成。
#include <stdio.h>
#define MONTHS 12
#define YEARS 5
void rainfall_total(const float (*rain)[MONTHS], int years);
void rainfall_aver(const float (*rain)[MONTHS], int years);
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},
};
rainfall_total(rain, YEARS);
rainfall_aver(rain, YEARS);
return 0;
}
void rainfall_total(const float (*rain)[MONTHS], int years)
{
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.1lf\n", 2010 + year, subtot);
total += subtot;
}
printf("\nThe yearly average is %.1f inches.\n\n", total / years);
return;
}
void rainfall_aver(const float (*rain)[MONTHS], int years)
{
float subtot;
int month, year;
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 (year = 0, subtot = 0; year < years; year++)
{
subtot += rain[year][month];
}
printf("%4.1f ", subtot / years);
}
putchar('\n');
return;
}
13.编写一个程序,提示用户输入3组数,每组数包含5个double类型的数(假设用户都正确地响应,不会输入非数值数据)。该程序应完成下列任务。
a.把用户输入的数据储存在3×5的数组中
b. 计算每组(5个)数据的平均值
c.计算所有数据的平均值
d.找出这15个数据中的最大值
e.打印结果
每个任务都要用单独的函数来完成(使用传统C处理数组的方式)。完成任务b,要编写一个计算并返回一维数组平均值的函数,利用循环调用该函数3次。对于处理其他任务的函数,应该把整个数组作为参数,完成任务c和d的函数应把结果返回主调函数。
#include <stdio.h>
#define ROWS 3
#define COLS 5
void store(double ar[], int n);
double average2d(double ar[][COLS], int rows);
double max2d(double ar[][COLS], int rows);
void showarr2(double ar[][COLS], int rows);
double average(const double ar[], int n);
int main(void)
{
int row;
double stuff[ROWS][COLS];
for (row = 0; row < ROWS; row++)
{
printf("请为第%d行输入%d个数\n", row + 1, COLS);
store(stuff[row], COLS);
}
printf("本数组如下:\n");
showarr2(stuff, ROWS);
for (row = 0; row < ROWS; row++)
{
printf("第%d行的平均值是:%g\n", row + 1, average(stuff[row], COLS));
}
printf("所有数的平均值是:%g\n", average2d(stuff, ROWS));
printf("最大值是:%g\n", max2d(stuff, ROWS));
printf("本程序完成!\n");
return 0;
}
void store(double ar[], int n)
{
int i;
for (i = 0; i < n; i++)
{
printf("请您输入第%d个数:", i + 1);
scanf("%lf", &ar[i]);
}
return;
}
double average2d(double ar[][COLS], int rows)
{
int i, j;
double sum = 0.0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < COLS; j++)
{
sum += ar[i][j];
}
}
if (rows * COLS > 0)
{
return sum / (rows * COLS);
}
else
{
return 0.0;
}
}
double max2d(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++)
{
max = max < ar[i][j] ? ar[i][j] : max;
}
}
return max;
}
void showarr2(double ar[][COLS], int rows)
{
int i, j;
for (i = 0; i < rows; i++)
{
for (j = 0; j < COLS; j++)
{
printf("%-5g", ar[i][j]);
}
putchar('\n');
}
return;
}
double average(const double ar[], int n)
{
int i;
double sum = 0.0;
for (i = 0; i < n; i++)
{
sum += ar[i];
}
if (n > 0)
{
return sum / n;
}
else
{
return 0.0;
}
}
14.以变长数组作为函数形参,完成编程练习13。
#include <stdio.h>
#define ROWS 3
#define COLS 5
void store(int n, double ar[n]);
double average2d(int rows, int cols, double ar[rows][cols]);
double max2d(int rows, int cols, double ar[rows][cols]);
void showarr2(int rows, int cols, double ar[rows][cols]);
double average(int n, const double ar[n]);
int main(void)
{
int row;
double stuff[ROWS][COLS];
for (row = 0; row < ROWS; row++)
{
printf("请为第%d行输入%d个数\n", row + 1, COLS);
store(COLS, stuff[row]);
}
printf("本数组是:\n");
showarr2(ROWS, COLS, stuff);
for (row = 0; row < ROWS; row++)
{
printf("第%d行的平均数是:%g\n", row + 1, average(COLS, stuff[row]));
}
printf("所有数的平均数是:%g\n", average2d(ROWS, COLS, stuff));
printf("最大值是:%g\n", max2d(ROWS, COLS, stuff));
printf("本程序完成!\n");
return 0;
}
void store(int n, double ar[n])
{
int i;
for (i = 0; i < n; i++)
{
printf("请您输入第%d个数:", i + 1);
scanf("%lf", &ar[i]);
}
return;
}
double average2d(int rows, int cols, double ar[rows][cols])
{
int i, j;
double sum = 0.0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
sum += ar[i][j];
}
}
if (rows * cols > 0)
{
return sum / (rows * cols);
}
else
{
return 0.0;
}
}
double max2d(int rows, int cols, double ar[rows][cols])
{
int i, j;
double max = ar[0][0];
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
max = max < ar[i][j] ? ar[i][j] : max;
}
}
return max;
}
void showarr2(int rows, int cols, double ar[rows][cols])
{
int i, j;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
printf("%-5g", ar[i][j]);
}
putchar('\n');
}
return;
}
double average(int n, const double ar[n])
{
int i;
double sum = 0.0;
for (i = 0; i < n; i++)
{
sum += ar[i];
}
if (n > 0)
{
return sum / n;
}
else
{
return 0.0;
}
}