C++字符串使用sizeof时注意

本文通过具体的C++代码示例,详细解释了sizeof运算符与strlen函数的区别及应用场景,帮助读者理解如何正确地获取数组大小和字符串长度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   char tmp1[20] = {"hello,你好"};
    char tmp2[] = {"hello,你好"};
    char *tmp3 = new char[20];
    sprintf(tmp3,"%s","hello,你好");
    string tmp4 = "hello,你好";

    printf("%d %d %d %d\n",sizeof(tmp1),sizeof(tmp2),sizeof(tmp3),sizeof(tmp4));
    printf("%d %d %d %d %d\n",strlen(tmp1),strlen(tmp2),strlen(tmp3),strlen(tmp4.c_str()),tmp4.size());

输出:

20 13 4 4

12 12 12 12 12

解释:

在编译时,tmp1数组指定分配20个字节;tmp2根据初始化内容分配最小容量,包含字符串末尾'\0',因此是13;tmp3在编译时只是一个指针变量,大小只有4字节;

string对象内容使用了指针指向了动态分配的空间,而对象本身只有4字节。

 

 

Sizeof与Strlen的区别与联系

一、sizeof
    sizeof(...)是运算符,在头文件中typedef为unsigned int,其值在编译时即计算好了,参数可以是数组、指针、类型、对象、函数等。
    它的功能是:获得保证能容纳实现所建立的最大对象的字节大小。
    由于在编译时计算,因此sizeof不能用来返回动态分配的内存空间的大小。实际上,用sizeof来返回类型以及静态分配的对象、结构或数组所占的空间,返回值跟对象、结构、数组所存储的内容没有关系。
    具体而言,当参数分别如下时,sizeof返回的值表示的含义如下:
    数组——编译时分配的数组空间大小;
    指针——存储该指针所用的空间大小(存储该指针的地址的长度,是长整型,应该为4);
    类型——该类型所占的空间大小;
    对象——对象的实际占用空间大小;
    函数——函数的返回类型所占的空间大小。函数的返回类型不能是void。
二、strlen
    strlen(...)是函数,要在运行时才能计算。参数必须是字符型指针(char*)。当数组名作为参数传入时,实际上数组就退化成指针了。
    它的功能是:返回字符串的长度。该字符串可能是自己定义的,也可能是内存中随机的,该函数实际完成的功能是从代表该字符串的第一个地址开始遍历,直到遇到结束符NULL。返回的长度大小不包括NULL。

转载于:https://www.cnblogs.com/guoxiaoqian/p/4314487.html

### 关于 C 语言 `sizeof` 运算符 在 C 语言中,`sizeof` 是一种运算符而非函数,用于计算指定的数据类型或变量所占用的内存大小(以字节为单位)。它返回的结果是一个无符号整数类型 `size_t`,该类型的定义位于 `<stddef.h>` 头文件中。 对于数组而言,当使用 `sizeof` 计算整个数组,会得到数组所有元素占据的总字节数。例如: ```c char str[] = "hello"; printf("sizeof(str) = %zu.\n", sizeof(str)); // 输出 6 (包括 '\0' 结束符) ``` 如果仅针对单个字符进行测量,则只获取到单一字符所需的存储空间: ```c printf("sizeof(str[0]) = %zu.\n", sizeof(str[0])); // 输出 1 ``` 值得注意的是,尽管字符串常量看起来像是普通的字符序列,但由于它们隐含了一个终止零(`\0`)作为结束标志,因此实际长度总是比可见字符多一位[^1]。 另外需要注意的一点是,在动态分配的情况下(比如通过指针指向一块堆上申请来的区域), 使用 `sizeof` 对这个指针本身求值只会给出指针本身的宽度而不是其所指向的内容的实际尺寸: ```c char *pStr = malloc(10); printf("%zu\n", sizeof(pStr)); // 打印指针大小, 不同平台可能不同. free(pStr); ``` 上述例子展示了即使我们给 pStr 分配了十个字节的空间,但是当我们尝试打印它的 size 的候却得到了不同的结果——这是因为这里实际上是对指针进行了取样操作而已,并未涉及真正的缓冲区范围[^2]. --- ### C++ 中 string 类型简介 相比之下,C++ 提供了一种更高级别的抽象形式来处理文本数据 —— 即标准模板库(STL)里的 std::string 类型。这种实现方式不仅简化了许多常见的字符串管理任务,而且提供了丰富的成员方法支持诸如拼接、查找替换等功能. 创建一个基本的 C++ 字符串非常简单直白: ```cpp #include <iostream> #include <string> int main(){ std::string greeting = "Hello world!"; std::cout << greeting.length(); // 返回当前字符串的有效长度不计结尾标记'\0' } ``` 不同于原始 c-style strings 需要手动追踪有效长度并考虑边界情况等问题,std::strings 自动维护内部状态信息从而极大地减少了错误发生的可能性. 此外还内置了一些实用功能如比较两个对象是否相等无需逐一遍历对比每一个单独位置上的字母差异等等优点明显优于传统做法[^3]. 最后强调一点区别在于当你询问某个特定实例化后的 object 能容纳多少最大数量级容量之前已经预先设定好的话可以调用 capacity 方法查看;而如果是想知道此刻真正保存了多少非空白填充部分则应该查阅 length 或者 size 属性获得确切数值反馈回来即可满足需求场景下的查询请求啦! --- ### 总结两者之间的异同 | 特性 | C Style Strings (`char []`) | C++ String Class (`std::string`) | |--------------------|-----------------------------------------------|-----------------------------------------| | 数据结构 | 数组 | 动态容器 | | 存储机制 | 固定大小 | 可变大小 | | 终止符 | `\0` 明确 | 内部跟踪 | | 获取长度的方法 | `strlen()` | `.length()`,`.size()` | | 安全性 | 较低 | 更高 | 综上所述可以看出虽然二者都能完成相似的任务即表示一段连续排列起来的文字单元集合体可是由于设计理念的不同导致他们在具体表现形态上有诸多显著差别值得开发者们深入理解以便做出最佳选择适应各自项目的需求特点.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值