指向二维数组的指针如何定义_C的指针(三)指针和二维数组

对于二维数组 array[4][5]. array 应理解为是包含四个元素的数组,每个元素是一个一维数组,它们有五个元素。

例:

int mat[3][4];

a9962f4a4bb85f9029c80df8219f1a04.png

数组含义:

  • 数组 mat 包含三个元素:mat[0], mat[1], mat[2]
  • mat 的第一个元素 mat[0] 是包含四个整形变量的数组

考虑到数组名代表数组第一个元素的地址

  • mat 是其第一个元素 mat[0] 的地址,即 mat = &mat[0]
  • mat[0] 是其第一个元素 mat[0][0] 的地址,即 mat[0] = &mat[0][0]
  • *mat = mat[0], 于是*matmat[0][0] 的地址

因为mat[0]mat[0][0] 的地址都是数组的起始位置,地址相同,所以:

mat = &mat[0] = mat[0] = &mat[0][0] = *mat
  • mat + 1 指向数组mat的第二个元素,是mat[1] 的地址
    • mat + 1 = &mat[1]
  • mat[0] + 1 指向数组mat[0] 的第二个元素,是mat[0][1] 的地址
    • mat[0] + 1 = &mat[0][1]

32fa379e2bc90ed6ae00ad3a8bae339b.png

程序示例

#include <stdio.h>
int main()
{
    int array[4][5] = {0};

    printf("sizeof int : %dn", sizeof(int));
    printf("array :      %pn", array);
    printf("array + 1 :  %pn", array + 1);

    return 0;
}
/*--------OUTPUT--------*/
sizeof int : 4
array      : 0x7ffee9ee0a60
array + 1  : 0x7ffee9ee0a74 // 跨越了五个元素

下面考虑解引用和指针的运算

  • 前面已经提到对二级指针mat 的解引用 *matmat[0]
  • 对一级指针 mat[0] 的解引用 *mat[0]mat[0][0]

d36b5976202a287b969fa620aac6c485.png

3bbc286967de69f24e296683688319bc.png

即:

// 一层解引用:
*mat = mat[0] = &mat[0][0]     
*mat[0] = mat[0][0]
*(mat+1) = mat[1] = &mat[1][0]  
*mat[1] = mat[1][0]
// 二层解引用:
**mat = *mat[0] = mat[0][0]
**(mat+1) = *(mat[1]) = mat[1][0]
*(*(mat+1)+1) = *(mat[1]+1) = mat[1][1]
// 总结:
*(array+i) == array[i]
*(*(array+i)+j) == array[i][j]
*(*(*(array+i)+j)+k) == array[i][j][k]

程序实例

#include <stdio.h>

int main()
{
    int array[4][5] = {0};
    int i, j, k = 0;

    for (i = 0; i < 4; i++){
        for (j = 0; j < 5; j++){
            array[i][j] = k++;
        }
    }

    printf("*(array + 1):   %pn", *(array + 1));
    printf("array[1]:       %pn", array[1]);
    printf("&array[1][0]:   %pn", &array[1][0]);
    printf("**(array + 1):  %dn", **(array + 1));

    return 0;
}
/*--------OUTPUT--------*/
*(array + 1): 0x7ffee924aa74
array[1]:     0x7ffee924aa74
&array[1][0]: 0x7ffee924aa74
**(array + 1): 5

行指针和列指针

int a[3][4];
  • a, a+1 分别指向第一行,第二行的一维数组, 称为行指针
    • a+1 = &a[1]
    • 解引用行指针得到一维数组
  • a[0] = *(a+0), a[0]+1 = *(a+1) 分别指向第一行第一列,第一行第二列元素的地址,称为列指针(元素指针)
    • a[i] = &a[i][0] , a[i]+j = &a[i][j]
    • 解引用列指针得到一维数组内的元素
    • *(a[i]+j) = a[i][j]
  • 行指针解引用后是列指针
    • *a = a[0]
    • *(a+i) = a[i] = &a[i][0]

数组指针和二维数组

#include <stdio.h>
int main()
{
    int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
    int *p;
    p = *a;     // p 是列指针/一级指针,指向第一行第一列
//  p = &a[0][0]; (对),也是第一行第一列的地址
//  p = a;         (错), a是行指针/二级指针
    for(p=a[0]; p < a[0] + 12; p++) 
    {
        if((p - a[0]) % 4 == 0)
            printf("n");
        printf("%4d  ", *p);  // 解引用得到元素
    }

    return 0;
}

这是普通指针,下面使用数组指针。数组指针指向一个一维数组,解引用数组指针得到数组。

#include <stdio.h>
int main()
{
    int array[2][3] = {{0, 1, 2},
                       {3, 4, 5}};
    int (*p)[3] = array;

// 一层解引用
    printf("*p: %pn", *p);          // 0x7ffee2b20aa0
    printf("p[0]:%pn", p[0]);       // 0x7ffee2b20aa0
    printf("*p+1:%pn", *p+1);       // 0x7ffee2b20aa4
    printf("*(p+1):%pn", *(p+1));   // 0x7ffee2b20aac
// 二层解引用
    printf("**p:%dn", **p);    // 0
    printf("*p[0]:%dn", *p[0]);      // 0
    printf("*(*p+1):%dn", *(*p+1));  // 1
    printf("**(p+1):%dn", **(p+1));  // 3
    printf("*p[1]:%dn", *p[1]);      // 3
    printf("**(array+1):%dn", **(array + 1));  // 3
    printf("array[1][0]:%dn", array[1][0]);    // 3
    printf("*(*(p+1)+1):%dn", *(*(p+1)+1));    // 4

    return 0;
}

这里p指向array 的第一行,即四个元素的一维数组(因为这就是array 储存的地址信息) p的跨度是 3个int ,于是

  • *p 得到array的第一行一维数组,*p是第一行第一个元素的地址
    • **p得到第一行第一个元素
  • *p 看作一个一维数组p[0],跨度为int + (*p+1) = p[0]+1 得到第一行第二个元素的地址
    • *(*p+1) = *(p[0]+1)得到第一行第二个元素

p+1 指向 array 的第二行

  • *(p+1) 得到数组的第二行一维数组, *(p+1) 是第二行第一个元素的地址
    • **(p+1) 得到第二行的第一个元素
  • *(p+1) 看作一个一维数组p[1],跨度为int
    • *(p+1)+1 = p[1]+1 得到第二行第二个元素的地址
    • *(*(p+1)+1) = *(p[1]+1) 得到第二行第二个元素

36052493f00a2fa4414319b27407efa0.png
int (*p)[3] = array+1   // 指向array的第二行

还可以这样写:

#include <stdio.h>

int main() 
{
    int array[2][3] = {{0, 1, 2},
                       {3, 4, 5}};
    int (*p)[2][3] = &array;
    int i,j;

    for ( i = 0; i < 2; ++i) {
        for ( j = 0; j < 3; ++j) {
            printf("%2d ", *(*(*p+i)+j));
        }
        printf("n");
    }
    return 0;

}

这里p指向这个二维数组,先解引用*p 得到array,后面就是一样的了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值