指针进阶(3) -- 关于sizeof和strlen的详细总结(中)

简介: 指针进阶(3) -- 关于sizeof和strlen的详细总结(中)

char arr[]={'a','b','c','d','e','f'}的strlen的使用

#include<string.h>
int main()
{
  char arr[] = { 'a','b','c','d','e','f'};
  printf("%d\n", strlen(arr));//随机值,因为不知道\0的位置
  printf("%d\n", strlen(arr + 0));//随机值
  printf("%d\n", strlen(*arr));//非法访问
  printf("%d\n", strlen(arr[1]));//'b' - 98当成地址,形参非法访问
  printf("%d\n", strlen(&arr));//随机值
  printf("%d\n", strlen(&arr + 1));//随机值 - 6 
  printf("%d\n", strlen(&arr[0] + 1));//随机值 - 1
    return 0;
}


1.strlen(arr)

数组名没有单独放在sizeof内部,因为这是strlen,这时就从第一个元素'a'这个地址开始统计,直到遇到'\0'的地址停止,但是这个数组没有存'\0',所以'\0'的地址在内存中的位置是随机存放的,所以结果是随机值

运行结果:

7a1522de9cbb491d914ce8b60cedee7b.png

2.strlen(arr + 0)

没有取值地址,没有单独放在sizeof内部,+0还是指向'\a'位置,所以结果还是随机值

运行结果:

93feb84153bb46eb92975d5546d2fd8c.png

3.strlen(*arr)

*arr得到了首元素'a',对应的ascll码值是 -- 97,是整型类型,而strlen的参数必须是 char*  类型,

所以就是非法访问了

运行结果:

875c60e32ad84bbeb5b1e503a8f50397.png


4.strlen(arr[1])

数组第二个元素,也就是'b',其对应的ascll码值为98,非法访问

运行结果:

11a201a39e194ddeb0370b63168f8de4.png


关于1和2点以下图解:

5b574258b80e4b4ab3ab7a05954b895e.png

39fe4bf1b42c47e1a45a1cfa546c993d.png

strlen的参数必须是 char*  类型

5.strlen(&arr)

数组的地址,跟1和2点的值是一样的,随机值

运行结果:

38861703724c40a5968d0e10aaf9f770.png

6.strlen(&arr + 1)

随机值- 6

运行结果:

c8aa19f6920c4424b8d810b910b2686a.png

7.strlen(&arr[0] + 1)

随机值 -  1

运行结果:

37b7fc6e2f0a4d8597c44b57d4a0f026.png


字符串的sizeof和strlen


char arr="abcdef"的sizeof的使用

前提:

sizeof会根据数据类型进行计算

特殊:

'\0'这个放进去数组里面,如果是字符数组,那它的字节大小就是1,如果是整型数组那它的字节大小就是4

也就是说,无论里面放什么类型的数据,sizeof的统计是按数组的大小去统计的,不关心数据类型

图解:

3d9cd0f4767042a4b7c7cd444325aba7.png

int main()
{
  char arr[] = "abcdef";
  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));
 return 0;
}

1.sizeof(arr)

统计结果整个数组大小:7

运行结果:

592c1e38816740d0972e09819d59332e.png

2.sizeof(arr + 0)

arr+0是首元素地址,是地址大小为4/8

运行结果:

5f426c1f13a74cc3bcbf1ca6f5efd3f5.png

3.sizeof(*arr)

字符数组第一个元素大小:1

arr[0] ==*arr== *(arr+0)

计算数组大小另一种方式:

总数/首元素:  int sz= sizeof(arr)/sizeof(*arr) <==> sizeof(arr)/sizeof(arr[0])

运行结果:

29c950b6c7d34ba0b77a9c35bbc051e3.png

4. sizeof(arr[1])

字符数组第二个元素大小:1

运行结果:

f980f626356c409dab0587b6290fe4fd.png


5.sizeof(&arr)

数组的地址,是地址就是4/8byte

运行结果:

686a0c3f990a495eb503fecc20483b08.png

6.sizeof(&arr + 1)

