使用sizeof()和strlen()去计算【数组】和【指针】的大小
文章目录
- 一、知识回顾
- 1、回顾sizeof()、strlen的作用:
- 2、数组和指针
- 3、数组名
- 二、sizeof()、strlen()的使用区别
- 1、注意区别:
- 2、一维数组与一级指针
- 3、二维数组与二级指针
- 三、总结回顾
一、知识回顾
1、回顾sizeof()、strlen的作用:
sizeof()是用来求取变量或者类型所占内存空间的大小(单位:字节)。- sizeof计算的是占用内存空间的大小,单位是字节,不关注内存中到底存放的是什么。sizeof不是函数,是操作符
strlen()是一个库函数是专门用来计算字符串长度的,在对其进行调用前是需要包含头文件<string.h>。- strlen()函数是通过字符串结束标志
\0来计算字符串长度的,但计算出来的字符串长度是不包括\0的,也就是说所谓的长度就是\0 前字符的个数。strlen是函数
sizeof是一个运算符,用于计算一个变量或数据类型所占的字节数,不论变量中存储的数据是否为空。而strlen是一个函数,用于计算一个字符串中的字符数,不包括字符串末尾的空字符’\0’。
另外,sizeof可以用于计算任意数据类型的大小,包括基本数据类型和自定义数据类型。
而strlen只能用于计算字符串的长度。
因此,sizeof通常用于确定数组所占的存储空间,而strlen用于确定字符串的长度。
2、数组和指针
- 数组 - 能够存放一组相同类型的元素,数组的大小取决于数组的元素个数和元素类型。
- 指针就是地址,大小都是4/8。(32位机器是4字节,64位机器是8字节)
3、数组名
- 大部分情况下
数组名是首元素地址。 - 2个例外
sizeof(数组名)—— 数组名表示整个数组,计算的是整个数组的大小。(看数组名是否是单独放在sizeof()里面)
&数组名————-数组名表示整个数组,取出的是数组的地址
二、sizeof()、strlen()的使用区别
1、注意区别:
- 字符数组 - char arr1[]={‘a’,‘b’,‘c’,‘d’,‘e’,‘f’} ->[a,b,c,d,e,f]
- 字符串数组 - char arr2[]=“abcdef” ->[a,b,c,d,e,f,
/0]
- sizeof()计算的是占用内存空间的大小,单位是字节,
不关注内存中到底存放的是什么。 - strlen()是针对字符串的,求的是字符串的长度,本质上统计的是
/0之前出现的字符个数。
2、一维数组与一级指针
整型数组
int a[] = { 1,2,3,4 };printf("%d\n", sizeof(a[1]));//4printf("%d\n", sizeof(a));//16 //sizeof(a) 就是数组名单独放在sizeof内部 计算的是整个数组的大小。printf("%d\n", sizeof(a + 0));// 4/8//a + 0 a不是单独放在sizeof()里面,则是数组首元素的地址,sizeof则是计算数组首元素地址的大小printf("%d\n", sizeof(*a));//4//a不是单独放在sizeof()里面,则是数组首元素的地址 *a == a[0],sizeof()则是计算首元素的大小。//*a -> *&a[0] -> a[0]printf("%d\n", sizeof(a + 1));// 4/8//a不是单独放在sizeof()里面,则是数组首元素的地址 -- int*//a+1 跳过1个整型,是第二个元素的地址 sizeof()是计算第二个元素地址的大小。printf("%d\n", sizeof(&a));// /4/8//&a - 取出的是数组的地址,但是数组的地址也是地址,地址的的大小就是4/8。//int (*pa)[4] = &a;printf("%d\n", sizeof(*&a));//16//等于sizeof(a)printf("%d\n", sizeof(&a+1));// 4/8//&a --> int (*)[4],取出的是数组的地址。//&a + 1 则要跳过一个数组。printf("%d\n", sizeof(&a[0]));//取出首元素地址,sizeof计算的是元素的地址4/8printf("%d\n", sizeof(&a[0]+1));//4/8//取出的是第二个元素的地址,sizeof()计算的是地址的大小。
编译器调试结果:

