1.修改程序清单10.7的rain.c程序, 用指针进行计算(仍然要声明并初始化数组)
#include<stdio.h>
#define MONTHS 12
#define YEARS 5
int main(void)
{
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];
pr = 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("MONTHLY 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("%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>
#define SIZE 5
void copy_arr(double t[], double s[], int n);
void copy_ptr(double *pt, double *ps, int n);
void copy_ptrs(double *pt, double *ps, double *end);
int main(void)
{
double source[SIZE] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
double target1[SIZE], target2[SIZE], target3[SIZE];
printf("target1:\n");
copy_arr(target1, source, SIZE);
printf("target2:\n");
copy_ptr(target2, source, SIZE);
printf("target3:\n");
copy_ptrs(target3, source, source + SIZE);
return 0;
}
void copy_arr(double t[], double s[], int n)
{
int i;
for (i = 0; i < n; i++)
{
t[i] = s[i];
printf("%g\t", t[i]);
}
putchar('\n');
return;
}
void copy_ptr(double *pt, double *ps, int n)
{
int i;
for (i = 0; i < n; i++)
{
*pt = *ps;
printf("%g\t", *ps);
pt++;
ps++;
}
putchar('\n');
return;
}
void copy_ptrs(double *pt, double *ps, double *end)
{
while (ps < end)
{
*pt = *ps;
printf("%g\t", *ps);
pt++;
ps++;
}
putchar('\n');
return;
}
3.编写一个函数, 返回储存在int类型数组中的最大值, 并在一个简单的程序中测试该函数
#include<stdio.h>
int max(int ar[], int n);
int main(void)
{
int array[6] = { 4, 6, 104, -43, -32, 23 };
printf("the largest integer is %d\n", max(array, 6));
return 0;
}
int max(int ar[], int n)
{
int i;
int max = ar[0];
for (i = 1; i < n; i++)
if (max < ar[i])
max = ar[i];
return max;
}
4.编写一个函数, 返回储存在double类型数组中最大值的下标, 并在一个简单的程序中测试该函数
#include<stdio.h>
int location(double ar[], int n);
int main(void)
{
double array[6] = { 32.643, 32.7, -34343, 53, 9.321, 0 };
printf("the index of the largest value is %d\n", location(array, 6));
return 0;
}
int location(double ar[], int n)
{
int index = 0;
int j;
for (j = 1; j < n; j++)
if (ar[index] < ar[j])
index = j;
return index;
}
5.编写一个函数, 返回储存在double类型数组中最大值和最小值的差值, 并在一个简单的程序中测试该函数
#include<stdio.h>
double difference(double ar[], int n);
int main(void)
{
double array[10] = { 321, 0, 320.432, 2e3, 23.45, -0.34, 23, -321, 48, 34 };
printf("the difference between the largest and smallest elements is %g\n", difference(array, 10));
return 0;
}
double difference(double ar[], int n)
{
double smallest = ar[0];
double largest = ar[0];
int i;
for (i = 1; i < n; i++)
{
if (smallest > ar[i])
smallest = ar[i];
if (largest < ar[i])
largest = ar[i];
}
return (largest - smallest);
}
6.编写一个函数, 把double类型数组中的数据倒序排列, 并在一个简单的程序中测试该函数
#include<stdio.h>
#define SIZE 10
void reverse(double s[], double t[], int n);
int main(void)
{
double source[SIZE] = { 321, 0, 320.432, 2e3, 23.45, -0.34, 23, -321, 48, 34 };
double target[SIZE];
int i;
reverse(source, target, SIZE);
printf("target[10]: ");
for (i = 0; i < SIZE; i++)
printf("%g ", target[i]);
putchar('\n');
return 0;
}
void reverse(double s[], double t[], int n)
{
int i, j;
for (i = 0, j = n-1; i < n; i++, j--)
t[j] = s[i];
return;
}
7.编写一个程序, 初始化一个double类型的二维数组, 使用编程练习2中的一个拷贝函数把该数组中的数据拷贝至另一个二维数组中(因为二维数组是数组的数组, 所以可以使用处理一维数组的拷贝函数来处理数组中的每个子数组)
#include<stdio.h>
#define SIZE 3
void copy(double s[], double t[], int n);
int main(void)
{
double source[SIZE][5] =
{
{ 1.1, 2.2, 3.3, 4.4, 5.5 },
{ 321, 0, 320.432, 2e3, 23.45 },
{ -0.34, 23, -321, 48, 34 }
};
double target[SIZE][5];
int i, j;
for (i = 0; i < SIZE; i++)
copy(source[i], target[i], 5);
for (i = 0; i < SIZE; i++)
{
for (j = 0; j < 5; j++)
printf("%g\t", target[i][j]);
putchar('\n');
}
return 0;
}
void copy(double s[], double t[], int n)
{
int i;
for (i = 0; i < n; i++)
t[i] = s[i];
return;
}
8.使用编程练习2中的拷贝函数, 把一个内含7个元素的数组中第3~第5个元素拷贝至内含3个元素的数组中。 该函数本身不需要修改, 只需要选择合适的实际参数(实际参数不需要是数组名和数组大小, 只需要是数组元素的地址和待处理元素的个数)
#include<stdio.h>
#define SIZE1 7
#define SIZE2 3
void copy(double *ps, double *pt, int n);
int main(void)
{
double sourse[SIZE1] = { 321, 0, 320.432, 2e3, 23.45, -0.34, 23 };
double target[SIZE2];
copy(&sourse[2], target, SIZE2);
int i;
for (i = 0; i < SIZE2; i++)
printf("%g\t", target[i]);
putchar('\n');
return 0;
}
void copy(double *ps, double *pt, int n)
{
int i;
for (i = 0; i < n; i++)
{
*pt = *ps;
ps++;
pt++;
}
return;
}
9.编写一个程序, 初始化一个double类型的3×5二维数组, 使用一个处理变长数组的函数将其拷贝至另一个二维数组中。 还要编写一个以变长数组为形参的函数以显示两个数组的内容。 这两个函数应该能处理任意N×M数组(如果编译器不支持变长数组, 就使用传统C函数处理N×5的数组)
#include<stdio.h>
void copy(int n, int m, double s[n][m], double t[n][m]);
void show(int n, int m, double ar[n][m]);
int main(void)
{
int row = 3;
int col = 5;
double source[3][5] =
{
{ 1.1, 2.2, 3.3, 4.4, 5.5 },
{ 321, 0, 320.432, 2e3, 23.45 },
{ -0.34, 23, -321, 48, 34 }
};
double target[row][col];
copy(row, col, source, target);
printf("source: \n");
show(3, 5, source);
printf("target:\n");
show(row, col, target);
return 0;
}
void copy(int n, int m, double s[n][m], double t[n][m])
{
int i, j;
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
t[i][j] = s[i][j];
return;
}
void show(int n, int m, double ar[n][m])
{
int i, j;
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
printf("%g\t", ar[i][j]);
putchar('\n');
}
return;
}
10.编写一个函数, 把两个数组中相对应的元素相加, 然后把结果储存到第 3 个数组中。 也就是说, 如果数组1中包含的值是2、 4、 5、 8, 数组2中包含的值是1、 0、 4、 6, 那么该函数把3、 4、 9、 14赋给第3个数组。 函数接受3个数组名和一个数组大小。 在一个简单的程序中测试该函数
#include<stdio.h>
#define SIZE 5
void add(double s1[], double s2[], double t[], int n);
int main(void)
{
double source1[SIZE] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
double source2[SIZE] = { 321, 0, 320.432, 2e3, 23.45};
double target[SIZE];
add(source1, source2, target, SIZE);
int i;
for (i = 0; i < SIZE; i++)
printf("%g\t", target[i]);
putchar('\n');
return 0;
}
void add(double s1[], double s2[], double t[], int n)
{
int i;
for (i = 0; i < n; i++)
t[i] = s1[i] + s2[i];
return;
}
11.编写一个程序, 声明一个int类型的3×5二维数组, 并用合适的值初始化它。 该程序打印数组中的值, 然后各值翻倍(即是原值的2倍) , 并显示出各元素的新值。 编写一个函数显示数组的内容, 再编写一个函数把各元素的值翻倍。 这两个函数都以函数名和行数作为参数
#include<stdio.h>
void doub(int s[][5], int t[][5], int n);
void show(int ar[][5], int n);
int main(void)
{
int source[3][5] =
{
{ -5, 0, 23, 84, 3 },
{ 9, -32, 45, 2, 1 },
{ 0, 32, 5, -34, 3 }
};
int target[3][5];
doub(source, target,3);
printf("source:\n");
show(source, 3);
printf("target:\n");
show(target, 3);
return 0;
}
void doub(int s[][5], int t[][5], int n)
{
int i, j;
for (i = 0; i < n; i++)
for (j = 0; j < 5; j++)
t[i][j] = s[i][j] * 2;
return;
}
void show(int ar[][5], int n)
{
int i, j;
for (i = 0; i < n; i++)
{
for (j = 0; j < 5; j++)
printf("%d\t", ar[i][j]);
putchar('\n');
}
return;
}
12.重写程序清单10.7的rain.c程序, 把main()中的主要任务都改成用函数来完成
#include<stdio.h>
#define MONTHS 12
#define YEARS 5
void summary_year(float r[][MONTHS], int n);
void summary_month(float r[][MONTHS], int n);
int main(void)
{
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 }
};
summary_year(rain, YEARS);
summary_month(rain, YEARS);
return 0;
}
void summary_year(float r[][MONTHS], int n)
{
int i, j;
float subtot, total;
printf("YEAR RAINFALL (inches)\n");
for (i = 0, total = 0; i < n; i++)
{
for (j = 0, subtot = 0; j < MONTHS; j++)
subtot += r[i][j];
printf("%5d %15.1f\n", 2010 + i, subtot);
total += subtot;
}
printf("\nThe yearly average is %.1f inches.\n\n", total / YEARS);
return;
}
void summary_month(float r[][MONTHS], int n)
{
int i, j;
float subtot;
printf("MONTHLY AVERAGES:\n\n");
printf(" Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec\n");
for (j = 0; j < MONTHS; j++)
{
for (i = 0, subtot = 0; i < n; i++)
subtot += r[i][j];
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 GROUP 3
#define SIZE 5
void save(double ar[][SIZE], int n);
double average_group(double ar[], int n);
double average_all(double ar[][SIZE], int n);
double max(double ar[][SIZE], int n);
void display(double ar[][SIZE], int n);
int main(void)
{
double array[GROUP][SIZE];
int i;
printf("enter 3 sets of 5 double numbers each\n");
save(array, GROUP);
printf("array:\n");
display(array, GROUP);
printf("the average of each set of 5 values:\n");
for (i = 0; i < GROUP; i++)
printf("%10g", average_group(array[i], SIZE));
printf("\nthe average of all the values: %g\n", average_all(array, GROUP));
printf("the largest value of the 15 values: %g\n", max(array, GROUP));
return 0;
}
void save(double ar[][SIZE], int n)
{
int i, j;
for (i = 0; i < n; i++)
for (j = 0; j < SIZE; j++)
scanf("%lf", &ar[i][j]);
return;
}
double average_group(double ar[], int n)
{
int i;
double sum = 0.0;
for (i = 0; i < n; i++)
sum += ar[i];
return sum / n;
}
double average_all(double ar[][SIZE], int n)
{
int i, j;
double sum = 0.0;
for (i = 0; i < n; i++)
for (j = 0; j < SIZE; j++)
sum += ar[i][j];
return sum / (n * SIZE);
}
double max(double ar[][SIZE], int n)
{
int i, j;
double max = ar[0][0];
for (i = 0; i < n; i++)
for (j = 0; j < SIZE; j++)
if (max < ar[i][j])
max = ar[i][j];
return max;
}
void display(double ar[][SIZE], int n)
{
int i, j;
for (i = 0; i < n; i++)
{
for (j = 0; j < SIZE; j++)
printf("%8g", ar[i][j]);
putchar('\n');
}
return;
}
14.以变长数组作为函数形参, 完成编程练习13
#include<stdio.h>
#define GROUP 3
#define SIZE 5
void save(int n, int m, double ar[n][m]);
double average_group(int n, double ar[n]);
double average_all(int n, int m, double ar[n][m]);
double max(int n, int m, double ar[n][m]);
void display(int n, int m, double ar[n][m]);
int main(void)
{
double array[GROUP][SIZE];
int i;
printf("enter 3 sets of 5 double numbers each\n");
save(GROUP, SIZE, array);
printf("array:\n");
display(GROUP,SIZE, array);
printf("the average of each set of 5 values:\n");
for (i = 0; i < GROUP; i++)
printf("%10g", average_group(SIZE, array[i]));
printf("\nthe average of all the values: %g\n", average_all(GROUP, SIZE, array));
printf("the largest value of the 15 values: %g\n", max(GROUP, SIZE, array));
return 0;
}
void save(int n, int m, double ar[n][m])
{
int i, j;
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
scanf("%lf", &ar[i][j]);
return;
}
double average_group(int n, double ar[n])
{
int i;
double sum = 0.0;
for (i = 0; i < n; i++)
sum += ar[i];
return sum / n;
}
double average_all(int n, int m, double ar[n][m])
{
int i, j;
double sum = 0.0;
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
sum += ar[i][j];
return sum / (n * m);
}
double max(int n, int m, double ar[n][m])
{
int i, j;
double max = ar[0][0];
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
if (max < ar[i][j])
max = ar[i][j];
return max;
}
void display(int n, int m, double ar[n][m])
{
int i, j;
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
printf("%8g", ar[i][j]);
putchar('\n');
}
return;
}