C语言 二维数组

182 阅读2分钟

1. 关于地址

//    三行五列
    int a[3][5] = {{1, 2, 3, 4, 5},
                   {11, 21, 31, 41, 51},
                   {12, 22, 32, 42, 52}};

     /*以下地址相同*/
//    整个数组的地址
    printf("------------------------%d\n", &a);
//    第一行的首地址
    printf("------------------------%d\n", a);
//    第一行第一个元素的首地址
    printf("------------------------%d\n", *a);

2. 关于长度

//    三行五列
    int a[3][5] = {{1, 2, 3, 4, 5},
                   {11, 21, 31, 41, 51},
                   {12, 22, 32, 42, 52}};

    printf("------------------------%d\n", a);
//    相差 20 个字节     &a = 3 * 5 * 4    a = 5 * 4    *a = 4
    printf("------------------------%d\n", a + 1);

3. 关于长度

//    三行五列
    int a[3][5] = {{1, 2, 3, 4, 5},
                   {11, 21, 31, 41, 51},
                   {12, 22, 32, 42, 52}};

//    3 * 5 * 4 = 60 个字节
    printf("------------------------%d\n", sizeof(*&a));
//    4 * 5   每行有五个数    实际取的是 a 的字节
    printf("------------------------%d\n", sizeof(*a));
//    4 实际取的是 *a 的字节
    printf("------------------------%d\n", sizeof(**a));

4. 关于取值

    int a[3][5] = {{1, 2, 3, 4, 5},
                   {11, 21, 31, 41, 51},
                   {12, 22, 32, 42, 52}};
//    下标法取值  从 0 开始计算
    printf("------------------------%d\n", a[2][3]);

指针法取值

还是以上述三行五列的数组为数据来源,该如何命名指针呢

int (*p)[5] = a;

没错,你没看错,它是以列数为数组的大小,为什么不是 3 呢?原因很简单,还记得 a 的字节数是多大吧,对,就是 5 * 4,那么对 p + 1 不就是 a + 1 嘛,所以 p + 1 就指向了下一行。那如何取值呢

//    取值 11
    printf("-----------11111-------------%d\n", **(p + 1));
//    取值 42
    printf("-------------11111-----------%d\n", *(*(p + 2) + 3));

为什么是两个 * 呢,不应该是一个 * 吗?其实想想也能明白了,*p 是整个二维数组的地址,也就是 &a,那么 *p 得到的就是 *a 的地址,也就是第一行首个元素的地址,那么 **p 就是解析首个元素的地址,得到值,想想上边的长度计算就能明白了。