天天看點

C Primer Plus 第六版 第10章 程式設計答案C Primer Plus 第六版 第10章 程式設計練習

C Primer Plus 第六版 第10章 程式設計練習

1.修改程式清單 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}
    };
    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;
    }
    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 ");
    printf(" Oct  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 個數組)。使用帶數組表示法的函數進行第 1 份拷貝。使用帶指針表示法和指針遞增的函數進行第 2 份拷貝。把目标數組名和待拷貝的元素個數作為前兩個函數的參數。第 3 個函數以目标數組名、源數組名和指向源數組的最後一個元素後面元素的指針。也就是說,給定以下聲明,則函數調用如下所示:

copy_arr(target1, source, 5);
copy_ptr(target2, source, 5);

copy_ptrs(target3, source, source+5);

print(source,5);
print(target1,5);
print(target2,5);
print(target3,5);
           
#include <stdio.h>

void copy_arr(double ar[], double so[], int n);
void copy_ptr(double *ar, double *so, int n);
void copy_ptrs(double *ar, double *so, double *end);
void print(double *ar, int n);

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);

    print(source,5);
    print(target1,5);
    print(target2,5);
    print(target3,5);
}

void copy_arr(double ar[], double so[], int n)
{
    int i;

    for (i = 0; i < n; i++)
        ar[i] = so[i];
}

void copy_ptr(double *ar, double *so, int n)
{
    while (--n >= 0)
        *(ar++) = *(so++);
}

void copy_ptrs(double *ar, double *so, double *end)
{
    while (so < end)
    {
        *(ar++) = *(so++);
    }
}

void print(double *ar, int n)
{
    int i;

    for (i = 0; i < n; i++)
    {
        printf("%.1f ",ar[i]);
    }
    printf("\n");
}
           

3.編寫一個函數,傳回存儲在 int 類型的數組中的最大值,并在一個簡單的程式中測試該函數。

#include <stdio.h>

int maxar(int ar[], int n);

int main(void)
{
    int ar[10]={12,2,9,8,7,6,5,4,11,2};

    printf("最大值為:%d\n",maxar(ar,10));

    return 0;
}

