C语言之 指针与多维数组最强解析

假设有以下声明:

int multiArray [4] [2] 				//声明一个int类型的二维数组

数组名multiArray是该数组首元素( multiArray[0] )的地址
在本例中,multiArray的首元素是一个内含两个int值的数组,所以multiArray是这个内含两个int值的数组的地址。如下图所示:
在这里插入图片描述

#include <stdio.h>
int main(void){
    
    int multiArray[4][2] ={{2,4},{6,8},{1,3},{5,7}};
    
    printf(" multiArray=%p, multiArray+1 =%p \n",multiArray,multiArray+1);
    printf(" multiArray[0]=%p, multiArray[0]+1 =%p \n",multiArray[0],multiArray[0]+1);
    printf(" *multiArray=%p, *multiArray+1 =%p \n",*multiArray,*multiArray+1);
    printf(" multiArray[0][0]=%d \n",multiArray[0][0]);
    printf(" *multiArray[0]=%d\n",*multiArray[0]);
    printf(" **multiArray=%d\n",**multiArray);
    printf(" multiArray[2][1]=%d \n",multiArray[2][1]);
    printf(" *(*(multiArray+2)+1)=%d \n",*(*(multiArray+2)+1));
    
    return 0;
    
}

Output:

 multiArray=0x7ffeefbff540, multiArray+1 =0x7ffeefbff548 
 multiArray[0]=0x7ffeefbff540, multiArray[0]+1 =0x7ffeefbff544 
 *multiArray=0x7ffeefbff540, *multiArray+1 =0x7ffeefbff544 
 multiArray[0][0]=2 
 *multiArray[0]=2
 **multiArray=2
 multiArray[2][1]=3 
 *(*(multiArray+2)+1)=3 

下面我们从指针的属性进一步分析。

1.我们发现,multiArray,multiArray[0], *multiArray的值相同,这是为什么呢??

  • 因为multiArray是数组首元素的地址,所以multiArray的值与&multiArray[0]的值相同。而multiArray[0]本身是一个内含两个整数的数组,所以multiArray[0]的值和它的首元素(一个整数)的地址(即&multiArray[0] [0]的值)相同。 multiArray[0]表示的是第一个数组中第一个元素的地址。
  • 简单而言,multiArray[0]本质就是一个占用一个int大小对象的地址,因为multiArray[0]表示的是第一个数组中第一个元素的地址(注意这里是用了一个方括号,与用两个方括号不同!比如multiArray[0][0]表示的是第一个元素的值),而multiArray是一个占用两个int大小对象的地址,因为multiArray是数组首元素(如文章开始的图所示)的地址。
  • 由于multiArray和multiArray[0]的地址都是各自数组首元素的地址,所以multiArray和multiArray[0]的值相同。
  • 我们知道解引用一个指针(在指针前使用*)或者在数组名后使用带下标的[]运算符,得到引用对象代表的值multiArray 代表该数组首元素( multiArray[0] ) 的值,而 multiArray[0] 本身是一个int类型值的地址,所以*multiArray就是表示该数组首元素的地址值。即,与multiArray,multiArray[0]的值同为multiArray[0][0]的地址值。

2.既然,multiArray,multiArray[0], *multiArray的值相同,为什么multiArray+1,multiArray[0]+1,*multiArray+1的值不同呢???

  • multiArray是一个内含2个int类型值的数组的地址,所以multiArray指向一个8字节的数据对象,因此multiArray+1,它所指向的地址加8字节(十六进制中,38+8=40)
  • 而multiArray[0]指向一个4字节的数据对象,multiArray[0]+1,其值加4(十六进制中,38+4得3c)
  • *multiArray指向一个4字节的数据对象,与multiArray[0]同理,其值相同。

3.为什么multiArray[0][0], *multiArray[0],**multiArray的值相等??

  • 因为对二维数组解引用一次,相当于获取到了一维数组的地址,两次解引用才能得到二维数组的值 可以用*,也可以用[]来解引用。所以multiArray[0][0],*multiArray[0],**multiArray的值都为一个具体的int数值

4.*(*(multiArray+2)+1)=3是什么意思??

  • multiArray ⬅️表示二维数组首元素的地址(每个元素都是内含两个int类型元素的一维数组)
  • multiArray+2 ⬅️表示二维数组的第三个元素的地址
  • *(multiArray+2) ⬅️表示二维数组的第三个元素的首元素的地址
  • *(multiArray+2)+1 ⬅️表示二维数组的第三个元素的第二个元素的地址
  • ((multiArray+2)+1)=3 ⬅️表示二维数组的第三个元素的第二个元素的值,即multiArray[3][2]的值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值