C primer plus 第十章(数组和指针)编程练习--第五版

C primer plus 第十章(数组和指针)编程练习–第五版


C 语言编程练习都为本人学习时的编写代码记录或学习笔记,若有不当之处欢迎指正,感激不尽。(其中编程设计也可有其他设计方案,本人目前仅在学习中,所以仅为个人学习记录,仅供参考。)


1.修改程序清单 10.7 中的程序 rain,使它不使用数组下标,而是使用指针进行计算(程序中仍然需要声明并初始化数组)。

/* rain.c -- find yearly totals, yearly average, and monthly                                  average for several years of rainfall data */

#include
#define MONTHS 12       /* number of months in a year */
#define YEARS   5       /* number of years of data */

int main(void)
{
    /* initializing rainfall data for 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;

    printf(" YEAR       RAINFALL (inches)\n");
    for(year = 0, total = 0; year < YEARS; year++) {
        /* for each year, sum rainfall for each month */
        for(month = 0, subtot = 0; month < MONTHS; month++)
            subtot += *(*(rain+year) + month);      /* use pointer */
        printf("%5d %15.1f\n", 2000 + year, subtot);
        total += subtot;        /* total for all years */
    }

    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 each month, sum rainfall over years */
        for(year = 0, subtot = 0; year < YEARS; year++)
            subtot += *(*(rain+year) + month);      /* use pointer */
        printf("%4.1f ", subtot/YEARS);
    }
    printf("\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

void copy_arr(double [],double [], int );
void copy_ptr(double *,double *, int );

int main(void)
{
    double source[] = {1.1,2.2,3.3,4.4,5.5};
    double target1[5];
    double target2[5];

    printf("source\t\ttarget1\n");
    copy_arr(source, target1, 5);
    printf("\n");
    printf("source\t\ttarget2\n");
    copy_ptr(source, target2, 5);

    return 0;
}

/* use array notaion  */
void copy_arr(double a[], double b[], int n)
{
    int i;
    for(i = 0; i < n; i++) {
        b[i] = a[i];
        printf("%.1lf\t\t%.1lf\n",a[i], b[i]);
    }

}

/* use pointer notaion and pointer incrementing */
void copy_ptr(double * p1, double * p2, int n)
{
    int i;
    for(i = 0; i < n; i++) {
        * (p2 + i) = *(p1 + i);
        printf("%.1lf\t\t%.1lf\n", *(p1 + i), *(p2 + i));
    }
}


3.编写一个函数,返回一个 int 数组中存储的最大数值,并在一个简单的程序中测试这个函数。

#include

#define ELT 6

int ret_max(int [], int );

int main(void)
{
    int arr[ELT] = {3, 2, 1, 8, 4, 7};
    int i;

    printf("arr[ELT] = {3, 2, 1, 8, 4, 7};\n");
    printf("max = %d\n", ret_max(arr , ELT));

    return 0;
}

int ret_max(int a[], int n)
{
    int i, max;

    for(i = 1, max = a[0]; i < n; i++) {
        if(max < a[i])
            max = a[i];
    }

    return max;
}


4.编写一个函数,返回一个 double 数组中存储的最大数值的索引,并在一个简单程序中测试这个函数。

#include

#define ELT 6

int ret_index(double [], int );

int main(void)
{
    double arr[ELT] = {3.3, 2.2, 1.1, 8.8, 4.4, 7.7};

    printf("arr[ELT] = {3.3, 2.2, 1.1, 8.8, 4.4, 7.7};\n");
    printf("max_index = %d\n", ret_index(arr , ELT));

    return 0;
}

int ret_index(double a[], int n)
{
    int i, max;

    for(i = 1, max = 0; i < n; i++) {
        if(a[max] < a[i])
            max = i;
    }

    return max;
}


5.编写一个函数 , 返回一个 double 数组中最大的和最小的数之间的差值 , 并在一个简单的程序中测试这个函数。

#include

#define ELT 6

double ret_sub(double [], int );

int main(void)
{
    double arr[ELT] = {3.3, 2.2, 1.1, 8.8, 4.4, 7.7};

    printf("arr[ELT] = {3.3, 2.2, 1.1, 8.8, 4.4, 7.7};\n");
    printf("max - min = %.1lf\n", ret_sub(arr , ELT));

    return 0;
}

double ret_sub(double a[], int n)
{
    int i, max, min;

    for(i = 1, max = min = 0; 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

#define ROWS 2
#define COLS 3

void copy_2d(double [][COLS],double [][COLS], int );
void copy_arr(double [],double [], int );

int main(void)
{
    int i, j;
    double source[ROWS][COLS] = {1.1,2.2,3.3,4.4,5.5,6.6};
    double target1[ROWS][COLS];

    copy_2d(source, target1, ROWS);
    printf("source\t\ttarget1\n");
    for( i = 0; i < ROWS; i++) {
        for(j = 0; j < COLS; j++)
            printf("%g\t\t%g\n",source[i][j],target1[i][j]);
    }
    return 0;
}
void copy_2d(double (*source)[COLS], double target1[][COLS], int n)
{
    int i;
    for(i = 0; i < n; i++) {
        copy_arr(*(source+i), target1[i], COLS);
    }

}

void copy_arr(double a[], double b[], int n)
{
    int i;
    for(i = 0; i < n; i++)
        b[i] = a[i];
}


7.利用练习 2 中的复制函数,把—个包含 7 个元素的数组内第 3 到第 5 元素复制到一个包含 3 个元素的数组中。函数本身不需要修改,只需要选择合适的实际参数(实际参数不需要是数组名和数组大小,而只须是数组元素的地址和需要复制的元素数目)。

#include

void copy_arr(double [],double [], int );
void copy_ptr(double *,double *, int );

int main(void)
{
    double source[] = {1.1,2.2,3.3,4.4,5.5,6.6,7.7};
    double target1[3];
    double target2[3];

    printf("source\t\t1.1 2.2 3.3 4.4 5.5 6.6 7.7\n");
    copy_arr(source+2, target1, 3);
    printf("\n");
    printf("source\t\t1.1 2.2 3.3 4.4 5.5 6.6 7.7\n");
    copy_ptr(source+2, target2, 3);

    return 0;
}

/* use array notaion  */
void copy_arr(double a[], double b[], int n)
{
    int i;

    printf("target1:\t");
    for(i = 0; i < n; i++) {
        b[i] = a[i];
        printf("%.1lf ", b[i]);
    }
    printf("\n");
}

/* use pointer notaion and pointer incrementing */
void copy_ptr(double * p1, double * p2, int n)
{
    int i ;

    printf("target2:\t");
    for(i = 0; i < n; i++) {
        * (p2 + i) = *(p1 + i);
        printf("%.1lf ", *(p2 + i));
    }
    printf("\n");
}


8.编写一个程序,初始化一个 3x5 的二维 double 数组,并利用一个基于变长数组的函数把该数组复制到另一个二维数组。还要编写。个基于变长数组的函数来显示两个数组的内容。这两个函数应该能够处理任意的 NxM 数组(如果没有可以支持变长数组的编译器,就使用传统 C 中处理 Nx5 数组的函数方法)。

#include

#define ROWS 3
#define COLS 5

/* r-rows, c-cols, sou-source, tar-target */
void vla_copy(int r, int c, double sou[r][c], double tar[r][c]);
void vla_show(int r, int c, double ptr[r][c]);

int main(void)
{
    double sou[ROWS][COLS] = {
                            {1,1,1,1,1},
                            {2,2,2,2,2},
                            {3,3,3,3,3}
                        };

    double tar[ROWS][COLS];

    vla_copy(ROWS, COLS, sou, tar);

    printf("source:\n");
    vla_show(ROWS, COLS, sou);
    printf("target:\n");
    vla_show(ROWS, COLS, tar);

    return 0;
}

void vla_copy(int r, int c, double sou[r][c], double tar[r][c])
{
    int i, j;
    for(i = 0; i < r; i++) {
        for(j = 0; j < c; j++)
            tar[i][j] = sou[i][j];
    }
}

void vla_show(int r, int c, double ptr[r][c])
{
    int i, j;
    for(i = 0; i < r; i++) {
        for(j = 0; j < c; j++)
            printf("%.1lf ", ptr[i][j]);
        printf("\n");
    }
}


9.编写一个函数,把两个数组内的相应元素相加,结果存储到第 3 个数组内。也就是说,如果数组 1具有值 2、4、5、8,数组 2 具有值 1、0、4、6,则函数对数组 3 赋值为 3、4、9、140 函数的参数包括 3 个数组名和数组大小。并在一个简单的程序中测试这个函数。

#include

#define NUM 4

/* 根据题中说明以整型示例 */
void add(int [], int [], int [], int );

int main(void)
{
    int i;
    int one[] = {2, 4, 5, 8};
    int two[] = {1, 0, 4, 6};
    int three[NUM];

    add(one, two, three, NUM);

    printf("one\ttwo\tthree\n");
    for(i = 0; i < NUM; i++) {
        printf("%d\t%d\t%d\n",one[i], two[i], three[i]);
    }

    return 0;
}

void add(int a[], int b[], int c[], int n)
{
    int i;

    for(i = 0; i < NUM; i++)
        c[i] = a[i] + b[i];
}


10.编写…个程序,声明一个 3x5 的数组并初始化,具体数值可以随意。程序打印出数值,然后数值翻 1 番,接着再次打印出新值。编写一个函数来显示数组的内容,再编写另一个函数执行翻倍功能。数组名和数组行数作为参数由程序传递给函数。

#include

#define ROWS 3
#define COLS 5
void show(int [][COLS], int );
void twice(int [][COLS], int );

int main(void)
{
    int x1[][5] = {
                    {1,1,1,1,1},
                    {2,2,2,2,2},
                    {3,3,3,3,3}

                  };

    printf("before:\n");
    show(x1, ROWS);

    twice(x1, ROWS);

    printf("after:\n");
    show(x1, ROWS);

    return 0;
}

void show(int a1[][COLS], int row)
{
    int i, j;

    for(i = 0; i < row; i++) {
        for(j = 0; j < 5; j++)
            printf("\t%d ", a1[i][j]);
        printf("\n");
    }

}

void twice(int a1[][COLS], int row)
{
    int i, j;

    for(i = 0; i < row; i++) {
        for(j = 0; j < COLS; j++)
            a1[i][j] = 2 * a1[i][j];
    }
}


11.重写程序清单 10.7 的程序 rain,main()中的主要功能改为由函数来执行。

/* rain.c -- find yearly totals, yearly average, and monthly                                  average for several years of rainfall data */

#include

#define MONTHS 12       /* number of months in a year */
#define YEARS   5       /* number of years of data */

void show(float rain[][MONTHS], int years);

int main(void)
{
    /* initializing rainfall data for 2000 - 2004 */
      float rain[][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},
      };

    show(rain, YEARS);

    return 0;
}

void show(float rain[][MONTHS], int years)
{

    int year, month;
    float subtot, total;

    printf(" YEAR       RAINFALL (inches)\n");
    for(year = 0, total = 0; year < YEARS; year++) {
        /* for each year, sum rainfall for each month */
        for(month = 0, subtot = 0; month < MONTHS; month++)
            subtot += rain[year][month];
        printf("%5d %15.1f\n", 2000 + year, subtot);
        total += subtot;        /* total for all years */
    }

    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 each month, sum rainfall over years */
        for(year = 0, subtot = 0; year < YEARS; year++)
            subtot += rain[year][month];
        printf("%4.1f ", subtot/YEARS);
    }
    printf("\n");

}


12.编写一个程序,提示用户输入 3 个数集,每个数集包括 5 个 double 值。程序应当实现下列所有功能:

  a.把输入信息存储到一个 3x5 的数组中

  b.计算出每个数集(包含 5 个数值)的平均值

  c. 计算所有数值的平均数

  d.找出这 15 个数中的最大值

  e. 打印出结果

每个任务需要用一个单独的函数来实现(使用传统 C 处理数组的方法)。对于任务 b,需要编写计算并返回一维数组平均值的函数,循环 3 次调用该函数来实现任务 b。对于其他任务,函数应当把整个数组做为参数,并且完成任务 c 和 d 的函数应该向它的调用函数返回答案。

#include

#define ROWS 3
#define COLS 5

void storage(double arr[ROWS][COLS]);           /* task a */
void row_aver(double *arr, int );               /* task b */
double all_aver(double arr[ROWS][COLS]);        /* task c */
double max(double arr[ROWS][COLS]);             /* task d */
void print(double arr[ROWS][COLS]);             /* task e */

int main(void)
{
    int i;
    double arr[ROWS][COLS];

    storage(arr);

    for(i = 0; i < ROWS; i++) {
        row_aver(arr[i], COLS);
    }

    printf("all_average = %.2lf\n",all_aver(arr));

    printf("max = %.2lf\n", max(arr));

    print(arr);

    return 0;
}

void storage(double arr[ROWS][COLS])             /* task a */
{
    int i, j;

    printf("Please input 15 double(3x5).\n");
    for(i = 0; i < ROWS; i++) {
        for(j = 0; j < COLS; j++)
            scanf("%lf", &arr[i][j]);
    }
}

void row_aver(double * arr, int rows)            /* task b */
{
    int i;
    double sum =  0;

    for(i = 0; i < rows; i++)
        sum += arr[i];

    printf("row_average = %.2lf\n", sum / (1.0*rows));
}

double all_aver(double arr[ROWS][COLS])          /* task c */
{
    int i, j;
    double total = 0;

    for(i = 0; i < ROWS; i++) {
        for(j = 0; j < COLS; j++)
            total += arr[i][j];
    }

    return (total / (1.0*ROWS*COLS));
}

double max(double arr[ROWS][COLS])                /* task d */
{
    int i, j;
    double max = arr[0][0];

    for( i = 0; i < ROWS; i++) {
        for(j = 0; j < COLS; j++)
            max = (max > arr[i][j]?max:arr[i][j]);
    }

    return max;
}

void print(double arr[ROWS][COLS])                /* task e */
{
    int i, j;

    for( i = 0; i < ROWS; i++) {
        for(j = 0; j < COLS; j++)
            printf("%.2lf\t", arr[i][j]);
        printf("\n");
    }

}


13.利用变长数组做为函数参量重做练习 12。

#include

#define R 3         /* R-ROWS */
#define C 5         /* C-COLS */

void storage(int rows, int cols, double arr[rows][cols]);      /* task a */
void row_aver(int cols, double arr[cols]);                     /* task b */
double all_aver(int rows, int cols, double arr[rows][cols]);   /* task c */
double max(int rows, int cols, double arr[rows][cols]);        /* task d */
void print(int rows, int cols, double arr[rows][cols]);        /* task e */

int main(void)
{
    int i;
    double arr[R][C];

    storage(R, C, arr);

    for(i = 0; i < R; i++) {
        row_aver(C, arr[i]);
    }

    printf("all_average = %.2lf\n",all_aver(R, C, arr));

    printf("max = %.2lf\n", max(R, C, arr));

    print(R, C, arr);

    return 0;
}

void storage(int rows, int cols, double arr[rows][cols])       /* task a */
{
    int i, j;

    printf("Please input 15 double.\n");
    for(i = 0; i < rows; i++) {
        for(j = 0; j < cols; j++)
            scanf("%lf", &arr[i][j]);
    }
}

void row_aver(int cols, double arr[cols])                      /* task b */
{
    int i;
    double sum =  0;

    for(i = 0; i < cols; i++)
        sum += arr[i];

    printf("row_average = %.2lf\n", sum / (1.0*cols));
}

double all_aver(int rows, int cols, double arr[rows][cols])    /* task c */
{
    int i, j;
    double total = 0;

    for(i = 0; i < rows; i++) {
        for(j = 0; j < cols; j++)
            total += arr[i][j];
    }

    return (total / (1.0*rows*cols));
}

double max(int rows, int cols, double arr[rows][cols])         /* task d */
{
    int i, j;
    double max = arr[0][0];

    for( i = 0; i < rows; i++) {
        for(j = 0; j < cols; j++)
            max = (max > arr[i][j]?max:arr[i][j]);
    }

    return max;
}

void print(int rows, int cols, double arr[rows][cols])         /* task e */
{
    int i, j;

    for( i = 0; i < rows; i++) {
        for(j = 0; j < cols; j++)
            printf("%.2lf\t", arr[i][j]);
        printf("\n");
    }

}

你可能感兴趣的:(linux,C)