C语言之a,a+1,a[0],a[0][0],&a,&a[0],&a[0][0],*a,*(a[0]),*(a[0][0]),*(a[0]+1)...等等地址与数组元素的关系

最近我做了一些指针数组笔试题,感觉地址和数组元素的关系非常的冗杂,所以我打算整理一下,这篇文章我会先做一些总结,后续的文章会将面试题一一奉上,那我们现在进入正文。

第一点,最基础的结论

1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
2. & 数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
3. 除此之外所有的数组名都表示首元素的地址。

明白以上两种特殊情况,我们可以知道出第一,二点的内容,其他地方我们将数组名理解为首元素的地址,但是这其中又有区别,下面我们以二维数组为例:

#include <stdio.h>
int main()
{
	//二维数组
	int a[3][4] = { 0 };
	printf("%d\n", sizeof(a));
	printf("%d\n", sizeof(a[0][0]));
	printf("%d\n", sizeof(a[0]));
	printf("%d\n", sizeof(a[0] + 1));
	printf("%d\n", sizeof(*(a[0] + 1)));
	printf("%d\n", sizeof(a + 1));
	printf("%d\n", sizeof(*(a + 1)));
	printf("%d\n", sizeof(&a[0] + 1));
	printf("%d\n", sizeof(*(&a[0] + 1)));
	printf("%d\n", sizeof(*a));
	printf("%d\n", sizeof(a[3]));
	return 0;
}

在此,我们先讨论第三中情况(除此之外数组名表示首元素的地址),其他的内容请见下篇文章。

printf("%d\n",sizeof(a));
printf("%d\n",sizeof(a[0][0]));
printf("%d\n",sizeof(a[0]));
printf("%d\n",sizeof(a[0][0]+1));
printf("%d\n",sizeof(a[0]+1));

 前三种情况,代表的都是二维数组首元素的地址,但又在地址的范围上有所区别:

a+1则表示跳过这个二维数组第一行首元素地址之后的地址,即第二行首元素的地址;

a[0]+1表示跳过这个二维数组第一行之后的地址,即第二行的地址;

a[0][0]表示跳过第一行第一个元素的地址,即第二个元素的地址;

那么将这三个结论与上面三个结论结合起来,我们应对这种类型题也就有迹可循了。

那么我们就来尝试一下这些结论:

​
#include <stdio.h>
int main()
{
	int a[3][2] = { (0, 1), (2, 3), (4, 5) };//中间是用逗号表达式,从左到右,输出为最后一个值
	int* p;
	p = a[0];
	printf("%d", p[0]);
	return 0;
}

​

在这里有一个三行两列二维数组,且初始化部分是用逗号表达式,故只有三个元素;

创建一个指针变量p;

将a[0]的地址放到指针变量p里面,这时候a[0]表示的是第一行第一个元素的地址,幅度是一行;

那么输出p[0],p[0]等价于*(p+0),即*p,又考虑到指针变量p的类型是int*,所以解引用之后,

我们得到第一行第一个元素。

那么说到这里就有一个问题:这不是没啥区别吗?

那么我将代码改一下:

​
#include <stdio.h>
int main()
{
	int a[3][2] = { (0, 1), (2, 3), (4, 5) };//中间是用逗号表达式,从左到右,输出为最后一个值
	int* p;
	p = a[1];
	printf("%d", p[0]);
	return 0;
}

​

将a[0] -> a[1],如果没有以上的对于地址幅度的理解,我们可以会得出答案是:3

但实际上,答案是:5

 以上是我今天的分享,谢谢你们的观看。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值