字符数组
char arr[] = {'a','b','c','d','e','f'};printf("%d\n", sizeof(arr));//6printf("%d\n", sizeof(arr + 0));// 4/8//arr不单独放在sizeof里面,是数组首元素的地址 ,计算的大小为4/8printf("%d\n", sizeof(*arr));//1//arr不单独放在sizeof里面,arr是首元素地址,*arr 是首元素,大小为1printf("%d\n", sizeof(arr[1]));//元素'b'printf("%d\n", sizeof(&arr));// 4/8//&arr 是数组的地址,地址的大小的都是 4/8printf("%d\n", sizeof(&arr + 1));//4/8printf("%d\n", sizeof(&arr[0] + 1));//4/8//*****************************************printf("%d\n", strlen(arr));//随机值//arr数组首元素地址,找不到‘\0’,所以是计算的大小是随机值printf("%d\n", strlen(arr + 0));//随机值,同上printf("%d\n", strlen(*arr));//非法访问//strlen传入char*(地址)//*arr = 'a'——>(97)被当成地址,非法访问printf("%d\n", strlen(arr[1]));//非法访问,同上printf("%d\n", strlen(&arr));//随机值//找不到/0printf("%d\n", strlen(&arr + 1));//随机值 - 6printf("%d\n", strlen(&arr[0] + 0));//随机值 - 1
形成野指针非法访问
在编译器上调试可见,strlen接受的是char*类型,否则会报错

