C语言sizeof操作符与strlen函数

1.sizeof与strlen的介绍

(1).sizeof

  • 计算变量的内存空间大小
  • 底层实际上是对变量类型的计算。
  • 是一个单目操作符,不是函数,后面的括号可以省略

(2).strlen 

函数原型
  • strlen是一个函数,返回的size_t类型的数据,头文件为string.h
  • 计算字符串'\0'前的字符个数,计算字符长度
  • 如果没有找到'\0'就继续往下找,通常对于没有'\0'的字符生成的是一个随机值
  • 函数通过首元素的地址往下找。

(3)sizeof与strlen对比 

对比sizeofstrlen
所属类型单目操作符库函数
计算内容

元素的内存空间大小

(单位:字节)

元素的个数
特性

1.括号可有可无

2.只关注变量的类型

3.不关注变量中的数据是啥

1.通过地址往后找

2.找到' \0 '后结束

3.找不到' \0 '一直向后找

2.sizeof和strlen的使用

下面通过使用sizeof和strlen对数组进行操作的例子来加深我们的理解吧

在举例前我们先要知道数组和sizeof(数组名),以及取地址数组名的区别:

对比一维数组的数组名,以arr[10]为例:

对比arrsizeof(arr)&arr
含义数组首元素地址计算整个数组的大小整个数组的地址
条件除了后面两种情况arr单独在sizeof内部任何时候

 再对比一下二维数组的数组名,以arr[10][10]为例:

arr第一行数组的地址
arr[0]

第一行数组名,是数组名就等于第一行第一个元素的地址

&arr整个数组的地址
&arr[0]第一行数组的地址
sizeof(arr)整个数组的大小
sizeof(arr[0])第一行数组的大小

总结:

  1. 只要arr不单独存在sizeof内部或者被取地址,那么都是首元素的地址。
  2. 二维数组的数组名是第一行数组的地址,二维数组使用下标访问符一次是某一行数组的名字,同时这种情况也要除去单独在sizeof内部和取地址。

(1)一维整形数组和sizeof

题目以及分析:
int a[] = { 1,2,3,4 };
printf("%zd\n", sizeof(a));//数组总大小,4*4=16字节
printf("%zd\n", sizeof(a + 0));//数组首元素的地址,首地址+0=首地址,地址的大小是的4/8字节
printf("%zd\n", sizeof(*a));//a是数组首元素的地址,*a就是首元素,计算的就是首元素的大小,整形4字节
printf("%zd\n", sizeof(a + 1));//a是数组首元素的地址,地址+1跳过一个元素,那就是第二个元素的地址,4/8
printf("%zd\n", sizeof(a[1]));//第二个元素,整形int,4字节
printf("%zd\n", sizeof(&a));//&a取出的是数组整个元素的地址,还是地址,4/8/*****************************重点******************************/
printf("%zd\n", sizeof(*&a));//不是单独的&a,a表示首元素的地址,&a是取出首元素的地址的地址,再解引用就是首元素的地址,4/8
printf("%zd\n", sizeof(&a + 1));//取地址a是整个数组的地址,+1跳过整个数组,地址是数组末尾元素后面的地址的,//实际还是地址,sizeof只关注类型,不关注指针是否越界,// 换句话说这个指针并没有被使用只是计算大小,所以是可以计算的
/****************************************************************/printf("%zd\n", sizeof(&a[0]));//取出首元素的地址,是地址,4/8
printf("%zd\n", sizeof(&a[0] + 1));//取出首元素的地址,地址+1,跳过一个元素,第二个元素的地址,是地址,4/8
//正确率:错1,printf("%d\n", sizeof(*&a));
//正确理解1:&a是整个数组的地址,与&a单独作用无关,&a取出的就是整个数组的地址,解引用就是拿出整个数组,整个数组的大小就是16
//理解2:解引用*和取地址&相互抵消,剩下a,就是数组名,sizeof(a)==16
答案: 

(2).使用大括号存储的字符数组 

A.sizeof

题目以及分析:
	//字符数组,字符单个存储,只有abcdef这六个元素,没有'\0'printf("%zd\n", sizeof(arr));//sizeof操作时,单独只有个数组名时,整个数组的大小,1*6=6字节printf("%zd\n", sizeof(arr + 0));//arr表示数组首元素的地址,首元素的地址+0,就是首元素的地址,是地址,大小就是4/8printf("%zd\n", sizeof(*arr));//arr是数组首元素的地址,解引用首元素的地址就是首元素,字符char,1字节printf("%zd\n", sizeof(arr[1]));//第二元素,字符char,1字节printf("%zd\n", sizeof(&arr));//&arr是整个元素的地址,是地址,大小就是4/8printf("%zd\n", sizeof(&arr + 1));//整个数组的地址,地址是数组指针类型,+1跳过1个数组的大小,就是末元素后元素的地址,是地址,4/8printf("%zd\n", sizeof(&arr[0] + 1));//&arr[0]是取出首元素的地址,地址是字符指针,+1跳过一个元素,指向第二个元素,是地址,大小4/8//正确率:全对
答案: 

B.strlen

题目以及分析:
char arr[] = { 'a','b','c','d','e','f' };
//字符数组,字符单个存储,只有abcdef这六个元素,没有'\0'
printf("%zd\n", strlen(arr));//strlen函数计算字符个数,给的数组首元素的地址,strlen从这后向找,无\0,随机值
printf("%zd\n", strlen(arr + 0));//首元素地址+1还是首元素的地址,从首元素开始向后找,无\0,随机值
/*重点*/
//printf("%zd\n", strlen(*arr));//arr表示首元素的地址,首元素的地址解引用,得到第一个元素,就是a,
//因为,strlen函数的参数是地址,那么字符a就被转为它的ASCII码值,97,那么地址就是97,
//但是因为这个地址是个特殊地址,无法被访问,所以报错
//printf("%zd\n", strlen(arr[1]));//arr[1]表示第二个元素,那就是字符b,
//同样也被转为ASCII码值对应的数字98,地址98也是特殊地址无法访问
printf("%zd\n", strlen(&arr));//&arr是整个数组的地址,是数组指针,那就被转为字符指针,指针是首元素的地址,无\0,随机值
printf("%zd\n", strlen(&arr + 1));//&arr是整个数组的地址,+1跳过整个数组,
//地址就到末元素后面一个元素的地址,从这开始向后找,后面找不到'\0',就一直找下去,生成的随机值,随机值比第一个开始找的多6个
printf("%zd\n", strlen(&arr[0] + 1));//首元素的地址+1,到第二个元素的地址,从第二个元素向后找,没有斜杠0,随机值,
//比从第一个开始找的多一个数
//正确率:全对
//注意:1.特殊地址无法访问,会报错;2.大括号存字符无\0随机值
答案: 

(3).使用字符串存储的字符数组

A.sizeof

题目以及分析:
char arr[] = "abcdef";
//字符串存储,数组大小也没有限定,存完字符后后再存了一个'\0'
printf("%zd\n", sizeof(arr));//计算的是整个数组的内存大小,7*1=7个字节
printf("%zd\n", sizeof(arr + 0));//arr是数组首元素的地址,首元素的地址+0=首元素的地址,地址的大小,4/8
printf("%zd\n", sizeof(*arr));//arr是数组首元素的地址,首元素的地址解引用得到的是首元素,首元素的大小char,1个字节
printf("%zd\n", sizeof(arr[1]));//arr[1]是首元素,char,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跳过1个元素,那就是第二个元素的地址,是地址,4/8
//正确率:全对
答案: 

B.strlen

题目以及分析:
char arr[] = "abcdef";
//字符串存储,数组大小也没有限定,存完字符后后再存了一个'\0'
printf("%d\n", strlen(arr));//arr是首元素的地址,计算'\0'前的元素个数,6个
printf("%d\n", strlen(arr + 0));//arr是首元素的地址,+0还是首元素的地址,计算出6个元素
//printf("%d\n", strlen(*arr));//arr是首元素的地址,解引用得到首元素,字符a转换为ASCII码值97,97是个特殊地址无法访问,报错。
//printf("%d\n", strlen(arr[1]));//同上,arr[1]='b',转为ASCll码值98,特殊地址无法访问
printf("%d\n", strlen(&arr));//&arr取出的是整个数组的地址,而strlen的参数接收的是char*类型,就会进行强制类型转换,
//而整个数组的地址就是首元素的地址,那就是首元素的地址,从后计算得到6个元素
printf("%d\n", strlen(&arr + 1));//&arr取出的是整个数组的地址,+1就会跳过整个数组,到达\0后面
//拿到后面这个元素地址,注意这里操作的任然是地址,从这向后找,找不到'\0',随机值
printf("%d\n", strlen(&arr[0] + 1));//&arr[0],第一个元素的地址,+1第二个元素的地址,从第二个元素开始计算,5个
//正确率:全对
答案: 

