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;
}

上述题目总结:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/231295.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

金色传说:SAP-BC-SM36/SM37后台执行报表查询结果导出时分页和标题多行问题解决

文章目录 前言一、后台执行的启动方式?二、使用步骤1.点击程序-后台执行2.结果查看和导出三、结果显示和导出问题1.结果显示不全问题解决2.结果如何导出到Excel中3.==导出的文件有分页和标题和结果都是多行显示问题解决==总结前言 例如:随着项目数据量增长,很多报表的查询时…

Django连接数据库

连接数据库 接下来讲的几个步骤不需要区分先后,但都得进行操作 settings.py的操作 #!settings.py ....别的代码DATABASES {default: { ENGINE: django.db.backends.mysql, NAME: day1121, # 数据库名字,要先创建好 USER: root, PASSWORD: 123456, HO…

HarmonyOS——UI开展前的阶段总结

当足够的了解了HarmonyOS的相关特性之后,再去介入UI,你会发现无比的轻松,特别当你有着其他的声明式UI开发的经验时,对于HarmonyOS的UI,大致一扫,也就会了。 如何把UI阐述的简单易懂,又能方便大…

hyper-V操作虚拟机ubuntu 22.03

安装hyper-V 点击卸载程序 都勾选上即可 新建虚拟机,选择镜像文件 选择第一代即可 设置内存 配置网络 双击 启动安装虚拟机 输入用户名 zenglg 密码:LuoShuwen123456 按照enter键选中openssh安装 安装中 安装完成 选择重启 输入用户名、密码

20.Oracle11g中的触发器

oracle11g中的触发器 一、触发器的概述1、什么是触发器2、触发器的类型3、触发器的组成4、触发器的作用 二、触发器的创建语法1、创建语法2、数据库启动触发器3、 用户登录触发器: 三、对触发器的基本操作点击此处跳转下一节:21.Oracle的程序包(Package)…

redis的过期策略以及定时器的实现

Redis是客户端服务器结构的程序,客户端与服务器通过网络通信,所以对于keys *这种的操作在大型企业中不太建议,生产环境下的key会非常多,Redis是但现成的服务器,执行keys*的时间非常长,就会导致redis服务器阻…

【LeetCode】101. 对称二叉树

101. 对称二叉树 难度:简单 题目 给你一个二叉树的根节点 root , 检查它是否轴对称。 示例 1: 输入:root [1,2,2,3,4,4,3] 输出:true示例 2: 输入:root [1,2,2,null,3,null,3] 输出&#…

token认证机制,基于JWT的Token认证机制实现,安全性的问题

文章目录 token认证机制几种常用的认证机制HTTP Basic AuthOAuthCookie AuthToken AuthToken Auth的优点 基于JWT的Token认证机制实现JWT的组成认证过程登录请求认证 对Token认证的五点认识JWT的JAVA实现 基于JWT的Token认证的安全问题确保验证过程的安全性如何防范XSS Attacks…

Redis 基础、字符串、哈希、有序集合、集合、列表以及与 Jedis 操作 Redis 和与 Spring 集成。

目录 1. 数据类型 1.1 字符串 1.2 hash 1.3 List 1.4 Set 1.5 sorted set 2. jedis操作redis 3. 与spring集成 1. 数据类型 1.1 字符串 String是最常用的数据格式,普通的kay-value都归结为此类, value值不仅可以是string,可以是数字…

interface previously declared 的bug问题

其实就是重复定义了,只需要加如下的代码即可: 其中把APB的部分改成自己的接口名字就好了。

JS 绘制半径不一致的环形图进度条

HTML部分: <canvas id"mycanvas" width"100" height"100"></canvas>JS部分&#xff1a; const option {element: "mycanvas", // 元素count: 26, // 高亮数据totalCount: 129, // 总数据progressColor: #3266FB, // 进…

工会排队奖励模式:创新营销策略,实现共赢局面

在当今的商业环境中&#xff0c;创新营销策略的重要性日益凸显。工会排队奖励模式作为一种新型的营销策略&#xff0c;旨在通过结合线上和线下消费&#xff0c;激励消费者购买产品或服务&#xff0c;并获得返现奖励。这种模式通过将消费者的支出和商家的抽成资金纳入奖金池&…