一、对于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 是1个字节;
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博客

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