(4).使用指针存储常量字符串

A.sizeof

题目以及分析:
char* p = "abcdef";//首元素的地址
printf("%zd\n", sizeof(p));//p是一个指针,大小4/8
printf("%zd\n", sizeof(p + 1));//p+1跳过一个元素,b的地址,是地址,4/8
printf("%zd\n", sizeof(*p));//*p得到'a',char类型数据,1个字节
printf("%zd\n", sizeof(p[0]));//p[0]==*(p+0)==数组名[0]==第一个元素,char类型,1个字节
printf("%zd\n", sizeof(&p));//&p,取出第一个元素的地址的地址,是地址,4/8
printf("%zd\n", sizeof(&p + 1));//&p,取出第一个元素的地址的地址,+1跳过一个地址,还是地址,4/8
printf("%zd\n", sizeof(&p[0] + 1));//&p[0]==&p[0]==&*(p+0)=p,是地址,4/8
//正确率:全对
答案: 

B.strlen

题目以及分析:
char* p = "abcdef";//首元素的地址,常量字符串后面也有\0
printf("%zd\n", strlen(p));//从首元素开始计算,6个元素
printf("%zd\n", strlen(p + 1));//首元素地址+1,从第二个元素开始计算,5个元素
//printf("%d\n", strlen(*p));//*p是'a',转为ACSII码值97,特殊地址,无法访问,报错
//printf("%d\n", strlen(p[0]));//p[0]==数组名[0]==*(p+0)==*p=='a',同上,报错
printf("%zd\n", strlen(&p));//&p,取出地址的地址,从后计算,找不到'\0',随机值
printf("%zd\n", strlen(&p + 1));//&p,取出地址的地址,+1跳过一个地址,从后计算,找不到'\0',随机值
printf("%zd\n", strlen(&p[0] + 1));//&p[0]+1==&*(p+0+1==p+1,从第二个元素向后计算,5
//正确率:全对
答案: 

(5).二维数组和sizeof

B.strlen

题目以及分析:
//二维数组数组名是第一行数组的地址,&数组名是取出整个数组的地址
int a[3][4] = { 0 };
printf("%zd\n", sizeof(a));//数组单独存在sizeof的内部,计算的是整个数组的大小,3*4*4=48
printf("%zd\n", sizeof(a[0][0]));//第一行第一列元素啊,int类型,4个字节
//重点//
printf("%zd\n", sizeof(a[0]));//第一行数组名字,单独放在sizeof的内部,计算第一列数组的大小,4*4=16
printf("%zd\n", sizeof(a[0] + 1));//第一行第一个元素地址+1==第一行第二列元素地址,4/8
printf("%zd\n", sizeof(*(a[0] + 1)));//解引用第二列数组,计算数组大小,4*4=16
//
printf("%zd\n", sizeof(a + 1));//a是第一行的地址,+1第二行,还是地址,4/8
printf("%zd\n", sizeof(*(a + 1)));//a是第一行数组的地址,+1第二行,解引用是数组,4*4=16
printf("%zd\n", sizeof(&a[0] + 1));//取出第一行的地址,+1第二行的地址,是地址,4/8
printf("%zd\n", sizeof(*(&a[0] + 1)));//第二行的地址解引用,第二行数组大小,4*4=16
printf("%zd\n", sizeof(*a));//a是第一行的地址,解引用是第一行的数组大小,4*4=16
printf("%zd\n", sizeof(a[3]));//第四行数组名单独在sizeof内部,计算的是数组大小,虽然越界,但没使用,底层是类型,4*4=16
//正确率:错一个,printf("%d\n", sizeof(*(a[0] + 1));
错误分析:解引用第二列数组,计算数组大小,4*4=16
正确分析:第一行数组名表示第一行数组第一个元素的地址,得到元素,int,4个字节
答案: 

