详解数组名与数组


前言

先提前把总结内容放在前面:
①sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
②&数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
③除此之外的所有数组名表示的都是首元素的地址。

一、一维数组

//一维数组
	int a[] = { 1,2,3,4 };
	printf("%d\n", sizeof(a));//这里是整个数组的字节大小
	printf("%d\n", sizeof(a+0));//进行运算,这里是数组的首元素地址的字节大小
	printf("%d\n", sizeof(*a));//*a为int类型,其字节大小还是指针的字节大小(4/8)
	printf("%d\n", sizeof(a[1]));//等价*(a+1),为int类型,四个字节
	printf("%d\n", sizeof(&a));//取出的数组地址,为int(ptr*)[4],是一个数组指针,大小还是4/8字节
	printf("%d\n", sizeof(&a+1));//数组指针加一还是指针,只是跳过类型决定的字节数,其字节大小还是4/8
	printf("%d\n", sizeof(&a[0]+1));//取出首元素地址加一,与a[1]等价

运行结果:

在这里插入图片描述

二、字符数组

//一维数组
	int a[] = { 1,2,3,4 };
	printf("%d\n", sizeof(a));//这里是整个数组的字节大小
	printf("%d\n", sizeof(a+0));//进行运算,这里是数组的首元素地址的字节大小
	printf("%d\n", sizeof(*a));//*a为int类型,其字节大小还是指针的字节大小(4/8)
	printf("%d\n", sizeof(a[1]));//等价*(a+1),为int类型,四个字节
	printf("%d\n", sizeof(&a));//取出的数组地址,为int(ptr*)[4],是一个数组指针,大小还是4/8字节
	printf("%d\n", sizeof(&a+1));//数组指针加一还是指针,只是跳过类型决定的字节数,其字节大小还是4/8
	printf("%d\n", sizeof(&a[0]+1));//取出首元素地址加一,与a[1]等价
	
	//字符数组
	char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\n", sizeof(arr));//计算整个数组大小,1*6个字节
	printf("%d\n", sizeof(arr+0));//等价&(arr[0]),为首元素地址
	printf("%d\n", sizeof(*arr));//等价arr[0],char类型,大小为一个字节
	printf("%d\n", sizeof(&arr));//为数组指针,char (ptr*)[6],为4/8个字节
	//字符串
	char str[] = "abcdef";
	printf("%d\n", sizeof(str));//整个数组的大小,7*1=7个字节(末尾有'\0')
	printf("%d\n", sizeof(str+0));//首元素地址
	printf("%d\n", strlen(str));//计算字符串长度,为6
	printf("%d\n", strlen(str + 1));//str表示首元素地址,即从b开始计数,为5
	printf("%d\n", strlen(*str));//视a的ASCILL值97为地址,开始访问,最终结果为随机值(要注意的是,这里属于非法访问,运行时会报错)
	printf("%d\n", strlen(&str));//与str等价(strlen只需要一个起始地址,不论类型)
	printf("%d\n", strlen(&str + 1));//起始地址跳过一个char(ptr*)[6],结果是随机值
	printf("%d\n", strlen(&str[0] + 1));//起始地址为str[1]
	

三、二维数组

//二维数组
	int a[3][4] = { 0 };
	printf("%d\n", sizeof(a));//计算整个数组的大小,3*4*4=48
	printf("%d\n", sizeof(a[0][0]));//计算第一个元素类型字节大小,int型为4个字节
	printf("%d\n", sizeof(a[0]));//a[0]相当于第一行数组名,等价于*(a+0),计算第一行数组大小
	printf("%d\n", sizeof(a[0] + 1));//数组名加1,等价于第一行第二个元素地址
	printf("%d\n", sizeof(*(a[0] + 1)));//等价a[0][1]
	printf("%d\n", sizeof(a + 1));//a进行运算,等价于&a[1],即第二行数组地址
	printf("%d\n", sizeof(*(a + 1)));//与a[1]等价,即第二行首元素地址
	printf("%d\n", sizeof(&a[0] + 1));//第二行数组地址,等价与&a[1]
	printf("%d\n", sizeof(*(&a[0] + 1)));//计算第二行数组大小,等价a[1]
	printf("%d\n", sizeof(*a));//计算第一行数组大小,等价a[0]
	printf("%d\n", sizeof(&a[3]));//取出的是第三行数组的地址,所以还是指针的字节大小(sizeof不管越界,自动推测类型)

二维数组总结:
①对二维数组数组名解引用等价arr<==>(arr+0)<>arr[0]
②二维数组首元素加数字,等价arr+1<
>&arr[1],即第二行数组地址,是一个数组指针
③*(arr+1)<==>*&arr[1],即为arr[1],第二行首元素地址(也可看做是第二行数组名)

四、经典例题

笔试题1.

int main()
{
    int a[5] = { 1, 2, 3, 4, 5 };
    int *ptr = (int *)(&a + 1);
    printf( "%d,%d", *(a + 1), *(ptr - 1));
    return 0;
}
//程序的结果是什么?`

在这里插入图片描述

即答案为2,5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值