不灭的焱

革命尚未成功,同志仍须努力

作者:php-note.com  发布于:2019-10-05 11:25  分类:Linux_C  编辑

以前一直有种误解:

二维数组的是数组的数组,所以数组的首地址是指向第一个元素指针,而这个元素又是一个数组,所以把数组首地址理解为 指向指针的指针

#include <stdlib.h>

int main(int argc, char **argv) {
    
    int a[6][8];
    
    int **p;
    p = a;
        
    return EXIT_SUCCESS;
}

因为a代表着除了第一列以外的列数的维数大小,如a+1的地址就是a[1]的地址,也就是a[1][0]的地址,而p仅是整形指针的指针,每跨越一次就是4字节,因此他们的大小是不匹配的,所以这样子直接等于号是不正确的。

要真正的定义方式应概是定义指向n维数组的指针,n就是除第一维的另外维度,

如上面的指针定义应该为

int (*p)[8];
p = a;

这样子就 可以就可以通过p以下标形式来访问数组。

测试1:

#include <stdio.h>

int main(int argc, char **argv) {

    int gridArr[6][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},
            {26, 27, 28, 29, 30}
    };

    int (*grid)[5];    // grid 为指向int的数组(元素个数为5)的指针
    grid = gridArr;

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

    return 0;
}

输出:

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	
26	27	28	29	30	

测试2:

#include <stdio.h>

int main(int argc, char **argv) {

    int gridArr[6][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},
            {26, 27, 28, 29, 30}
    };

    int *grid[6];    // grid 为指向int的指针的数组(元素个数为6)

    for (int i = 0; i < 6; i++) {
        grid[i] = gridArr[i];
        for (int j = 0; j < 5; j++) {
            printf("%d\t", grid[i][j]);
        }
        printf("\n");
    }

    return 0;
}

输出:

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	
26	27	28	29	30	

测试3:使用 指向指针的指针

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {

    int gridArr[6][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},
            {26, 27, 28, 29, 30}
    };

    int i, j;
    int **grid = (int **) malloc(6 * sizeof(int *));  // 注意:是两个**

    for (i = 0; i < 6; i++) {
        grid[i] = (int *) malloc(5 * sizeof(int *));  // 注意:是一个*
        for (j = 0; j < 5; j++) {
            // 方式一:下标引用
            grid[i][j] = gridArr[i][j];
            
            // 方式二:指针计算
            // *(*(grid + i) + j) = gridArr[i][j];
        }
    }

    for (i = 0; i < 6; i++) {
        for (j = 0; j < 5; j++) {
            // 方式一:下标引用
            printf("%d\t", grid[i][j]);
            
            // 方式二:指针计算
            // printf("%d\t", *(*(grid + i) + j));
        }
        printf("\n");
    }
    
    return 0;
}

输出:

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	
26	27	28	29	30	

 

 

参考: