sizeof 和 strlen的对比及笔试题目

目录

题目1:

题目2:

题目3:

题目4:

题目5:

题目6:

二维数组题(重点):

上述题目总结:


若想了解其他的字符函数和字符串函数请移步:深入理解字符串函数和字符函数(一)-CSDN博客

sizeof 和 strlen主要区别如下:
1、sizeof是运算符,strlen是C语言标准库函数。
2、 strlen 测量的是字符串的实际长度,以’\0’ 结束,返回结果不包括’\0’ 。
3、而sizeof 测量的是字符的分配大小,它的参数可以是数组、指针、类型、对象、函数等。

题目1:

int main()
{
    char arr[20] = "abcdef";
    size_t len = strlen(arr);//6
    //统计的是从strlen函数的参数str中这个地址开始向后,\0之前字符串中字符的个数


    printf("len = %zd\n", len);
    size_t sz = sizeof(arr);//20
    printf("sz = %zd\n", sz);

  char arr[] = { 'a','b','c'};//42,随机的,编译器随机

      \0的位置不确定,终的数值也不确定

    printf("%zd\n", strlen(arr));


    

    char arr[6] = "abcdef";//err \0 有7个字符,越界

    return 0;

}

题目2:

int main()
{
    int a[] = { 1,2,3,4 };//a数组有四个元素,每个元素是int类型的数据

    printf("%d\n", sizeof(a));//16 - sizeof(数组名)的情况,计算整个数组的大小,单位是字节 - 4 * 4 = 16
    printf("%d\n", sizeof(a + 0));//4 or 8 取决于是32位还是64位
    //a表示的是数组首元素的地址,a+0还是首元素的地址

    printf("%d\n", sizeof(*a));//4  a表示的是数组首元素的地址,*a就是首元素,大小是4个字节
    printf("%d\n", sizeof(a + 1));//4 or 8

 

 //a + 1是第二个元素的地址

    printf("%d\n", sizeof(a[1]));//4  a[1]是数组的第二个元素,大小是4个字节
    printf("%d\n", sizeof(&a));//4 or 8  &a - 取出的是数组的地址,但是数组的地址也是地址,
    //int (*pa)[4] = &a
    //int (*)[4]
    
    printf("%d\n", sizeof(*&a));//16
    //1.抵消  &*  sizeof(*&a) == sizeof(a)
    //2.&a 的类型是数组指针,int(*)[4],*&a就是对数字指针解引用访问一个数组的大小,是16个字节

    printf("%d\n", sizeof(&a + 1));//4 or 8 &a+1是跳过整个数组后的地址,是地址,大小就是4/8个字符
    printf("%d\n", sizeof(&a[0])); //4 or 8 &a[0]是第一个元素的地址,大小就是4/8个字符
    printf("%d\n", sizeof(&a[0] + 1));//4 or 8
    //&a[0]+1是第二个元素的地址,大小就是4/8个字符

    return 0;
}

题目3:

int main()
{
    char arr[] = { 'a','b','c','d','e','f' };//arr数组中有6个元素

    printf("%d\n", sizeof(arr));//6 计算的是整个数组的大小
    printf("%d\n", sizeof(arr + 0));//4 or 8 arr+0是数组的第一个元素的地址
    printf("%d\n", sizeof(*arr));//1  *arr是首元素地址的解引用,就是1个字节
    printf("%d\n", sizeof(arr[1]));//1 - arr[1] = 'b' 
    printf("%d\n", sizeof(&arr));//4 or 8
    printf("%d\n", sizeof(&arr + 1));//4 or 8
    printf("%d\n", sizeof(&arr[0] + 1));//4 or 8

    return 0;
}

题目4:

int main()
{
    char arr[] = "abcdef";
    printf("%zd\n", sizeof(arr));
    //sizeof的返回值是size_t,是无符号型,应该用%zd接收

    printf("%zd\n", sizeof(arr + 0));//arr+0是数组首元素的地址,地址大小是4、8个字节
    printf("%zd\n", sizeof(*arr));//*arr是数组首元素,这里计算的是首元素的大小 1 
    printf("%zd\n", sizeof(arr[1]));//1
    printf("%zd\n", sizeof(&arr));//&arr - 是数组的地址,数组的地址也是地址 4/8
    printf("%zd\n", sizeof(&arr + 1));&arr+1,跳过整个数组,指向了数组的后边 4/8 
    printf("%zd\n", sizeof(&arr[0] + 1));//&arr[0]+1是第二个元素的地址 4/8

    return 0;

}

此时&arr+1跳过整个数组

