【C语言】一篇就够了(建议收藏)——超详解sizeof与strlen的用法

简介: 【C语言】一篇就够了(建议收藏)——超详解sizeof与strlen的用法

image.png

【C语言】万字详解——sizeof与strlen的用法

数组名的意义

一维数组

sizeof用法

字符数组

sizeof用法

strlen的用法

字符串数组

sizeof用法

strlen的用法

指针与字符串

sizeof用法

strlen用法

二维数组

sizeof

数组名的意义

在讲所有东西之前,需要先明确一个关键问题:


sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小, 单位是字节

&数组名,这里的数组名表示整个数组,取出的是整个数组的地址

除此之外所有的数组名都表示首元素的地址。

一维数组

sizeof用法

image.png

运行结果:

image.png

解:

image.png

因为int a[ ]里有4个元素,每个元素是int类型,占四个字节,所以整个数组大小为16字节

image.png

此时此刻的数组名a表示的是首元素地址,首元素地址+0,还是首元素地址,地址的大小为 4/8在32/64位平台下

image.png

a是数组名,表示首元素地址,然后对首元素地址解引用,所以*a就是首元素,首元素是个int型,大小为4字节

image.png

a是数组名,表示首元素地址,a+1是第二个元素的地址,所以大小为4/8字节在32/64位平台下

image.png

a[1]就是第二个元素,大小为4字节

image.png

&a取出的是整个数组的地址(从数值的角度看等于首元素地址),只要是地址,大小就为4/8字节在32/64位平台下

image.png

&a取出的是整个数组的地址,* &a是对整个数组的地址解引用,拿到的是整个数组,所以大小为16字节

image.png

&a是数组的地址,&a+1是数组的地址+1,虽然相当于跳过了整个数组,但还是一个地址,所以大小还是4/8

image.png

第1个元素地址,地址大小为4/8字节在32/64位平台下

image.png

第一个元素地址+1,就是第二个元素地址,地址大小为4/8字节在32/64位平台下

字符数组

sizeof用法

image.png

运行结果:

image.png

解:

image.png

此时此刻,sizeof(数组名) 计算的是整个数组的大小,这个数组有6个char类型元素,所以大小为6字节

image.png

这里的arr表示首元素地址,+0之后还是首元素a的地址,只要是地址,所以大小为4/8字节

image.png

arr是首元素地址,对首元素地址解引用,即得到首元素 a ,a是char类型,所以大小为1

image.png

arr[1]表示的就是第二个元素b,大小为1

image.png

这里&arr取的是整个数组的地址,是地址,所以大小为4/8字节

image.png

&arr是数组的地址,&arr+1是数组的地址+1,虽然相当于跳过了整个数组,但还是一个地址,所以大小还是4/8字节

image.png

&arr[0]是首元素地址,+1后取到的是第二位元素的地址,也就是 b 的地址,大小为4/8字节;

strlen的用法

strlen库函数是什么?请看下图

image.png

请看题:

image.png

解:

image.png

因为arr是首元素地址,strlen函数拿到一个地址,从这个地址一路往后读取计数,直到读到 \0 为止,然鹅在arr这个字符数组里,没有 \0 让其读取,所以它会顺着内存地址一直往后,具体哪个内存单元里存有 \0 是未知的,所以长度结果就是个随机未知数

image.png

arr是首元素地址,+0后还是首元素地址,情况与上一题同理,结果是随机数

image.png

*arr是对首元素地址解引用,得到的就是 字符a ,strlen接收到的其实是字符a的ASCII码值97 ,这个97不是一个合法地址,是个野指针,所以这行代码会报错

image.png

arr[1]是第二位元素,就是字符 b ,strlen接收到的是字符 b 的ASCII码值98,与上同理,会报错

image.png

&arr取到的是整个数组的地址,它的实际上等于首元素地址,由于strlen函数的类型是char* ,传过来之后会进行一个类型的隐式转换,地址类型可能会不一样,但是strlen能接收这个地址,即接收到首元素地址并由此往后计数,所以结果也是一个随机值

image.png

&arr是取整个数组的地址,+1是跳过整个数组,拿到的是整个数组之后的地址,所以同理,结果也是一个随机值,只不过这个随机值与strlen(arr)得到的随机值相差6,如图:

image.png

&arr[0]是取第一个元素地址,+1是取到第二个元素地址,即从 字符b 开始向后计数,但是不知道 \0 会出现在后边内存的哪个位置,所以结果也是随机数


