全网最详细的sizeof运算和strlen函数讲解(通过多种数据类型举例)

一、对于sizeof的理解

1. sizeof对常见数据类型的计算

        我们首先要明确的是sizeof是一个运算符,并不是函数它是用来计算所占内存空间的大小,单位是字节,主要是针对我们所给的数据类型分析得出的。

比如:我们用一段不完整的代码表示出来

int a = 2;
char b = '3';
short c = 2;
long long d = 2;

通过sizeof计算得到:
a 的大小是 4,因为 a 的数据类型是 int,int 是4个字节;
b 的大小是 1,因为 b 的数据类型是 char,char 是4个字节;
c 的大小是 2,因为 c 的数据类型是 short,short 是2个字节;
d 的大小是 8,因为 d 的数据类型是 longlong,longlong 是8个字节

所以我们不难看出的是:

sizeof计算所占内存的大小,就是看我们传入的数据,它的数据类型是几个字节,sizeof算出来的就是几个字节。

2. 常见数据类型所占字节大小

1字节 = 8比特位
1比特位 = 1个二进制数

数据类型占内存空间(单位字节)
int4
short2
long32位机器为4字节,64位机器为8字节
double8
float4
指针32位机器为4字节,64位机器为8字节

如:int*p,char*ch,short*s,...
这些都是指针类型,所以无论是int*,char*,short*,只要是指针,就是4/8个字节

3. sizeof对数组的计算

3.1 数组名和&数组名

数组名一般表示的是数组首元素的地址,但是有两个例外:

1.sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节
2.&数组名,这里的数组名表示整个数组,取出的是整个数组的地址

3.2 sizeof与数值型数组

我们知道了sizeof是对数据的数据类型的大小的计算,那么对数组是如何计算的呢?

比如:

#include "stdio.h"
 int main()
 {
     int arr[5] = {1,2,3,4,5};
     printf("%d\n",sizeof (arr));
     printf("%d\n",sizeof (arr[0]));
     return 0;
 }

        我们首先定义了一个一维数值型数组,数组arr有五个元素,我们这里 sizeof(arr)计算的是整个数组的大小,该数组元素有5个,都是int类型,整个数组大小就是 5 * 4 = 20,也就是20个字节。

        而 sizeof(arr[0]) 计算的是我们arr数组的第一个元素,下标是0,arr[0] 的数据类型是 int,所以是4个字节。
        那么对于其他种类的数值型数组,大家可以自己动手来观察一下。

        (记住sizeof是根据你给的数据的数据类型来计算的哦)

3.3 sizeof与字符数组

我们上面学会了对数值型的数组进行sizeof计算,那字符数组是否也一样呢?字符串类型呢?

#include "stdio.h"
 int main()
 {
     char arr[5] = {'a','b','c','d','e'};
     printf("%d\n",sizeof (arr));
     printf("%d\n",sizeof (arr[0]));
     return 0;
 }

        我们看到 sizeof(arr) 得到的是 5,因为这里的 arr 数组名是代表的整个数组,数组一共有五个元素,每个元素是 char类型,所以整个数组大小是5*1 = 5个字节,那么sizeof(arr[0])里面的 arr[0] 数据类型是 char,char是 1 个字节,所以 sizeof 得到就是1个字节。

        这跟上面数值型数据是一样的道理,都是看sizeof里面的数据类型是什么。

3.3 sizeof与字符串

#include "stdio.h"
 int main()
 {
     char arr[] = "abcde";
     printf("%d\n",sizeof (arr));
     printf("%d\n",sizeof (arr[0]));
     return 0;
 }

        在这里我们看到了不一样的结果了,跟以往不同,我们明明是给了字符串 5 个元素,那为什么sizeof(arr) 却得到了 6 呢?

        这是因为我们在给字符串赋值的时候,字符串末尾自动补上了一个 ‘\0’ 

        所以 sizeof 在计算大小的时候也会将 ‘\0’ 计算在里面,也就是说,在 sizeof(arr) 里认为,有6个元素,分别是 abcde\0,每个元素都是char类型,就是6个字节。

        大家学到了这里其实已经可以自己去推理更多数据类型的计算了,如union联合体类型,结构体类型,这里就涉及到内存对齐的规则了。

        具体博客:C/C++内存对齐规则(结构体、联合体、类)-CSDN博客

4. sizeof的深入

        我们在上面讲到,sizeof 计算得到的大小是括号内数据的数据类型所占的字节数
        那么sizeof是否可以对算法来计算大小呢?在sizeof里的算式是否真的进行计算了

我们在下面举例说明:

#include "stdio.h"
 int main()
 {
     int a = 2;
     int b = 3;
     short c = 1;
     printf("%d\n",sizeof (c = a + b));
     printf("c=%d\n",c);
 }

