zoukankan      html  css  js  c++  java
  • C Primer Plus_第10章_数组和指针_编程练习

    1.

    /*rain.c 针对若干年的降水量数据,计算年降水总量、年降水平均量,以及月降水平均量*/
    #include <stdio.h>
    #define MONTHS 12
    #define YEARS 5
    
    int main (void)
    {
        //把数组初始化为2000到2004年的降水量数据
        const float rain[YEARS][MONTHS] = //const声明和初始化数组可保护数据
        {
            {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 years,months;
        float totyear, totmonth;
    
        printf("YEAR  RAIN:
    ");
        for(years=0; years<YEARS; years++)
        {
            for(months=0,totyear=0; months<MONTHS; months++)
                totyear += *(*(rain+years)+months);  //此处应题目要求使用指针形式,同样可以用数组形式
            printf("%4d %4.2f
    ",2000+years,totyear);
        }
    
        printf("
    month average:
    ");
        printf("JUN  FEB  MAT  APR  MAY  JUN  JLY  AUG  SPT  OCT  NOV  DEC:
    ");
        for(months=0; months<MONTHS; months++)
        {
            for(years=0,totmonth=0; years<YEARS; years++)
                totmonth += *(*(rain+years)+months);  //可用数组形式
            printf("%-4.1f ",totmonth/5);
        }
        printf("
    Done!
    ");
    
        return 0;
    }

    2.

    /*一维数组函数调用*/
    #include <stdio.h>
    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] = {0};    //初始化一个元素全为0的数组可以这样赋值
        double target2[5] = {0};
    
        printf ("Before operation:
    ");
        printf ("source: 	%g	%g	%g	%g	%g
    ",
             source[0], source[1], source[2], source[3], source[4]);
        printf ("target1: 	%g	%g	%g	%g	%g
    ",
             target1[0], target1[1], target1[2], target1[3], target1[4]);
        printf ("target2: 	%g	%g	%g	%g	%g
    ",
             target2[0], target2[1], target2[2], target2[3], target2[4]);
    
        copy_arr (source, target1, 5);
        copy_ptr (source, target2, 5);
    
        printf ("
    
    After operation:
    ");
        printf ("source: 	%g	%g	%g	%g	%g
    ",
             source[0], source[1], source[2], source[3], source[4]);
        printf ("target1: 	%g	%g	%g	%g	%g
    ",
             target1[0], target1[1], target1[2], target1[3], target1[4]);
        printf ("target2: 	%g	%g	%g	%g	%g
    ",
             target2[0], target2[1], target2[2], target2[3], target2[4]);
        
        return 0;
    }
    
    void copy_arr (double a1[], double a2[], int n)
    {
        int i;
        for (i = 0; i < n; i++)
            a2[i] = a1[i];  //简单的赋值就可以实现复制数组
    }
    
    void copy_ptr (double *p1, double *p2, int n)
    {
        int i;
        for (i = 0; i < n; i++)
            *(p2 + i) = *(p1 + i);  //同样,赋值即可实现复制数组
    }
    
    /*******************************************PS: 有关%g输出的补充说明************************************************/
    //1.%g用于打印浮点型数据时,会去掉多余的零,至多保留六位有效数字(不同于%e的默认保留小数点后6位)
    //2.当%g用于打印超过6位的浮点型数据时,因为精度问题,%f不得不输出一个不精确的超过六位的数字,
    //  %e也是同样,而%g此时会选择%e格式进行输出,并且按第一条要求,去掉多余的零,并且四舍五入到6位数字。
    //3.当一个数字的绝对值很小的时候,要表示这个数字所需要的字符数目就会多到让人难以接受。
    //  例如,把π*10^-10写作0.00000000000314159就会显得非常丑陋不雅,反之,如果我们写作3.14159e-10,就不但简洁而且易读好懂。
    //  当指数是-4时,这两种表现形式大小相同。对于比较小的数值,除非该数的指数小于或者等于-5,%g才会采用科学计数(%e的格式)进行输出。

    3.

    /* 找出一个int数组中的最大数 */
    #include <stdio.h>
    int max (int[], int);
    
    int main (void)
    {
        int array[] = {4, 3, 6, 2, 8, 6};
        printf("%d
    ",sizeof(array)/sizeof(int));
        printf ("The max is: %d
    ", max (array, sizeof(array)/sizeof(int)));
    
        return 0;
    }
    
    int max (int a[], int n)
    {
        int i, max;
      //for (i = 0, max = a[0]; i < (sizeof(a)/sizeof(int)); i++)//sizeof(a)不能反应sizeof(array)的大小,所以处理数组的函数应该包括一个数组大小的参数
    for (i=0,max=a[0]; i<n; i++) //n反应出sizeof(array)的大小 max = (max>a[i]) ? max : a[i]; return max; }

    4.

    #include <stdio.h>
    int MaxIndex (double * ptr, int n);
    
    int main (void)
    {
        double array[] = {4.3, 5.3, 2.6, 9.2, 2.8, 3.6};
        printf ("The max number's index is: %d
    ", MaxIndex(array, sizeof(array)/sizeof(double)));
    
        return 0;
    }
    
    int MaxIndex (double a[], int n)
    {
        int i;
        double max;
        for (i=0,max=a[0]; i<n; i++)
            max = (max>a[i]) ? max : a[i];
        for (i=0; max!=a[i]; i++)
            continue;
        return i;
    }

    5.

    /*求数组中最大值最小值间的差值*/
    #include <stdio.h>
    double gap (double *, int);
    
    int main (void)
    {
        double array[] = {4.3, 5.3, 2.6, 9.2, 2.8, 3.6};
        printf ("The gap between max and min is: %g
    ", gap (array, sizeof(array)/sizeof(double)));
        
        return 0;
    }
    
    double gap (double a[], int n)
    {
        int i;
        double max, min;
        for (i = 1, max = a[0], min = a[0]; i < n; i++)
        {
            if (max < a[i])  max = a[i];
            if (min > a[i])  min = a[i];
        }
        return (max - min);
    }

    6.

    /*复制二维数组*/
    #include <stdio.h>
    #define ROWS 2
    #define COLS 3
    void copy_2d (double source[][COLS], double target[][COLS], int);    //复制二维数组,注意声明处理二维数组的函数时要给出子数组大小信息
    void copy_1d (double a1[], double a2[], int n);                        //复制一维数组
    
    int main (void)
    {
        int i, j;
        double source[ROWS][COLS] = {{1, 2, 3}, {4, 5, 6}};
        double target[ROWS][COLS] = {0};
    
        copy_2d (source, target, ROWS);
        for (i=0; i<ROWS; i++)
        {
            for (j = 0; j < COLS; j++)
                printf ("%g	", target[i][j]);
            printf ("
    ");
        }
        return 0;
    }
    
    void copy_2d (double (*source)[COLS], double target[][COLS], int n)
    {
        int i;
        for (i = 0; i < n; i++)
            copy_1d ( *(source + i), target[i], COLS);    //*(source + i), target[i]都是double(* )[3]型
    }
    
    void copy_1d (double a1[], double *a2, int n)
    {
        int i;
        for (i = 0; i < n; i++)
            a2[i] = a1[i];
    }

    7.

    /*一维数组函数调用,复制数组中某部分的元素们*/
    #include <stdio.h>
    void copy (double *, double *, int);
    
    int main (void)
    {
        double source[] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7};
        double target[3] = {0};
    
        printf ("Before operation:
    ");
        printf ("source: 	%g	%g	%g	%g	%g	%g	%g
    ",
             source[0], source[1], source[2], source[3], source[4], source[5], source[6]);
        printf ("target: 	%g	%g	%g
    ",
             target[0], target[1], target[2]);
        
        copy (source + 2, target, 3);    //函数在这里哦,怕你看得心烦不想找
    
        printf ("
    After operation:
    ");
        printf ("source: 	%g	%g	%g	%g	%g	%g	%g
    ",
             source[0], source[1], source[2], source[3], source[4], source[5], source[6]);
        printf ("target: 	%g	%g	%g
    ",
             target[0], target[1], target[2]);
        
        return 0;
    }
    
    void copy (double *p1, double *p2, int n)
    {
        int i;
        for (i = 0; i < n; i++)
            *(p2 + i) = *(p1 +i);
    }

    8.

    #include <stdio.h>
    #define COLS 5
    void copy (double (*)[COLS], double (*)[COLS], int);
    void display (double (*)[COLS], int);
    
    int main (void)
    {
        double source[3][COLS] = 
        {
            {1.1, 2.2, 3.3, 4.4, 5.5},
            {6.6, 7.7, 8.8, 9.9, 10.10},
            {11.11, 12.12, 13.13, 14.14, 15.15}
        };
        double target[6][COLS] = {0};
    
        copy (source, target, 3);
    
        puts ("source:");
        display (source, 3);
        puts ("
    target:");
        display (target, 5);
    
        return 0;
    }
    
    void copy (double (*source)[COLS], double target[][COLS], int rows)    //double (*source)[COLS]等同于double source[][COLS]
    {
        int i, j;
        for (i = 0; i < rows; i++)
        {
            for (j = 0; j < COLS; j++)
                target[i][j] = source[i][j];
        }
    }
    
    void display (double (*p)[COLS], int rows)
    {
        int i,j;
    
        for (i = 0; i < rows; i++)
        {
            for (j = 0; j < COLS; j++)
                printf ("%g	", p[i][j]);
            printf ("
    ");
        }
            
    }

    突然发现自己写的程序自己都不愿意去读,因为全是代码没有模块化的注释,仅仅偶尔有个细节注释啥的,所以看起来要找,要想,这一段函数是干什么的,实现某个功能的函数在哪里等等。本来程序就是密密麻麻的东西,而且又不是汉语形式的,本身看起来就很费劲。所以还是要多写注释,尤其是模块化地去注释,最好能让人一眼看清程序的整体思路以及模块。

    9.

    /*两数组对应元素相加放在第三个数组中*/
    #include <stdio.h>
    void add (double [], double *, double [], int n);
    
    int main (void)
    {
        /**************声明和初始化两个源数组和一个目标数组*****************/
        double source1[5] = {1.1, 2.2, 3.3, 4.4, 5.5};
        double source2[5] = {6.6, 7.7, 8.8, 9.9, 10.10};
        double target[5] = {0};
        
        /**************执行两个源数组相加并且赋值给目标数组*****************/
        add (source1, source2, target, sizeof(source1)/sizeof(double));
    
        /**************显示两个源数组和目标数组*****************/
        printf ("source1: 	%g	%g	%g	%g	%g
    ",source1[0],source1[1],source1[2],source1[3],source1[4]);
        printf ("source2: 	%g	%g	%g	%g	%g
    ",source2[0],source2[1],source2[2],source2[3],source2[4]);
        printf ("target:  	%g	%g	%g	%g	%g
    ",target[0],target[1],target[2],target[3],target[4]);
    
        return 0;
    }
    
    /**************定义函数:两个源数组相加并且赋值给目标数组*****************/
    void add (double source1[], double source2[], double target[], int n)
    {
        int i;
        for (i = 0; i < n; i++)
            target[i] = source1[i] + source2[i];
    }

    这样就清楚些了吧。其实写出来牛逼的代码确实牛逼,但是做好注释方便维护则是素养!

    10.

    打算用指针的形式,不能老用数组,正好可以加强一下对指针的认识。

    /*二维数组元素翻一番*/
    #include <stdio.h>
    #define ROWS 3
    #define COLS 5
    void twice (double (*)[COLS], int);
    void display (double (*)[COLS], int);
    
    int main (void)
    {
        /*******************声明和初始化二维源数组********************/
        double array[ROWS][COLS] = 
        {
            {1.1, 2.2, 3.3, 4.4, 5.5},
            {6.6, 7.7, 8.8, 9.9, 10.10},
            {11.11, 12.12, 13.13, 14.14, 15.15}
        };
    
        /*******************显示源数组,对源数组执行翻倍,显示翻倍后的数组********************/
        puts ("before: 
    ");
        display (array, 3);
        twice (array, 3);
        puts ("
    after:
    ");
        display (array, 3);
    
        return 0;
    }
    
    /*******************定义函数:翻倍源数组********************/
    void twice (double (*p)[COLS], int rows)
    {
        int i, j;
        for (i = 0; i < rows; i++)
        {
            for (j = 0; j < COLS; j++)
                *(*(p+i)+j) = 2 *(*(*(p+i)+j));
        }
    }
    
    /*******************定义函数:显示二维数组********************/
    void display (double (*p)[COLS], int rows)
    {
        int i, j;
        for (i = 0; i < rows; i++)
        {
            for (j = 0; j < COLS; j++)
                printf ("%g	", p[i][j]);
            printf ("
    ");
        }
    }

    11.

    /*rain.c 针对若干年的降水量数据,计算年降水总量、年降水平均量,以及月降水平均量*/
    #include <stdio.h>
    #define MONTHS 12
    #define YEARS 5
    void RainPerYear(const float (*)[12]);    //注意使用const定义形参(因为实参都用const定义了,更别说形参了)
    void RainAveMon(const float (*)[12]);
    
    int main (void)
    {
        /***********把数组初始化为2000到2004年的降水量数据****************/
        const float rain[YEARS][MONTHS] = //const声明和初始化数组可保护数据
        {
            {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}
        };
    
        /************计算和显示年总降水量*****************/
        RainPerYear(rain);
        /***********计算和显示月平均降水量****************/
        RainAveMon(rain);
    
        return 0;
    }
    
    /************定义函数:计算和显示年总降水量*****************/
    void RainPerYear(const float (*rain)[12])
    {
        int years,months;
        float totyear;
    
        printf("YEAR  RAIN:
    ");
        for(years=0; years<YEARS; years++)
        {
            for(months=0,totyear=0; months<MONTHS; months++)
                totyear += *(*(rain+years)+months);
            printf("%4d %4.2f
    ",2000+years,totyear);
        }
    }
        
    /***********定义函数:计算和显示月平均降水量****************/
    void RainAveMon(const float (*rain)[12])
    {
        int years,months;
        float totmonth;
    
        printf("
    month average:
    ");
        printf("JUN  FEB  MAT  APR  MAY  JUN  JLY  AUG  SPT  OCT  NOV  DEC:
    ");
        for(months=0; months<MONTHS; months++)
        {
            for(years=0,totmonth=0; years<YEARS; years++)
                totmonth += *(*(rain+years)+months);
            printf("%-4.1f ",totmonth/5);
        }
        printf("
    Done!
    ");
    }
    
        

    12.

    /*键盘输入储存3*5数组数据,计算平均,找最值,显示*/
    #include <stdio.h>
    #define COLS 5
    void store (double p[][COLS], int row);
    double average_row (double p[], int n);
    double average_total (double p[][COLS], int row);
    double max(double p[][COLS], int row);
    //void display (double p[][COLS], int rows, double average0, double average1, double average2, double average_total, double max);
    
    int main (void)
    {
        int i;
        double array[3][COLS];
        double ave_row[3];
        double ave_tot;
        double max_tot;
    
        /**********************读入array的3个数集,每个数集5个数据***********************/
        store (array, 3);
    
        /****************************计算每个数集的平均值********************************/
        for(i=0; i<3; i++)
            ave_row[i] = average_row (array[0],5);
    
        /****************************计算整个数集的平均值********************************/
        ave_tot = average_total(array, 3);
    
        /****************************找出整个数集的最大值********************************/
        max_tot = max (array, 3);
        
        /**********************************输出结果**************************************/
        printf("ave_row[0],ave_row[1],ave_row[2] are: %g %g %g
    ",ave_row[0],ave_row[1],ave_row[2]);
        printf("ave_total is %g:
    ", ave_tot);
        printf("max is %g:
    ", max_tot);
        printf("Done!
    ");
    
        return 0;
    }
    
    /**********************定义函数:读入array的3个数集,每个数集5个数据***********************/
    void store (double p[][COLS], int row)
    {
        int i, j;
        printf ("Please enter 15 double numbers:
    ");
        for (i = 0; i < row; i++)
        {
            for (j = 0; j < COLS; j++)
                scanf ("%lf", *(p+i)+j);    // *(p+i)+j等同于&p[i][j]
        }
        puts ("Now you have finished.
    ");
    }
    
    /****************************定义函数:计算每个数集的平均值********************************/
    double average_row (double p[], int n)
    {
        int i;
        double sum;
        for (i=0,sum=0; i<n; i++)
            sum += p[i];
    
        return sum/n;
    }
    
    /****************************定义函数:计算整个数集的平均值********************************/
    double average_total(double p[][COLS], int row)
    {
        int i,j;
        double total=0;
        for(i=0; i<row; i++)
        {    
            for(j=0; j<COLS; j++)
                total += p[i][j];
        }
    
        return total/row/COLS;
    }
    
    /****************************定义函数:找出整个数集的最大值********************************/
    double max(double p[][COLS], int row)
    {
        int i,j;
        double m=p[0][0];
    
        for(i=0; i<row; i++)
            for(j=0; j<COLS; j++)
                m = (m>p[i][j]) ? m : p[i][j];
    
        return m;
    }

    终于搞定,不难,就是有点烦,嘿嘿

  • 相关阅读:
    用Vue来实现音乐播放器(10):Scroll组件的抽象和应用
    Vue的生命周期
    用Vue来实现音乐播放器(九):歌单数据接口分析
    Java中StringBuilder和StringBuffer的区别
    StringBuilder类型与String类型相互转换
    List中Add()与AddAll()的区别
    Map集合遍历的四种方式
    Object类型转换为Integer
    web开发中常用到的状态码
    mysql--从不订购的客户
  • 原文地址:https://www.cnblogs.com/TomLily/p/5851333.html
Copyright © 2011-2022 走看看