C++字符串类型

C++和C不同,C++有专门的字符串类型,即std::string

那字符串在std::string是怎么存储的呢?可以简洁地理解为一个类,里面有一个const char*指针(指向字符串首地址)和一个 size(字符串大小)。


存储结构

可以将C++的字符串理解为是一个类的对象,初始化一个字符串就是初始化字符串类的对象。

#include <iostream>

int main()
{

    std::string str ="hello world";

    std::cout << sizeof(str) << std::endl;         //字符串类的大小
    std::cout <<"class = "<< &str << std::endl;    //字符串类的首地址

    std::cout <<"str = "<< static_cast<const void*>(str.data()) << std::endl;  //字符串指针

    return 0;
}

发现什么没有?类的大小为32字节,类首地址为0x...240,字符串指针为0x...250,说明,实际上字符串内容包括在类里面的。但,真的是这样吗?

#include <iostream>

int main()
{

    std::string str ="hello world hello world hello world hello world hello world";

    std::cout << sizeof(str) << std::endl;         //字符串类的大小
    std::cout <<"class = "<< &str << std::endl;    //字符串类的首地址

    std::cout <<"str = "<< static_cast<const void*>(str.data()) << std::endl;  //字符串指针

    return 0;
}

如果把str赋值更多的字符呢,你会发现,字符串对象的大小并没有增加,因为实际的字符串内容并不在类里面了。

这时候,我们可以猜测,当字符串对象被赋值超过相应size大小的字符串内容时,实际申请的字符串空间就不包括在类里面。

至于那个临界size是多大呢?我凑了一下,是15字节,包括后面隐藏的'\0'就是16字节。

:std::string str ="123456789012345";

不同编译器可能会有所不同


与C字符串的不同

 

那可能有人会疑惑了吧。

问题1:C++字符串后面有没有'\0' 

问题2:如果有,是不是和C一样,以‘\0’作为结束符?

#include <iostream>

int main()
{

    std::string str = "hello";    
    std::cout <<"size ="<<str.size() << std::endl;
    std::cout <<"str  = "<< static_cast<const void*>(str.data()) << std::endl;   //字符串指针

    str = "d";
    std::cout <<"size ="<<str.size() << std::endl;
    std::cout <<"str  = "<< static_cast<const void*>(str.data()) << std::endl;   //字符串指针

    std::cout << str[0] << std::endl;
    std::cout << str[1] << std::endl;
    std::cout << str[2] << std::endl;
    std::cout << str[3] << std::endl;
    std::cout << str[4] << std::endl;

    std::cout << std::endl;
    std::cout <<"str :" <<str << std::endl;

    return 0;
}

发现什么没有?给字符串重新赋值,其字符串指针不变。导致字符串"d"去覆盖字符串"hello" ,

你会发现覆盖了两个字节,一个字节的'd',还有一个隐藏的字节的'\0'  

所以上面解决了第一个问题。哈哈,这种验证方法是不是很妙?

#include <iostream>

int main()
{

    std::string str = "hello";    

    str[3] = '\0';
    std::cout << str[0] << std::endl;
    std::cout << str[1] << std::endl;
    std::cout << str[2] << std::endl;
    std::cout << str[3] << std::endl;
    std::cout << str[4] << std::endl;

    std::cout << std::endl;
    std::cout <<"str :" <<str << std::endl;

    return 0;
}

看了上面的结果,第二个问题也就解决了,很明显吧,C++中字符串并不是以‘\0’作为结束符

其实也好懂,不然还要size干嘛?那不是累赘了吗?

 

至于既然有了size判断字符串大小,那为什么要加‘\0’在后面,可能是为了C++与C的兼容吧。

#include <iostream>

int main()
{

   char c[20];
   std::string str = "1234";

   
   strcpy(c,str.data());         //注意:将C++字符串赋值C字符串规范是需要用到strcpy的
   
   const char *b = str.data();   //虽然下面这种方式也可以实现,但怕string若是被析构掉了,那就会出现段错误了,毕竟指向的字符串空间是C++类申请的

   std::cout << c << std::endl;
   std::cout << b << std::endl;

   return 0;
}

后面再写了,C++字符串还有很多需要知识点

  • 1
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值