总的来说只要理解了sizeof和strlen的作用,知道数组名不同场景下所表示的含义这种题目就很简单啦!!!


本章内容结束,我们下章见,拜拜!!!

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

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

相关文章

Python爬虫:requests模块的基本使用

学习目标: 了解 requests模块的介绍掌握 requests的基本使用掌握 response常见的属性掌握 requests.text和content的区别掌握 解决网页的解码问题掌握 requests模块发送带headers的请求掌握 requests模块发送带参数的get请求 1 为什么要重点学习requests模块&…

如何在安卓端的SAP里配置打印机

1、转到 SPAD 事务(“假脱机管理”屏幕)。单击“设备/服务器”选项卡,输入输出设备的名称,然后点击显示按钮。 2、如果打印机已配置,它将显示设备属性、输出设备属性和纸盒信息的所有详细信息。如果输入新的打印机名称…

AndroidStudio设计登录页源码(音悦app)

目录 一、代码 二、效果 一、代码 1.在activity_main.xml里的代码 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent&quo…

import gdal 报错

1.下载gdal https://www.lfd.uci.edu/~gohlke/pythonlibs/#gdal 2.安装正确版本 &#xff08;1&#xff09;查看python版本 python -v我的版本Python 3.7.9 建议下载 GDAL-3.4.2-cp37-cp37m-win_amd64.whl &#xff08;2&#xff09;放到Scripts文件夹下 执行 pip install GD…

mysql启动报错:ERROR! The server quit without updating PID file

mysql 重启或者启动时报错&#xff1a;ERROR! The server quit without updating PID file (/home/data/mysql/e787y33206.novalocal.pid).如下图: 重启报错&#xff1a; 启动也报错 这个错误是因为有mysql启动没有完全结束&#xff0c;如果是重启mysql服务&#xff0c;则在…

L2-035 完全二叉树的层序遍历(Python)

L2-035 完全二叉树的层序遍历 分数 25 全屏浏览 切换布局 作者 陈越 单位 浙江大学 一个二叉树&#xff0c;如果每一个层的结点数都达到最大值&#xff0c;则这个二叉树就是完美二叉树。对于深度为 D 的&#xff0c;有 N 个结点的二叉树&#xff0c;若其结点对应于相同深度…

超详细——VsCode连接远程主机/虚拟机并设置免密登录

超详细——VsCode连接远程主机/虚拟机并设置免密登录 文章目录 超详细——VsCode连接远程主机/虚拟机并设置免密登录[toc]连接到远程主机/虚拟机步骤1、打开vscode拓展 搜索 remote-ssh并安装步骤2、打开远程主机/虚拟机的ssh服务步骤3、设置连接远程主机的配置文件 设置免密登…

机械女生,双非本985硕,目前学了C 基础知识,转嵌入式还是java更好?

作为单片机项目开发的卖课佬&#xff0c;个人建议&#xff0c;先转嵌入式单片机开发方向&#xff0c;哈哈。 java我也学过&#xff0c;还学过oracle、mysql数据库&#xff0c;只是当时没做笔记&#xff0c;找不好充分的装逼证据了。 从实习通过业余时间&#xff0c;学到快正式毕…

可以用SEO进行市场分析吗?(川圣SEO)蜘蛛池

baidu搜索&#xff1a;如何联系八爪鱼SEO&#xff1f; baidu搜索&#xff1a;如何联系八爪鱼SEO&#xff1f; baidu搜索&#xff1a;如何联系八爪鱼SEO&#xff1f; SEO如何去进行关键词市场占比分析呢&#xff1f;可以进行市场分析吗&#xff1f; SEO&#xff0c;即搜索引…

Linux学习:权限

目录 1. shell命令的工作原理与存在意义1.1 shell命令解释器存在的意义1.2 shell解释器的工作原理 2. Linux操作系统&#xff1a;用户2.1 什么是用户2.2 用户的切换操作2.3 用户权限划分的意义 3. Linux中权限的种类和意义3.1 什么是权限3.2 sudo指令与短暂提权 4. 文件类型与文…

