指针和数组的sizeof和strlen举例解析

宗旨

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

  4. 举例

  • 一维数组

int a[] = {1,2,3,4};
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(a+0));
printf("%d\n",sizeof(*a));
printf("%d\n",sizeof(a+1));
printf("%d\n",sizeof(a[1]));
printf("%d\n",sizeof(&a));
printf("%d\n",sizeof(*&a));
printf("%d\n",sizeof(&a+1));
printf("%d\n",sizeof(&a[0]));
printf("%d\n",sizeof(&a[0]+1));
  1. sizeof(a):即第一种情况,是整个数组的大小,4个int型,一个int大小为4byte,共16字节。
  2. sizeof(a+0):此处注意要与第一种情况区别只能表示首元素地址,既然是地址则可能为4/8字节(32位下是4字节,64位下是8字节)。

  3. sizeof(*a):表示首元素大小,为4字节。
  4. sizeof(a+1):与第二种情况相似表示第二个元素的地址,大小为4/8字节。
  5. sizeof(a[1]):与第三种情况相似,表示数组的第二个元素,大小为4。
  6. sizeof(&a):表示整个数组的地址,也是地址,大小为4/8字节。
  7. sizeof(*&a):可以理解为&和*相互抵消,与第一种情况相同,即整个数组的大小,或理解为&a是int(*)[4]类型的数组指针,如果解引用,访问的就是4个int的数组,大小是16个字节。
  8. sizeof(&a+1):表示跨过整个数后的地址,是地址就是4/6.
  9. sizeof(&a[0]):表示取出第一的元素的地址。

总结:

  1. sizeof只关注占空间大小,单位是字节
  2. sizeof不关注类型
  3. sizeof是操作符

    字符数组

sizeof

char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr+0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr+1));
printf("%d\n", sizeof(&arr[0]+1));
  1. sizeof(arr):arr作为数组名单独放在sizeof中,计算整个数组的大小,为6字节。
  2. sizeof(arr+0):arr就是首元素地址,地址大小就是4/8.
  3. sizeof(*arr):表示首元素大小,为1字节。
  4. sizeof(arr[1]):表示第二个元素,大小为1字节。
  5. sizeof(&arr):取出了数组的地址,地址就是4/8字节。
  6. sizeof(&arr+1):跳过了整个数组,还是地址,大小为4/8.
  7. sizeof(&arr[0]+1):表示第二个元素的地址,地址就是4/8.

strlen

char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr+0));
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr+1));
printf("%d\n", strlen(&arr[0]+1));
  1. strlen(arr):因为末尾没有\0,所以是随机值。
  2. strlen(arr+0):与上一个相同,随机值。
  3. sizeof(*arr):表示第一个元素,大小为1字节。
  4. sizeof(arr[1]):表示第二个元素,大小为1字节。
  5. sizeof(&arr):表示整个数组的地址,是地址大小就是4/8.
  6. sizeof(&arr+1):表示跨过整个数组位置的地址,大小为4/8.
  7. sizeof(&arr[0]+1):表示第二个元素的地址,大小为4/8.

sizeof

char *p = "abcdef";
printf("%d\n", sizeof(p));
printf("%d\n", sizeof(p+1));
printf("%d\n", sizeof(*p));
printf("%d\n", sizeof(p[0]));
printf("%d\n", sizeof(&p));
printf("%d\n", sizeof(&p+1));
printf("%d\n", sizeof(&p[0]+1));
  1. sizeof(p):计算指针变量的大小,4/8字节。
  2. sizeof(p+1):下一个char位置的地址,大小为4/8.
  3. sizeof(*p):访问的是一个字节。
  4. sizeof(p[0]):p[0]<==>*(p+0),一个字节。
  5. sizeof(&p):二级指针也是指针,4/8字节。
  6. sizeof(&p+1):在内存中跳到p指针后一个地址,已经与数组无关,但也是地址大小为4/8.
  7. sizeof(&p[0]+1):p[0]是‘a’,&后为此处地址,加1是下一个元素‘b’的地址,是地址就是4/8.

strlen

char* p = "abcdef";
printf("%d\n", strlen(p));
printf("%d\n", strlen(p+1));
printf("%d\n", strlen(*p));
printf("%d\n", strlen(p[0]));
printf("%d\n", strlen(&p));
printf("%d\n", strlen(&p+1));
printf("%d\n", strlen(&p[0]+1));

1.strlen(p):p指向字符串首地址,strlen会从a开始一直读到'\0',即字符串的长度,为6.

2.p+1会指向b,从此处开始向后一共5个字符,长度为5

3.*p表示字符a对应的ASCII码值,放入strlen表示从0X00000061地址处一直读到\0,但没有访问权

会进行如下报错。

 4.p[0]==*(p+0),所以与3结果相同。

5.此处易错,p仅仅是指向字符串,&p之后将与数组无关,strlen会一直从p自己的位置一直往后读到'\0',此处结果为随机值。

6.与5相似,只不过结果会比5的结果小1.

7.先进行解引用在进行取地址,表示‘a'的地址,+1即从b开始向后,长度为5.


二维数组

int a[3][4] = {0};
printf("%d\n",sizeof(a));//1
printf("%d\n",sizeof(a[0][0]));//2
printf("%d\n",sizeof(a[0]));//3
printf("%d\n",sizeof(a[0]+1));//4
printf("%d\n",sizeof(*(a[0]+1)));//5
printf("%d\n",sizeof(a+1));//6
printf("%d\n",sizeof(*(a+1)));//7
printf("%d\n",sizeof(&a[0]+1));//8
printf("%d\n",sizeof(*(&a[0]+1)));//9
printf("%d\n",sizeof(*a));//10
printf("%d\n",sizeof(a[3]));//11

1.数组名单独放在sizeo内部表示整个数组的大小,3*4*4=48byte。

2.表示第第一行第一个元素的大小为4.

3.a[0]表示第一行的数组名,作为数组名单独放在sizeof内部表示整个数组的大小=16byte。

4.a[0]作为数组名没有单独放在sizeof内部,就是首元素地址,a[0]+1就是第二行地址,是地址就是4/8.

5.表示第一行第二个元素的大小=4.

6.a没有单独放在sizeof内部,a就是首元素地址,即第一行的地址,a+1是第二行的地址,是类型为int(*)[4]的指针数组,是地址就是4/8.

7.*(a+1)就是第二行的数组名,相当于a[1],sizeof( a[1] )大小为16byte。

8.a[0]是第一行,&a[0]是第一行的地址,&a[0]+1是第二行的地址,地址就是4/8.

9.第二行的地址解引用就是第二行 也就是a[1],大小是16byte.

10.a是二维数组数组名,没有&,没有单独在sizeof内部,a表示首元素地址,*a是二维数组的首元素,也就是第一行,=16byte。

11.感觉a[3]越界了,但它依然表示一个大小为int[4]的元素,=16byte。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值