C Primer Plus 编程习题-第十章-数组和指针
C Primer Plus 10.13
编程练习第一题
/* C Primer Plus 10.13 —— 编程练习第一题 */
/* 题目:修改程序清单10.7的rain.c程序,用指针进行运算
(仍然要声明并初始化数组)。 */
#include <stdio.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(*p)[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 += *(*(p + 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 += *(*(p + year) + month);
printf("%4.1f ", subtot / YEARS);
}
printf("\n");
getchar();
return 0;
}
编程练习第二题
/* C Primer Plus 10.13 —— 编程练习第二题 */
/* 题目:编写一个程序,初始化一个double类型的数组,然后把该数组的
内容拷贝至3个其他数组中(在main()中声明这4个数组)。使用带数组表示法
的函数进行第1次拷贝。使用带指针表示法和指针递增的函数进行第2份拷贝。
把目标数组名、源数组名和待拷贝的元素个数作为前两个函数的参数。第3个
函数以目标数组名、源数组名和指向源数组最后一个元素后面的元素的指针。 */
#include <stdio.h>
#define COLS 5
void copy_arr(double target1[], double source[], int c);
void copy_ptr(double *target2, double *source, int c);
void copy_ptrs(double *target3, double *source, double *last);
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, COLS);
printf("\n");
copy_ptr(target2, source, COLS);
printf("\n");
copy_ptrs(target3, source, source + 5);
getchar();
return 0;
}
void copy_arr(double target1[], double source[], int c)
{
int i;
for (i = 0; i < c; i++)
target1[i] = source[i];
for (i = 0; i < c; i++)
printf("%.1f ", target1[i]);
}
void copy_ptr(double *target2, double *source, int c)
{
int i;
for (i = 0; i < c; i++)
*target2++ = *source++;
// 将 *source 所指地址的内容赋给 *target2 所指地址的内容。储存单元 +1
for (i = 0; i < c; i++)
printf("%.1f ", target2[i]);
}
void copy_ptrs(double *target3, double *source, double *last)
{
while (source < last)
*target3++ = *source++;
for (int i = 0; i < COLS; i++)
printf("%.1f ", target3[i]);
}
编程练习第三题
/* C Primer Plus 10.13 —— 编程练习第三题 */
/* 题目:编写一个函数,返回储存在int类型数组中的最大值,并在一个
简单的程序中测试该函数。 */
#include <stdio.h>
int MAX(int array[]);
int main(void)
{
int arr[6] = {10, 4, 18, 8, 50, 0};
int max;
max = MAX(arr);
printf("The max number of the array is %d.\n", max);
getchar();
return 0;
}
int MAX(int array[])
{
int max;
max = array[0];
for (int i = 0; i < 6; i++)
{
if (max <= array[i])
max = array[i];
}
return max;
}
编程练习第四题
/* C Primer Plus 10.13 —— 编程练习第四题 */
/* 题目:编写一个函数,返回储存在double类型数组中的最大值的下标,并在
一个简单的程序中测试该函数。 */
#include <stdio.h>
int max_index(int array[]);
int main(void)
{
double arr[6] = {10.2, 4.6, 18.9, 8.8, 50.4, 0.6};
int max;
max = max_index(arr);
printf("The max number's index of the array is %d.\n", max);
getchar();
return 0;
}
int max_index(int array[])
{
int max = 0;
for (int i = 0; i < 6; i++)
{
if (array[max] <= array[i])
max = i;
}
return max;
}
编程练习第五题
/* C Primer Plus 10.13 —— 编程练习第五题 */
/* 题目:编写一个函数,返回储存在double类型数组中最大值和最小值的
差值,并在一个简单的程序中测试该函数。 */
#include <stdio.h>
double sub(double *arr);
int main(void)
{
double array[6] = {10.2, 4.6, 18.9, 8.8, 50.4, 0.6};
double res;
res = sub(array);
printf("max - min = %lf\n", res);
getchar();
return 0;
}
double sub(double arr[])
{
double max, min;
double value;
max = arr[0];
min = arr[0];
for (int i = 0; i < 6; i++)
{
if (min > arr[i])
min = arr[i];
if (max < arr[i])
max = arr[i];
}
printf("max:%lf\nmin:%lf\n", max, min);
value = max - min;
return value;
}
编程练习第六题
/* C Primer Plus 10.13 —— 编程练习第六题 */
/* 题目:编写一个函数,把double类型数组中数据倒序排列,并在
一个简单的程序中测试该函数。 */
#include<stdio.h>
void reverse_order(double *array, int n);
int main(void)
{
int i;
double arr[10] = {98.2, 6.8, 23.2, 87.973, -0.5678,
-15.89, 44.432, 2.4, 5.09, 100.0};
printf("The array is: ");
for (i = 0; i < 10; i++)
printf("%.4lf ", arr[i]);
printf("\n");
reverse_order(arr, 10);
printf("The Reverse array is: ");
for (i = 0; i < 10; i++)
printf("%.4lf ", arr[i]);
getchar();
return 0;
}
void reverse_order(double *array, int n)
{
double temp;
int i;
for (i = 0; i < n / 2; i++)
{
temp = array[i];
array[i] = array[n - 1 - i];
array[n - 1 - i] = temp;
}
}
编程练习第七题
/* C Primer Plus 10.13 —— 编程练习第七题 */
/* 题目:编写一个函数,初始化一个double类型的二维数组,使用编程
练习2中的一个拷贝函数把该数组中的数据拷贝至另一个二维数组中(因
为二维数组是数组的数组,所以可以用处理一维数组的拷贝函数来处理数
组中每个子数组)。 */
#include <stdio.h>
void copy_arr(double target1[][5], double source[][5], int c);
void copy_ptr(double *target2, double *source, int c);
int main(void)
{
double source[3][5] = {{1.1, 2.2, 3.3, 4.4, 5.5},
{2.2, 3.3, 4.4, 5.5, 6.6},
{3.3, 4.4, 5.5, 6.6, 7.7}};
double target1[3][5];
copy_arr(target1, source, 3);
for (int i = 0; i < 3; i++){
for (int j = 0; j < 5; j++)
printf("%.1f ", target1[i][j]);
printf("\n");
}
printf("\n");
getchar();
return 0;
}
void copy_arr(double target1[][5], double source[][5], int c)
{
int i;
for (i = 0; i < c; i++)
copy_ptr(target1[i], source[i], 5); // 第 i 行进行处理
}
void copy_ptr(double *target2, double *source, int c)
{
int i;
for (i = 0; i < c; i++)
*target2++ = *source++;
// 将 *source 所指地址的内容赋给 *target2 所指地址的内容。储存单元 +1
}
编程练习第八题
/* C Primer Plus 10.13 —— 编程练习第八题 */
/* 题目:使用编程练习2中的拷贝函数,把一个内容7个元素的数组中第3~
第5个元素拷贝至内含3个元素的数组中。该函数本身不需要修改,只需要合
适的实际参数(实际参数不需要是数组名和数组大小,只需要适数组元素的
地址和待处理元素的个数) */
#include <stdio.h>
#define COLS 7
void copy_arr(double target1[], double source[], int c);
void copy_ptr(double *target2, double *source, int c);
void copy_ptrs(double *target3, double *source, double *last);
int main(void)
{
double source[7] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7};
double target1[3];
double target2[3];
double target3[3];
copy_arr(target1, source, COLS);
printf("\n");
copy_ptr(target2, source, COLS);
printf("\n");
getchar();
return 0;
}
void copy_arr(double target1[], double source[], int c)
{
int i;
for (i = 2; i < c - 2; i++)
target1[i - 2] = source[i];
for (i = 0; i < 3; i++)
printf("%.1f ", target1[i]);
}
void copy_ptr(double *target2, double *source, int c)
{
int i;
for (i = 2; i < c - 2; i++)
*target2++ = *(source + i);
// 将 *source 所指地址的内容赋给 *target2 所指地址的内容。储存单元 +1
for (i = 0; i < 3; i++)
printf("%.1f ", target2[i]);
}
编程练习第九题
/* C Primer Plus 10.13 —— 编程练习第九题 */
/* 题目:编写一个函数,初始化一个double类型的3×5二维数组,使用一个
处理变长数组的函数将其拷贝至另一个二维数组中。还要编写一个以变长数组
为形参的函数以显示两个数组的内容。这两个函数应该能处理任意N×M数组。 */
#include <stdio.h>
void copy_arr(int rows, int cols, double arr[rows][cols]);
void show_arr(int rows, int cols, double arr[rows][cols]);
int main(void)
{
int row = 3;
int col = 5;
double source[3][5] = {{1.1, 2.2, 3.3, 4.4, 5.5},
{2.2, 3.3, 4.4, 5.5, 6.6},
{3.3, 4.4, 5.5, 6.6, 7.7}};
show_arr(row, col, source);
printf("\n");
copy_arr(row, col, source);
printf("\n");
getchar();
return 0;
}
void copy_arr(int rows, int cols, double arr[rows][cols])
{
double array[rows][cols];
int i, j;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
array[i][j] = arr[i][j];
}
show_arr(rows, cols, array);
}
void show_arr(int rows, int cols, double arr[rows][cols])
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
printf("%.1f ", arr[i][j]);
printf("\n");
}
}
编程练习第十题
/* C Primer Plus 10.13 —— 编程练习第十题 */
/* 题目:编写一个函数,把两个数组中相对应的元素相加,然后把结果
储存到第3个数组中。也就是说,如果数组1中包含的值是2、4、5、8,数
组2中包含的值是1、0、4、6,那么该函数把3、4、9、14赋给第3个数组。
函数接受3个数组名和一个数组大小。在一个简单的程序中测试该函数。 */
#include <stdio.h>
void add_arr(int c, int target1[c], int target2[c], int res[c]);
int main(void)
{
int cols = 4;
int t1[4] = {2, 4, 5, 8};
int t2[4] = {1, 0, 4, 6};
int res[cols];
add_arr(cols, t1, t2, res);
for (int i = 0; i < cols; i++)
printf("%d ", res[i]);
printf("\n");
getchar();
return 0;
}
void add_arr(int c, int target1[c], int target2[c], int res[c])
{
int j;
for (j = 0; j < c; j++)
res[j] = target1[j] + target2[j];
}
编程练习第十一题
/* C Primer Plus 10.13 —— 编程练习第十一题 */
/* 题目:编写一个函数,声明一个int类型的3×5二维数组,并用合适的值初始化它。
该程序打印数组中的值,然后各值翻倍,并显示出各元素的新值。编写一个函数显示
数组的内容,再编写一个函数把各元素的值翻倍。这两个函数都以函数名和行数作为
参数。 */
#include <stdio.h>
#include <stdlib.h>
void pr(int c, int arr[][5]);
void db(int c, int arr[][5]);
int main(void)
{
int source[3][5] = {{1, 2, 3, 4, 5},
{6, 7, 8, 9, 10},
{11, 12, 13, 14, 15}};
pr(3, source);
printf("\n");
db(3, source);
pr(3, source);
getchar();
return 0;
}
void pr(int c, int arr[][5])
{
for (int i = 0; i < c; ++i) {
for (int j = 0; j < 5; ++j) {
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
void db(int c, int arr[][5])
{
for (int i = 0; i < c; ++i) {
for (int j = 0; j < 5; ++j) {
arr[i][j] *= 2;
}
}
}
编程练习第十二题
/* C Primer Plus 10.13 —— 编程练习第十二题 */
/* 题目:重写程序清单10.7的rain.c程序,把main()中的主要
任务都改成用函数来完成。*/
#include <stdio.h>
#include <stdlib.h>
#define MONTHS 12 // 一年的月份数
#define YEARS 5 // 年数
void yearaver(const float rain[YEARS][MONTHS]);
void monthaver(const float rain[YEARS][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 }
};
yearaver(rain);
monthaver(rain);
return 0;
}
void yearaver(const float rain[YEARS][MONTHS])
{
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; // 5年的总降水量
}
printf("\nThe yearly average is %.1f inches.\n\n", total / YEARS);
}
void monthaver(const float rain[YEARS][MONTHS])
{
int year, month;
float subtot, total;
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);
printf("%4.1f ", subtot / YEARS);
}
printf("\n");
}
编程练习第十三题
/* C Primer Plus 10.13 —— 编程练习第十三题 */
/* 题目:编写一个函数,提示用户输入3组数,每组数包含5个double
类型的数(假设用户都正确地响应)。该程序完成下列任务:
a. 把用户输入的数据储存在3×5的数组中
b. 计算每组(5个)数据的平均值
c. 计算所有数据的平均值
d. 找出这15个数据中的最大值
e. 打印结果
每个任务都要用单独的函数来完成(使用传统C处理数组的方式)。完成
任务b,要编写一个计算并返回一维数组平均值的函数,利用循环调用该
函数3次。对于处理其他任务的函数,应该把整个数组作为参数,完成任
务c和d的函数应把结果返回主调函数。 */
#include <stdio.h>
#include <stdlib.h>
double aver(double array[5]);
double allaver(double array[3][5]);
double max_(double *a, double *b);
int main(void)
{
double arr[3][5];
double sum = 0;
for (int i = 0; i < 3; i++){
printf("Enter 5 number:");
for (int j = 0; j < 5; j++)
scanf("%lf", &arr[i][j]);
}
for (int m = 0; m < 3; m++) {
printf("%.2lf ", aver(arr[m]));
}
printf("\n");
printf("%.2lf\n", allaver(arr));
printf("%.2lf\n", max_(*arr, *arr + 15));
system("pause");
return 0;
}
double aver(double array[5])
{
double sum = 0;
for (int i = 0; i < 5; i++) {
sum += array[i];
}
return sum / 5;
}
double allaver(double array[3][5])
{
double sum = 0;
for (int i = 0; i < 3; i++) {
sum += aver(array[i]);
}
return sum / 3;
}
double max_(double* a, double* b)
{
double max = 0;
for(;a < b; a++)
max = max > *a ? max : *a;
return max;
}
编程练习第十四题
/* C Primer Plus 10.13 —— 编程练习第五题 */
/* 题目:以变长数组作为函数形参,完成编程练习13。 */
#include <stdio.h>
#include <stdlib.h>
double aver(int , double array[]);
double allaver(int row, int col, double array[row][col]);
double max_(int row, int col, double array[row][col]);
int main(void)
{
double arr[3][5];
double sum = 0;
for (int i = 0; i < 3; i++){
printf("Enter 5 number:");
for (int j = 0; j < 5; j++)
scanf("%lf", &arr[i][j]);
}
for (int m = 0; m < 3; m++) {
printf("%.2lf ", aver(5, arr[m]));
}
printf("\n");
printf("%.2lf\n", allaver(3, 5, arr));
printf("%.2lf\n", max_(3, 5, arr));
system("pause");
return 0;
}
double aver(int col, double array[col])
{
double sum = 0;
for (int i = 0; i < col; i++)
sum += array[i];
return sum / 5;
}
double allaver(int row, int col, double array[3][5])
{
double sum = 0;
for (int i = 0; i < row; i++) {
sum += aver(col, array[i]);
}
return sum / 3;
}
double max_(int row, int col, double array[row][col])
{
double max = 0;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
max = max > array[i][j] ? max : array[i][j];
}
return max;
}