嵌入式3-12

1.整理思维导图 2.把上课没做完的结构体大小求完(写出过程) 3.把枚举部分的练习题&#xff0c;再做一遍 4.三种验证大小端存储大的代码写一遍 1.思维导图在最后 2.结构体大小 struct data{ 1233000044444444&#xff0c;16字节char t1; char t2; unsigned …

【PLIO学习总结】laserMapping中的时间戳与状态更新逻辑

本文仅用于个人学习总结记录。如有错误&#xff0c;请批评指正。 0、PLIO简要思路 从PLIO的论文中&#xff0c;可以知道&#xff0c;完整的PLIO算法采用IMU和LiDAR数据同时作为“输入”&#xff0c;维护状态变量包括加速度和角速度。 同时&#xff0c;PLIO是一种distortion-…

springboot266基于Web的农产品直卖平台的设计与实现

农产品直卖平台的设计与实现 摘 要 计算机网络发展到现在已经好几十年了&#xff0c;在理论上面已经有了很丰富的基础&#xff0c;并且在现实生活中也到处都在使用&#xff0c;可以说&#xff0c;经过几十年的发展&#xff0c;互联网技术已经把地域信息的隔阂给消除了&#x…

C#构造函数

C#中的构造函数是一种特殊的方法&#xff0c;用于创建和初始化类的对象。构造函数的名称与类的名称相同&#xff0c;并且没有返回类型。 在C#中&#xff0c;构造函数有以下几种类型&#xff1a; 默认构造函数&#xff1a;如果在类中没有定义构造函数&#xff0c;系统将自动提供…

二、HarmonyOS 操作系统以及相关生态

前言 2019年8月9日&#xff0c;华为技术有限公司在华为开发者大会上正式发布了HarmonyOS 1.0&#xff0c;同时宣布该操作系统源代码开源。 2020年9月10日&#xff0c;HarmonyOs 2.0正式发布。与HarmonyOs 1.0版本相比&#xff0c;HarmonyOs 2.0在分布式软总线、分布式数据管理、…

Java数据结构-二叉树

文章目录 前言一、树型结构1.1概念1.2 知识点1.3 树的表示形式1.4 树的应用 二、二叉树2.1 概念2.2 两种特殊的二叉树2.3 二叉树的性质2.4 二叉树的存储2.5 二叉树的基本操作2.5.1 二叉树的遍历2.5.2 二叉树的基本操作 前言 对学习的二叉树的知识进行总结。 一、树型结构 1.1…

蓝桥杯--日期统计

目录 一、题目 二、解决代码 三、代码分析 ​四、另一种思路 五、关于set文章推荐 一、题目 二、解决代码 #include <bits/stdc.h> using namespace std; int main() {int arr[100] { 5,6,8,6,9,1,6,1,2,4,9,1,9,8,2,3,6,4,7,7,5,9,5,0,3,8,7,5,8,1,5,8,6,1,8,3,0,…

【大模型API调用初尝试二】星火认知大模型 百度千帆大模型

大模型API调用初尝试二 科大讯飞—星火认知大模型单轮会话调用多轮会话调用 百度—千帆大模型获取access_token单轮会话多轮会话 科大讯飞—星火认知大模型 星火认知大模型是科大讯飞开发的&#xff0c;直接使用可以点击星火认知大模型&#xff0c;要调用API的话在讯飞开发平台…

C#版开源免费的Bouncy Castle密码库

前言 今天大姚给大家分享一款C#版开源、免费的Bouncy Castle密码库&#xff1a;BouncyCastle。 项目介绍 BouncyCastle是一款C#版开源、免费的Bouncy Castle密码库&#xff0c;开发人员可以通过该项目在他们的 C# 应用程序中使用 Bouncy Castle 提供的各种密码学功能&#x…

虚幻4 | 制作游戏——学习记录(一)

1. 启动Epic后下载虚幻4&#xff0c;打开虚幻4后新建一个第三人称游戏项目&#xff0c;效果如下&#xff1a; &#xff08;1&#xff09;内容/ThirdPersonBP/Blueprints中的ThirdPersonCharacter&#xff08;左下角人物&#xff09; 这是模板中使用的主要蓝图类&#xff0c;它…