C Primer Plus 第六版编程练习第十章答案和记录一些学习历程
2020-02-03 00:24
796 查看
终于到了最重要的部分了。
1.修改程序清单10.7的rain.c程序,用指针进行计算(仍然要声明并初始化数组)。
这一题主要是考虑数组表示法和指针表示法的转换。
数组名相当于数组第一个元素的地址,数组名加下标就是该下标元素的地址。
对于二维数组来说(二维数组其实就是数组的数组)
*(*(rain + year) + month)=rain[year][month]。
但是:处理二维数组时,使用数组表示法是最简单的。
/* Programming Exercise 10-1 */ #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 } }; // 用2010~2014年的降水量数据初始化数组 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);//平均每年降水量 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++)// 每个月,5年的总降水量 subtot += *(*(rain + 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];
target2[5];
double target3[5];
copy_arr(target1, source, 5);
copy_ptr(target2, source, 5);
copy_ptrs(target3, source, source + 5)
本题也是考察数组表示法和指针表示法:可以明显看出处理二维数组时数组表示法要简单的多。
/* Programming Exercise 10-2 */ #include <stdio.h> void copy_arr(double * target1, double * source, int x); void copy_ptr(double * target2, double * source, int x); void copy_ptrs(double * target3, double * source, double * source2); 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; } void copy_arr(double * target1, double * source, int x)//使用数组表示法 { int t; for (t=0; t < x; t++) { target1[t] = source[t]; printf("%15.1f", target1[t]); } printf("\n"); } void copy_ptr(double * target2, double * source, int x) //使用指针表示法和指针递增,使用待拷贝的元素个数作参数 { int t; for (t=0; t < x; t++) { *(target2 + t) = *(source + t); printf("%15.1f", *(target2 + t)); } printf("\n"); } void copy_ptrs(double * target3, double * source, double * source2)//使用指向最后一个元素的指针作为参数 { double *i; int t; for(i = source, t = 0; i < source2; i++, t++) { *(target3 + t) = *i; printf("%15.1f", *(target3 + t)); } printf("\n"); }
运行结果:
3.编写一个函数,返回储存在int类型数组中的最大值,并在一个简单的程序中测试该函数。
正常遍历找最大值即可:在前面的循环和分支里有相关题型。
/* Programming Exercise 10-3 */ #include <stdio.h> #define LEN 10 int max_arr(const int ar[], int n); void show_arr(const int ar[], int n); int main(void) { int orig[LEN] = {1,2,3,4,12,6,7,8,9,10}; //测试数组 int max; show_arr(orig, LEN); //显示测试数组内容 max = max_arr(orig, LEN); //求数组中最大值 printf("%d = largest value\n", max); return 0; } int max_arr(const 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; } void show_arr(const int ar[], int n) //显示数组 { int i; for (i = 0; i < n; i++) printf("%d ", ar[i]); putchar('\n'); }
运行结果:
4.编写一个函数,返回储存在double类型数组中最大值的下标,并在一个简单的程序中测试该函数。
这个题也很简单。
/* Programming Exercise 10-4 */ #include <stdio.h> #define LEN 10 int max_arr(const double ar[], int n); void show_arr(const double ar[], int n); int main(void) { double orig[LEN] = {1.0,2.0,3.0,4.0,12.0,6.0,7.0,8.0,9.0,10.0}; //测试数组 int j; show_arr(orig, LEN); //显示测试数组内容 j = max_arr(orig, LEN); //求数组中最大值的下标 printf("%d = largest value index\n", j); return 0; } int max_arr(const double ar[], int n) { int i; int j = 0; //记录数组第一个元素的下标 double max = ar[0]; //先令最大值为数组第一个元素 for (i = 1; i < n; i++) if (max < ar[i]) { max = ar[i]; //记录较大值 j = i; //记录较大值的下标 } return j; } void show_arr(const double ar[], int n) //显示数组 { int i; for (i = 0; i < n; i++) printf("%f\t", ar[i]); putchar('\n'); }
运行结果:
5.编写一个函数,返回储存在double类型数组中最大值和最小值的差值,并在一个简单的程序中测试该函数。
这个题就是第三题的变式,找出最大最小然后相减即可。
/* Programming Exercise 10-5 */ #include <stdio.h> #define LEN 10 double max_diff(const double ar[], int n); //声明 最大值与最小值之差最大函数 void show_arr(const double ar[], int n); //声明显示数组函数 int main(void) { double orig[LEN] = {1.1,2,3,4,12,61.3,7,8,9,10}; double max; show_arr(orig, LEN);//调用显示数组函数 max = max_diff(orig, LEN);//调用数组中最大值与最小值之差 最大函数 printf("%g = maximum difference\n", max); return 0; } double max_diff(const double ar[], int n) //定义最大值与最小值之差最大函数 { int i; double max = ar[0]; double min = ar[0]; for (i = 1; i < n; i++) { if (max < ar[i]) max = ar[i]; else if (min > ar[i]) min = ar[i]; } return max - min; } void show_arr(const double ar[], int n)//定义显示数组函数 { int i; for (i = 0; i < n; i++) printf("%g ", ar[i]); putchar('\n'); }
运行结果:
6.编写一个函数,把double类型数组中的数据倒序排列,并在一个简单的程序中测试该函数。
倒序排列和倒序不同
倒序排列是将原来放在数组最后一个位置的数据放到第一个,以此类推。
倒序是按从大到小或从小到大的顺序放置数据。
/* Programming Exercise 10-6 */ #include <stdio.h> #define LEN 10 void reverse_arr( double ar[], int n); //声明倒序排列函数 void show_arr( double ar[], int n); //声明显示数组函数 int main(void) { double orig[LEN] = {1.1,2,3,4,12,61.3,7,8,9,10}; double max; show_arr(orig, LEN);//调用显示数组函数 reverse_arr(orig, LEN);//调用倒序排列函数 show_arr(orig, LEN);//调用显示数组函数 return 0; } void reverse_arr( double ar[], int n) //定义倒序排列函数 { long int i; double t; for (i = 0; i < n/2; i++)//循环一半即可 { double t = ar[i]; ar[i] = ar[n - 1 - i]; ar[n - 1 - i] = t; } } void show_arr( double ar[], int n)//定义显示数组函数 { long long int i; for (i = 0; i < n; i++) printf("%g\t", ar[i]); putchar('\n'); }
运行结果:
7.编写一个程序,初始化一个double类型的二维数组,使用编程练习2中的一个拷贝函数把该数组中的数据拷贝至另一个二维数组中(因为二维数组是数组的数组,所以可以使用处理一维数组的拷贝函数来处理数组中的每个子数组)。
我在这里使用的是指针表示法,主要是想加强一下指针这方面的理解。可以看到指针表示法还是很麻烦的,大家可以用数组的办法来做一下。
/* Programming Exercise 10-7 */ #include <stdio.h> #define ROWS 3 #define COLS 5 void copy_arr(double target[][COLS], double source[][COLS], int x, int y); //声明复制二维数组函数——声明target,source是指向内含5个double类型值的指针 int main(void) { double source[ROWS][COLS] = { {1, 2.0, 4.0, 5, 9}, {1.5, 2, 4.0, 5, 5}, {1, 7.0, 2.6, 6, 3} };//初始化二维数组 double target[ROWS][COLS];//定义目标二维数组 copy_arr(target, source, ROWS, COLS);//调用复制二维数组函数 return 0; } void copy_arr(double target[][COLS], double source[][COLS], int x, int y) //定义复制二维数组函数 { int i,j; for (i = 0; i < x; i++) { for(j = 0; j < y; j++) { *(*(target + i) + j) = *(*(source + i) + j); //令目标数组的元素的值等于初始数组的元素值 printf("%f\t", *(*(target + i) + j), COLS); } printf("\n"); } }
运行结果:
8.使用编程练习2中的拷贝函数,把一个内含7个元素的数组中第3~第5个元素拷贝至内含3个元素的数组中。该函数本身不需要修改,只需要选择合适的实际参数(实际参数不需要是数组名和数组大小,只需要是数组元素的地址和待处理元素的个数。
把指针指向第三个元素直到第五个元素。
或者用数组形式也可以。
/* Programming Exercise 10-8 */ #include <stdio.h> #define LEN1 7 #define LEN2 3 void copy_arr(int ar1[], const int ar2[], int n); //声明复制函数 void show_arr(const int[], int); //声明显示数组函数 int main(void) { int orig[LEN1] = {1,2,3,4,5,6,7}; int copy[LEN2]; show_arr(orig, LEN1); copy_arr(copy, orig + 2, LEN2); show_arr(copy, LEN2); return 0; } void copy_arr(int ar1[], const int ar2[], int n) //定义复制函数 { int i; for (i = 0; i < n; i++) ar1[i] = ar2[i]; } void show_arr(const int ar[], int n) //定义显示数组函数 { int i; for (i = 0; i < n; i++) printf("%d ", ar[i]); putchar('\n'); }
运行结果;
9.编写一个程序,初始化一个double类型的3×5二维数组,使用一个处理变长数组的函数将其拷贝至另一个二维数组中。还要编写一个以变长数组为形参的函数以显示两个数组的内容。这两个函数应该能处理任意N×M数组(如果编译器不支持变长数组,就使用传统C函数处理N×5的数组)。
定义一个变长数组,直到要使用他的时候告知其数组的大小。
/* Programming Exercise 10-9 */ #include <stdio.h> #define ROWS 3 #define COLS 5 void copy(int rows,int cols,double arr[rows][cols],double arr2[rows][cols]);//声明复制二维数组函数 void display(int rows,int cols,double arr[rows][cols]);//声明显示二维数组函数 int main() { double source[ROWS][COLS] = { {1.2,2,3.6,4,5.5}, {2,2.7,3.8,5.3,10}, {1.1,6,4,6.5,5.3} }; double target[ROWS][COLS]; copy(ROWS, COLS, target, source); display(ROWS, COLS, source); putchar('\n'); display(ROWS, COLS, target); return 0; } void copy(int rows,int cols,double arr[rows][cols],double arr2[rows][cols])//定义复制二维数组函数 { int i, j; for (i = 0; i < rows; i++) for (j = 0; j < cols; j++) arr[i][j] = arr2[i][j]; } void display(int rows,int cols,double arr[rows][cols])//定义显示二维数组函数 { int i, j; for (i = 0; i < rows; i++) for (j = 0; j < cols; j++) printf("%g ", arr[i][j]); }
运行结果:
10.编写一个函数,把两个数组中相对应的元素相加,然后把结果储存到第 3 个数组中。也就是说,如果数组1中包含的值是2、4、5、8,数组2中包含的值是1、0、4、6,那么该函数把3、4、9、14赋给第3个数组。函数接受3个数组名和一个数组大小。在一个简单的程序中测试该函数。
也很简单,就正常的相加。
#include <stdio.h> #define SIZE 4 void sum_arr(double *arr1, double *arr2, double *sum, int lx);//声明求和数组函数 void show_arr(double * arr, int x);//声明显示数组函数 int main(void) { double arr1[SIZE] = {2, 4, 5, 8}; double arr2[SIZE] = {1, 0, 4, 6}; double sum[SIZE]; sum_arr(arr1, arr2, sum, SIZE); show_arr(sum, SIZE); return 0; } void sum_arr(double *arr1, double *arr2, double *sum, int x)//定义求和数组函数 { int i; for ( i= 0; i < x; i++) sum[i] = arr1[i] + arr2[i]; } void show_arr(double * arr, int x)//定义显示数组函数 { int i; for ( i= 0; i < x; i++) printf("%.1f\t", arr[i]); }
运行结果:
11.编写一个程序,声明一个int类型的3×5二维数组,并用合适的值初始化它。该程序打印数组中的值,然后各值翻倍(即是原值的2倍),并显示出各元素的新值。编写一个函数显示数组的内容,再编写一个函数把各元素的值翻倍。这两个函数都以数组名和行数作为参数。
乘以2即可。
/* Programming Exercise 10-11 */ #include <stdio.h> #define ROWS 3 #define COLS 5 void times2(int ar[][COLS], int r);//声明二维数组翻倍函数 void showarr2(int ar[][COLS], int r);//声明显示二维数组函数 int main(void) { int stuff[ROWS][COLS] = { {1,2,3,4,5}, {6,7,8,-2,10}, {11,12,13,14,15} }; showarr2(stuff, ROWS); putchar('\n'); times2(stuff, ROWS); showarr2(stuff, ROWS); return 0; } void times2(int ar[][COLS], int r)//定义二维数组翻倍函数 { int row, col; for (row = 0; row < r; row++) { for (col = 0; col < COLS; col++) ar[row][col] *= 2; } } void showarr2(int ar[][COLS], int r)//定义显示二维数组函数 { int row, col; for (row = 0; row < r; row++) { for (col = 0; col < COLS; col++) printf("%d\t", ar[row][col]); putchar('\n'); } }
运行结果:
12.重写程序清单10.7的rain.c程序,把main()中的主要任务都改成用函数来完成。
按照10.7的算法改成函数即可。
/* Programming Exercise 10-12 */ #include <stdio.h> #define MONTHS 12 #define YEARS 5 float yearsRainfall(float rain[][MONTHS]);//声明计算年均下雨量 void monthAverage(float rain[][MONTHS]);//声明计算月均下雨量 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} }; int year, month; float total, subtot; printf("YEARS RAINFALL (inches) \n"); total = yearsRainfall(rain); printf("The yearly average is %.1f inches. \n", total / YEARS); printf("\n"); monthAverage(rain); return 0; } float yearsRainfall(float rain[][MONTHS])//定义计算年均下雨量 { float total = 0; float subtot = 0; int year,month; for (year = 0; year < YEARS; year++) { for (month = 0; month < MONTHS; month++) subtot += rain[year][month]; printf("%5d %15.1f \n", 2010 + year, subtot); total += subtot; } return total; } void monthAverage(float rain[][MONTHS])//定义计算月均下雨量 { float subtot = 0; int year,month; printf("MONTHLY AVERAGE: \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; year < YEARS; year++) subtot += *(*(rain+year)+month); printf("%5.1f ", subtot / YEARS); } }
运行结果:
13.编写一个程序,提示用户输入3组数,每组数包含5个double类型的数(假设用户都正确地响应,不会输入非数值数据)。该程序应完成下列任务。
a.把用户输入的数据储存在3×5的数组中
b.计算每组(5个)数据的平均值
c.计算所有数据的平均值
d.找出这15个数据中的最大值
e.打印结果 每个任务都要用单独的函数来完成(使用传统C处理数组的方式)。
完成任务b,要编写一个计算并返回一维数组平均值的函数,利用循环调用该函数3次。对于处理其他任务的函数,应该把整个数组作为参数,完成任务c和d的函数应把结果返回主调函数
/* Programming Exercise 10-13 */ #include <stdio.h> #define ROWS 3 #define COLS 5 void store(double ar[][COLS], int row); //声明存储二维数组数据函数 void showarr2(double ar[][COLS]);//声明显示二维数组函数 double average(double ar[][COLS], int row);//声明计算每行平均值函数 double average2d(double ar[][COLS]); //声明计算所有数据平均值 double max2d(double ar[][COLS]); //声明计算所有数据最大值 int main(void) { double stuff[ROWS][COLS]; int row; for (row = 0; row < ROWS; row++)//读取输入 { printf("Enter %d numbers for row %d\n", COLS, row + 1); store(stuff, row);//存储二维数组值 } printf("array contents:\n"); showarr2(stuff);//显示输入 for (row = 0; row < ROWS; row++)//显示每行平均值 printf("average value of row %d = %g\n", row + 1, average(stuff, row)); printf("average value of all rows = %g\n", average2d(stuff));//显示所有数据平均值 printf("largest value = %g\n", max2d(stuff));//显示所有数据最大值 printf("Bye!\n"); return 0; } void store(double ar[][COLS], int row) //定义存储数据二维数组函数 { int i; for (i = 0; i < COLS; i++) { printf("Enter value #%d: ", i + 1); scanf("%lf", &ar[row][i]); } } void showarr2(double ar[][COLS])//定义显示二维数组函数 { int row, col; for (row = 0; row < ROWS; row++) { for (col = 0; col < COLS; col++) printf("%g\t", ar[row][col]); putchar('\n'); } } double average(double ar[][COLS], int row)//定义计算每行平均值函数 { int col; double sum = 0.0; if (ROWS > 0) { for (col = 0; col < COLS; col++) sum += ar[row][col]; return sum / COLS; } else return 0.0; } double average2d(double ar[][COLS])//定义计算所有数据平均值 { int row, col; double sum = 0.0; if (ROWS > 0) { for (row = 0; row < ROWS; row++) { for (col = 0; col < COLS; col++) sum += ar[row][col]; } return sum / (ROWS*COLS); } else return 0.0; } double max2d(double ar[][COLS])//定义计算所有数据最大值 { int row, col; double max = **ar; for (row = 0; row < ROWS; row++) { for (col = 0; col < COLS; col++) { if (max < ar[row][col]) max = ar[row][col]; } } return max; }
运行结果:
14.以变长数组作为函数形参,完成编程练习13
/* Programming Exercise 10-14 */ #include <stdio.h> #define ROWS 3 #define COLS 5 void store(double ar[], int n); //声明存储二维数组数据函数 void showarr2(int rows, int cols, double ar[rows][cols]);//声明显示二维数组函数 double average(const double ar[], int n);//声明计算每行平均值函数 double average2d(int rows, int cols, double ar[rows][cols]); //声明计算所有数据平均值 double max2d(int rows, int cols, double ar[rows][cols]); //声明计算所有数据最大值 int main(void) { double stuff[ROWS][COLS]; int row; for (row = 0; row < ROWS; row++)//读取输入 { printf("Enter %d numbers for row %d\n", COLS, row + 1); store(stuff[row], COLS); } printf("array contents:\n"); showarr2(ROWS, COLS, stuff);//显示输入 for (row = 0; row < ROWS; row++)//显示每行平均值 printf("average value of row %d = %g\n", row + 1, average(stuff[row], COLS)); printf("average value of all rows = %g\n", average2d(ROWS, COLS, stuff));//显示所有数据平均值 printf("largest value = %g\n", max2d(ROWS, COLS, stuff));//显示所有数据最大值 printf("Bye!\n"); return 0; } void store(double ar[], int n) //定义存储数据一维数组函数 { int i; for (i = 0; i < n; i++) { printf("Enter value #%d: ", i + 1); scanf("%lf", & ar[i]); } } void showarr2(int rows, int cols, double ar[rows][cols])//定义显示二维数组函数 { int row, col; for (row = 0; row < rows; row++) { for (col = 0; col < cols; col++) printf("%g ", ar[row][col]); putchar('\n'); } } 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; } double average2d(int rows, int cols, double ar[rows][cols])//定义计算所有数据平均值 { int r, c; double sum = 0.0; for (r = 0; r < rows; r++) { for (c = 0; c < cols; c++) sum += ar[r][c]; } if (rows * cols > 0) return sum / (rows * cols); else return 0.0; } double max2d(int rows, int cols, double ar[rows][cols])//定义计算所有数据最大值 { int r, c; double max = ar[0][0]; for (r = 0; r < rows; r++) { for (c = 0; c < cols; c++) { if (max < ar[r][c]) max = ar[r][c]; } } return max; }
运行结果:
- 点赞 3
- 收藏
- 分享
- 文章举报
相关文章推荐
- C Primer Plus 第六版编程练习第十一章答案和记录一些学习历程
- C Primer Plus 第六版编程练习第六章答案和记录一些学习历程
- C Primer Plus 第六版编程练习第四章答案和记录一些学习历程
- C Primer Plus 第六版编程练习第二章答案和记录一些学习历程
- C Primer Plus 第六版编程练习第一章答案和记录一些学习历程
- C++ primer Plus(第六版)中文版 第十章 对象和类 编程练习答案
- 【学习C++】C++ Primer Plus (第六版)第十章编程练习1-8
- C primer plus 第六版 第十章 编程练习 答案
- C ++ Primer Plus 第六版 第十章编程练习答案
- C++ Primer Plus第六版 第十章 编程练习答案
- C Primer Plus (第六版)中文版 第十章 编程练习答案
- C++ Primer Plus 第六版 学习笔记 第七章 编程练习答案
- C++ primer Plus(第六版)中文版 第二章 开始学习C++ 编程练习答案
- C++primer plus第六版课后编程练习答案10.3
- C++ Primer Plus (第6版) 中文版 第二章 开始学习C++ 编程练习答案
- 【学习C++】C++ Primer Plus (第六版)第八章编程练习1-7
- C++primer plus第六版课后编程练习答案3.7
- C Primer Plus 第六版 章节课后编程练习答案(上)
- C++ primer plus第六版课后编程练习答案:6.5
- C++primer plus第六版课后编程练习答案6.1