標籤:c primer plus 編程練習 第十章 數組和指標
第十章 數組和指標
編程練習
1.修改程式清單10.7中的程式rain,使它不使用數組下標,而是使用指標進行計算(程式中仍然需要聲明並初始化數組)。
# include <stdio.h># define MONTHS 12# define YEARS 5int main(void){//把數組初始化為2000年到2004年的降水量資料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;//降水總量for (year = 0, total = 0; year < YEARS; year++){for (month = 0, subtot = 0; month < MONTHS; month++){subtot += *(*(rain + year) + month);//(rain+year)表示行地址增加,移動範圍是一個數組大小。//*rain + year表示列地址增加,移動範圍是一個int類型大小。}printf("%d年的總降水量:%.2f\n", 2010+year, subtot);total += subtot;}printf("%d年的平均降水量:%.2lf\n", YEARS, total / YEARS);printf("5年來每個月份的平均降水量:\n" );printf(" 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月\n");for (month = 0; month < MONTHS; month++){for (year = 0, total = 0; year < YEARS; year++)total += *(*(rain + year) + month);printf("%4.1f ", total / YEARS);}putchar(‘\n‘);return 0;}
2.編寫一個程式,初始化一個double數組,然後把數組內容複寫到另外兩個數組(3個數組都需要在主程式中聲明)。
製作第一份拷貝的函數使用數組符號。製作第二份拷貝的函數使用指標符號,並使用指標的增量操作。
把目標數組名和要複製的元素數目做為參數傳遞給函數。也就是說,如果給定了下列聲明,函數調用應該如下面所示:
double source [5]={1.1, 2.2, 3.3, 4.4, 5.5};
double targetl[5];
double target2 [5];
copy_arr (source, target1, 5);
copy_ptr (source, target1,5);
#include <stdio.h>void copy_ptr(double * source, double * target, int n);void copy_arr(double source[], double target[], int n);void show(double *, int);int main(void){double source[5] = { 1.1, 2.2, 3.3, 4.4, 5.5 };double target1[5] = { 0 };double target2[5] = { 0 };copy_arr(source, target1, 2);copy_ptr(source, target2, 4);printf("source: "); show(source, 5);printf("target1: "); show(target1, 5);printf("target2: "); show(target2, 5);return 0;}void copy_ptr(double * source, double * target, int n){int i;for (i = 0; i < n; i++)*target++ = *source++;}void copy_arr(double source[], double target[], int n){int i;for (i = 0; i < n; i++)target[i] = source[i];}void show(double * a, int n){int i;for (i = 0; i < n; i++)printf("%.2lf ", a[i]);printf("\n");}
3.編寫一個函數,返回一個int數組中儲存的最大數值,並在一個簡單的程式中測試這個函數。
#include <stdio.h>int max(int *, int);int main(void){int a[5] = { 2, 4, 1, 0, -3 };printf("數組中最大的值:%d\n", max(a, 5));return 0;}int max(int * a, int n){int i, temp = a[0];for (i = 1; i < n; i++){if (temp < a[i])temp = a[i];}return temp;}
4.編寫一個函數,返回一個double數組中儲存的最大數值的索引,並在一個簡單程式中測試這個函數。
#include <stdio.h>int max(double *, int);int main(void){double a[5] = { 25.6, 41.2, 13.0, 0.5, -0.03 };printf("數組中最大值的索引:%d\n", max(a, 5));return 0;}int max(double * a, int n){int i, temp = 0;for (i = 1; i < n; i++){if (a[temp] < a[i]){temp = i;}}return temp;}
5.編寫一個函數,返回一個double數組中最大的和最小的數之間的差值,並在一個簡單的程式中測試這個函數。
#include <stdio.h>double sub(const double *, int);int main(void){double a[5] = { 25.6, 41.2, 13.0, 0.5, 0.03 };printf("數組中最大值和最小值的差值:%.2lf\n", sub(a, 5));return 0;}double sub(const double * a, int n){int i, max = 0, min = 0;for (i = 1; i < n; i++){if (a[max] < a[i])max = i;if (a[min] > a[i])min = i;}return a[max] - a[min];}
6.編寫一個程式,初始化一個二維double數組,並利用練習2中的任一函數來把這個數組複製到另一個二維數組(因為二維數組是數組的數組,所以可以使用處理一維數組的函數來複製數組的每個子數組)。
#include <stdio.h>void copy_ptr(double * source, double * target, int n);int main(void){double source[2][5] = {{ 25.6, 41.2, 13.0, 0.5, 0.03 },{ 12.0, 23.0, -12.0, 3.0, 0.9 }};double target[2][5] = { 0 };copy_ptr(source[0], target[0], 8);printf("target: ");for (int i = 0; i < 2; i++){for (int j = 0; j < 5; j++)printf("%.2lf ", target[i][j]);}printf("\n");return 0;}void copy_ptr(double * source, double * target, int n){int i;for (i = 0; i < n; i++)*target++ = *source++;}
7.利用練習2中的複製函數,把一個包含7個元素的數組內第3到第5元素複製到一個包含3個元素的數組中,函數本身不需要修改,只需要選擇合適的實際參數(實際參數不需要是數組名和數組大小,而只需是數組元素的地址和需要複製的元素數目)
#include <stdio.h>void copy_ptr(double * source, double * target, int n);int main(void){double source[7] = { 25.6, 41.2, 13.0, 0.5, 0.03, 3.0, 0.9 };double target[3] = { 0 };copy_ptr(&source[2], target, 3);printf("target: ");for (int i = 0; i < 3; i++)printf("%.2lf ", target[i]);printf("\n");return 0;}void copy_ptr(double * source, double * target, int n){int i;for (i = 0; i < n; i++)*target++ = *source++;}
8.編寫一個程式,初始化一個3*5的二維double數組,並利用一個基於變長數組的函數把該數組複製到別一個二維數組。還要編寫一個基於變長數組的函數來顯示兩個數組的內容。這兩個函數應該能夠處理任意的N*M數組(如果沒有可支援變長數組的編譯器,就使用傳統C中處理N*5數組的函數方法)。
#include <stdio.h>void copy_ptr(int x, int y, double source[x][y], double target[x][y]);void show(int x, int y, double source[x][y], double target[x][y]);int main(void){double source[3][5] = {{ 25.6, 41.2, 13.0, 0.5, 0.03},{ 21.0, 32.0, 10.9, 5.6, 4.2 },{ 41.2, 13.0, 0.5, 2.0, 32.1 }};double target[3][5] = { 0 };copy_ptr(3, 5, source, target);printf("source: \n"); show(3, 5, source, target);printf("target: \n");show(3, 5, source, target);return 0;}/* VC2013不支援變長數組,用gcc編譯可通過 */void copy_ptr(int x, int y, double source[x][y], double target[x][y]){int i, j;for (i = 0; i < 3; i++){for (j = 0; j < 5; j++)target[i][j] = source[i][j];}}void show(int x, int y, double source[x][y], double target[x][y]){int i, j;for (i = 0; i < 3; i++){for (j = 0; j < 5; j++)printf("%.2lf ", target[i][j]);printf("\n");}}
9.編寫一個函數,把兩個數組內的相應元素相加,結果儲存到第3個數組內。也就是說,如果數組l具有值2、4、5、8,數組2具有值1、0、4、6,則函數對數組3賦值為3、4、9、140函數的參數包括3個數組名和數組大小。並在一個簡單的程式中測試這個函數。
#include <stdio.h>#define LEN 5void add(const int *, const int *, int *, int);void show(int *, int);int main(void){int array1[LEN] = { 1, 3, 6, 8, 2 };int array2[LEN] = { 2, 4, 7, 4, 9 };int array3[LEN] = { 0 };add(array1,array2,array3,LEN);printf("array1: \n"); show(array1, LEN);printf("array2: \n"); show(array2, LEN);printf("array3: \n"); show(array3, LEN);return 0;}void add(const int *a1, const int *a2, int *a3, int n){for (int i = 0; i < n; i++)a3[i] = a1[i] + a2[i];}void show(int *a, int n){for (int i = 0; i < n; i++)printf("%5d ", a[i]);printf("\n");}
10.編寫一個程式,聲明一個3x5的數組並初始化,具體數值可以隨意。程式列印出數值,然後數值翻1番,接著再次列印出新值。編寫一個函數來顯示數組的內容,再編寫另一個函數執行翻倍功能。數組名和數組行數作為參數由程式傳遞給函數
#include <stdio.h>void add(int array[][5], int c);void show(int (*a)[5], int);int main(void){int array[3][5] ={{ 1, 3, 6, 8, 2 },{ 2, 4, 7, 4, 9 },{ 3, 2, 1, 2, 3 }};printf("array: \n"); show(array, 3);add(array, 3);printf("array: \n"); show(array, 3);return 0;}void add(int array[][5], int c){for (int i = 0; i < c; i++)for (int j = 0; j < 5; j++)array[i][j] *= 2;}void show(int (*a)[5], int n){for (int i = 0; i < n; i++){for (int j = 0; j < 5; j++)printf("%5d ", a[i][j]);printf("\n");}}
11.重寫程式清單10.7的程式rain,main()中的主要功能改為由函數來執行。(針對若干年的降水量資料,計算年降水總量、年降水平均量,以及月降水平均量)
# include <stdio.h># define MONTHS 12# define YEARS 5float year_total(float a[][MONTHS], int n);//五年總降水量float month_sub(float a[][MONTHS], int 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_total(rain, YEARS);month_sub(rain, YEARS);return 0;}float year_total(float a[][MONTHS], int n){int i, j;float total_y, total;for (i = 0, total = 0; i < n; i++){for (j = 0, total_y = 0; j < MONTHS; j++)total_y += a[i][j];printf("%d年總降水量:%.1f\n", 2010 + i, total_y);total += total_y;}printf("%d年-%d年平均降水量:%.1f\n", 2010, 2010 + i-1, total / YEARS);return total;}float month_sub(float a[][MONTHS], int n){int i, j;float total;for (i = 0; i < MONTHS; i++){for (j = 0, total = 0; j < n; j++)total += a[j][i];printf("%d年-%d年 %d月的平均降水量%.1f\n", 2010, 2010+j-1, i+1, total/YEARS);}return total;}
12.編寫…個程式,提示使用者輸入3個數集,每個數集包括5個double值。程式應當實現下列所有功能:
a.把輸入資訊儲存到一個3x5的數組中
b.計算出每個數集(包含5個數值)的平均值
c.計算所有數值的平均數
d.找出這15個數中的最大值.
e.列印出結果
每個任務需要用一個單獨的函數來實現(使用傳統C處理數組的方法)。對於任務b,需要編寫計算並返回一維數組平均值的函數,迴圈3次調用該函數來實現任務b。
對於其他任務,函數應當把整個數組做為參數,並且完成任務c和d的函數應該向它的調用函數返回答案。
#include <stdio.h>void input(double(*a)[5], int n);double sub(const double *a, int n);double sub_total(const double a[][5], int n);double max(const double a[][5], int n);void show(const double a[][5], int n);int main(void){double array[3][5];int i;input(array, 3);for (i = 0; i < 3; i++)printf("第%d個數集的平均值:%.2lf\n",i+1, sub(array[i], 5));printf("所有數的平均值:%.2lf\n", sub_total(array, 3));printf("所有數中最大的數:%.2lf\n", max(array, 5));printf("整個數集:\n");show(array, 3);return 0;}void input(double(*a)[5], int n){int i, j;for (i = 0; i < n; i++){printf("請輸入第%d個數集中的5個值:", i+1);for (j = 0; j < 5; j++)scanf("%lf", &a[i][j]);}}double sub(const double *a, int n){int i;double total = 0;for (i = 0; i < n; i++)total += a[i];return total / n;}double sub_total(const double a[][5], int n){int i, j;double total = 0;for (i = 0; i < n; i++){for (j = 0; j < 5; j++)total += a[i][j];}return total / (n * 5);}double max(const double a[][5], int n){int i, j;double temp = a[0][0];for (i = 0; i < n; i++){for (j = 0; j < 5; j++)if (temp < a[i][j])temp = a[i][j];}return temp;}void show(const double a[][5], int n){int i, j;double max = a[0][0];for (i = 0; i < n; i++){for (j = 0; j < 5; j++)printf("%.2lf ", a[i][j]);printf("\n");}}
13.下面是兩個函數原型:
void show(double ar[], int n); //n是元素數
void show2(double ar2[][3], int n); //n是行數
a,編寫一個函數調用,把包含數值8、3、9和2的複合文字傳遞給函數shows()。
b,編寫一個函數調用,把包含2行3列數值的複合文字傳遞給函數show2(),其中第一行為8、3、9;第二行為5、4、1。
#include <stdio.h>void show(double ar[], int n);void show2(double ar2[][3], int n);int main(void){show((double[]){ 8, 3, 9, 2 }, 4);show2((double[][3]){ { 8, 3, 9 }, { 5, 4, 1 } }, 2);return 0;}void show(double ar[], int n){int i;for (i = 0; i < n; i++)printf("%.2lf ", ar[i]);printf("\n");}void show2(double ar2[][3], int n){int i, j;for (i = 0; i < n; i++){for (j = 0; j < 3; j++)printf("%.2lf ", ar2[i][j]);printf("\n");}}
本文出自 “30歲學編程” 部落格,請務必保留此出處http://xiongyi85.blog.51cto.com/8756903/1655700
C Primer Plus (第五版) 第十章 數組和指標 編程練習