题目5:

int main()
{
    char arr[] = "abcdef";

    printf("%zd\n", strlen(arr));//arr是数组首元素的地址 6
    printf("%zd\n", strlen(arr + 0));//arr + 0 是数组首元素的地址 6
    printf("%zd\n", strlen(*arr));//  传递的是'a' - 97 //err
    printf("%zd\n", strlen(arr[1]));// 'b' - 98 //err
    printf("%zd\n", strlen(&arr));//6 ,&arr虽然是数组的地址,但是也是指向数组arr的起始位置
    printf("%zd\n", strlen(&arr + 1));//随机值
    printf("%zd\n", strlen(&arr[0] + 1));//&arr[0] + 1是第二个元素的地址 - 5
    
    return 0;
}

这里如果要传参,则用char *p来接收&arr,接收后的类型为char (*)[7],但strlen所需要的形参类型为char *str,编译会警告,但仍然能传递

(补充:因为strlen函数要求传入一个指向字符的指针,而不是一个指向字符数组的指针。而char (*p)[7]是一个指向字符数组的指针,所以当它传入strlen函数时会出现警告。

题目6:

 int main()
{
    char* p = "abcdef";
    printf("%d\n", sizeof(p));//4/8 计算的指针变量的大小
    printf("%d\n", sizeof(p + 1));//p + 1是'b'的地址,是地址大小就是4/8个字节
    printf("%d\n", sizeof(*p));//*p就是'a',大小是1个字节
    printf("%d\n", sizeof(p[0]));//p[0]-->*(p+0) - *p//1个字节
    printf("%d\n", sizeof(&p));//&p也是地址,是指针变量p的地址大小是4/8字节
    printf("%d\n", sizeof(&p + 1));//&p+1是指向p指针变量后面的空间,也是地址 - 4/8
    printf("%d\n", sizeof(&p[0] + 1));//&p[0]+1是'b'的地址 - 4/8
    return 0;
}

int main()
{
    char* p = "abcdef";
    printf("%zd\n", strlen(p)); //6
    printf("%zd\n", strlen(p + 1));//5
    printf("%zd\n", strlen(*p));//'a'-97 err
    printf("%zd\n", strlen(p[0]));//p[0]--*(p+0)-->*p //err
    printf("%zd\n", strlen(&p));//随机值 不确定\0的位置
    printf("%zd\n", strlen(&p + 1));//同上
    printf("%zd\n", strlen(&p[0] + 1));//从b的地址往后数 - 5

    return 0;
}

二维数组题(重点):

int main()
{
    //二维数组也是数组,之前对数组名的理解也同样适用
    int a[3][4] = { 0 };
    printf("%zd\n", sizeof(a));

    //12*4 = 48个字节,数组名单独放在sizeof内部
    printf("%zd\n", sizeof(a[0][0]));//4
    printf("%zd\n", sizeof(a[0]));

    //a[0]是第一行这个一维数组的数组名,数组名单独放在了sizeof内部了
    //计算的是第一行的大小,单位是字节,16个字节

    printf("%zd\n", sizeof(a[0] + 1));

    //a[0]是第一行这个一维数组的数组名,这里表示首元素地址
    //也就是a[0][0]的地址,a[0]+1是a[0][1]的地址

    printf("%zd\n", sizeof(*(a[0] + 1)));//a[0][1] - 4个字节
    printf("%zd\n", sizeof(a + 1));

     //a是二维数组的数组名,但是没有&,也没有单独放在sizeof内部
    //所以这里的a是数组首元素的地址,应该是第一行的地址,a+1是第二行的地址
    //大小也是4/8个字节
    printf("%zd\n", sizeof(*(a + 1)));

    //*(a+1)==>a[1] - 第二行的数组名,单独放在sizeof内部,计算的是第二行的大小 - 16个字节
    printf("%zd\n", sizeof(&a[0] + 1));

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


    printf("%zd\n", sizeof(*(&a[0] + 1)));

     //访问第二行,计算的是第二行的大小,16个字节
    //int(*p)[4] = &a[0]+1

    printf("%zd\n", sizeof(*a));

    //这里的a是第一行的地址,*a就是第一行,sizeof(*a)计算的是第一行的大小 - 16
    //*a -->*(a+0)-->a[0]
    printf("%zd\n", sizeof(a[3]));

    //这里不存在越界
    //sizeof内部的表达式不会真实计算的
    //计算的是第四行的大小 - 16

    return 0;
}

上述题目总结:

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

走在努力路上的自己

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

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

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

打赏作者

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

抵扣说明:

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

余额充值