让人分不清的sizeof和strlen

接下来我们来说说sizeof和strlen。

1.sizeof

  • 函数or关键字?

    对于sizeof,第一点我们要清楚的是,它是一个关键字,并不是一个函数。正因为sizeof不是函数,因此我们不把它所要求得长度的对象叫做参数,这也是

  • sizeof不能求得void类型的长度
    你无法求出sizeof(void),其实你是无法声明出void的一个变量的,void指的是一个空类型,空类型你是无法知道变量内存空间大小的,所以你用sizeof去求肯定是不行的。

  • sizeof可以求void类型指针的长度
    sizeof对于void类型的指针,因为指针,是用来存放地址的变量,在32位平台,所有版本的编译器都把它看作4个字节,所以你后续只要用sizeof求的是指针,就绝对是4。

  • sizeof能求得静态分配内存的数组的长度
    这个其实很好解释,例如:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int arr[] = { 1, 2, 3, 4 };
    printf("%d", sizeof(arr));
    system("pause");
    return 0;
}

在这里你可以看到这里的sizeof=类型所占字节大小*元素个数。

  • sizeof求数组做形参的情况
    sizeof求形参是会有个陷阱,比如:
void lab(int arr[4])
{
         int m = sizeof(arr);
         printf("%d",m);
}

在这里的m就是一个陷阱的提现,如果你说结果m是16,那么你就错了,当数组做形参时,所传递的并不是数组本身,在这里数组被转化成了指针,因为如果数组太大了,如果你要传数组,那么所需要创建的拷贝就很大,这样会导致效率很低。所以其实你进行的还是对指针的sizeof,结果依然是4。

2.strlen

strlen()函数,它是一个字符串函数,它相当于一个计数器,当它遇到’\0’时就停止计数。
strlen的实现:

int my_strlen(const char *str)
{
    int len=0;
    assert(str != NULL);
    while ((*str++) != '/0')
    {
        len++;
    }
    return len;
}

strlen函数是遇到‘/0’就会停止。

3. 关于strlen和sizeof的示例:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    char *p = "abcdef0\0";//
    char arr1[] = "abcdef";
    char arr2[] = { 'a', 'b', 'c','d', 'e', 'f' };
    int a[] = { 1, 2, 3, 4 };
    printf("%d\n",sizeof(p));//4  这里的原因是p是一个指针变量,所有的指针变量都是所占字节数都为4
    printf("%d\n",sizeof(arr1));//7  这里是对arr1数组求大小,别忘了‘\0’。
    printf("%d\n",sizeof(arr2));//6  这里是对arr2数组求大小。
    printf("%d\n",strlen(p));//7     这里对p求大小,遇到‘\0’会终止。
    printf("%d\n",strlen(arr1));//6  这是求arr1,这里记得字符串中有‘\0’;
    printf("%d\n",strlen(arr2));//比6大的随机值  这里对arr2求时,会发生一个问题,不存在‘\0’,继续向找,直到在内存中找到‘\0’为止
    printf("%d\n",sizeof(a));//16    这里是sizeof(int)*元素个数。
    printf("%d\n",sizeof(a+0));//4   这里是a[0],就是一个整形元素的大小。
    printf("%d\n",sizeof(*a));//4    这里a保存的是首元素的地址,所以解引用出来的就是第一个元素,然后求取大小。
    printf("%d\n",sizeof(a+1));//4   这里相当于是对a[1]求取元素大小。
    printf("%d\n",sizeof(a[1]));//4  上同
    printf("%d\n",sizeof(&a));//4    这求得是整个数组的地址的大小,整个数组的地址就相当于指针变量的大小,都是4个字节。
    printf("%d\n",sizeof(&a+1));//4  这里是对整个数组取地址,再加一,这时候指向下一个同等大小的数组的首位置,所以依然是4。
    printf("%d\n",sizeof(&a[0]));//4  这里还是个地址。所以是4
    printf("%d\n",sizeof(&a[0]+1));//4 就相当于指向第二个元素。还是4
    printf("%d\n",sizeof(*&a));//16 先取整个数组的地址,然后解引用,就相当于整个数组的大小,所以是16。



    char name[] = "abcdef";
    printf("%d\n", sizeof(name[0]));//1  这里说的就是‘a’,一个字节。
    printf("%d\n", sizeof(&name));//4    这里说的是整个数组的地址,地址是4个字节
    printf("%d\n", sizeof(*name));//1    这里说的是解引用数组的地址,即‘a’,一个字节
    printf("%d\n", sizeof(&name + 1));//4   这里说的还是个地址,指向的是name数组之后的位置,即指向‘\0’后的位置
    printf("%d\n", sizeof(name + 1));//4   这里就相当于第二个元素的地址,所以还是四个字节。
    printf("%d\n", sizeof(name));//7   这里的name求字符串所占大小,记得‘\0’
    printf("%d\n", strlen(name));//6   共有6个元素
    printf("%d\n", strlen(&name));//6  这里面其实相当于还是传了name,参考strlen的实现,所以还是6
    printf("%d\n", strlen(&name + 1));//随机值 在这到下一个数组,知道遇到‘\0’才能停下来。
    printf("%d\n", strlen(name + 1));//5 name+1 指向‘b’,然后从‘b’向后一直到‘\0’最终就可以得出是5



    char *name = "abcdef";
    printf("%d\n", sizeof(name[0]));//1  这里说的就是‘a’,一个字节。
    printf("%d\n", sizeof(&name));//4   这里说的是name的地址,地址是4个字节
    printf("%d\n", sizeof(*name));//1  这里说的是解引用数组的地址,即‘a’,一个字节
    printf("%d\n", sizeof(&name + 1));//4    这里说的还是个地址,指向的是name数组之后的位置,即指向‘\0’后的位置
    printf("%d\n", sizeof(name + 1));//4   这里就相当于第二个元素的地址,所以还是四个字节。
    printf("%d\n", sizeof(name));//4 name是个指针变量,所以就是4个字节。
    printf("%d\n", strlen(name));//6 共有6个元素
    printf("%d\n", strlen(&name));//随机值  这里是给name的地址strlen,所以看地址中有没有‘\0’,当遇到‘\0’以后才会停下来
    printf("%d\n", strlen(&name + 1));//随机值  这里是给name+1的地址strlen,所以看地址中有没有‘\0’,当遇到‘\0’以后才会停下来
    printf("%d\n", strlen(name + 1));//5  指向‘b’,然后从‘b’向后一直到‘\0’最终就可以得出是5

    system("pause");
    return 0;
}

运行结果:这里写图片描述

博客写的不免有缺陷,请大家多多指出,谢谢!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值