C语言 ——对数组名进行解引用,取地址,还有sizeof和strlen进行操作解析


前言

  1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
  2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
  3. 除此之外所有的数组名都表示首元素的地址。
  4. strlen()是求字符串长度的,关注的是字符串中的\0,计算的是\0之前出现的字符的个数
  5. sizeof()只关注占用内存空间的大小,不在乎内存中放的是什么

一、数组名的理解(一维数组)

数组名表示首元素地址

//一维数组
int main()
{
	int a[] = {1,2,3,4};			初始化四个元素
	printf("%d\n",sizeof(a));		16
	sizeof(a),a表示整个数组,计算的是整个数组的大小,单位是字节。
	
	printf("%d\n",sizeof(a+0));		4/8  (32位或者64)  
	a + 0 == &a[0]+0
	sizeof(a+0),数组名a+0等于首元素+0,结果就是 4/8
	
	printf("%d\n",sizeof(*a));		4
	sizeof(*a) 		*a中的a是数组首元素的地址,*a就是对首元素的地址解引用,找到的就是首元素
	
	printf("%d\n",sizeof(a+1));		4/8
	sizeof(a+1)		首元素 + 1
	
	printf("%d\n",sizeof(a[1]));	4
	sizeof(a[1])   	计算的是下标位1的大小
	
	printf("%d\n",sizeof(&a));		4/8
	sizeof(&a)		&a取出的数组的地址,数组的地址,也就是个地址,数组的地址就是4/8字节,主要是地址就是4/8
	
	printf("%d\n",sizeof(*&a));		16	 
	sizeof(*&a) *&抵消剩下个a
	数组的解引用就是访问整个数组
	&a拿到的是数组名的地址,类型是int(*)[4],是一种数组指针
	数组指针解引用找到的是 *&a ----> a

	printf("%d\n",sizeof(&a+1));	4/8
	&a + 1 是从数组a的地址向后跳过一个(4个整形元素的)数组的大小
	&a + 1 还是地址,是地址就是4/8字节
	
	printf("%d\n",sizeof(&a[0]));	4
	就是首元素元素的地址
	计算的是地址的大小
	
	printf("%d\n",sizeof(&a[0]+1));	4/8
	计算的是第二个元素的地址

	return 0;
}

二、数组名的理解(字符数组)

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = {'a','b','c','d','e','f'};		7个元素(\0)
	printf("%d\n", sizeof(arr));		6
	一个数组1个字节不算\0
	
	printf("%d\n", sizeof(arr+0));		4/8
	sizeof(arr+0)	是数组首元素的地址  是地址在这就是4/8
	
	printf("%d\n", sizeof(*arr));	1
	8arr就是数组首元素,大小是1字节
	*arr == arr[0]
	*(arr+0) == arr[0]
	arr+0就是首元素大小
	printf("%d\n", sizeof(arr[1]));	1
	
	printf("%d\n", sizeof(&arr));4/8	
	&arr是数组的地址,是地址就是4/8
	
	printf("%d\n", sizeof(&arr+1));	4/8
	&arr+1跳过整个数组,指向下个地址,是地址就是4/8
	
	printf("%d\n", sizeof(&arr[0]+1));	4/8
	&arr[0] + 1  是第二个元素的地址
	是地址就是4/8个字节




	strlen
	printf("%d\n", strlen(arr));	随机值
	arr首元素strlen会一直向后跑知道找到\0
	一直往后寻找知道找到\0
	
	printf("%d\n", strlen(arr+0));	还是随机值
	arr+0  还是首元素地址
	
	printf("%d\n", strlen(*arr)); 	strlen('a');--->strlen(97);野指针
	strlrn要传过去地址
	不传地址会报错
	
	printf("%d\n", strlen(arr[1]));	strlen('b');--->strlen(98);野指针
	报错
	
	printf("%d\n", strlen(&arr));	随机值
	
	printf("%d\n", strlen(&arr+1));	随机值-6
	因为跳过一个数组进入下一个数组
	
	printf("%d\n", strlen(&arr[0]+1));	随机值-1
	从下标01开始向后找\0.所以-1
	
	return 0
}

三、数组名的理解(字符串数组)

