53 CPP string容器

 

一、构造和析构

静态常量成员 string::npos为字符串数组的最大长度(通常是unsigned int的最大值);

NBTS(null-terminated string):C风格的字符串(以字符串0结束的字符串)

#include <iostream>
using namespace std;

void test()
{
    cout << "npos=" << string::npos << endl;

    string s;
    cout << s.capacity() << " " << s.size() << endl;
    cout << "容器动态数组的首地址=" << (void *)s.c_str() << endl;
    s = "sssssssssssssssssssssssss";
    cout << s.capacity() << " " << s.size() << endl;
    cout << "容器动态数组的首地址=" << (void *)s.c_str() << endl;
    /* 上面代码输出结果:
    15 0
    容器动态数组的首地址=0x61fdd0
    30 25
    容器动态数组的首地址=0xf71760 */
    //可以看出,两个数组的首地址不一样,string类扩展容器的时候,
    // 先分配更大的空间,然后把内容复制到型的空间,再把以前的空间释放掉

    // 2)string(const char *s):将string对象初始化为s指向的NBTS(转换函数)。
    string s2("hello world");
    cout << "s2=" << s2 << endl; // 将输出s2=hello world
    string s3 = "hello world";   //一个参数的构造函数可以用于转换函数,所以上面的方法等同于下面的代码
    cout << "s3=" << s3 << endl; // 将输出s3=hello world

    // 3)string(const string & str):将string对象初始化为str(拷贝构造函数)。
    string s4(s3);               // s3 = "hello world";
    cout << "s4=" << s4 << endl; // 将输出s4=hello world
    string s5 = s3;
    cout << "s5=" << s5 << endl; // 将输出s5=hello world

    // 4)string(const char* s, size_t n):将string对象初始化为s指向的NBTS的前n个字符,即使超过了NBTS结尾。
    string s6("hello world", 5);
    cout << "s6=" << s6 << endl;                       // 将输出s6=hello
    cout << "s6.capacity()=" << s6.capacity() << endl; // 返回当前容量,可以存放字符的总数。
    cout << "s6.size()=" << s6.size() << endl;         // 返回容器中数据的大小。
    //从"hello world"位置开始复制后面50个字节的内容.
    string s7("hello world", 50);
    cout << "s7=" << s7 << endl;                       // 将输出s7=hello world未知内容
    cout << "s7.capacity()=" << s7.capacity() << endl; // 返回当前容量,可以存放字符的总数。
    cout << "s7.size()=" << s7.size() << endl;         // 返回容器中数据的大小。

    // 5)string(const string & str, size_t pos = 0, size_t n = npos):
    // 将string对象初始化为str从位置pos开始到结尾的字符,或从位置pos开始的n个字符。
    string s8(s3, 3, 5);         // s3 = "hello world";
    cout << "s8=" << s8 << endl; // 将输出s8=lo wo
    string s9(s3, 3);
    cout << "s9=" << s9 << endl;                       // 将输出s9=lo world
    cout << "s9.capacity()=" << s9.capacity() << endl; // 返回当前容量,可以存放字符的总数。
    cout << "s9.size()=" << s9.size() << endl;         // 返回容器中数据的大小。
    string s10("hello world", 3, 5);
    cout << "s10=" << s10 << endl; // 将输出s10=lo wo
    string s11("hello world", 3);  // 注意:不会用构造函数5),而是用构造函数4)
    cout << "s11=" << s11 << endl; // 将输出s11=hel

    // 6)template<class T> string(T begin, T end):将string对象初始化为区间[begin, end]内的字符,
    //      其中begin和end的行为就像指针,用于指定位置,范围包括begin在内,但不包括end。
    string s15(s3.begin(), s3.end() - 3);
    cout << "s15=" << s15 << endl; // s12=hello wo

    // 7)string(size_t n, char c):创建一个由n个字符c组成的string对象。
    string s12(8, 'x');
    cout << "s12=" << s12 << endl;                       // 将输出s12=xxxxxxxx
    cout << "s12.capacity()=" << s12.capacity() << endl; // s12.capacity()=15
    cout << "s12.size()=" << s12.size() << endl;         // s12.size()=8
    string s13(30, 0);
    cout << "s13=" << s13 << endl;                       // 将输出s13=
    cout << "s13.capacity()=" << s13.capacity() << endl; // s13.capacity()=31
    cout << "s13.size()=" << s13.size() << endl;         // s12.size()=30

    string s14(30, '0');
    cout << "s14=" << s14 << endl; // 将输出s14=000000000000000000000000000000
}
int main()
{
    test();
    return 0;
}
shrink_to_fit

