使用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]));//4
	
	printf("%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/8
	
	printf("%d\n", sizeof(&a[0]+1));//4/8
	//取出的是第二个元素的地址,sizeof()计算的是地址的大小。

编译器调试结果:
在这里插入图片描述


字符数组

	char arr[] = {'a','b','c','d','e','f'};
	
	printf("%d\n", sizeof(arr));//6
	
	printf("%d\n", sizeof(arr + 0));// 4/8
	//arr不单独放在sizeof里面,是数组首元素的地址 ,计算的大小为4/8
	
	printf("%d\n", sizeof(*arr));//1
	//arr不单独放在sizeof里面,arr是首元素地址,*arr 是首元素,大小为1
	
	printf("%d\n", sizeof(arr[1]));//元素'b'
	
	printf("%d\n", sizeof(&arr));// 4/8
	//&arr 是数组的地址,地址的大小的都是 4/8
	
	printf("%d\n", sizeof(&arr + 1));//4/8
	printf("%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));//随机值
	//找不到/0
		
	printf("%d\n", strlen(&arr + 1));//随机值 - 6
	printf("%d\n", strlen(&arr[0] + 0));//随机值 - 1

形成野指针非法访问
在编译器上调试可见,strlen接受的是char*类型,否则会报错
在这里插入图片描述


字符串数组

	char arr[]="abcdef";//[a b c d e f /0]
	
	printf("%d\n",sizeof(arr));//整个数组大小 7
	printf("%d\n",sizeof(arr+0));//首元素地址大小 4/8
	
	printf("%d\n",sizeof(*arr));//首元素大小 1
	//*arr = arr[0] = *(arr+0)
	
	printf("%d\n",sizeof(arr[1]));//1
	
	printf("%d\n",sizeof(&arr));//数组的地址,大小 4/8
	printf("%d\n",sizeof(&arr+1));//+1 跳过一个数组的地址,大小 4/8
	printf("%d\n",sizeof(&arr[0]+1));//+1 跳过一个元素的地址,大小 4/8
	
	//******************************************************************

	printf("%d\n",strlen(arr));//arr表示首元素地址,计算得到数组大小为 6
	printf("%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表示整个数组的大小,6
	printf("%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/8
	
	printf("%d\n",sizeof(p+1));//字符’b‘的地址,大小为4/8
	
	printf("%d\n",sizeof(*p));
	//解引用的一个char类型元素,大小为1
	
	printf("%d\n",sizeof(p[0]));//1
	//p[0] = *(p+0)
	printf("%d\n",sizeof(&p));//4/8
	
	printf("%d\n",sizeof(&p+1));
	//+1跳过一个char*地址,还是地址,大小还是4/8

	//********************************************

	printf("%d\n",strlen(p));//大小为 6
	printf("%d\n",strlen(p+1));//p+1是'b'的地址,从'b'开始算,大小为5
	printf("%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)));//表示第二行,大小为16
	printf("%d\n",sizeof(*a));//16
	//*a --> *(a+0)表示第一行,大小为16
	

三、总结回顾

  • sizeof(数组名),这里的数组名表示整个数组,计算的是数组的大小。
  • &数组名,这里的数组名表示整数数组,取出的是整个数组的地址。
  • 除此之外所有的数组名都表示首元素的地址。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LinkedList的插入速度一定比ArrayList快吗?

目录 一、有一道经典的面试题&#xff0c;“ArrayList 和 LinkedList 的区别是什么&#xff1f;”1、小白答法&#xff1a;2、入门答法&#xff1a;3、系统回答 二、LinkedList的插入速度一定比ArrayList快吗&#xff1f;三、分析一下两种数据结构的add源码1、先分析熟悉的Arra…

07【保姆级】-GO语言的程序流程控制【if switch for while 】

之前我学过C、Java、Python语言时总结的经验&#xff1a; 先建立整体框架&#xff0c;然后再去抠细节。先Know how&#xff0c;然后know why。先做出来&#xff0c;然后再去一点点研究&#xff0c;才会事半功倍。适当的囫囵吞枣。因为死抠某个知识点很浪费时间的。对于GO语言&a…

【C++】复杂的多继承及其缺陷(菱形继承)

本篇要分享的内容是C中多继承的缺陷&#xff1a;菱形继承。 以下为本篇目录 目录 1.多继承的缺陷与解决方法 2.虚继承的底层原理 3.虚继承底层原理的设计原因 1.多继承的缺陷与解决方法 首先观察下面的图片判断它是否为多继承 这实际上是一个单继承&#xff0c;单继承的特…

clang插件对llvm源码插桩,分析函数调用日志(2)--google镜像

tick_plot__compile.ipynb clang插件对llvm源码插桩&#xff0c;分析函数调用日志(1) 分析 进出、链、出 df进出df[ df[tickKind].isin( [FuncEnter,FuncReturn] ) ]#代码中&#xff0c;只有在函数进入时&#xff0c;计算了链条长度 并写磁盘 df入df[ df[tickKind].isin…

18 CDN详解

1、理解CDN 1.CDN 和电商系统的分布式仓储系统一样&#xff0c;就近发货给客户(客户端)&#xff0c;所以&#xff0c;必然是提前在仓库中存储了某些商品. 2.CDN最擅长的是缓存静态数据&#xff0c;比如电商系统的热点静态页面&#xff0c;秒杀场景的页面等.问题&#xff1a;向…

tqdm学习

from tqdm import tqdmepochs 10 epoch_bar tqdm(range(epochs)) count 0 for _ in epoch_bar:count count1print("count {}".format(count))print(_)每次就是一个epoch

磁盘空间占用巨大的meta.db-wal文件缓存(tracker-miner-fs索引服务)彻底清除办法

磁盘命令参考本博客linux磁盘空间满了怎么办. 问题: 磁盘空间被盗 今天瞄了一下我的Ubuntu系统盘&#xff0c; nftdiggernftdigger-Ubuntu:~$ df -h 文件系统 容量 已用 可用 已用% 挂载点 udev 16G 0 16G 0% /dev tmpfs 3.2G 1.9…

【今日文章】:如何用css 实现星空效果

【今日文章】&#xff1a;如何用css 实现星空效果 需求实现tips: 需求 用CSS 实现星空效果的需求&#xff1a; 屏幕上有“星星”&#xff0c;且向上移动。移动的时候&#xff0c;动画效果要连贯&#xff0c;不能出现闪一下的样子。 实现 这里我们需要知道&#xff0c;“星星”是…

简单剖析程序的翻译过程!

本文旨在讲解一段源程序如何翻译成机器所能识别的二进制的命令的&#xff0c;希望通过本文&#xff0c;能使读者对一段程序的翻译过程有进一步的认识&#xff01; 这里首先要介绍的是一段程序从编写完成到执行需要经过以下几个步骤&#xff01; 1.预处理 首先讲到的是预处理&…

UI设计软件有哪些好用和免费的吗?

在我们分享五个有用的原型工具之前&#xff0c;完成原型&#xff0c;将优化界面&#xff0c;这次是UI设计师的任务&#xff0c;UI设计软件对设计师非常重要&#xff0c;UI设计工具是否使用直接影响最终结果&#xff0c;然后有人会问&#xff1a;UI界面设计使用什么软件&#xf…

IP-guard WebServer RCE漏洞复现

0x01 产品简介 IP-guard是由溢信科技股份有限公司开发的一款终端安全管理软件&#xff0c;旨在帮助企业保护终端设备安全、数据安全、管理网络使用和简化IT系统管理。 0x02 漏洞概述 漏洞成因 在Web应用程序的实现中&#xff0c;参数的处理和验证是确保应用安全的关键环节…

大数据毕业设计选题推荐-设备环境监测平台-Hadoop-Spark-Hive

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

基于工业智能网关的汽车充电桩安全监测方案

近年来&#xff0c;我国新能源汽车产业得到快速发展&#xff0c;电动车产量和销量都在持续增长&#xff0c;不仅国内市场竞争激烈&#xff0c;而且也远销海外&#xff0c;成为新的经济增长点。但与此同时&#xff0c;充电设施的运营却面临着安全和效率的双重挑战。 当前的充电桩…

node插件MongoDB(四)—— 库mongoose 的文档操作使用

文章目录 前言&#xff08;1&#xff09;问题&#xff1a;安装的mongoose 库版本不应该过高导致的问题&#xff08;2&#xff09;重新安装低版本 一、插入文档1. 代码2. node终端效果3. 使用mongo.exe查询数据库的内容 二、删除文档1. 删除一条2. 批量删除3. 代码 前言 &#…

Python--列表及其应用场景

1.为什么需要列表 思考&#xff1a;有一个人的姓名(laowang)怎么书写存储程序&#xff1f; 用 变量。如&#xff1a;name laowang 但是&#xff0c;如果要记录很多人的名字&#xff0c;怎么办&#xff1f; 思考&#xff1a; 如果一个班级100位学生&#xff0c;每个人的…

Vue.js 学习总结(3)—— vite 打包图片时报错 Rollup failed to resolve import...

问题 图片依赖&#xff1a; Vite 打包前端项目时图片无法引入&#xff0c;报如下错误&#xff1a; ERROR [vite]: Rollup failed to resolve import "%7BlibeiDanmuKongmu%7D" from "D:/java/workspace/jeecgboot-vue3/src/views/funeral/tombInfo/area.vue?…

ros自定义消息包无法编译生成.h文件的问题解决

ros自定义消息包无法编译生成.h文件的问题解决 想要创建一个ROS功能包专门存放自己自定义的消息&#xff0c;想将这些消息都生成.h&#xff0c;可以由别的功能包来调用。 但是参照网上的诸多帖子未能解决&#xff0c;例如 https://blog.csdn.net/feidaji/article/details/10360…

yolov5 通过视频进行目标检测

打开yolov5-master文件夹&#xff0c;可以看到一个名为data的文件夹&#xff0c;在data中创建一个新的文件夹&#xff0c;命名为videos。 打开yolov5-master中的detect.py可以看到一行代码&#xff08;大概在245行左右&#xff09;为 parser.add_argument(--source, typestr,…

逐次变分模态分解(Sequential Variational Mode Decomposition,SVMD)(附代码)

代码原理 逐次变分模态分解&#xff08;Sequential Variational Mode Decomposition&#xff0c;SVMD&#xff09;是一种用于信号处理和数据分析的方法。它可以将复杂的信号分解为一系列模态函数&#xff0c;每个模态函数代表了信号中的一个特定频率成分。SVMD的主要目标是提取…

ZYNQ_project:key_breath

[Synth 8-327] inferring latch for variable led_breath_reg ["C:/Users/warrior/Desktop/ZYNQ/pl/key_breath/rtl/led_breath.v":66] 因为在组合逻辑中&#xff0c;用了非阻塞赋值的方式赋值信号。 组合逻辑自己给自己赋值会产生组合回环&#xff0c;输出不稳定。 …
最新文章