字符串数组

image.png

sizeof用法

image.png

解:

image.png

abcdef\0 一共7个字节

image.png

arr表示首元素字符地址,+0之后还是首元素字符 a 的地址,大小为4/8字节

image.png

arr是首元素地址,解引用*arr后就是首元素 字符a,大小为1字节

image.png

arr[1] 表示第二个元素,也就是字符 b ,大小为1字节

image.png

&arr 是整个数组的地址,数组的地址也是地址,大小为4/8字节

image.png

&arr 是数组的地址,&arr+1是跳过整个数组,得到数组后一位的地址,4//8字节

image.png

&arr[0]是第一个元素地址,&arr[0]+1 是第二个元素地址,大小为4/8字节

strlen的用法

image.png

解:

image.png

strlen只对abcdef计数, 不算\0一共6个字符,也就是6字节

image.png

arr是首元素地址,+0后还是首元素的地址,从首地址开始计数,仍然为6字节

image.png

*arr传入的是数组首元素,就是字符a,strlen接收到的其实是字符a的ASCII码值97,97不是合法地址,相当于野指针,所以会报错

arr[1]同理,传入的是第二个元素字符 b ,strlen接收到的是字符b 的ASCII码值98,是非法地址,所以也会报错

image.png

&arr是取得整个数组的地址,数值上等于首元素地址,strlen接收到的就是首元素地址,于是从首元素开始计数,结果为6字节

image.png

&arr+1得到的地址如上图所示,一直向后读取,不知道什么时候才能读取到\0,所以strlen得到的结果为随机值

image.png

&arr[0]是第一个元素地址,+1之后得到第二个元素地址,从第二个元素地址开始读取,读到\0前,一共5个字节

指针与字符串

sizeof用法


image.png

解:

image.png

p是一个指针变量,存的是字符串首元素地址,所以是4/8字节

image.png

p是一个指针变量,存的是字符串首元素址,+1之后就是字符串第二个元素的地址,也就是 b 的地址,是4/8个字节

image.png

p是一个指针变量,存的是字符串首元素地址,对其解引用,*p得到的是字符 a ,类型为char,大小为1个字节

image.png

p[0] = *(p+0) = *p,这三种写法表示的都是首元素字符 a ,大小为1个字节

image.png

p是一个指针变量,是一个地址,对指针变量取地址,得到的是一个地址的地址,还是一个地址,所以大小还是4/8字节

image.png

p是个指针变量,字符串通过指针存到内存中,其实也可以理解成这是内存中一块连续的储存空间,就像数组一样,这里的 &p+1 ,p是一个指向字符串首元素的一级指针,&p是指针变量p的地址,是一个二级指针,+1之后,相当于二级指针+1,指向的是一块我们不知道的未知空间,但说到底还是一个地址,大小仍是4/8字节,如图所示:

image.png

字符串也是一块连续空间,可以像数组一样通过 [ ] 访问p[0] = *(p+0) = *p这三种表示方法都可以表示字符串元素,这里&p[0]表示首元素地址,+1就是第二个元素字符b的地址,是地址,大小为4/8字节

strlen用法

image.png

解:

image.png

p存放的是字符串首元素地址,相当于给strlen传入了字符a的地址,strlen向后读取,直到\0,总计6个字符,就是6字节

image.png

p存放的是字符串首元素地址,p+1就是第二个元素字符b的地址,相当于给strlen传入了字符b的地址,strlen向后读取,直到\0,总计5个字符,就是5字节

image.png

p是首元素地址,*p相当于访问这个地址,传入strlen的是字符a的ASCII码值97,97是非法地址,是个野指针,系统报错

image.png

p[0] = *(p+0) = *p表示的都是首元素字符a,传入strlen的是字符a的ASCII码值97,97是非法地址,是个野指针,系统报错

image.png

如图所示,&p是一个二级指针究其根本还是是一个地址,strlen接收到的还是一个地址,会从这个地址向后读取,不知道在何处能读到\0,所以结果会是一个随机值,&p+1同理

image.png

&p[0]是首元素地址,+1变成第二个元素地址,从该地址向后读取直到\0,总计5个字符

二维数组

image.png

sizeof

image.png

sizeof(数组名)表示的是整个数组的大小,这个int型二维数组是3×4的,大小为12×4=48个字节

image.png

sizeof(a[0][0]) 计算的是第一行第一列的元素的大小,这是一个int型二维数组,大小为4字节