在上面代码中我们可以看到,sizeof 算出来的是 2,c 的值是1;

        那也就是说,sizeof 收到的数据类型是 short,c的值并没有改变,也就是sizeof里面并没有进行计算,但是进行了数据类型的统一。


        所以我们在使用sizeof时,只需要关注括号里的数据类型最后是什么,括号里的任何计算都没有进行。

二、strlen函数的定义与用法:

1. strlen函数的定义

        首先 strlen 是一个库函数,用来计算字符串长度的,遇到字符串中的‘\0’终止得到的长度是'\0'之前的字符个数,不包括'\0'本身
        在引用 strlen 函数需要写 #include <string.h> 这个头文件。

2. strlen函数定义类型

 size_t   strlen   (const char * str)

我们可以看到 strlen 的参数是一个指针(地址),返回类型是size_t

size_t 类型也是 unsigned int ,是由 typedef unsigned int size_t 得到的

所以我们可以用 size_t 类型 来接收strlen函数的返回值 ,实参部分要传入一个地址,也就是指针。

3. strlen与字符串

#include "string.h"
#include "stdio.h"
 int main()
 {
     char ch[] = "abcde";
     unsigned int n = strlen(ch);
     size_t m = strlen(ch);
     printf("长度是%d\n",n);
     printf("长度是%d\n",m);
     return 0;
 }

        如图可以看出,我们给strlen函数传的形参是ch,也就是数组名,代表首元素地址,所以strlen函数在接收这个首元素地址之后,会往后走下去,直到找到'\0'才停止,返回'\0'之前的字符个数
        也可以看出size_t和unsigned int是一个类型,只不过是通过typedef重命名来的。

4. strlen与字符数组

#include <stdio.h>
#include <string.h>
int main()
{
    char ch[5] = {'a', 'b', 'c', 'd', 'e'};
    printf("%zu\n", strlen(ch));
    return 0;
}

此时的结果是一样的,这是为什么呢?因为strlen是要遇到\0才结束的,字符串的末尾是有隐藏的\0的,但是字符数组的\0是随机的,可能出现在任何位置,所以结果也就是不唯一的;

5.sizeof和strlen的区别

  • strlen是一个库函数使用时需要引用#include<string.h>这个头文件,而sizeof是一个运算符号;
  • strlen计算的是’\0'之前的字符个数,sizeof计算的是所占空间内存的大小,单位是字节;
  • strlen计算时不包含'\0',而sizeof包含'\0';
  • strlen遇到'\0'才结束;
  • strlen只能用 char* 或者 const char* 做参数,sizeof可以用类型做参数;

三、sizeof和strlen的面试题

sizeof运算与strlen函数的面试笔试题(排版很舒服)-CSDN博客

sizeof运算与strlen函数笔试题(二)-CSDN博客