跳过一个数组,依然是地址,大小4/8byte

运行结果:

5c30504820784212bd201ead82e18c7b.png

1817c93cf49b48e6ad5b6930039a8274.png

7. sizeof(&arr[0] + 1)

字符数组第二个元素地址,4/8字节

运行结果:

a0423ef9ebe648779aa39f69d0ac7de6.png

sizeof(字符串) 与 sizeof ( 数组 )的区别

区别:字符串比字符数组存储时要多一个'\0'


sizeof(字符串):

char arr[] = "abcdef";
printf("%d\n", sizeof(arr));


ad8b5fef483f4e8daf40933a6adc6b44.png

双引号会在尾部自动添加转义字符'\0',即数据0X00,所以结果是7

双引号作用: (1)字符串尾部加0, (2)开辟内存空间, (3)提取地址


sizeof ( 数组 ):

791bd122c81742d484e71009888c6a29.png

返回数组的大小,因为arr1[]没有写入数字,所以就按照字符个数统计

下面是[]写入数据的情况:

sizeof ( 数组 ):

char arr[50] = { 'a','b','c','d','e','f' };
printf("%ld", sizeof(arr));

7cf991bb12fa40db99becec04f31f37c.png

因为数组的下标长度是50,所以返回数组总字节大小


char arr="abcdef"的strlen的使用

int main(){
   char arr[] = "abcdef";
  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));
return 0;
}


1.strlen(arr)

数组名没有单独放在sizeof内部,这是strlen,所以表示为数组首元素地址

运行结果:

ba381d048d5d4aa7b09ae8f484bab0eb.png

2.strlen(arr + 0)

没有距离上的跨越,依旧是数组首元素地址,

运行结果:

c8f72d56e9f44ae68d7e49a3e1166e41.png

3.strlen(*arr)

数组第一个元素'a',strlen需要的是地址,错误

运行结果:

896db459de0a44f6af1472956de55aeb.png

4.strlen(arr[1])

数组第二个元素'b',strlen需要的是地址,错误

运行结果:

19be7904d02d4df0a5e807e1e6b3f15f.png

5.strlen(&arr)

会报出警告:这里的&arr取出的地址所用的指针类型是 char(*)[7]

然而strlen的参数类型是const char*

不影响使用,strlen会转化成它所适配的类型

运行结果:

5daebc30d56742b59dafe60fec7d13ca.png

6.strlen(&arr + 1)

跳过了一个数组,注意是连'\0'也跳过了,那就是随机值了

运行结果:

10413a2d64684e6d95d230cc8049ab4f.png

1817c93cf49b48e6ad5b6930039a8274.png

7.strlen(&arr[0] + 1)

看上图,数组第二个元素地址,向后数到'\0',5个数

运行结果:

ca88cfbdca794bc18ca4333003cf88c9.png

相关文章
|
6月前
|
C语言
指针进阶(C语言终)
指针进阶(C语言终)
|
2月前
|
Serverless 编译器 C语言
【C语言】指针篇- 深度解析Sizeof和Strlen:热门面试题探究(5/5)
【C语言】指针篇- 深度解析Sizeof和Strlen:热门面试题探究(5/5)
|
6月前
|
C语言
指针进阶(回调函数)(C语言)
指针进阶(回调函数)(C语言)
|
6月前
|
存储 C语言 C++
指针进阶(函数指针)(C语言)
指针进阶(函数指针)(C语言)
|
6月前
|
编译器 C语言
指针进阶(数组指针 )(C语言)
指针进阶(数组指针 )(C语言)
|
6月前
|
搜索推荐
指针进阶(2)
指针进阶(2)
52 4
|
6月前
指针进阶(3)
指针进阶(3)
45 1
|
6月前
|
C++
指针进阶(1)
指针进阶(1)
47 1
|
6月前
|
Java 程序员 Linux
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
52 0
|
6月前
|
存储 安全 编译器
C++进阶之路:探索访问限定符、封装与this指针的奥秘(类与对象_上篇)
C++进阶之路:探索访问限定符、封装与this指针的奥秘(类与对象_上篇)
47 0