使用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…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...
针对药品仓库的效期管理问题,如何利用WMS系统“破局”
案例: 某医药分销企业,主要经营各类药品的批发与零售。由于药品的特殊性,效期管理至关重要,但该企业一直面临效期问题的困扰。在未使用WMS系统之前,其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...