int maxar(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 maxar(double ar[], int n);

int main(void)
{
    double ar[10]={1.1,2.2,4.4,3.3,9.9,
                   5.5,10.10,8.8,7.7,11.11};
    printf("最大值下标為:%d\n",maxar(ar,10));

    return 0;
}

int maxar(double ar[], int n)
{
    int i;
    int index = 0;

    for (i = 1; i < n; i++)
        if (ar[index] < ar[i])
            index = i;

    return index;
}
           

5.編寫一個函數,傳回存儲在 double 類型數組中的最大值和最小值的內插補點,并在一個簡單的程式中測試該函數。

#include <stdio.h>

double diffar(double ar[], int n);

int main(void)
{
    double ar[10]={10.1,2.2,3.5,6.5,1.0,22.3,5.5,6.6,7.7,8.8};

    printf("內插補點為:%f\n",diffar(ar,10));

    return 0;
}

double diffar(double ar[], int n)
{
    int i;
    double max,min;
    max = min = ar[0];

    for (i = 0; i < n; i++)
        if (min > ar[i])
            min = ar[i];

    for (i = 0; i < n; i++)
        if (max < ar[i])
            max = ar[i];

    return (max-min);
}
           

6.編寫一個函數,把 double 類型數組中的資料倒序排列,并在一個簡單的程式中測試該函數。

#include <stdio.h>

void revorde(double ar[], int n);
void print(double ar[], int n);

int main(void)
{
    double ar[10]={10.2,45.2,111.43,22.45,99.1,223.3,
                   55.44,66.55,66.77,77.88};

    print(ar,10);
    revorde(ar,10);
    print(ar,10);

    return 0;
}

void revorde(double ar[], int n)
{
    int i,j;
    double temp;

    for (j = 0; j < n-1; j++)
        for (i = j+1; i < n; i++)
            if (ar[j] > ar[i])
            {
                temp = ar[j];
                ar[j] = ar[i];
                ar[i] = temp;
            }
}

void print(double ar[], int n)
{
    int i;

    for (i = 0; i < n; i++)
    {
        printf("%.2f  ",ar[i]);
    }
    putchar('\n');
}
           

7.編寫一個程式,初始化一個 double 類型的二維數組,使用程式設計練習 2 中的一個拷貝函數把該數組中的資料拷貝至另一個二維數組中 (因為二維數組是數組的數組,是以可以使用處理一維數組的拷貝函數來處理數組中的每個子數組)。

#include <stdio.h>

void copy(double *ar, double *so, int n);
void print(double (*ar)[5], int n);

int main(void)
{
    int i;
    double ar[5][5]={1,2,3,4,5,
       				 6,7,8,9,10,
    				 11,12,13,14,15,
    				 16,17,18,19,20,
                     21,22,23,24,25};
    double so[5][5];

    for (i = 0; i < 5; i++)
        copy(ar[i],so[i],5);

    print(so,5);

    return 0;
}

void copy(double *ar, double *so, int n)
{
    int i;

    for (i = 0; i < 5; i++)
        *(so+i) = *(ar+i);
}

void print(double (*ar)[5], int n)
{
    int i,j;

    for (i = 0; i < n; i++)
    {
        for (j = 0; j < n; j++)
            printf("%.1f ",*(*(ar+i)+j));
        putchar('\n');
    }
}
           

8.使用程式設計練習 2 中的拷貝函數,把一個内含 7 個元素的數組中第 3~第 5 個元素拷貝至内含 3 個元素的數組中。該函數本身不需要修改,隻需要選擇合适的實際參數(實際參數不需要是數組名和數組大小,隻需要是數組元素的位址和待處理元素的個數)。

#include <stdio.h>

void copy_arr(int *ar, int *so, int n);
void print(int *ar, int n);

int main(void)
{
    int so[7]={1,2,3,4,5,6,7};
    int ar[3];

    copy_arr(ar,so+2,3);
    print(ar,3);

    return 0;
}

void copy_arr(int *ar, int *so, int n)
{
    int i;

    for (i=0;i<n;i++)
        ar[i] = so[i];
}

void print(int *ar, int n)
{
    int i;

    for (i=0;i<n;i++)
        printf("%d ",ar[i]);
    printf("\n");
}
           

9.編寫一個程式,初始化一個 double 類型 3 x 5 二維數組,使用一個處理變長數組的函數将其拷貝至另一個二維數組中。還要編寫一個以變長數組為形參的函數以顯示兩個數組的内容。這兩個函數應該能處理任意 N x M 數組。

#include <stdio.h>

void copy(int n, int m, double so[n][m], double ar[n][m]);
void print(int n, int m, double ar[n][m]);

int main(void)
{
    double so[5][5]={{1,2,3,4,5},
                     {6,7,8,9,10},
                     {11,12,13,14,15}};
    double ar[5][5];
    copy(5,5,so,ar);
    print(5,5,so);
    print(5,5,ar);

    return 0;
}

void copy(int n, int m, double so[n][m], double ar[n][m])
{
    int i,j;

    for (i=0;i<n;i++)
        for (j=0;j<m;j++)
            ar[i][j] = so[i][j];
}

void print(int n, int m, double ar[n][m])
{
    int i,j;

    for (i=0;i<n;i++)
    {
        for (j=0;j<5;j++)
            printf("%.2f ",ar[i][j]);
        printf("\n");
    }
}
           

10.編寫一個函數,把兩個數組中相對應的元素相加,然後把結果存儲在第 3 個數組中。也就是說,如果數組 1 中包含的值是 2、4、5、8,數組 2 中包含的值是 1、0、4、6,那麼該函數把 3、4、9、14 賦給第 3 個數組。函數接受 3 個數組名和一個數組大小。在一個簡單的程式中測試該函數。

#include <stdio.h>

void sum(int *ar1, int *ar2, int *ar3, int n);
void print(int *ar, int n);

int main(void)
{
    int ar1[4]={1,3,5,7};
    int ar2[4]={2,4,6,8};
    int ar3[4];

    sum(ar1,ar2,ar3,4);

    print(ar1,4);
    print(ar2,4);
    print(ar3,4);

    return 0;
}

void sum(int *ar1, int *ar2, int *ar3, int n)
{
    int i;

    for (i = 0; i < n; i++)
            *(ar3+i) = *(ar1+i) + *(ar2+i);
}

void print(int *ar, int n)
{
    int i;
    for (i = 0; i < n; i++)
        printf("%5d",ar[i]);
    printf("\n");
}
           

11.編寫一個程式,聲明一個 int 類型的 3 x 5 二維數組,并用合适的值初始化它。該程式列印數組中的值,然後個值翻倍(即是原值的 2 倍),并顯示出各元素的新值。編寫一個函數顯示數組的内容,在編寫一個函數把各元素的值翻倍。這兩個函數都以函數名和行數作為參數。

#include <stdio.h>

void print(int (*ar)[5], int n);
void dou(int (*ar)[5], int n);

int main(void)
{
    int ar[3][5]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

    print(ar,3);
    dou(ar,3);
    print(ar,3);

    return 0;
}

void print(int ar[][5], int n)
{
    int i,j;
    for (i=0;i<n;i++)
    {
        for (j=0;j<5;j++)
            printf("%5d",ar[i][j]);
        printf("\n");
    }
}

void dou(int (*ar)[5], int n)
{
    int i,j;
    for (i=0;i<n;i++)
        for (j=0;j<5;j++)
            ar[i][j] *= 2;
}
           

12.重寫程式清單 10.7 的 rain.c 程式,把 main() 中的主要任務都改成用函數來完成。

#include <stdio.h>
#define MONTHS 12
#define YEARS  5

float year(const float (*ar)[MONTHS], int n);
void month(const float (*ar)[MONTHS], int n);
int main(void)
{
    float sum;
    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");
    sum=year(rain,YEARS);
    printf("\nThe yearly average is %.1f inches.\n\n",
                 sum / YEARS);
    printf("MONTHLY AVERAGES:\n\n");
    printf(" Jan  Feb  Mar  Apr  May  Jun  Jul  Aug  Sep ");
    printf(" Oct  Nov  Dec\n");
    month(rain,MONTHS);

    return 0;
}

float year(const float (*ar)[MONTHS], int n)
{
    int i,j;
    float total = 0;
    float sum = 0;

    for (i = 0; i < n; i++)
    {
        for (j = 0, total = 0; j < MONTHS; j++)
            total += ar[i][j];
        printf("%5d %15.1f \n", 2010+i,total);
        sum += total;
    }
    return sum;
}

void month(const float (*ar)[MONTHS], int n)
{
    int i,j;
    float total = 0;

    for (i = 0; i < n; i++)
    {
        for (j = 0, total = 0; j < YEARS; j++)
            total += ar[j][i];
        printf("%4.1f ", total/YEARS);
    }
    printf("\n");
}
           

13.編寫一個程式,提示使用者輸入 3 組數,每組數包含 5 個 double 類型的數(假定使用者都正确地響應,不會輸入非數值資料)。改程式完成以下任務。

a.把使用者輸入的資料存儲在 3 x 5 的數組中

b.計算每組(5 個)資料的平均值

c.計算所有資料的平均值

d.找出這 15 個資料中的最大值

e.列印結果

每個任務都要用單獨的函數來完成(使用傳統 C 處理數組的方式)。完成任務 b ,要編寫一個計算并傳回一維數組平均值的函數,利用循環調用該函數 3 次。對于處理其他任務的函數,應該把整個數組作為參數,完成任務 c 和 d 的函數應該把結果傳回主調函數。

#include <stdio.h>

#define N 3
#define M 5

void input(double (*ar)[M]);
void mean(double (*ar)[M], double *sum);
void means(double (*ar)[M], double *sums);
void sort(double (*ar)[M], double *max);
void print(double (*ar)[M],double *sum, double *sums, double *max);
int  menu(void);

int main(void)
{
    int ch;
    double ar[N][M];
    double sum[M],sums,max;

    while ((ch = menu()) != 0)
    {
        switch (ch)
        {
            case 1 : input(ar);break;
            case 2 : mean(ar,sum);break;
            case 3 : means(ar,&sums);break;
            case 4 : sort(ar,&max);break;
            case 5 : print(ar,sum,&sums,&max);break;
        }
    }
    return 0;
}

int  menu(void)
{
    int ch;
    puts("======================");
    puts("1) 輸入3x5的資料     |");
    puts("2) 每組資料的平均值  |");
    puts("3) 所有資料的平均值  |");
    puts("4) 資料中的最大值    |");
    puts("5) 列印結果          |");
    puts("0) 退出              |");
    while (scanf("%d",&ch) != 1)
    {
        while (getchar() != '\n');
        puts("請輸入<0-5>:");
    }
    while (getchar() != '\n');

    return ch;
}

void input(double (*ar)[M])
{
    int i,j;

    for (i = 0; i < N; i++)
    {
        printf("請輸入第%d組資料%d個:\n",i+1,M);
        for (j = 0; j < M; j++)
            scanf("%lf",&ar[i][j]);
    }
}

void mean(double (*ar)[M], double *sum)
{
    int i,j;
    double total=0;

    for (i = 0; i < N; i++)
    {
        for (j = 0, total = 0; j < M; j++)
        {
           total += ar[i][j];
        }
        sum[i] = total / M;
    }
}

void means(double (*ar)[M], double *sums)
{
    int i,j;
    double total=0;

    for (i = 0; i < N; i++)
    {
        for (j = 0; j < M; j++)
        {
            total += ar[i][j];
        }
    }
    *sums = total / (N * M);
}

void sort(double (*ar)[M], double *max)
{
    int i,j;
    *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];
}

