sizeof()与strlen()

sizeof()可以计算所有类型,strlen()仅计算字符串。

sizeof计算对象所占内存字节数,strlen()计算字符个数,遇到'\0'截止。

char *a;
char b[5];
sizeof(a) = 8 ;        // 64位系统,8代表的是指针的大小,指针占8字节
sizeof(b) = 5 ;        // 计算字符串数组的结果是真实的字符数组大小
//strlen(a) strlen(b)  // 无固定值,因为strlen判断的唯一标准是'\0',
//它会根据a和b的指针看是一直向后找,知道碰到'\0',无论是不是自己字符串的结束标志'\0'。


char a =”Hello”;
sizeof(a) = 6;        // /0

以指针形式定义的数组,和用[]定义的数组。为什么sizeof(数组名)的结果不同呢。

首先,我们看看sizeof是什么?是一个操作符,也是关键字,就不是一个函数,这和strlen()不同,strlen()是一个函数。

那么sizeof的作用是什么?
返回一个对象或者类型所占的内存字节数。

所以要看sizeof的对象是谁。

总结:

1. 未初始化的情况下,用strlen是不可行的,因为strlen的唯一标准是找‘\0’,记住这个就能明确strlen会执行处什么值

2. 初始化与否sizeof()的结果不不变,但是反应的并非真实字符串长度而是所占空间大小,所以memset初始化的时候用sizeof较好

3. char* 类型应特别注意,sizeof()计算出来的是指针大小,32位系统4字节,64位占8字节,与char*的字符串毫无关系,只有char[N]字符数组使用sizeof ()计算大小,结果是数组元素个数,而非指针大小,但是如果将其用于参数传递的话,子函数中获取的将不再是字符串数组类型,而是指针,这个要特别注意。

4. 系统函数返回值是char *类型的往往会在末尾加上'\0'。

5. 总归,初始化后strlen计算真实字符串大小不会出错,真实大小的判断方法是找'\0'。sizeof()结果与字符串真实大小无关,与初始化与否无关,计算的是变量所占空间。

`sizeof` 和 `strlen` 是 C 语言中两个常被混淆的概念,它们都“大小”有关,但含义和用途完全不同。 --- ### 一、基本定义 | 名称 | 类型 | 作用 | |------|------|------| | `sizeof` | **运算符**(编译时计算) | 计算**数据类型或对象所占的字节数**(包括数组、结构体、指针等) | | `strlen` | **函数**(运行时计算) | 计算**字符串中字符的个数**(不包含末尾的 `\0`) | --- ### 二、代码对比示例 ```c #include <stdio.h> #include <string.h> int main() { char str[] = "hello"; // 包含 'h','e','l','l','o','\0' → 共6字节 char *ptr = "world"; // 字符串字面量,ptr 是指向它的指针 printf("sizeof(str) = %zu\n", sizeof(str)); // 输出:6(包括 \0) printf("sizeof(ptr) = %zu\n", sizeof(ptr)); // 输出:8(64位系统上指针大小为8字节) printf("sizeof(char*)= %zu\n", sizeof(char*)); // 输出:8 printf("strlen(str) = %zu\n", strlen(str)); // 输出:5(只算有效字符,不含 \0) printf("strlen(ptr) = %zu\n", strlen(ptr)); // 输出:5 return 0; } ``` #### 输出结果(64位系统): ``` sizeof(str) = 6 sizeof(ptr) = 8 sizeof(char*)= 8 strlen(str) = 5 strlen(ptr) = 5 ``` --- ### 三、详细解释 #### ✅ `sizeof` - 是一个 **编译时运算符**,在编译阶段就确定值。 - 对数组使用时,返回整个数组占用的字节数。 - 对指针使用时,返回的是指针本身的大小(如 8 字节 on x86_64)。 - 不会进入内存去读数据,只是根据类型判断。 ```c char arr[100]; printf("%zu\n", sizeof(arr)); // 输出 100 ``` > 即使数组未完全初始化,`sizeof` 仍返回声明的总大小。 #### ✅ `strlen` - 是 `<string.h>` 中的库函数:`size_t strlen(const char *s);` - 从给定地址开始逐字节扫描,直到遇到 `\0`(空字符)为止。 - 返回的是字符个数(不包含 `\0`)。 - 必须保证传入的是以 `\0` 结尾的字符串,否则行为未定义(可能崩溃)。 ```c char *p = NULL; // strlen(p); // ❌ 危险!空指针解引用 → 段错误 ``` --- ### 四、常见陷阱误区 #### ❌ 误区 1:认为 `sizeof` 能获取动态字符串长度 ```c char *s = malloc(100); strcpy(s, "hi"); printf("sizeof(s) = %zu\n", sizeof(s)); // 输出 8(指针大小),不是 100 或 2! ``` ✅ 正确做法:用 `strlen(s)` 获取实际内容长度。 --- #### ❌ 误区 2:对函数参数中的数组使用 `sizeof` ```c void func(char arr[]) { printf("%zu\n", sizeof(arr)); // 输出 8(实际是 char* 的大小) } int main() { char data[100]; printf("%zu\n", sizeof(data)); // 输出 100 func(data); // 传数组名 → 实际上传的是地址 return 0; } ``` 原因:当数组作为函数参数时,会退化为指针,`sizeof(arr)` 就变成了指针大小。 ✅ 解决方案:额外传递长度参数: ```c void func(char arr[], size_t len) { printf("Length: %zu\n", len); } ``` --- #### ❌ 误区 3:`strlen` 对非字符串内存调用 ```c int nums[] = {1, 2, 3, 4}; // strlen((char*)nums); // ❌ 非法!这不是字符串,没有 \0 终止符 ``` 会导致无限扫描,直到碰到 `\0` 或访问非法内存。 --- ### 五、总结对比表 | 特性 | `sizeof` | `strlen` | |------|----------|---------| | 类型 | 运算符 | 函数 | | 头文件 | 无需包含 | `#include <string.h>` | | 计算时机 | 编译时 | 运行时 | | 是否包含 `\0` | 是(如果是数组) | 否 | | 参数可以是 NULL 吗? | 可以(`sizeof(NULL)` 合法) | 不可以(会崩溃) | | 返回值单位 | 字节数 | 字符数(不包括 `\0`) | | 对数组有效吗? | 是(完整大小) | 是(需以 `\0` 结尾) | | 对指针有效吗? | 是(返回指针本身大小) | 是(但必须指向合法字符串) | --- ### 六、实用技巧 #### ✅ 安全地获取数组长度(仅限本地数组) ```c #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) int arr[] = {1, 2, 3, 4, 5}; printf("Elements: %zu\n", ARRAY_SIZE(arr)); // 输出 5 ``` ⚠️ 注意:只能用于**本地定义的数组**,不能用于函数参数或动态分配的内存。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

子木呀

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

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

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

打赏作者

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

抵扣说明:

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

余额充值