sizeof和strlen求一维数组、字符数组、二维数组的区别

目录

一、一维数组

二、字符数组1.char arr[] = { 'a','b','c','d','e','f' };

2.char arr[] = "abcdef";

3.char* p = "abcdef";

三、二维数组


在正式开始前我们要明晰几个概念:

1、sizeof和strlen的区别

sizeof是操作符,功能是计算变量类型或变量的大小,单位是字节。

strlen是库函数,功能是求字符串的长度。strlen实现功能的方式是,遍历字符串,每遍历一个元素返回值加1,直到遇见\0停止,返回返回值。

2、数组名所代表的含义

数组名通常情况下表示数组首元素的地址,但有两种特殊情况:

2.1、sizeof(数组名),数组名表示整个数组的地址

2.2、&数组名,数组名表示整个数组的地址

//注意:数组首元素的地址和整个数组的地址在十六进制表示的数值上是相同的,但它们向后走一步的步长却截然不同。数组首元素地址+1,指针向后走,一个数组元素类型大小;整个数组地址+1,指针向后走,数组中所有的元素×数组中元素的类型。

3、指针的大小

32位系统中,指针大小是4;64位系统中,指针大小是8

一、一维数组

int a[] = { 1,2,3,4 };//创建一个数组a,将1,2,3,4放入数组中
printf("%d\n", sizeof(a));//16,sizeof数组名,数组名表示整个数组,数组里面有4个元素,每个元素类型是整型。
printf("%d\n", sizeof(a + 0));//4\8,sizeof(数组名+0),数目名表示首元素的地址,地址加0还是地址,sizeof地址名,求首元素地址的大小
printf("%d\n", sizeof(*a));//4,*a中的a是数组首元素的地址,对首元素地址解引用,求出数组首元素的大小
printf("%d\n", sizeof(a + 1));//4\8,a+1中的a表示数组首元素的地址,地址加1表示跳过一个元素的地址,得到数组第二个元素的地址,求数组第二个元素地址的大小
printf("%d\n", sizeof(a[1]));//4,a[1]表示数组下标为1的元素
printf("%d\n", sizeof(&a));//4\8,&a表示整个数组的地址,求这个地址的大小
printf("%d\n", sizeof(*&a));//16,*&a,先将整个数组的地址取出,在对其解引用操作得到整个数组,数组里面有4个元素,每个元素类型是整型。
printf("%d\n", sizeof(&a + 1));//4\8,&a+1,取出整个数组的地址,加1表示跳过整个数组元素大小个地址,来到下一个地址。求这个地址大小
printf("%d\n", sizeof(&a[0]));//4,将数组下标为0的元素地址取出,求这个地址的大小
printf("%d\n", sizeof(&a[0] + 1));//4,将数组下标为0的元素地址取出,加1表示跳过1个数组元素大小地址,得到下标为1的数组元素的地址。求这个地址的大小

二、字符数组
1.char arr[] = { 'a','b','c','d','e','f' };