image.png

我们可以将二维数组的每一行看成一个一维数组,a[0]就相当于一维数组的数组名,所以sizeof(a[0]),数组名单独放在sizeof里,计算的就是第一行数组的大小,就是16字节


sizeof(a[0]+1)表示,a[0]是第一行数组的数组名,并没有单独放在sizeof内部,也没有&

所以a[0]表示首元素的地址,也就是第一行这个数组的第一个元素的地址

所以a[0]+1就是第一行,第二个元素的地址,大小为4/8字节

image.png

(a[0]+1)表示第一行第二个元素的地址,解引用后就是第一行第二个元素,大小是4字节

image.png

这里二维数组的数组名表示首元素地址 (注意:这里的首元素指的是第一行)

a的指针类型是int(*)[4]

a+1代表的是第二行数组的地址,也就是4/8字节

image.png

*(a+1)就是第二行数组,相当于a[1],数组名单独放在sizeof内部,sizeof(a[1]), 第二行数组大小为16字节

image.png

a[0]是第一行的数组名,&a[0]是对数组名取地址,拿到的是第一行数组的地址,所以这时候+1,拿到的是第二行数组的地址,所以大小为4/8

image.png

&a[0]+1 是第二行数组地址,对其解引用*(&a[0]+1))得到的就是第二行数组第二行数组名单独放在sizeof内部,求的是第二行数组的大小,是16字节

image.png

a是首元素地址,就是二维数组的第一行数组,对其解引用,*a拿到的是第一行数组,第一行数组名单独放在sizeof内部,求的是第一行数组的大小,大小是16字节

image.png

sizeof内部表达式是不参与运算的,a[3]是第四行数组名,二维数组创建好了之后,元素是固定的,这个时候,假如第四行存在,sizeof会根据a这个二维数组,根据二维数组每一行的类型推导出第四行大小,所以sizeof(a[3])求出第四行大小是16字节


































相关文章
|
1月前
|
C语言
如何在C 语言中使用运算符sizeof
如何在C 语言中使用运算符sizeof
12 0
|
1月前
|
C语言
【C语言】指针进阶之sizeof和strlen函数的对比
【C语言】指针进阶之sizeof和strlen函数的对比
|
1月前
|
算法 编译器 C语言
C语言猜数字小游戏(也包含python实现的用法)
本文基于VS2022、pycharm和前面的知识,写一个凭借分支与循环的小游戏,比如: 写一个猜数字游戏 游戏要求: 电脑自动生成1~100的随机数 玩家猜数字,猜数的过程中,根据猜测数据的大小给出大了或小了的反馈,直到猜对,游戏结束 在pyhton中生成随机数是比较简单的,可以直接导入random的包,直接生成随机数,导致写猜数字小游戏变成了判读语句和循环语句嵌套就能写出来,所以我不做过多的介绍了,可以直接看后面的代码展示,想了解更多的python可看python的基础知识,这里面有我在学习python的过程中写的笔记
31 0
|
4月前
|
C语言
C语言转义字符第二篇和strlen库函数的使用
C语言转义字符第二篇和strlen库函数的使用
|
4月前
|
编译器 C语言
C语言的转义字符,转义字符的用法
C语言的转义字符,转义字符的用法
|
4月前
|
C语言
C 语言中布尔值的用法和案例解析
在编程中,您经常需要一种只能有两个值的数据类型,例如: - 是/否 - 开/关 - 真/假 为此,C语言有一个 `bool` 数据类型,称为布尔值。
113 1
|
22天前
|
存储 C语言
【我爱C语言】详解字符函数isdigit和字符串转换函数(atoi和snprintf实现互相转换字符串)&&三种strlen模拟实现1
【我爱C语言】详解字符函数isdigit和字符串转换函数(atoi和snprintf实现互相转换字符串)&&三种strlen模拟实现
|
1月前
|
存储 编译器 C语言
c语言——关于不使用strlen求字符串长度
在日常生活中,我们有时会遇到这样的题目,不使用strlen函数求字符串长度,关于这种问题,我们其实有很多的方法来解决,首先我们要了解strlen
30 0
|
1月前
|
存储 C语言
c语言中strlen与sizeof的区别(指针面试题详解帮你深度区分!)
c语言中strlen与sizeof的区别(指针面试题详解帮你深度区分!)
|
1月前
|
C语言
C语言中关键字static的三种用法
C语言中关键字static的三种用法