void print(double (*ar)[M],double *sum, double *sums, double *max)
{
    int i,j;

    for (i = 0; i < N; i++)
    {
        printf("第%d組資料為:\n",i+1);
        for (j = 0; j < M; j++)
            printf("%6.1lf ",ar[i][j]);
        putchar('\n');
    }

    for (i = 0; i < N; i ++)
    {
        printf("第%d組資料的平均值為:%lf\n",i+1,sum[i]);
    }
    printf("資料的最大值為:%lf\n",*max);
}
           

14.以變長數組作為函數形參,完成程式設計練習 13。

#include <stdio.h>

#define N 3
#define M 5

void input(int n, int m, double ar[n][m]);
void mean(int n, int m, double ar[n][m]);
void means(int n, int m, double ar[n][m]);
void sort(int n, int m, double ar[n][m]);
int  menu(void);

int main(void)
{
    int ch;
    double ar[N][M];

    while ((ch = menu()) != 0)
    {
        switch (ch)
        {
            case 1 : input(N,M,ar);break;
            case 2 : mean(N,M,ar);break;
            case 3 : means(N,M,ar);break;
            case 4 : sort(N,M,ar);break;
        }
    }
    return 0;
}

int  menu(void)
{
    int ch;
    puts("======================");
    puts("1) 輸入3x5的資料     |");
    puts("2) 每組資料的平均值  |");
    puts("3) 所有資料的平均值  |");
    puts("4) 資料中的最大值    |");
    puts("0) 退出              |");
    while (scanf("%d",&ch) != 1)
    {
        while (getchar() != '\n');
        puts("請輸入<0-4>:");
    }
    while (getchar() != '\n');

    return ch;
}

