【C语言】指针篇- 深度解析Sizeof和Strlen:热门面试题探究(5/5)



🌈个人主页:是店小二呀
🌈C语言笔记专栏:C语言笔记
🌈C++笔记专栏: C++笔记
🌈喜欢的诗句:无人扶我青云志 我自踏雪至山巅

文章目录
- 一、简单介绍Sizeof和Strlen
- 1.1 Sizeof
- 1.2 Strlen函数
- 1.3 Siezof与Strlen小总结:
- 二、 关于Sizeof和Strlen面试题
- 2.1 sizeof题目
- 2.2 strlen题目
- 2.3 二维数组
本篇是关于Sizeof和Strlen常考面试题解析,也是指针篇的末尾 ,在此感谢大家的支持!
一、简单介绍Sizeof和Strlen
1.1 Sizeof
Sizeof使用指南:
- Sizeof属于单目操作符
- 功能:用于计算任何类型的数据所占内存空间的大小
- 用途广泛,适用于计算数据类型,变量,数组,指针等大小(函数指针变量是不可以的)
- 在编译中已经完成了计算,返回值是无符号整形size_t,它的单位是字节
- 对于变量名和数值不是必须要加括号,而数据类型就是必须要加上括号
- 只关注数据占用内存空间大小,不在乎数据中内容
1.2 Strlen函数
函数原型:
size_t strlen(const char *len)
Strlen函数使用指南:
- strlen属于库函数,在头文件
string.h声明 - strlen在编译过程中进行计算,局限于字符/字符串的计算中
- 功能:计算字符串有效长度(结束标志’\0’之前长度)。
- 在使用strlen的过程中,如果访问了不存在的 索引,可能会出现数据溢出/越界访问的问题。
- 字符串的初始化,没有对字符串有专门的类型,所以用char类型来初始化
char alen[]="abcd";//字符串数组
char blen[]={'a','b','c','d'};//字符数组
【说明】:如果是字符串数组,编译器会自动在结尾补充\0作为结束标志。而对于字符数组,是将字符单个放入数组中,不存在自动补充\0的情况。导致了字符数组中\0的位置是不可知的,通过strlen计算数组大小,需要可能越界访问,找到后面位置\0位置停止。
1.3 Siezof与Strlen小总结:
- sizeof是操作符 、 strlen是库函数
- sizeof用于计算任何类型数据的大小、strlen专门计算字符串中的长度
- sizeof不在乎数据内容、strlen关注字符串结束标志
二、 关于Sizeof和Strlen面试题
【温馨提示】:
- sizeof(数组名):这里面的数组名是整个数组,用于计算整个数组的大小
- &数组名:这里取出来的是整个数组的地址
- 二维数组物理逻辑是连续,将一维数组看成二维数组的一个元素,对此二维数组数组名是第一个一维数组的整个地址。
2.1 sizeof题目
通过sizeof函数计算–整型数组
int a[] = { 1,2,3,4 };printf("%d\n", sizeof(a));--16printf("%d\n", sizeof(a + 0));--4/8printf("%d\n", sizeof(*a));--4printf("%d\n", sizeof(a + 1));--4/8printf("%d\n", sizeof(a[1]));--4printf("%d\n", sizeof(&a));--4/8printf("%d\n", sizeof(*&a));--16printf("%d\n", sizeof(&*a));--4/8printf("%d\n", sizeof(&a + 1));--4/8printf("%d\n", sizeof(&a[0]));--4/8printf("%d\n", sizeof(&a[0] + 1));--4/8
【解析】:
- sizeof(数组名),用于计算整个数组的大小16
- 这里()数组名不是独自的,所以这里a是首元素的地址,+0,没有变化,地址大小就是4/8
- 这里()数组名不是独自的,这里a是首元素的地址,*之后就是首元素的数值,大小就是4
- 这里()数组名不是独自的,这里a是首元素的地址,+1,就是第二个元素的地址,地址大小就是4/8
- 这里就是第二个元素的数值,大小就是4
- 这里就是取出了全部数值的地址,地址大小就是4/8
- 显示取出整个数组的地址,再解引用得到整个数组的大小16
- 这里a就是首元素的地址,*取出的就是首元素的数值,再取地址就是首元素的地址4/8
- 先是取出这个全部数组的地址,+1就是跳过整个数组地址,是地址大小4/8
- 可以看成&(*(a+0)),这里就是a就是首元素的地址, *取出首元素值,在取地址,还是首元素的地址,地址的大小4/8
- 由上面可得到,这里是首元素的地址,+1,就是第二个元素的地址,是地址大小4/8
通过sizeof计算–字符数组
char arr[] = { 'a','b','c','d','e','f' };printf("%d\n", sizeof(arr));--6printf("%d\n", sizeof(arr + 0));--4/8printf("%d\n", sizeof(*arr));--1printf("%d\n", sizeof(arr[1]));--1printf("%d\n", sizeof(&arr));--4/8printf("%d\n", sizeof(&arr + 1));--4//8printf("%d\n", sizeof(&arr[0] + 1));--4/8
【解析】:
- 这里代表的是整个数组,用于计算整个数组的大小,6
- 这里()数组名不是独自的,这里a是首元素的地址,地址大小就是4/8
- 这里()数组名不是独自的,这里a是首元素的地址,就是首元素的数值,1
- 这里就是第二个元素的数值,1
- 这里就是取出整个数组的地址,是地址大小就是4/8
- 这里就是取出整个数组的地址,+1,就是跳过整个数组,是地址大小4/8
- 这里就是首元素的地址,+1,就是第二个元素的地址,地址大小就是4/8,&[]可以抵消的呀
通过sizeof计算–字符串数组
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));
通过sizeof计算–常量字符串
char *p= "abcdef";printf("%d\n", sizeof(p));--4/8printf("%d\n", sizeof(p + 1));--4/8printf("%d\n", sizeof(*p));--1printf("%d\n", sizeof(p[0]));--1printf("%d\n", sizeof(&p));--4/8printf("%d\n", sizeof(&p + 1));--4/8printf("%d\n", sizeof(&p[0] + 1));--4/8
【解析】:
- p是一个指针变量,也是存放a的地址,是地址的话大小是4/8
- p是第一个字符的地址,+1,就是b的地址,地址大小就是4/8
- p是第一个字符的地址,所以得到了字符‘a’, 大小是1
- 得到了字符‘a’, 大小是1
- &p就是取了p的地址,地址大小就是4/8
- 取了p的地址,之后跳过p变量后,得到的地址,是地址大小4/8
- 这里的看成 & ( *(p + 0)) + 1, 那么就是b的地址,地址大小就是4/8
2.2 strlen题目
通过strlen函数计算–字符数组
char arr[] = { 'a','b','c','d','e','f' };printf("%d\n", strlen(arr));--随机值printf("%d\n", strlen(arr + 0));--随机值printf("%d\n", strlen(*arr));--err/报错printf("%d\n", strlen(arr[1]));--err/报错printf("%d\n", strlen(&arr));--随机值printf("%d\n", strlen(&arr + 1));--随机值printf("%d\n", strlen(&arr[0] + 1));--随机值
【解析】:
- 这个是首元素的地址,不知道‘\0’在哪里的,大小就是随机值
- 这个是首元素的地址,不知道‘\0’在哪里的,大小就是随机值
- 这里取出的是字符‘a’, 不是char* 类型,就是说它不是地址,所以是err
- 这里取出的是字符‘b’, 不是char* 类型,就是说它不是地址,所以是err
- 整个数组的地址,不知道‘\0’在哪里的,大小就是随机值
- 整个数组的地址,+1,跳过整个数组,不知道‘\0’在哪里的,大小就是随机值
- 这个是‘b’的地址,不知道‘\0’在哪里的,大小就是随机值
通过strlen函数计算–字符串数组
char arr[] = "abcdef";printf("%d\n", strlen(arr));--6printf("%d\n", strlen(arr + 0));--6printf("%d\n", strlen(*arr));--err/报错printf("%d\n", strlen(arr[1]));--err/报错printf("%d\n", strlen(&arr));--6printf("%d\n", strlen(&arr + 1));--随机值printf("%d\n", strlen(&arr[0] + 1));--5
【解析】:
- 首元素的地址,‘f’后面有‘\0’,大小是6
- 首元素的地址,‘f’后面有‘\0’,大小是6
- 这里取出的是字符‘a’,不是char *类型,就是说它不是地址,所以是err
- 这里取出的是字符‘b’,不是char *类型,就是说它不是地址,所以是err
- 虽然这个是整个数组的地址,当时地址还是指向a,所以大小是6
- 这里跳过了‘f’后面的‘\0’,所以要继续寻找新的‘\0’,大小是随机值
- 这里就是‘b’的地址,所以就是大小是5
通过strlen函数计算–常量字符串
char* p = "abcdef";printf("%d\n", strlen(p));--6printf("%d\n", strlen(p + 1));--5printf("%d\n", strlen(*p));--err/报错printf("%d\n", strlen(p[0]));--err/报错printf("%d\n", strlen(&p));--随机值printf("%d\n", strlen(&p + 1));--随机值printf("%d\n", strlen(&p[0] + 1));--5
【解析】:
- p是a的地址,大小就是6,遇到\0后停下
- p+1就是b的地址,大小就是5
- *p得到字符a,err
- 这个也是得到了字符a,err
- 取出p的地址,要继续寻找新的‘\0’,大小是随机值
- 这里是p本身的地址,要继续寻找新的‘\0’,大小是随机值
- 先是得到了a的地址,+1,得到b的地址,属于大小是5
2.3 二维数组
int a[3][4] = { 0 };printf("%d\n", sizeof(a));--48printf("%d\n", sizeof(a[0][0]));--4printf("%d\n", sizeof(a[0]));--16printf("%d\n", sizeof(a[0] + 1));--4/8printf("%d\n", sizeof(*(a[0] + 1)));--4printf("%d\n", sizeof(a + 1));--4/8printf("%d\n", sizeof(*(a + 1)));--16printf("%d\n", sizeof(&a[0] + 1));--4/8printf("%d\n", sizeof(*(&a[0] + 1)));--16printf("%d\n", sizeof(*a));--16printf("%d\n", sizeof(a[3]));--16
【解析】:
- 代表整个数组,用于计算整个数组的大小48
- 就是第一行第一列的元素数值,大小是4
- 这个就是二维数组的首元素,就是第一行数组名,计算第一行数组的大小,16
- 第一行数组名,但是这个数组名不是单独,就是第一行一个元素的地址,+1,第一行第二个元素的地址,是地址的大小就是4/8
- 第一行数组名,就是arr[0][0]的地址,+1,就是arr[0][1]的地址,再解引用就是得到数值,大小就是4
- a不是独自的,是二维数组的首元素的地址,就是第一行数组的地址,+1,第二行数组的地址,是地址的大小就是4/8
- a不是独自的,是二维数组的首元素的地址,+1,第二行数组的地址,再解引用就是第二行数组的数值,大小就是16
- a[0]是第一行数值名,&之后取得第一行数组的地址,+1,就是第二行数组地址,4/8
- 这个就是第二行数组,大小就是16
- 就是的第一行数组地址,解引用就是,第一行的数组,大小就是16
- 就是的第三行数组名,计算第三行的数组的大小,16

