内存和长度

笔记针对以下问题:

  1. 在c语言中,sizeof运算符和strlen()函数有什么区别的?
  2. 如果/字符串/字符指针/用来存储汉字,对于这两者的计算结果有影响吗?
  3. 在C++中,sizeof运算符和strlen()函数的定位?
  4. 在C++中,string的lengt()size()
  5. 在C++中,string用来存储汉字时,……

有关 sizeof和strlen的总结

sizeof是计算括号中变量的类型所占的储存空间(不考虑内容);

strlen是计算变量值为起点的内存地址到第一个'/0'的距离,以字节为单位。

  • 参数区别

    先明确,strlen()用来计算字符串的长度,所以其参数只能是字符数组或字符指针(其实字符数组退化,也就是字符指针),而且,字符串必须以'/0'结尾,对任何不以'/0'结尾的字符数组或字符指针使用strlen()函数都是未定义的;而sizeof用来计算内存占用,其参数可以是类型名或者数据变量。

    所以,对于两者的对比主要放在字符串(字符数组或字符指针)这一块。需要强调的是,strlen(字符数组),函数传参时字符数组会退化为指针;sizeof(字符数组),字符数组不会发生退化。

  • 使用方法

    强调运算符和函数,那么两者的区别在哪?首先就在于使用方法上,sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。

  • sizeof

    • 当适用了于一个结构类型时或变量,sizeof 返回实际的大小;当适用一静态地空间数组,sizeof 归还全部数组的尺寸。sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸 。
    • 适用于函数时,sizeof 返回函数的返回类型所占的空间大小。函数的返回类型不能是void

为了验证以上,看一段测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
#include "stdio.h"
#include "string.h"
int main(void)
{
char* ch = "我喜欢你";
printf("strlen is %d\n", strlen(ch));
printf("sizeof is %d\n", sizeof ch);
char str[] = "我喜欢你";
printf("strlen is %d\n", strlen(str));
printf("sizeof is %d\n", sizeof str);
return 0;
}

执行结果如下:

测试代码的执行结果

推荐:字符数组,字符指针,sizeof,strlen总结

问题 3 的答案

在stackoverflow的一篇问答中提到:sizeofstrlen()区别很大,但是,在C++中 其实并不应该涉及这两者。C风格的字符串在C++中应该使用std::string类型替换;sizeof主要应用在内存分配、内存管理操作中,而这些在C++中有了新的函数,不再需要sizeof。原文如下:

The two are almost different. In C++, you do not need either very much, strlen() is for C-style strings, which should be replaced by C++-style std::strings, whereas the primary application for sizeof() in C is as an argument to functions like malloc(), memcpy() or memset(), all of which you shouldn’t use in C++ (use new, std::copy(), and std::fill() or constructors).

std::string 类的长度

先说结论:string类的size与length,二者在功能上没有区别。

basic_string <> 有双重身份,一是代替传统的C字符串,所以应该针对C中的strlen,给出相应的函数length()。另一个身份是可以用作STL容器,所以要按照STL容器的惯例给出size()。basic_string就是一个能够根据需要自动调整内存分配的对象容器。可以说是一个动态数组。

1
2
3
4
5
6
7
8
9
//C++标准库中的string中两者的源代码如下:
size_type __CLR_OR_THIS_CALL length() const
{ // return length of sequence
return (_Mysize);
}
size_type __CLR_OR_THIS_CALL size() const
{ // return length of sequence
return (_Mysize);
}

所以两者没有区别。length是因为沿用C语言的习惯而保留下来的,string类最初只有length,引入STL之后,为了兼容又加入了size,它是作为STL容器的属性存在的,便于符合STL的接口规则,以便用于STL的算法。

string类的size()/length()方法返回的是字节数,不管是否有汉字。