字符串数组
char arr[]="abcdef";//[a b c d e f /0]printf("%d\n",sizeof(arr));//整个数组大小 7printf("%d\n",sizeof(arr+0));//首元素地址大小 4/8printf("%d\n",sizeof(*arr));//首元素大小 1//*arr = arr[0] = *(arr+0)printf("%d\n",sizeof(arr[1]));//1printf("%d\n",sizeof(&arr));//数组的地址,大小 4/8printf("%d\n",sizeof(&arr+1));//+1 跳过一个数组的地址,大小 4/8printf("%d\n",sizeof(&arr[0]+1));//+1 跳过一个元素的地址,大小 4/8//******************************************************************printf("%d\n",strlen(arr));//arr表示首元素地址,计算得到数组大小为 6printf("%d\n",strlen(arr+0));//6,同上printf("%d\n",strlen(*arr));//非法访问printf("%d\n",strlen(arr[1]));//非法访问//strlen是传入char*地址,*arr和arr[1]是数组的元素,传给strlen会被当做地址,造成非法访问printf("%d\n",strlen(&arr));//&arr表示整个数组的大小,6printf("%d\n",strlen(&arr+1));//数组的地址 +1后就找不到 /0 ,大小为随机值printf("%d\n",strlen(&arr[0]+1));//从第二个元素开始算,大小为5
指针
char* p="abcdef";printf("%d\n",sizeof(p));//4/8//指针变量p 存放着的是地址,所以大小为4/8printf("%d\n",sizeof(p+1));//字符’b‘的地址,大小为4/8printf("%d\n",sizeof(*p));//解引用的一个char类型元素,大小为1printf("%d\n",sizeof(p[0]));//1//p[0] = *(p+0)printf("%d\n",sizeof(&p));//4/8printf("%d\n",sizeof(&p+1));//+1跳过一个char*地址,还是地址,大小还是4/8//********************************************printf("%d\n",strlen(p));//大小为 6printf("%d\n",strlen(p+1));//p+1是'b'的地址,从'b'开始算,大小为5printf("%d\n",strlen(*p));//*p为'a',不是地址,非法访问printf("%d\n",strlen(&p));//随机值//&p取的是变量p的地址,不是p里面存放的地址,所以无法找打字符串printf("%d\n",strlen(&p+1));//随机值,同上printf("%d\n",strlen(&p[0]+1));//大小为 5//p[0]是’a‘,&p[0]去'a'的地址,+1的'b'的地址,从'b'开始计算
3、二维数组与二级指针
整型数组
int a[3][4]={0};//三行四列的数组printf("%d\n",sizeof(a));//4*3*4=48//a这个数组名单独放在sizeof里面,表示整个数组,计算的是整个数组的大小printf("%d\n",sizeof(a[0][0]));//第一行第一个元素,大小4字节printf("%d\n",sizeof(a[0]));//16//a[0] 是第一行的数组名,这是数组名单独放在sizeof内部,计算的是第一行数组的大小printf("%d\n",sizeof(a[0]+1));//4/8//a[0]不是单独放在sizeof内部,表示的是首元素的地址。即第一行第一个元素的地址,相当于&a[0][0]//a[0]+1 是第一行第二个元素的地址,相当于&a[0][1]printf("%d\n",sizeof(a+1));//4/8//a作为二维数组的数组名,并非单独放在sizeof内部,所以表示首元素是地址//二维数组的首元素是第一行,这里的a就是第一行的地址//a+1是跳过第一行,指向第二行printf("%d\n",sizeof(*(a+1)));//16//*(a+1) -> a[1],计算的是第二行的大小printf("%d\n",sizeof(&a[0]+1));//4/8//&a[0]是第一行的地址//&a[0]+1是第二行的地址printf("%d\n",sizeof(*(&a[0]+1)));//表示第二行,大小为16printf("%d\n",sizeof(*a));//16//*a --> *(a+0)表示第一行,大小为16
三、总结回顾
- sizeof(数组名),这里的数组名表示整个数组,计算的是数组的大小。
- &数组名,这里的数组名表示整数数组,取出的是整个数组的地址。
- 除此之外所有的数组名都表示首元素的地址。
相关文章:
使用sizeof()和strlen()去计算【数组】和【指针】的大小
文章目录 一、知识回顾1、回顾sizeof()、strlen的作用:2、数组和指针3、数组名 二、sizeof()、strlen()的使用区别1、注意区别:2、一维数组与一级指针3、二维数组与二级指针 三、总结回顾 一、知识回顾 1、回顾sizeof()、strlen的作用: siz…...
viple进阶4:打印空心三角形
题目:根据用户输入的行数n打印空心三角形,下图分别为n3、n4、n5和n10的效果图 第一步:观察效果图 输入的行数为3,打印结果就有3行;输入的行数为4,则打印结果就有4行;以此类推,输入的…...
Oauth2.0的内容
OAuth 2.0是一个授权协议,用于允许第三方应用程序访问用户在另一个应用程序上存储的受保护资源,而不需要将用户名或密码公开给第三方应用程序。 OAuth2.0基于客户端-服务器模型,通常需要三个主体:客户端、资源所有者和授权服务器…...
npm 下载包失败解决方案
1.【问题描述】使用 npm 下载vue项目依赖包时失败,版本不一致。 【解决方法】使用 npm install --force npm install --force 是一个命令行指令,用于在 Node.js 环境中使用 npm(Node Package Manager)安装包或模块。–force 参数表…...
C语言---插入排序、希尔排序、冒泡排序、选择排序、快速排序简单介绍
文章目录 插入排序希尔排序冒泡排序选择排序快速排序 本文主要介绍用C语言实现的一些排序方法,有插入排序、希尔排序、冒泡排序、选择排序和快速排序,文章中给出的例子都是按照升序排列的。 插入排序 若数组只有一个元素,自然不用排序&#…...
撸视频号收益这个副业靠谱吗?
我是卢松松,点点上面的头像,欢迎关注我哦! 昨天有个人问我说做视频号能月入过万吗? 我的回复是:99%的人不能。 但为什么会经常有人这么问呢,松松思考了一下,原因是最近很多人在晒视频号撸收益的项目&am…...
2、数组、Map+HashMap、Set+Hashset、Char和Character类、String类和Char类、Math类
数组 \\一个普通的长度为1的整数数组 Integer[] arr new Integer[1];\\一个普通长度为1的同时元素初始化为1的整数数组。 Integer[] arr new Integer[]{1};\\一个长度为0的空数组 Integer[] arr new Integer[0];Map 常见方法 void clear( ) 从此映射中移除所有映射关系&#…...
ESP8266 WiFi模块快速入门指南
ESP8266是一种低成本、小巧而功能强大的WiFi模块,非常适合于物联网和嵌入式系统应用。本指南将为您提供关于ESP8266 WiFi模块的快速入门步骤和基本知识。 第一步:硬件准备 首先,您需要将ESP8266 WiFi模块与您的开发板连接。通常情况下&#…...
微信小程序将后端返回的图片文件流解析显示到页面
说明 由于请求接口后端返回的图片格式不是一个完整的url,也不是其他直接能显示的图片格式,是一张图片 后端根据模板与二维码生成图片,返回二进制数据 返回为文件流的格式,用wx.request请求的时候,就自动解码成为了下面这样的数据数据格式,这样的数据没…...
网络基础(1)
目录: 1.了解局域网(LAN)和广域网(WAN) 2.认识“协议” 3.浅谈OSI七层模型 4.网络传输的基本流程 5.路由器这个设备 ---------------------------------------------------------------------------------------…...
flink的AggregateFunction,merge方法作用范围
背景 AggregateFunction接口是我们经常用的窗口聚合函数,其中有一个merge方法,我们一般情况下也是实现了的,但是你知道吗,其实这个方法只有在你使用会话窗口需要进行窗口合并的时候才需要实现 AggregateFunction.merge方法调用时…...
Day25力扣打卡
打卡记录 寻找旋转排序数组中的最小值(二分) 链接 由于是旋转排序数组,所以整个数组有两部分是递增的,选取右侧最后元素,即可将整个数组分为大于该元素和小于该元素,碰头地段即为最小值。 class Solutio…...
SpringCloud - OpenFeign 参数传递和响应处理(全网最详细)
目录 一、OpenFeign 参数传递和响应处理 1.1、feign 客户端参数传递 1.1.1、零散类型参数传递 1. 例如 querystring 方式传参 2. 例如路径方式传参 1.1.2、对象参数传递 1. 对象参数传递案例 1.1.3、数组参数传递 1. 数组传参案例 1.1.4、集合类型的参数传递…...
Postgresql数据类型-布尔类型
前面介绍了PostgreSQL支持的数字类型、字符类型、时间日期类型,这些数据类型是关系型数据库的常规数据类型,此外PostgreSQL还支持很多非常规数据类型,比如布尔类型、网络地址类型、数组类型、范围类型、json/jsonb类型等,从这一节…...
SPASS-交叉表分析
导入数据 修改变量测量类型 分析->描述统计->交叉表 表中显示行、列变量通过卡方检验给出的独立性检验结果。共使用了三种检验方法。上表各种检验方法显著水平sig.都远远小于0.05,所以有理由拒绝实验准备与评价结果是独立的假设,即认为实验准备这个评价指标是…...
用Python的requests库来模拟爬取地图商铺信息
由于谷歌地图抓取商铺信息涉及到API使用和反爬虫策略,直接爬取可能会遇到限制。但是,我们可以使用Python的requests库来模拟爬取某个网页,然后通过正则表达式或其他文本处理方法来提取商铺信息。以下是一个简单的示例: # 导入requ…...
使用EvoMap/Three.js模拟无人机灯光秀
一、创建地图对象 首先我们需要创建一个EM.Map对象,该对象代表了一个地图实例,并设置id为"map"的文档元素作为地图的容器。 let map new EM.Map("map",{zoom:22.14,center:[8.02528, -29.27638, 0],pitch:71.507,roll:2.01,maxPit…...
11.9存储器实验总结(单ram,双ram,FIFO)
实验设计 单端口RAM实现 双端口RAM实现 FIFO实现 文件结构为...
linux(ubuntu)安装并使用scrcpy
scrcpy 是一款开源的在计算机上显示和控制 Android 设备的工具。要在 Ubuntu 上使用 scrcpy,你可以按照以下步骤进行安装: 通过命令行安装 scrcpy: 安装 scrcpy: 打开终端(Terminal)并执行以下命令来安装…...
linux rsyslog安装配置
syslog是Linux系统默认的日志守护进程。默认的syslog配置文件是/etc/rsyslog.conf文件。syslog守护进程是可配置的,它允许人们为每一种类型的系统信息精确地指定一个存放地点。syslog使用UDP 514/TCP 514端口。 1.环境信息 环境信息 HostnameIpAddressOS versionModuleNoterh…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么?它的作用是什么? Spring框架的核心容器是IoC(控制反转)容器。它的主要作用是管理对…...
【Java多线程从青铜到王者】单例设计模式(八)
wait和sleep的区别 我们的wait也是提供了一个还有超时时间的版本,sleep也是可以指定时间的,也就是说时间一到就会解除阻塞,继续执行 wait和sleep都能被提前唤醒(虽然时间还没有到也可以提前唤醒),wait能被notify提前唤醒…...