1.char arr[] = { 'a','b','c','d','e','f' };//创建一个数组arr,将字符'a','b','c','d','e','f'挡在数组中
printf("%d\n", sizeof(arr));//6,整个数组元素的大小,一共6个元素,数组元素类型是char
printf("%d\n", sizeof(arr + 0));//4\8,数组首元素的地址+1,数组第二个元素的地址
printf("%d\n", sizeof(*arr));//1,对数组首元素的地址解引用操作,得到数组的首元素
printf("%d\n", sizeof(arr[1]));//1,求数组下标为1的元素大小
printf("%d\n", sizeof(&arr));//4\8,取出整个数组的地址,求整个数组地址的大小
printf("%d\n", sizeof(&arr + 1));//4\8,取出整个数组的地址,指针跳过1个整个数组大小个地址,求这个地址的大小
printf("%d\n", sizeof(&arr[0] + 1));//4\8,取出数组下标为0的元素的地址,+1得到下标为1的数组元素的地址
printf("%d\n", strlen(arr));//随机值,数组中不存在\0。strlen得到数组首元素的地址一直往后遍历,直到遇到地址中的值为0停止
printf("%d\n", strlen(arr + 0));//随机值,数组中不存在\0。strlen得到数组首元素+0的地址一直往后遍历,直到遇到地址中的值为0停止
printf("%d\n", strlen(*arr));//错误用法。strlen函数的参数是指针,*arr对数组首元素的地址进行解引用操作,并将其作为地址传递给strlen函数。产生了野指针,strlen函数会从该地址处往后遍历
printf("%d\n", strlen(arr[1]));//错误用法。strlen函数的参数是指针,将数组下标为1的元素作为地址传递给strlen函数。产生了野指针,strlen函数会从该地址处往后遍历
printf("%d\n", strlen(&arr));//随机值,数组中不存在\0。strlen得到整个数组的地址一直往后遍历,直到遇到地址中的值为0停止
printf("%d\n", strlen(&arr + 1));//随机值,数组中不存在\0。strlen得到整个数组的地址,+1跳过整个数组大小个地址一直往后遍历,直到遇到地址中的值为0停止
printf("%d\n", strlen(&arr[0] + 1));//随机值,数组中不存在\0。strlen得到整个数组下标为0的地址,+1跳过一个数组元素大小个地址一直往后遍历,直到遇到地址中的值为0停止

2.char arr[] = "abcdef";

2.char arr[] = "abcdef";//创建一个数组arr,将字符串"abcdef\0"放在arr中,字符串结尾默认含有\0
printf("%d\n", sizeof(arr));//7,求整个数组的大小,数组有7个元素,每个元素为char
printf("%d\n", sizeof(arr + 0));//4\8,求数组首元素的地址+0
printf("%d\n", sizeof(*arr));//1,对数组首元素的地址进行解引用操作,求数组首元素大小
printf("%d\n", sizeof(arr[1]));//1,求数组下标为1的元素大小
printf("%d\n", sizeof(&arr));//4\8,求整个数组地址的大小
printf("%d\n", sizeof(&arr + 1));//4\8,求数组首元素地址+1的地址大小
printf("%d\n", sizeof(&arr[0] + 1));//4\8,求数组下标为0元素地址+1的地址的大小
printf("%d\n", strlen(arr));//6,将数组首元素地址传给strlen
printf("%d\n", strlen(arr + 0));//6,将数组首元素地址+0的地址传给strlen
printf("%d\n", strlen(*arr));//错误用法。strlen函数的参数是指针,*arr对数组首元素的地址进行解引用操作,并将其作为地址传递给strlen函数。产生了野指针,strlen函数会从该地址处往后遍历
printf("%d\n", strlen(arr[1]));//错误用法。strlen函数的参数是指针,将数组下标为1的元素作为地址传递给strlen函数。产生了野指针,strlen函数会从该地址处往后遍历
printf("%d\n", strlen(&arr));//随机值,将整个数组的地址传给strlen,strlen向后遍历,直到遇见\0
printf("%d\n", strlen(&arr + 1));//随机值,将整个数组的地址+1的地址传给strlen,strlen向后遍历,直到遇见\0
printf("%d\n", strlen(&arr[0] + 1));//5,将数组下标为0的地址+1的地址(数组第二个元素的地址)传给strlen

3.char* p = "abcdef";