void input(int n, int m, double ar[n][m])
{
    int i,j;

    for (i = 0; i < n; i++)
    {
        printf("請輸入第%d組資料%d個:\n",i+1,m);
        for (j = 0; j < m; j++)
            scanf("%lf",&ar[i][j]);
    }

    for (i = 0; i < n; i++)
    {
        printf("第%d組資料為:\n",i+1);
        for (j = 0; j < m; j++)
            printf("%6.1lf ",ar[i][j]);
        putchar('\n');
    }
}

void mean(int n, int m, double ar[n][m])
{
    int i,j;
    double total=0;
    double sum[m];

    for (i = 0; i < n; i++)
    {
        for (j = 0, total = 0; j < m; j++)
        {
           total += ar[i][j];
        }
        sum[i] = total / m;
    }

    for (i = 0; i < n; i ++)
    {
        printf("第%d組資料的平均值為:%lf\n",i+1,sum[i]);
    }
}

void means(int n, int m, double ar[n][m])
{
    int i,j;
    double sums;
    double total=0;

    for (i = 0; i < n; i++)
    {
        for (j = 0; j < m; j++)
        {
            total += ar[i][j];
        }
    }
    sums = total / (n * m);

    printf("所有資料的平均值為:%4.1lf\n",sums);
}

void sort(int n, int m, double ar[n][m])
{
    int i,j;
    double max;
    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];

    printf("資料最大值為:%4.1lf\n",max);
}