int main()
{
	char arr[] = "abcdef";	7

	printf("%d\n", sizeof(arr));	7 
	
	printf("%d\n", sizeof(arr+0));	4/8
	arr+0就是首元素地址  只要是地址就是4/8
	
	printf("%d\n", sizeof(*arr));	1
	*arr  arr表示首元素地址  a的解引用得到a
	a就是1一个字节
	
	printf("%d\n", sizeof(arr[1])); 1
	计算下标为1的大小
	
	printf("%d\n", sizeof(&arr));4/8
	是地址就是4/8
	
	printf("%d\n", sizeof(&arr+1));	4/8
	跳过整个数组 指向下一个数组
	
	printf("%d\n", sizeof(&arr[0]+1));	4/8
	这里取的是b的地址   是地址那就是4/8
	
	

	strlen
	
	printf("%d\n", strlen(arr));	6
	
	printf("%d\n", strlen(arr+0));	6
	arr+0首元素+0还是首元素
	
	printf("%d\n", strlen(*arr));	报错
	把首元素地址解引用
	strlen只能传地址
	
	printf("%d\n", strlen(arr[1]));	报错
	
	printf("%d\n", strlen(&arr));	6
	
	printf("%d\n", strlen(&arr+1));	随机
	
	printf("%d\n", strlen(&arr[0]+1));	5
	首元素+1开始计算


	return 0;
}

四、数组名的理解(字符串指针)

int main()
{
	char *p = "abcdef";
	p有自己的空间
	存放的是abcdef的地址

	printf("%d\n", sizeof(p));		4/8
	p是个指针变量,用sizeof来算那就是4/8字节
	
	printf("%d\n", sizeof(p+1));	4/8
	p的地址+1  还是地址,是地址就是4/8字节
	
	printf("%d\n", sizeof(*p));		1
	
	printf("%d\n", sizeof(p[0]));	1
	p[0]-->*(p+0)p本来就是指向首元素的+0等于没加==*p
	
	对一级指针取地址运算就是就相当于二级指针
	printf("%d\n", sizeof(&p));		4/8
	取出的是字符指针的地址 还是地址,只要是地址就是4/8

	printf("%d\n", sizeof(&p+1));	4/8
	地址+1还是地址
	&+1跳过本地址,指向下一个地址

	printf("%d\n", sizeof(&p[0]+1));4/8
	&p[0]+1 指向b的地址	地址就是4/8


	strlen()

	
	printf("%d\n", strlen(p));		6
	p里面放的是a的地址,传给strlen后计算到\0就停止
	
	printf("%d\n", strlen(p+1));	5
	p+1 首地址+1指向第二个字符b 开始计算就是5
	
	printf("%d\n", strlen(*p));		报错
	p存放a 将p解引用就是得到a,然后就报错
	
	printf("%d\n", strlen(p[0]));	报错
	
	printf("%d\n", strlen(&p));		随机值
	&p与abcdef的空间无关什么时候找到\0不知道
	
	printf("%d\n", strlen(&p+1));	随机值
	
	printf("%d\n", strlen(&p[0]+1));	5
	&p[0]已经指向a, +1后指向b,然后计算到\0停止
	

	return 0;
}

五、二维数组

在内存中是一段连续的空间

int main()
{
	//二维数组
	int a[3][4] = {0};
	&a + 1 跳过整个二维数组 


	printf("%d\n",sizeof(a));			3x4x4= 48
	 
	printf("%d\n",sizeof(a[0][0]));		4
	第一行第一列	
	
	printf("%d\n",sizeof(a[0]));		4x4 = 16
	a[0] = 是第一行这个一维数组的数组名,单独放在sizeof内部,a[0]表示第一个整个这个一维数组
	sizeof(a[]0)计算的就是第一行的大小
	
	printf("%d\n",sizeof(a[0]+1)); 		4/8
	a[0]并没有单独放在sizeof内部,也没有取地址,a[0]就表示首元素的地址
	就是第一行这个一维数组的第一个元素的地址,
	a[0]+1计算第一行第二个元素的地址
	
	printf("%d\n",sizeof(*(a[0]+1))); 	4
	a[0]+1是第一行第二个元素
	*(a[0]+1)就是第一行第二个元素
	
	printf("%d\n",sizeof(a+1));			16
	a虽然是二维数组的地址,但是并没有单独放在sizeof内部,也没取地址
	a表示首元素的地址,二维数组的首元素是它的第一行,a就是第一行的地址
	a+1就是跳过第一行,表示第二行的地址
	
	printf("%d\n",sizeof(*(a+1)));		16
	对第二行的地址解引用 就拿到第二行了
	计算的是第二行
	*(a+1) -->  a[1]
	sizeof(*(a+1))--> sizeof(a[1])
	
	printf("%d\n",sizeof(&a[0]+1));		16
	&a[0]-->a[0]在二维数组中表示第一行,取出第一行地址后进行+1
	拿到第二行的地址
	
	printf("%d\n",sizeof(*(&a[0]+1)));	4/8
	对第二行解引用拿到第二行的地址
	但只是拿到了地址
	
	printf("%d\n",sizeof(*a));			16
	a首元素地址
	第一行解引用拿到第一行
	
	printf("%d\n",sizeof(a[3]));		16
	表示第四行的地址sizeof(a[3])进行计算不进行访问
	
	return 0;
}
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值