3.char* p = "abcdef";//创建一个指针,指向常量字符串"abcdef"的首元素的地址
printf("%d\n", sizeof(p));//4\8,求指向常量字符串"abcdef"的首元素的地址的大小
printf("%d\n", sizeof(p + 1));//4\8,求指向常量字符串"abcdef"的首元素的地址+1的大小
printf("%d\n", sizeof(*p));//1,对向常量字符串"abcdef"的首元素的地址进行解引用操作,求常量字符串首元素的大小
printf("%d\n", sizeof(p[0]));//1,p[0]相当于*(p+0)对向常量字符串"abcdef"的首元素的地址+0进行解引用操作,求常量字符串首元素的大小
printf("%d\n", sizeof(&p));//4\8,对指针进行取地址操作,得到二级指针的地址,求二级指针的地址的大小
printf("%d\n", sizeof(&p + 1));//4\8,对指针进行取地址操作,得到二级指针的地址,求二级指针+1的地址大小
printf("%d\n", sizeof(&p[0] + 1));//4\8,对指向数组首元素的地址取地址,得到二级指针的地址,求二级指针+1的地址大小
printf("%d\n", strlen(p));//6,将指向常量字符串"abcdef"的首元素的地址传给strlen
printf("%d\n", strlen(p + 1));//5,将指向常量字符串"abcdef"的首元素的地址+1传给strlen
printf("%d\n", strlen(*p));//错误用法。strlen函数的参数是指针,*p对指向常量字符串"abcdef"的首元素的地址进行解引用操作,并将其作为地址传递给strlen函数。产生了野指针,strlen函数会从该地址处往后遍历
printf("%d\n", strlen(p[0]));//错误用法。strlen函数的参数是指针,将常量字符串"abcdef"首元素作为地址传递给strlen函数。产生了野指针,strlen函数会从该地址处往后遍历
printf("%d\n", strlen(&p));//随机值,将指向常量字符串"abcdef"的首元素的地址的地址传给strlen,strlen函数会从该地址处往后遍历,直到遇见\0
printf("%d\n", strlen(&p + 1));//随机值,将指向常量字符串"abcdef"的首元素的地址的地址+1传给strlen,strlen函数会从该地址处往后遍历,直到遇见\0
printf("%d\n", strlen(&p[0] + 1));//5,将常量字符串"abcdef"的首元素的地址+1传给strlen

三、二维数组

int a[3][4] = { 0 };//创建一个3行4列的二维数组,将里面的所有元素初始化为0
printf("%d\n", sizeof(a));//48,求整个数组元素的大小。数组一共12个元素,每个元素为int
printf("%d\n", sizeof(a[0][0]));//4,求数组行下标为0,列下标为0的元素的大小
printf("%d\n", sizeof(a[0]));//16,a表示数组首元素的地址,二维数组的首元素是行下标为0的一维数组。a[0]相当于*(a+0),对行下标为0的一维数组地址+0的地址,进行解引用操作,得到行下标为0的一维数组。求这个一维数组的大小,数组里面有4个元素,每个元素为int
printf("%d\n", sizeof(a[0] + 1));//4\8,根据上一个判断可知,a[0]相当于二维数组里面行下标为0的一维数组的数组名。数组名等于数组首元素的地址,+1相当于a[0]数组中第二个元素的地址。求a[0]数组中第二个元素地址的大小
printf("%d\n", sizeof(*(a[0] + 1)));//4,对数组a[0]中第二个元素的地址解引用操作,求该元素的大小
printf("%d\n", sizeof(a + 1));//4\8,数组名相当于数组首元素的地址,二维数组首元素的地址是行下标为0的一维数组的地址,+1指针向后走一个一维数组大小个地址。求二维数组中行下标为1的数组的整个数组的地址大小
printf("%d\n", sizeof(*(a + 1)));//16,对二维数组中行下标为1的数组的整个数组进行解引用操作,求二维数组中行下标为1的数组的大小
printf("%d\n", sizeof(&a[0] + 1));//4\8,取出二维数组中行下标为0的数组的整个数组的地址,+1指针向后走一个整个行数组大小个地址的地址。求二维数组中行下标为1的整个数组的地址的大小
printf("%d\n", sizeof(*(&a[0] + 1)));//16,对二维数组中行下标为1的整个数组的地址进行解引用操作,得到二维数组中行下标为1的数组,求二维数组中行下标为1的数组的大小
printf("%d\n", sizeof(*a));//16,对二维数组中行下标为0的整个数组的地址进行解引用操作,求二维数组中行下标为0的数组的大小
printf("%d\n",sizeof(a[3]));//4\8,a[3]相当于*(a+3),表示指向二维数组行下标为0的整个数组的地址的指针,往后走3个整个数组地址大小个地址,求这个地址的大小


 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ljiyu0506

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值