一、sizeof

sizeof 是 编译期 操作符 计算变量所占内存内存空间大小的,单位是字节,若操作数是类型,则计算使用类型创建的变量所占内存空间的大小
sizeof 只关注占用内存空间的大小,不关注内存中存放什么数据
使用:

二、strlen

头文件:<string.h>
参数:const char* string :指向要统计字符串的指针(只读)
返回值:size_t,本质是 unsigned int

功能:求 string 的长度,是 库函数
strlen 在运行时从传入的字符串地址开始,逐个字节向后读取,一直读取直到遇到第一个 '\0'(空字符)停止,并返回 '\0' 之前字符的总个数(不包含 '\0' 本身)
注:strlen 函数会一直向后找 '\0' 字符,直到找到为止,所以可能存在越界查找
同时,给 strlen 传参时,要保证传进去的是一个指向以 '\0' 结尾的字符串的指针
使用

💡 思考:
题目 1 :

这段代码的运行结果是什么?

解析:

sizeof 是一个编译期运算符,它只关心表达式的类型,而不对表达式本身求值
表达式 s = i + 4 的类型是赋值表达式的结果类型(所有的结果赋值给 s ,最终取决于 s 的类型),即左侧操作数 s 的类型:short
因此,sizeof(s = i + 4) 等价于 sizeof(short),结果为 2
重点:s = i + 4 这行代码根本没有被执行,编译时只会检查语法和确定类型,不会生成实际的赋值指令
( sizeof 在编译期间确定这个表达式最终取决于 s,s 是 short 类型,这句代码在编译器编译时等同于: sizeof(short),所以编译器计算结果是 2 ,而 s = i + 4 计算是在运行时)
所以 sizeof 里的表达式不参与运算

对应的汇编:

表达式的两个属性:
-
值属性
-
类型属性
比如:这里 s = i + 4 的值属性为 6 ,类型属性为 short
题目 2 :
关于这两个数组说法正确的是?

A. 数组 acX 和数组 acY 等价
B. 数组 acX 和数组 acY 的长度相同
C. sizeof(acX) > sizeof (acY)
D. strlen (acX) > strlen (acY)
答案:C
解析:
acX 和 acY 都是字符数组,但是初始化表达式不同,acX 和 acY 的区别如下:
acX:数组中总共有8个元素,分别是:'a','b','c','d','e','f','g','\0'
acY:数组中总共有7个元素,分别是:'a','b','c','d','e','f','g'
sizeof 这里求的是数组大小,数组大小等于有效元素个数*每个元素的大小
sizeof(acX) = 8
sizeof(acY) = 7
strlen 求的是字符串长度,从首元素开始计算,遇到 ' \0 ' 停止,由于 acY 数组没有 ' \0 ',所 以strlen(acY) 的结果是随机值
因此,选择C
三、对比
|---------------------------|----------------------------------|
| sizeof | strlen |
| 操作符 | 库函数 |
| 编译时 | 运行时(会逐字节扫描内存) |
| sizeof 计算操作数所占内存的大小,单位是字节 | srtlen 求字符串长度,统计的是 \0 之前字符的个数 |
| 不关注内存中存放什么数据 | 关注内存中是否有 \0,如果没有就会持续往后找,可能会导致越界 |
