🎁🎁创作不易,关注作者不迷路🎀🎀
前言
本章将详解strlen与sizeof(),几乎覆盖到与之对应所有相关重难点,不管您是编程小白,还是行业大佬,相信阅读过后对您有一定启发。如果您有任何不懂的地方,欢迎您将疑惑点置于评论区,让更多人看到,一起讨论或许是不错的解决办法哟,当然也欢迎您私信我,看到后也将为您详细解答,能够帮助到他人是我莫大的荣幸。如果您觉得作者写得不错,抑或对您有所帮助,不妨给俺点个免费的赞和玩玩呢? 关注俺不迷路,后续将有更多原创内容更新哟
一、两者的定义
1.sizeof和strlen的对⽐
sizeof()
sizeof 计算变量所占内存内存空间⼤⼩的,单位是字节,如果操作数是类型的话,计算的是使⽤类型创建的变量所占内存空间的⼤⼩。
sizeof 只关注占⽤内存空间的⼤⼩,不在乎内存中存放什么数据。
strlen()
strlen 是C语⾔库函数,功能是求字符串⻓度。函数原型如下:
size_t strlen ( const char * str ); 一定要注意其参数是字符类型的指针
统计的是从 strlen 函数的参数 str 中这个地址开始向后, '\0' 之前字符串中字符的个数。strlen 函数会⼀直向后找 \0 字符,直到找到为⽌,所以可能存在越界查找。
2.sizeof()和strlen()的对⽐
sizeof() | strlen() |
1. sizeof是操作符 2. sizeof计算操作数所占内存的⼤⼩,单位是字节 3. 不关注内存中存放什么数据 | 1. strlen是库函数,使⽤需要包含头⽂件 string.h 2. srtlen是求字符串⻓度的,统计的是 \0 之前字符的个数 3. 关注内存中是否有 \0 ,如果没有 \0 ,就会持续往后找,可能会越界 |
二、就重难点与易错的点播
在此知识点的考察中,数组名是重点考察对象。
在多数情况下,可以认为数组名就是数组首元素的地址,但排除以下两种情况:
sizeof(arr) | 表示的是整个数组 |
&arr | 表示的是整个数组的地址 |
三、题例分析
1.一维数组
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a+0));
printf("%d\n",sizeof(*a));
printf("%d\n",sizeof(&a));
printf("%d\n",sizeof(*&a));
printf("%d\n",sizeof(&a+1));
printf("%d\n",sizeof(&a[0]+1));
sizeof(a+0) | a没有以sizeof(a)的形式出现,因此a为首元素的地址。a+0依然表示是元素地址,地址与元素类型、大小均无关,仅与编译环境有关。在x86环境下为4字节,在x64环境下为8字节 | 4或8 |
sizeof(*a) | a没有以sizeof(a)的形式出现,因此a为首元素的地址。*a解引用得到整数1。 | 4 |
sizeof(&a) | &a得到的是整个数组的地址,而地址与元素类型、大小均无关,仅与编译环境有关。在x86环境下为4字节,在x64环境下为8字节。 | 4或8 |
sizeof(*&a) | &a得到的是整个数组的地址,解引用得到整个数组 | 16 |
sizeof(&a+1) | &a+1跳过了整个数组后的那个地址,但也是地址 | 4或8 |
sizeof(&a[0]+1) | &a[0]+1得到的是第二个元素的地址 | 4或8 |
2.字符数组
字符数组(一)
strlen
char arr[] = {"a,b,c,d,e,f"};
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));
strlen(arr+0)) | arr得到的是首元素的地址 | 6 |
strlen(*arr)) | 对arr解引用得到的是首元素‘a’,其ASCII 码值是97,因此计算机将从为97的地址向后寻找‘\0’,这显然是不合理的因此其结果为err(错误) | err |
strlen(arr[1])) | arr[1]得到第二个元素,与上同理,亦为err | err |
strlen(&arr)) | &arr得到整个数组的地址,指针同样在首元素的前边 | 6 |
strlen(&arr+1)) | 得到第二个元素的地址 | 5 |
strlen(&arr[0]+1)) | 第二个元素的地址 | 5 |
sizeof()
char arr[] = "abcdef";
printf("%d\n", sizeof(arr));
sizeof(arr) | 数组arr中不仅包含六个字母字符,还包含字符‘\0’ | 7 |
字符数组(二)
注意:p为指针,存放的是数组首元素的地址
sizeof()
char *p = "abcdef";
printf("%d\n", sizeof(p));
printf("%d\n", sizeof(*p));
printf("%d\n", sizeof(p[0]));
printf("%d\n", sizeof(&p));
printf("%d\n", sizeof(&p[0]+1));
sizeof(p) | p为首元素的地址 | 4或8 |
sizeof(*p) | 对p解引用得到首元素 | 1 |
sizeof(p[0]) | p[0]就等价于*(p+0)因此得到的还是首元素 | 1 |
sizeof(&p) | 得到的是指针p的存储地址 | 4或8 |
sizeof(&p[0]+1) | 首元素地址加一得到的是第二个元素的地址 | 4或8 |
strlen
char *p = "abcdef";
printf("%d\n", strlen(p));
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));
strlen(p) | p为首元素的地址 | 6 |
strlen(*p) | 解引用得到首元素,结果为err(详解见上) | err |
strlen(p[0]) | p[0]等价于*(p+0),结果为err | err |
strlen(&p) | 随机值 | |
strlen(&p+1) | 随机值 | |
strlen(&p[0]+1) | p[0]等价于*(p+0)得到‘a’,再取其地址,指针再向后移动一位 | 5 |
3.二维数组
注:对于二维数组来讲,其数组名是第一行的地址
int a[3][4] = {0};
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(a[0]));
printf("%d\n",sizeof(a[0]+1));
printf("%d\n",sizeof(&a[0]+1));
printf("%d\n",sizeof(*(&a[0]+1)));
printf("%d\n",sizeof(a[3]));
sizeof(a) | 以sizeof(a)形式出现,表示整个数组 3*4*4 | 48 |
sizeof(a[0]) | 以sizeof(a[0])形式出现,表示第一行 4*4 | 16 |
sizeof(a[0]+1) | a[0]并没有单独出现在sizeof()内部,因此a[0]表示的是第一行的首元素的地址,即此处a[0]等价于a[0][0]的地址 | 4或8 |
sizeof(&a[0]+1) | a[0]以&a[0]的形式出现,表示第一行的地址,后移一位,得到第二行的地址 | 4或8 |
sizeof(*(&a[0]+1)) | 得到的是第二行 | 16 |
sizeof(a[3]) | 注意:此处并不存在越界,因为不会真是访问空间内存,仅通过推导便可得到长度 | 16 |
- 如果对大家有帮助,请三连支持一下!
- 有问题欢迎评论区留言,及时帮大家解决!