#include <iostream>
using namespace std;

void test()
{
    string a;
    cout << a.capacity() << " " << a.length() << " " << a.size() << endl;
    a = "xxxxxxxxxxxxxxxxxxxxx";
    cout << a.capacity() << " " << a.length() << " " << a.size() << endl;
    a.shrink_to_fit();
    cout << a.capacity() << " " << a.length() << " " << a.size() << endl;
}
int main()
{
    test();
    return 0;
}
15 0 0
30 21 21
21 21 21

string容器-设计目标

计算机的内存就是一块空间,没有数据类型的说法。数据类型时编程语言中的概念,指出了操作内存中的数据的方法。

#include <iostream>
#include <cstring>
using namespace std;

void test()
{
    char cc[8]; //在栈上分配8字节的内存空间
    //把cc的内存空间用于字符串

    //把cc的内存空间用于int型整数
    int *a, *b;
    a = (int *)cc;
    b = (int *)cc + 1;
    cout << (long long)a << endl;
    cout << (long long)b << endl;
    *a = 1999;
    *b = 2222;
    cout << "*a=" << *a << endl;
    cout << "*b=" << *b << endl;

    //把cc的内存空间用于double
    double *d = (double *)cc;
    *d = 333.222;
    cout << "*d=" << *d << endl;

    //把cc的内存空间用于结构体
    struct stt
    {
        int a;
        char b[4];
    } * st;

    st = (struct stt *)&cc;
    st->a = 111;
    /*     strcpy(st->b, "abcd"); //如果是这样,不会报错,但是输出为:
    st->a=6821633   这个值每次都变,不知道指向了哪里
    st->b=  打印出来为空*/
    strcpy(st->b, "abc");
    cout << "st->a=" << st->a << endl;
    cout << "st->b=" << st->b << endl;

    // void * malloc(size_t size)
    // char *cc1 = (char *)malloc(8);
    // int *cc1 = (int *)malloc(8);
}
int main()
{
    test();
    return 0;
}
6421952
6421956
*a=1999
*b=2222
*d=333.222
st->a=111
st->b=abc

 

size()==8的string对象时什么意思?

长度为8的字符串,这么理解太狭隘了,

应该说是已使用了8字节的内存空间。

string对象是以字节为嘴小存储单元的动态顺序容器。

主要有两种用途

1 用于存放字符串(不存空字符0,空字符0是C风格字符串特有的)

2 用于存放数据的内存空间(缓冲区)

在实际开发中,最常见的是用作缓冲区。

string内部的三个指针

    cahr *start_;  //动态分配内存块开始的地址.
    cahr *end_;    //动态分配内存块最后的地址.
    cahr *finish_; //已使用空间的最后的地址

有这3个指针,所以 用它存放字符串的时候,不需要空字符0

字符串的长度用finish-start就出来了

#include <iostream>
using namespace std;
void test()
{
    string s1 = "111111111111111"; //不交换动态数组地址
    string s2 = "222222222222222"; //不交换动态数组地址
    // string s1 = "111111111111111";//交换动态数组地址
    // string s2 = "222222222222222";//交换动态数组地址
    cout << "s1的内容:" << s1 << endl;
    cout << "s2的内容:" << s2 << endl;
    cout << "s1动态数据的地址:" << (void *)s1.data() << endl;
    cout << "s2动态数据的地址:" << (void *)s2.data() << endl;
    s1.swap(s2);
    cout << "交换后" << endl;
    cout << "s1的内容:" << s1 << endl;
    cout << "s2的内容:" << s2 << endl;
    cout << "s1动态数据的地址:" << (void *)s1.data() << endl;
    cout << "s2动态数据的地址:" << (void *)s2.data() << endl;
}
int main()
{
    test();
    return 0;
}

/* s1的内容:111111111111111
s2的内容:222222222222222
s1动态数据的地址:0x61fdc0
s2动态数据的地址:0x61fda0
交换后
s1的内容:222222222222222
s2的内容:111111111111111
s1动态数据的地址:0x61fdc0
s2动态数据的地址:0x61fda0


s1的内容:1111111111111111
s2的内容:2222222222222222
s1动态数据的地址:0x761760
s2动态数据的地址:0x761780
交换后
s1的内容:2222222222222222
s2的内容:1111111111111111
s1动态数据的地址:0x761780
s2动态数据的地址:0x761760 */

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值