以上就是本篇文章的所有内容,在此感谢大家的观看!这里是店小二C语言笔记,希望对你在学习C语言中有所帮助!
相关文章:
【C语言】指针篇- 深度解析Sizeof和Strlen:热门面试题探究(5/5)
🌈个人主页:是店小二呀 🌈C语言笔记专栏:C语言笔记 🌈C笔记专栏: C笔记 🌈喜欢的诗句:无人扶我青云志 我自踏雪至山巅 文章目录 一、简单介绍Sizeof和Strlen1.1 Sizeof1.2 Strlen函数1.3 Sie…...
【设计模式】单例模式的前世今生
文章目录 引言简介起航!向“确保某个类在系统中只有一个实例”进发 ⛵️Lazy SingletonDouble-checked locking(DCL) SingletonVolatile SingletonAtomic SingletonMeyers Singleton 附:C静态对象的初始化 引言 说起单例模式&…...
厦门网上在线教育系统,线下老师怎么转型到线上网上授课?
现在很多 线下老师都想转到线上做网课,但是在转线上过程中会出现很多问题,很多人都不知道怎么开始,今天小编和大家说一下要注意的。 一、你要有一套适合线上的教学视频 首先你要准备做的课程内容是什么,怎么讲,讲什么&…...
Spring底层入门(九)
boot的执行流程分为构造SpringApplication对象、调用run方法两部分 1、Spring Boot 执行流程-构造 通常我们会在SpringBoot的主启动类中写以下的代码: 参数一是当前类的字节码,参数二是main的args参数。 public class StartApplication {public static…...
掌握Android Fragment开发之魂:Fragment的深度解析(下)
在上一篇文章中,我们深入探讨了Fragment 通信,包含Fragment 向 Activity 传递数据、Activity 向 Fragment 传递数据、Fragment 之间的通信方式。感兴趣的朋友,请前往查阅: 掌握Android Fragment开发之魂:Fragment的深度…...
小巧简单实用的Linux端口转发工具Rinetd
Linux下实现端口转发有很多种方法,尤其是在可以联网的情况下,更是容易。最近在资源受限的定制系统中,找到一个方便离线安装和使用的端口转发工具Rinetd,安装包仅几十K,而且有很多版本的Linux发行系统的支持。 1、安装…...
HackBar 新手使用教程(入门)
啥是Hackbar? Hackbar是一个Firefox 的插件,它的功能类似于地址栏,但是它里面的数据不受服务器的相应触发的重定向等其它变化的影响。 有网址的载入于访问,联合查询,各种编码,数据加密功能。 这个Hackbar可以帮助你在测试SQL注入,XSS漏洞和网站的安全性,主要是帮助…...
<Linux> 权限
目录 权限人员相对于文件来说的分类更改权限文件的拥有者与所属组umask粘滞位 权限 权限是操作系统用来限制对资源访问的机制,权限一般分为读、写、执行。系统中的每个文件都拥有特定的权限、所属用户及所属组,通过这样的机制来限制哪些用户、哪些组可以…...
Nacos Docker 快速部署----解决nacos鉴权漏洞问题
Nacos Docker 快速部署 1. 说明 1.1 官方文档 官方地址 https://nacos.io/zh-cn/docs/v2/quickstart/quick-start.html docker启动文件的gitlhub地址 https://github.com/nacos-group/nacos-docker.git 问题: 缺少部分必要配置与说明 1.2 部署最新版本Nacos&…...
存储或读取时转换JSON数据
一、 数据库类型 二、使用Hutool工具 存储时将数据转换为JSON数据 获取时将JSON数据转换为对象 发现问题: 原本数据对象是Address 和 Firend但是转换完成后数据变成了JSONArray和JSONObject 三、自定义TypeHandler继承Mybatis的BaseTypeHandler处理器 package …...
Spring Data JPA的作用和用法
Spring Data JPA 是 Spring 框架的一个模块,它提供了一种数据访问抽象,允许以一种声明式和简洁的方式来处理数据库操作。它基于 Java Persistence API (JPA),是一个行业标准的 ORM(对象关系映射)规范,用于将…...
【go项目01_学习记录08】
学习记录 1 模板文件1.1 articlesStoreHandler() 使用模板文件1.2 统一模板 1 模板文件 重构 articlesCreateHandler() 和 articlesStoreHandler() 函数,将 HTML 抽离并放置于独立的模板文件中。 1.1 articlesStoreHandler() 使用模板文件 . . . func articlesSt…...
Java中的线程
一、创建线程的几种方式? ① 通过继承Thread类并重写run方法 ,实现简单但不可以继承其他类 Thread底层也是实现了Runnable接口,重写的是run而不是start方法 ②实现Runnable接口并重写run方法, 避免了单继承的局限性ÿ…...
顺序表的实现(迈入数据结构的大门)(完整代码)
seqlist.h #pragma once typedef int SLDataType;#include<stdio.h> #include<stdlib.h> #include<assert.h>typedef struct SeqList {SLDataType* a;int size; // 有效数据个数int capacity; // 空间容量 }SL;//初始化和销毁 void SLInit(SL* ps); void SL…...
neo4j-5.11.0安装APOC插件or配置允许使用过程的权限
在已经安装好neo4j和jdk的情况下安装apoc组件,之前使用neo4j-community-4.4.30,可以找到配置apoc-4.4.0.22-all.jar,但是高版本neo4j对应没有apoc-X.X.X-all.jar。解决如下所示: 1.安装好JDK与neo4j 已经安装对应版本的JDK 17.0…...
mybatis 中 #{}和 ${}的区别是什么?
在 MyBatis 中,#{} 和 ${} 是两种用于参数替换的语法,但它们之间存在一些重要的区别,主要体现在安全性、预编译和动态 SQL 上。 安全性: #{}:这是预编译处理,MyBatis 会为传入的参数生成 PreparedStatement…...
深入解析C#中的接口设计原则
深入解析C#中的接口设计原则 目录 深入解析C#中的接口设计原则 一、接口设计的SOLID原则 二、接口设计的最佳实践 三、接口设计的高级技术 四、结论 接口在面向对象编程中扮演着至关重要的角色。它们是定义行为契约的一种方式,允许实现者提供这些行为的具体实现…...
106短信群发平台在金融和法务行业的应用分析
一、金融行业应用 1.客户通知与提醒:银行、证券、保险等金融机构经常需要向客户发送各类通知和提醒,如账户余额变动、交易确认、扣费通知、理财产品到期提醒等。106短信群发平台可以快速、准确地将这些信息发送到客户的手机上,确保客户及时获…...
Spring AOP(2)
目录 Spring AOP详解 PointCut 切面优先级Order 切点表达式 execution表达式 切点表达式示例 annotation 自定义注解MyAspect 切面类 添加自定义注解 Spring AOP详解 PointCut 上面代码存在一个问题, 就是对于excution(* com.example.demo.controller.*.*(..))的大量重…...
Spring-依赖注入的处理过程
前置知识 1 入口 DefaultListableBeanFactory#resolveDependency 2 每个依赖都有对应的DependencyDescriptor 3 自定绑定候选对象处理器AutowireCapableBeanFactory 注入处理 我们可以看到接口AutowireCapableBeanFactory中有两个方法。 第一个是单个注入: Null…...
K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
