c语言二维数组与指针的关系

今天写代码用到了二维数组,

int **p;
int a[3][2];
p=a;

发现是不对的,那对于二维数组我应该怎么与指针建立联系呢,仔细研究了一下发现挺有意思的,又加深了我对于指针的理解

  1. 二维数组的数组名是不是指针,里面存放的是谁的地址?
    看下面的代码
#include<stdio.h>
#include<stdlib.h>
int main(){
    int a[4][2]={{1,2},{3,4},{5,6},{7,8}};
    printf("a的值   %d\n",a);
    printf("&a[0]的值  %d\n",&a[0]);
    printf("a[0]的值  %d\n",a[0]);
    printf("&a[0][0]的值   %d\n",&a[0][0]);
}

在这里插入图片描述
我们发现这些值都是相同的,那说明二维数组名是一个指针,里面存放的是a[0][0]的地址
但是&a[0]为什么与a[0]的值相同呢?
我们再看

#include<stdlib.h>
int main(){
     int **p;
      int a[3][5]={{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15}};
      p=a;
}

在这里插入图片描述
程序可以运行但是返回一个warning,
assignment from incompatible pointer type
意思是来自不兼容指针类型的赋值
我们修改一下

#include<stdlib.h>
int main(){
     int *p;
      int a[3][5]={{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15}};
      p=a;
}

运行后发现还是有这个warning,意思是说,a代表一个指针,但是这个指针和指针p或者二级指针p类型都是不一样的,我们再来看

#include<stdio.h>
#include<stdlib.h>
int main(){
      int a[3][5]={{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15}};
      printf("a  %d       &a[0][0] %d\n",a,&a[0][0]);
      printf("a+1  %d       &a[0][0]+1  %d\n",a+1,&a[0][0]+1);
      printf("*a+1  %d       &a[0][0]+1  %d\n",*a+1,&a[0][0]+1);
}

在这里插入图片描述
我们可以发现,都执行加1操作,但是移动的地址是不一样的,对于a来说,我+1,但是地址加了20(4*5=20)
所以说,虽然a与&a[0][0]的值相同,但是a指向的是一行,每次加减都是20个字节。可以这么理解,指针存放的是地址,相同类型的指针必须存放相同类型的地址,
除了 double *p 与int *p这样的区别外,还有同样是int 但是有的地址表示的是20个字节为一个整体的地址,有的呢表示的是四个字节为整体的地址。
所以说int a[3][5]; =>int[5] a[3]; 令type为int [5],所以int[5] a[3]为type a[5],这说明,a是一个一维数组,有3个元素;每个元素是type,即int [5]类型的。

  1. 那我们如何使用指针呢

有两种方式
1.

# include <stdio.h>
int main(void)
{
    int a[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
    int i, j;
    int *p = &a[0][0];  //把a[0][0]的地址赋给指针变量p
    for (i=0; i<3; ++i)
    {
        for (j=0; j<4; ++j)
        {
            printf("%d\n", *(p+i*4+j));
        }
        printf("\n");
    }
    return 0;
}
# include <stdio.h>
int main(void)
{
    int a[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
    int i, j;
    int (*p)[4] = a;  //记住这种定义格式
    for (i=0; i<3; ++i)
    {
        for (j=0; j<4; ++j)
        {
            printf("%d\n", *(*(p+i)+j)); 
        }
        printf("\n");
    }
    return 0;
}

有些是看别人的才明白,大家也可以看大佬的理解理解
感谢
感谢

  • 12
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值