sizeof运算和strlen函数的笔试题(三)-CSDN博客

  • 35
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论
第九章 数组 9.1 理解数组 C语言数组是一个由若干同类型数据组成的集合,数组由连续的存储单元组成,最低地址对应于数组的第一个元素,最高地址对应于最后一个元素。 9.2 一维数组 9.2.1 一维数组定义 定义形式: 类型说明符 数组名[常量表达式] 类型说明符是任一种基本数据类型或构造数据类型。数组名是用户定义的数组标识符。方括号中的常量表达式表示数据元素的个数,也称为数组的长度,数组中每个成员称为数组元素。 对于数组的说明: (1)类型说明符实际上是指数组元素的类型。 (2)数组名实际上就是第一个元素的地址,是一个常量。 (3)方括号中常量表达式表示数组元素的个数,可以是符号常量。因为数组和一般变量的空间在编译阶段分配,而变量的值在运行时才获得,编译时并不知道变量的值,因此不能用变量定义数组的大小。 (4)数组占用空间大小的计算,可以用sizeof运算符。数组总字节数=sizeof(类型说明符)*数组长度=sizeof(数组名)。 9.2.2 一维数组引用 数组元素的的标识方法为数组名后跟下标。引用数组元素的一般形式为:数组名[下标]。下标只能为整型常量、整型变量、整型表达式。 每个数组元素和变量一样,可以进行读写、输入输出操作等。 数组定义的方括号中给出的是数组长度,只能是常量。数组元素引用中的下标是元素在数组中位置的标识,可以是整型常量、整型变量、整型表达式。 注意: (1)使用具有N个元素的数组时,引用下标为0~N-1,第一个元素为数组名[0],最后一个元素为数组名[N-1]。数组名代表起始地址,下标代表从起始地址开始偏移几个元素,第一个元素偏移0,第N个元素偏移N-1,下标为N-1。 (2)引用数组元素下标越界时,运行并不报错(因为检查是否越界占用系统时间,C语言崇尚高效),但越界使用可能破坏其他数据。 (3)C语言中只能单个的使用下标标识每个数组元素。 用循环语句输入、输出数组元素的值: int iArr[5]; for(i=0;i<5;i++) scanf("%d",&iArr;); for(i=0;i<5;i++) printf("%d",iArr[i]); 对元素分别赋值1,2,3,4,5 int iArr[5]; for(i=0;i<5;i++) iArr[i]=i+1; (4)数组定义后若不给元素赋值,则值由编译器指定无意义的数据。 9.2.3 一维数组初始化 给数组赋值有两种方法:赋值语句对数组元素逐个赋值,初始化赋值。初始化赋值指在数组定义时给数组元素赋予初值。 数组初始化是在编译阶段进行的,可以减少运行时间,提高效率。 初始化赋值的形式: 类型说明符 数组名[常量表达式]={值1,值2,···,值n}; 对数组初始化赋值的说明: (1)可以只给部分元素赋初值,当{}中值的个数少于元素个数时,只给前面部分元素赋初值,未赋值的元素会赋予与数组元素类型相关的特定值,整型为0,浮点型为0.0,字符型为'\0'。 补充说明:字符'0'和'\0'区别: 字符'0':ASCII码为48,内存中存放表示:00110000。 字符'\0' :ASCII码为0,表示一个字符串结束的标志。这是转义字符(整体视为一个字符)。由于内存中存储字符,存储的是对应字符集的字符编码,所以内存中的表现形式为00000000。 (2)只能给元素逐个赋值。如给5个元素全部赋初值1,要写成: int iA[5]={1,1,1,1,1}; (3)如果给元素全部赋值,可以不给出数组长度(即数组元素的个数)。 9.2.4 一维数组案例分析 例:把一个整数插入到已经按照从小到大顺序排好序的整型数组中,使得整型数组依然有序。 【问题分析】
### 回答1: strlen函数是用来计算字符串长度的,它只能用于字符串,而sizeof是用来计算变量或数据类型所占用的内存大小的,可以用于任何数据类型。另外,strlen函数返回的是字符串的实际长度,不包括字符串末尾的'\',而sizeof返回的是变量或数据类型所占用的字节数,包括末尾的'\'。 ### 回答2: strlen函数sizeof运算符都是用来获取变量的长度的,但两者有以下区别: 1. 数据类型strlen函数只适用于字符串,即以null结尾的字符数组,而sizeof运算符适用于任何数据类型,包括基本类型、数组、结构体等。 2. 返回值类型strlen函数返回的是字符串的实际长度(不包括null字符),即一个整数值,而sizeof运算符返回的是变量或类型的字节大小,即一个size_t类型的值。 3. 运算对象:strlen函数的参数是一个字符串变量或指针,而sizeof运算符的参数可以是任何表达式、变量或类型。 4. 编译时和运行时:sizeof是编译时确定的,它在编译时计算变量或类型的大小,并且返回的是一个常量值;而strlen是运行时确定的,它在程序运行时扫描字符串直到遇到null字符,并返回扫描的字符个数。 总的来说,strlen函数主要用于获取字符串的实际长度,而sizeof运算符主要用于获取变量或类型在内存中所占用的字节大小。 ### 回答3: 在C语言中,strlen函数sizeof操作符都用于获取字符串的长度,但是它们的实现方式和使用方法有所不同。 strlen函数是C标准库中的函数,其原型为“size_t strlen(const char *str)”。它用于计算以null结尾的字符串的长度,即统计字符串中字符的个数,不包括null字符。strlen函数会从字符串的第一个字符开始遍历,直到遇到null字符为止。因此,strlen函数只适用于处理以null结尾的字符串。 sizeof是C语言的一个操作符,用于获取类型或变量的字节大小。当用于获取字符串的长度时,sizeof操作符会返回字符串所占的字节数,包括null字符。注意,sizeof操作符计算的是编译时确定的静态内存大小,不会根据字符串的内容动态变化。 因此,strlen函数sizeof的区别在于: - strlen函数返回字符串中字符的个数,不包括null字符。 - sizeof操作符返回字符串所占的字节数,包括null字符。 举个例子来说明这两者的区别: ```c char str[] = "Hello"; size_t len1 = strlen(str); // len1的值为5,不包括null字符 size_t len2 = sizeof(str); // len2的值为6,包括null字符 ``` 综上所述,strlen函数sizeof操作符在获取字符串的长度时有区别,需要根据具体的需求选择使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

实习秋招必胜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值