C++ —— string容器(上)

string 容器的优点

string字符容器,内部维护了一个动态的字符数组。
与普通的字符数组相比,string容器有三个优点:

  1. 使用的时候,不必考虑内存分配释放的问题;
  2. 动态管理内存(可扩展);
  3. 提供了大量操作容器的API

string 的构造函数

缺点是效率略有降低,占用的资源也更多。string类是std::basic_string类模板的一个具体化版本的别名。
NBTS(null-terminated string):C风格的字符串(以空字符0结束的字符串)。
string类有七个构造函数(C++11新增了两个,前三个用的多):

  1. string(); 创建一个长度为0string对象(默认构造函数)。
  2. string(const char *s);string对象初始化为s指向的NBTS(转换函数)。
  3. string(const string &str);string对象初始化为str(拷贝构造函数)。
  4. string(const char *s,size_t n);string对象初始化为s指向的地址后n字节的内容。
  5. string(const string &str, size_t pos=0, size_t n=npos);sring对象初始化为str从位置pos开始到结尾的字符(或从位置pos开始的n个字符)。
  6. template<class T> string(T begin,T end);string对象初始化为区间[begin,end]内的字符,其中beginend的行为就像指针,用于指定位置,范围包括begin在内,但包括end
  7. string(size_t n,char c); 创建一个由n个字符c组成的string对象。

示例代码

直接看示例代码更加清楚:

#include <iostream>
using namespace std;

int main() {
    // 1)string(); // 创建一个长度为0的string对象(默认构造函数)。
    string s1;
    cout << "s1 = " << s1 << endl; // 因为容器是空的,所以输出空:s1 = 
    cout << "s1.size() = " << s1.size() << endl; // 输出:0
    cout << "s1.capacity() = " << s1.capacity() << endl; // 输出:15
    cout << "容器动态数组的首地址:" << (void*)s1.c_str() << endl;
    // 容器动态数组的首地址:0x7ffd29eb5890
    s1 = "qwewvfwfe235dery13";
    cout << "s1 = " << s1 << endl;
    cout << "s1.size() = " << s1.size() << endl; // 输出:18
    cout << "s1.capacity() = " << s1.capacity() << endl; // 输出:30
    cout << "容器动态数组的首地址:" << (void*)s1.c_str() << endl;
    // 容器动态数组的首地址:0x5609c668bec0
    
    // 2)string(const char *s); // 将string对象初始化为s指向的NBTS(转换函数)。
    string s2("aaaaaaaaa");
    cout << "s2 = " << s2 << endl; // 输出:aaaaaaaaa
    cout << (void*)s2.c_str() << endl; // 0x7ffd29eb58b0
    string s3 = "bbbbbbbbb";
    cout << "s3 = " << s3 << endl; // 输出:bbbbbbbbb
    cout << (void*)s3.c_str() << endl; // 0x7ffd29eb58d0

    // // 3)string(const string &str); // 将string对象初始化为str(拷贝构造函数)。
    string s4(s3);
    cout << "s4 = " << s4 << endl; // 输出:bbbbbbbbb
    cout << (void*)s4.c_str() << endl; // 0x7ffd29eb58f0 与s3不同
    string s5 = s2;
    cout << "s5 = " << s5 << endl; // 输出:aaaaaaaaa
    cout << (void*)s5.c_str() << endl; // 0x7ffd29eb5910 与s2不同

    // // 4)string(const char *s,size_t n); // 将string对象初始化为s指向的地址后n字节的内容。
    string s6("1234567890", 5);
    cout << "s6 = " << s6 << endl; // 输出:12345
    string s7("abcde", 50);
    cout << "s7 = " << s7 << endl; // 输出:abcde再加上一堆乱码
    
    // // 5)string(const string &str,size_t pos=0,size_t n=npos); // 将sring对象初始化为str从位置pos开始到结尾的字符(或从位置pos开始的n个字符)。
    string s = "0123456789";
    string s8(s, 3);
    cout << "s8 = " << s8 << endl; // s8 = 3456789
    string s9(s, 5, 3);
    cout << "s9 = " << s9 << endl; // s9 = 567

    // // 6)template<class T> string(T begin,T end); // 将string对象初始化为区间[begin,end]内的字符,其中begin和end的行为就像指针,用于指定位置,范围包括begin在内,但不包括end。(以后再补充)
    
    // // 7)string(size_t n,char c); // 创建一个由n个字符c组成的string对象。
    string s10(10, 'a');
    cout << "s10 = " << s10 << endl; // 输出:aaaaaaaaaa
    cout << "s10.size() = " << s10.size() << endl; // 输出:10
    cout << "s10.capacity() = " << s10.capacity() << endl; // 输出:15

    return 0;
}

capacity()获取容器的当前容量。意思是,如果不重新分配内存,当前可以存放字符的总个数。
size()获取容器数据的大小,意思是,里面已经存放了多少个字符。
string容器中存放数据时,如果数据多大就分配多大的内存,那么每次扩展容器时,都要重新分配内存,效率低。所以,合理的做法是预先分配比数据实际大小更多的空间,避免过于频繁的分配和释放内存。
扩展空间时,先分配更大的空间,再把内容复制过去,最后释放以前的空间。所以,s1扩展前后首地址不一样。

感谢浏览,一起学习!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值