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

    这章感觉好难啊,放个别人的总结.

    // 多维数组和指针
    #include <stdio.h>
    int main(void)
    {
        int zippo[4][2] = {{2, 4}, {6, 8}, {1, 3}, {5, 7}};
        /*
           zippo[0]是一个整数大小对象的地址,而zippo是两个整数大小对象的地址。
           因为(一个)整数和两个整数组成的数组开始于同一个地址,因此zippo和zippo[0]具有相同的数值。
           验证:
           输出也显示出二维数组zippo的地址和一维数组zippo[0]的地址是相同的,均为相应的数组
           首元素的地址,它的值是和&zippo[0][0]相同的;
           而且,*zippo也是一个指针,它与一维数组zippo[0](也是一个指针)的地址相同,证明了我的猜想!
        */
        printf("===========首先验证第一条结论===========
    ");
        printf("zippo: 		%p
    &zippo[0]: 	%p
    ", zippo, &zippo[0]);
        printf("zippo[0]: 	%p
    &zippo[0][0]: 	%p
    ",zippo[0],&zippo[0][0]);
        printf("*zippo: 	%p
    &*zippo: 	%p
    ", *zippo, &*zippo);
        printf("
    ");
        /*
           zippo所指向对象的大小是两个int,而zippo[0]所指向对象的大小是一个int
           验证:
           zippo[0]指向4字节长的数据对象。对zippo[0]加1导致它的值增加4。数组名zippo是包含
           两个int数的数组的地址,因此它指向8字节长的数据对象。所以,对zippo加1导致它的值增加8。
        */
        printf("===========然后验证第二条结论===========
    ");
        printf("zippo: 		%p
    zippo+1: 	%p
    ", zippo, zippo+1);
        printf("zippo[0]: 	%p
    zippo[0]+1: 	%p
    ", zippo[0], zippo[0]+1);
        printf("
    ");
        /*
           *zippo也是一个指针,它与一维数组zippo[0](也是一个指针)的地址相同,它们指向同一个int变量
           即zippo[0][0]
           *zippo[0] = zippo[0][0]
           **zippo = *zippo[0] = zippo[0][0](得证)
           ------------------------------------------------
           分析*(*(zippo+2)+1)
           zippo------------------第1个大小为2个int的元素的地址
           zippo+2----------------第3个大小为2个int的元素的地址
           *(zippo+2)-------------第3个元素,即包含2个int值的数组,因此也是其第1个元素的(int值)的地址
           *(zippo+2)+1-----------包含2个int值的数组的第2个元素(int值)的地址
           *(*(zippo+2)+1)--------数组第3行第2列int(zippo[2][1])的值
    
           总结:更一般地,要表示单个元素,可以使用数组符号或指针符号;并且在这两种表示中即可以使用
           数组名,也可以使用指针:
           zippo[m][n] == *(*(zippo+m)+n)
        */
        printf("===========最后验证第三条结论===========
    ");
        printf("*zippo: 	%p
    zippo[0]: 	%p
    ", zippo, zippo[0]);
        printf("*(zippo+1): 	%p
    zippo[1]: 	%p
    ", *(zippo+1), zippo[1]);
        printf("**zippo: 	%d
    zippo[0][0]: 	%d
    ", **zippo, zippo[0][0]);
        printf("*(*(zippo+2)+1)	%d
    zippo[2][1]: 	%d
    ", *(*(zippo+2)+1), zippo[2][1]);
        return 0;
    }
    ===========首先验证第一条结论===========
    zippo:      0x7fff1c31a900
    &zippo[0]:  0x7fff1c31a900
    zippo[0]:   0x7fff1c31a900
    &zippo[0][0]:   0x7fff1c31a900
    *zippo:     0x7fff1c31a900
    &*zippo:    0x7fff1c31a900
    
    ===========最后验证第三条结论===========
    *zippo:     0x7fff1c31a900
    zippo[0]:   0x7fff1c31a900
    *(zippo+1):     0x7fff1c31a908
    zippo[1]:   0x7fff1c31a908
    **zippo:    2
    zippo[0][0]:    2
    *(*(zippo+2)+1) 3
    zippo[2][1]:    3
    // 指针的兼容性
    #include <stdio.h>
    int main(void)
    {
        /*
           指针之间的赋值规则比数值类型的赋值更严格
           举例说明:
        */
        int n = 5;
        double x;
        int * pi = &n;
        double * pd = &x;
        x = n;  // 不需要进行类型转换就直接把一个int数值赋给一个double类型的变量(隐藏的类型转换)
        pd = pi // 编译时错误,原因:pd指向一个double类型的数值,pi指向一个int类型的数值
    
        int * pt;
        int (* pa) [3];
        int ar1[2][3];
        int ar2[3][2];
        int **p2; // (指向int指针)的指针
        pt = &ar1[0][0];   // pt为指向一个int数值的指针,ar1[0][0]是一个int数值的变量
        pt = ar1[0];       // pt为指向一个int数值的指针,ar1[0]也为指向一个int数值的指针
        pt = ar1;          // pt为指向一个int数值的指针,ar1指向由3int值构成的指针(非法)
        pa = ar1;          // pa指向由3int值构成的数组,ar1也指向由3int值构成的数组
        pa = ar2;          // pa指向由3int值构成的数组,ar2指向由2int值构成的数组(非法)
        p2 = &pt;          // p2是(指向int指针)的指针,&pt(头一次见,得记下来)也是(指向int指针)的指针
        *p2 = ar2[0];      // *p2为指向int的指针,ar2[0]也是指向int的指针
        p2 = ar2;          // p2是(指向int指针)的指针,ar2是指向由2int值构成的数组(非法)
        return 0;
    }

    复习题.

    int ref[] = { 8, 4, 0, 2 };
    3.
    ref的地址是什么?ref + 1 是什么意思?++ref指向什么?
    答:ref的数组名是指向首元素的地址。ref + 1 是指向该数组的第二个元素。 ++ref是错误的,因为ref是常量而不是变量。 (数组元素也是一种变量,其标识方法为数组名后跟一个下标。)有关变量和常量:http://c.biancheng.net/cpp/html/19.html
    
    6.
    假设有下面的声明:int grid[30][100];
    a.用1种写法表示grid[22][56]
    b.用2种写法表示grid[22][0]
    c.用3种写法表示grid[0][0]
    答:a:&grid[22][56]  b:grid[22], &grid[22][0]  c:grid[0], &grid[0][0], (int *) grid
    (grid 是内含100个元素的grid[0]数组的地址。这两个地址数值相同,但是类型不同,可以用强制类型转换把他们转换成相同的类型。)
    
    7.
    d.psa是一个内含20个元素的数组,每个元素都是指向int的指针
    e.pstr是一个指向数组的指针,该数组内含20个char类型的值
    答:d. int * psa[20]; //[]比*先生效,所以每个元素都是指向int的指针.
       e. char (*pstr)[20]; //这样就*先生效,所以pstr指向的数组含有20个char类型的值.

    编程练习

    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}
                };
        const float (*pt)[MONTHS] = rain; //const数据不可赋给普通指针,否则通过指针就能改变const中的数据.
        float subtot, total;
        int year, month;
    
        printf(" YEAR    RAINFALL  (inches)
    ");
        for (year = 0, total = 0; year < YEARS; year++) {
            for (month = 0, subtot = 0; month < MONTHS; month++)
                subtot += *(*(pt + year) + month);
            printf("%5d %15.1f
    ", 2010 + year, subtot);
            total = total + subtot;
        }
    
        printf("
    The yearly average is %.1f inches.
    
    ",
               total / YEARS);
        printf("MONTHLY AVERAGES:
    
    ");
        printf(" Jan  Feb  Mar  Apr  May  Jun  Jul  Aug  Sep  Oct ");
        printf(" Nov  Dec
    ");
    
        for (month = 0; month < MONTHS; month++) {
            for (year = 0, subtot = 0; year < YEARS; year++)
                subtot += *(*(pt + year) + month);
            printf("%4.1f ", subtot / YEARS);
        }
        printf("
    ");
    
        return 0;
    }
    2.
    #include <stdio.h>
    
    void copy_arr(double *ar, double *pt, int n);
    void copy_arr2(double *ar, double *pt, int n);
    void copy_arr3(double *ar, double *pt, double *pr);
    
    int main(void) {
        double source[5] = {1.1, 2.2, 3.3, 4.4, 5.5};
        double targe1[5], targe2[5], targe3[5];
    
        printf("targe1:
    ");
        copy_arr(targe1, source, 5);
        putchar('
    ');
        printf("targe2:
    ");
        copy_arr2(targe2, source, 5);
        putchar('
    ');
        printf("targe3:
    ");
        copy_arr3(targe3, source, source + 5);
    
        return 0;
    }
    
    void copy_arr(double *ar, double *pt, int n) {
        int i;
        for (i = 0; i < n; i++) {
            ar[i] = pt[i];
            printf("[%d]:  %.1lf
    ", i, ar[i]);
        }
    }
    
    void copy_arr2(double *ar, double *pt, int n) {
        int i;
        for (i = 0; i < n; i++) {
            *(ar + i) = *(pt + i);
            printf("[%d]:  %.1lf
    ", i, *(ar + i));
        }
    }
    
    void copy_arr3(double *ar, double *start, double *end) {
        int i = 0;
        while (start < end) {
            *ar = *start;
            printf("[%d]:  %.1lf
    ", i++, *ar);
            start++;
            ar++;
        }
    }
    3.
    #include <stdio.h>
    int max(int *ar, int n);
    
    int main(void) {
        int source[5] = {1, 10, 3, 4, 5};
        printf("MAX: %d", max(source, 5));
        return 0;
    }
    
    int max(int *ar, int n){
        int max = ar[0];
        for (int i = 0; i < n; ++i) {
            if (max < ar[i])
                max = ar[i];
        }
        return max;
    }
    4.
    #include <stdio.h>
    int max(double *ar, int n);
    
    int main(void) {
        double source[5] = {1, 10, 11, 4, 5};
        printf("MAX_: %d", max(source, 5));
        return 0;
    }
    
    int max(double *ar, int n){
        int max = ar[0];
        int x = 0;
        for (int i = 0; i < n; ++i) {
            if (max < ar[i]){
                max = ar[i];
                x = i;
            }
        }
        return x;
    }
    5.
    #include <stdio.h>
    int max(int *ar, int n);
    
    int main(void) {
        int source[5] = {1, 10, 3, 4, 5};
        printf("Difference: %d", max(source, 5));
        return 0;
    }
    
    int max(int *ar, int n){
        int max = ar[0];
        int min = ar[0];
        for (int i = 0; i < n; ++i) {
            if (max < ar[i])
                max = ar[i];
        }
        for (int i = 0; i < n; ++i) {
            if (min > ar[i])
                min = ar[i];
        }
        return max - min;
    }
    6.
    #include <stdio.h>
    void copy(double *pr, double *ar, int n);
    
    int main(void) {
        double source[5] = {1, 10, 3, 4, 5}, targe[5];
        copy(targe, source, 5);
        for (int i = 0; i < 5; ++i) {
            printf("%5.1lf",targe[i]);
        }
        return 0;
    }
    
    void copy(double *pr, double *ar, int n){
        int x = n - 1;
        for (int i = 0; i < n; ++i,x--) {
            pr[x] = ar[i];
        }
    }
    7.
    //运行完成后会出现*** stack smashing detected ***这个,我也不知道啥情况记一下先吧.
    #include <stdio.h>
    void copy(double ar[][3], double pt[][3], int n);
    
    int main(void)
    {
        double soure[2][3] = {{1,2,3},{4,5,6}};
        double target[2][3];
        copy(target,soure,2);
        for (int i = 0; i < 2; ++i) {
            for (int m = 0; m < 3; ++m) {
                printf("target[%d][%d]:%.1lf
    ", i, m, target[i][m]);
            }
        }
        return 0;
    }
    
    void copy(double ar[][3], double pt[][3], int n){
        for (int i = 0; i < n; ++i) {
            for (int m = 0; m < 5; ++m) {
                ar[i][m] = pt[i][m];
            }
        }
    }
    8.
    #include <stdio.h>
    
    void copy(double ar[], double pt[], int n);
    
    int main(void) {
        double soure[7] = {1, 2, 3, 4, 5, 6, 7};
        double target[3];
        copy(target, soure + 2, 3);
        for (int m = 0; m < 3; ++m) {
            printf("target[%d]:%.1lf
    ", m, target[m]);
        }
    
        return 0;
    }
    
    void copy(double ar[], double pt[], int n) {
        for (int m = 0; m < n; ++m) {
            ar[m] = pt[m];
        }
    }
    9.
    #include <stdio.h>
    void copy(int n, int m, double ar[n][m], double pt[n][m]);
    void print(int n, int m, double ar[n][m]);
    int main(void){
        double soure[3][5] = {{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15}};
        double target[3][5];
        copy(3, 5, target, soure);
        printf("soure:
    ");
        print(3, 5, soure);
        printf("target:
    ");
        print(3, 5, target);
        return 0;
    }
    
    void copy(int n, int m, double ar[n][m], double pt[n][m]){
        for (int i = 0; i < n; ++i) {
            for (int a = 0; a < m; ++a) {
                ar[i][a] = pt[i][a];
            }
        }
    }
    void print(int n, int m, double ar[n][m]){
        for (int i = 0; i < n; ++i) {
            for (int a = 0; a < m; ++a) {
                printf("[%d][%d]:%.1lf
    ", i, a, ar[i][a]);
            }
        }
    }
    10.
    #include <stdio.h>
    void copy(double pt[],double zr[], double ar[],int n);
    void print(double ar[], int n);
    int main(void){
        double soure[5] = {1,2,3,4,5};
        double soure2[5] = {1,2,3,4,5};
        double target[5];
        copy(target, soure, soure2, 5);
        print(target, 5);
        return 0;
    }
    
    void copy(double pt[],double zr[], double ar[],int n){
        for (int i = 0; i < n; ++i) {
            pt[i] = zr[i] + ar[i];
        }
    }
    
    void print(double ar[], int n){
        for (int i = 0; i < n; ++i) {
                printf("[%d]:%.1lf
    ", i, ar[i]);
        }
    }
    11.
    #include <stdio.h>
    
    void doub(int n, int m, double ar[n][m]);
    void print(int n, int m, double ar[n][m]);
    
    int main(void) {
        double soure[3][5] = {{1,  2,  3,  4,  5},
                              {6,  7,  8,  9,  10},
                              {11, 12, 13, 14, 15}};
        doub(3, 5, soure);
        printf("soure:
    ");
        print(3, 5, soure);
    
        return 0;
    }
    
    void doub(int n, int m, double ar[n][m]) {
        for (int i = 0; i < n; ++i) {
            for (int a = 0; a < m; ++a) {
                ar[i][a] = ar[i][a] * 2;
            }
        }
    }
    
    void print(int n, int m, double ar[n][m]) {
        for (int i = 0; i < n; ++i) {
            for (int a = 0; a < m; ++a) {
                printf("[%d][%d]:%.1lf
    ", i, a, ar[i][a]);
            }
        }
    }
    12.
    #include <stdio.h>
    
    #define MONTHS 12
    #define YEARS   5
    
    void eachmonths(const float [][MONTHS], int n);
    float sum(const float [][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}
                };
        float total;
    
        printf(" YEAR    RAINFALL  (inches)
    ");
    
        total = sum(rain, YEARS);
    
        printf("
    The yearly average is %.1f inches.
    
    ",
               total / YEARS);
        printf("MONTHLY AVERAGES:
    
    ");
        printf(" Jan  Feb  Mar  Apr  May  Jun  Jul  Aug  Sep  Oct ");
        printf(" Nov  Dec
    ");
    
        eachmonths(rain, YEARS);
    
        return 0;
    }
    
    float sum(const float ar[][MONTHS], int n) {
        float subtot, total;
        int i, m;
        for (i = 0, total = 0; i < n; i++) {
            for (m = 0, subtot = 0; m < MONTHS; m++)
                subtot += ar[i][m];
            printf("%5d %15.1f
    ", 2010 + i, subtot);
            total += subtot;
        }
        return total;
    }
    
    void eachmonths(const float ar[][MONTHS], int n) {
        float subtot;
        int m;
        for (int i = 0; i < MONTHS; ++i) {
            for (m = 0, subtot = 0; m < n; ++m) {
                subtot += ar[m][i];
            }
            printf("%4.1f ", subtot / YEARS);
        }
        printf("
    ");
    }
    
    //做完这题之后就感觉自己是个弱智!
    /*爆炸级别弱智错误还找了半天.
    float sum(const float ar[][MONTHS], int n) {
        float subtot, total;
        for (int i = 0, total = 0; i < n; i++) {
            for (int m = 0, subtot = 0; m < MONTHS; m++)
                subtot += ar[i][m];
            printf("%5d %15.1f
    ", 2010 + i, subtot);
            total += subtot;
        }
        return total;
    }
    这样子之后就在for循环中把total和subtot声明成了int格式了,
    然后我不就是个傻逼了吗!!哇 真的是被自己蠢哭了.*/
    13 and 14
    #include <stdio.h>
    
    void enter_number(int n, int m, double ar[n][m]);
    double average_group(double ar[], int n);
    double average_all(int n, int m, double ar[n][m]);
    double MAX(int n, int m, double ar[n][m]);
    void show(int n, int m, double ar[n][m]);
    
    int main(void) {
        int row, col;
        printf("请输入你需要的数组(例如3×5):");
        scanf("%d %d", &row, &col);
        double target1[row][col];
    
        printf("请输入数据:
    ");
        enter_number(row, col, target1);
        for (int i = 0; i < row; ++i) {
            printf("第 %d 组 (%d个) 的平均值是:  %.1lf
    ", i + 1, col, average_group(target1[i], col));
        }
        printf("所有数据的平均值是: %.1lf
    ", average_all(row, col, target1));
        printf("所有数据的最大值是: %.1lf
    
    
    ", MAX(row, col, target1));
        printf("你输入的数组是:
    ");
        show(row, col, target1);
        return 0;
    }
    
    void enter_number(int n, int m,double ar[n][m]) {
        double number;
        for (int i = 0; i < n; ++i) {
            for (int x = 0; x < m; ++x) {
                scanf("%lf", &number);
                ar[i][x] = number;
            }
        }
    }
    
    double average_group(double ar[], int n){
        double total = 0;
        for (int i = 0; i < n; ++i) {
            total += ar[i];
        }
        return total / n;
    }
    
    double average_all(int n, int m, double ar[n][m]){
        double total = 0;
        for (int i = 0; i < n; ++i) {
            for (int x = 0; x < m; ++x) {
                total += ar[i][x];
            }
        }
        return total / (n * m);
    }
    
    double MAX(int n, int m, double ar[n][m]) {
        double max = ar[0][0];
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                if (max < ar[i][j])
                    max = ar[i][j];
            }
        }
        return max;
    }
    
    void show(int n, int m, double ar[n][m]){
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                printf("%8.1lf", ar[i][j]);
            }
            putchar('
    ');
        }
    }
  • 相关阅读:
    React 之form表单、select、textarea、checkbox使用
    React 事件对象、键盘事件、表单事件、ref获取dom节点、react实现类似Vue双向数据绑定
    React事件方法、React定义方法的几种方式、获取数据、改变数据、执行方法传值
    react综合案例-todolist、localstorage缓存数据
    【剑指offer15】二进制中1的个数(位运算),C++实现
    【剑指offer】10矩阵覆盖
    【剑指offer】09-3变态跳台阶
    【剑指offer】顺时针打印矩阵,C++实现
    【剑指offer】09-2跳台阶,C++实现
    leetcode1143
  • 原文地址:https://www.cnblogs.com/cccj/p/7667958.html
Copyright © 2011-2022 走看看