C语言二级指针和二维数组

一、原理

看一下这个C代码输出什么?

#include <stdio.h>
int main()
{
    int array[5][4] ={{1,2,3,4},{11,12,13,14},{21,22,23,24},{31,32,33,34},{41,42,43,44}};
    int** p = array;
    printf("%d\n",*p);
    printf("%d\n",array[0][0]);
    return 0;
}
  • array 是一个二级数组
  • p 是一个指针
    在这里插入图片描述
    可以看出:

int (p)[3] 中 p 指向一个位长度为 3sizeof(int) 的int数组,
int *p 中 p 指向一个位长度为sizeof(int) 的int指针。

array 从数值上来说是一个地址,这个地址是二维数组的首地址。

  • p = array

实例代码

int b = 120;
int *p1 = &b;
int** p = &p1;
printf("%d\n",**p);

这个示例就是我上面二级指针的图示对应。

这个程序输出多少呢?

我们知道array 我们就把它当成一个地址

那么 p 就是把p这个地址的值给取出来,array是数组的首地址,那么p 应该就可以取到二维数组首元素的值。

所以输出应该是

1
1

二、实例分析

#include <stdio.h>
int main()
{
    int array[5][4] ={{1,2,3,4},{11,12,13,14},{21,22,23,24},{31,32,33,34},{41,42,43,44}};
    int** p = array;
    printf("%d\n",*(p+1));
    printf("%d\n",array[0][0]);
    return 0;
}

这个代码输出什么?

直接分析一下,p 的类型是 int** ,p +1 ,它跳过的地址大小应该是

sizeof(int*)

所以

*(&array + sizeof(int*)) 
sizeof(int*) = 8

那就应该是输出:

3
1

为了验证上面,我们的代码修改如下:

#include <stdio.h>
int main()
{
    int array[5][4] ={{1,2,3,4},{11,12,13,14},{21,22,23,24},{31,32,33,34},{41,42,43,44}};
    int** p = array;
    printf("sizeof(int*):%d\n",sizeof(int*));
    printf("%d\n",*(p+1));
    printf("%d\n",array[0][0]);
    return 0;
}

结果:

sizeof(int*):8
3
1

那怎么用一个指针来指向一个二维数组呢?

其实不管是多少维度的数组,它都是直尺,一直变长的直尺,我们把二维数组说成长宽之类的,都是为了方便我们理解。

也可以用一个一维的指针指向一个二维数组

#include <stdio.h>
int main()
{
    int array[5][4] ={1,2,3,4,11,12,13,14,21,22,23,24,31,32,33,34,41,42,43,44};
    int* p = array;
    printf("%d\n",*(p+1));
    printf("%d\n",array[0][0]);
    return 0;
}

结果:

2
1

也可以用二维指针来指向二维数组

#include <stdio.h>
int main()
{
    int array[5][4] ={1,2,3,4,11,12,13,14,21,22,23,24,31,32,33,34,41,42,43,44};
    int(*p)[4]= &array[0];
    printf("%d\n",*(*(p+0)+0));
    printf("%d\n",*(*(p+0)+1));
    printf("%d\n",*(*(p+1)+0));
    printf("%d\n",*(*(p+1)+1));
    printf("%d\n",array[0][0]);
    return 0;
}

结果:

1
2
11
12
1

或者:

#include <stdio.h>
int main()
{
    int array[5][4] ={1,2,3,4,11,12,13,14,21,22,23,24,31,32,33,34,41,42,43,44};
    int(*p)[4]= &array[0];
    printf("%d\n",(*p)[0]);
    printf("%d\n",(*p)[1]);
    printf("%d\n",(*p)[2]);
    printf("%d\n",(*p)[3]);
    p++;
    printf("%d\n",(*p)[0]);
    printf("%d\n",(*p)[1]);
    printf("%d\n",(*p)[2]);
    printf("%d\n",(*p)[3]);
    printf("%d\n",array[0][0]);
    return 0;
}

结果:

1
2
3
4
11
12
13
14
1

或者:

#include <stdio.h>
int main()
{
    int array[5][4] ={1,2,3,4,11,12,13,14,21,22,23,24,31,32,33,34,41,42,43,44};
    int(*p)[4]= &array[0];
    printf("%d\n",(*p)[0]);
    printf("%d\n",(*p)[1]);
    printf("%d\n",(*p)[2]);
    printf("%d\n",(*p)[3]);
    printf("%d\n",(*p)[4]);
    printf("%d\n",(*p)[5]);
    printf("%d\n",(*p)[6]);
    printf("%d\n",(*p)[7]);
    printf("%d\n",array[0][0]);
    return 0;
}

结果:

1
2
3
4
11
12
13
14
1
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值