C++学习笔记(7)

181、string 容器
string 是字符容器,内部维护了一个动态的字符数组。
与普通的字符数组相比,string 容器有三个优点:1)使用的时候,不必考虑内存分配和释放的问题;
2)动态管理内存(可扩展);3)提供了大量操作容器的 API。缺点是效率略有降低,占用的资源也更
多。
string 类是 std::basic_string 类模板的一个具体化版本的别名。
using std::string=std::basic_string<char, std::char_traits<char>, std::allocator<char>> 一、构造和析构
静态常量成员 string::npos 为字符数组的最大长度(通常为 unsigned int 的最大值);
NBTS(null-terminated string):C 风格的字符串(以空字符 0 结束的字符串)。
string 类有七个构造函数(C++11 新增了两个):
1)string(); // 创建一个长度为 0 的 string 对象(默认构造函数)。
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]内的字
符,其中 begin 和 end 的行为就像指针,用于指定位置,范围包括 begin 在内,但不包括 end。
7)string(size_t n,char c); // 创建一个由 n 个字符 c 组成的 string 对象。
析构函数~string()释放内存空间。
C++11 新增的构造函数:
1)string(string && str) noexcept:它将一个 string 对象初始化为 string 对象 str,并可能修改 str
(移动构造函数)。
2)string(initializer_list<char> il):它将一个 string 对象初始化为初始化列表 il 中的字符。
例如:string ss = { 'h','e','l','l','o' };
示例:
#include <iostream>
using namespace std;
int main()
{
// 1)string():创建一个长度为 0 的 string 对象(默认构造函数)。
string s1; // 创建一个长度为 0 的 string 对象
cout << "s1=" << s1 << endl; // 将输出 s1=
cout << "s1.capacity()=" << s1.capacity() << endl; // 返回当前容量,可以存放字符的
总数。
cout << "s1.size()=" << s1.size() << endl; // 返回容器中数据的大小。
cout << "容器动态数组的首地址=" << (void *)s1.c_str() << endl;
s1 = "xxxxxxxxxxxxxxxxxxxx";
cout << "s1.capacity()=" << s1.capacity() << endl; // 返回当前容量,可以存放字符的
总数。
cout << "s1.size()=" << s1.size() << endl; // 返回容器中数据的大小。
cout << "容器动态数组的首地址=" << (void *)s1.c_str() << endl;
// 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; // 返回容器中数据的大小。
string s7("hello world", 50);
cout << "s7=" << s7 << endl; // 将输出 s7=hello 未知内容
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。
// 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
}
示例 2:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
int main()
{
char cc[8]; // 在栈上分配 8 字节的内存空间。
// 把 cc 的内存空间用于字符串。
strcpy(cc, "hello");
cout << "cc=" << cc << endl << endl;
// 把 cc 的内存空间用于 int 型整数。
int* a, * b;
a = (int *)cc; // 前 4 个字节的空间用于整数 a。
b = (int *)cc + 4; // 后 4 个字节的空间用于整数 b。
*a = 12345; *b = 54321;
cout << "*a=" << *a << endl;
cout << "*b=" << *b << endl << endl;
// 把 cc 的内存空间用于 double。
double* d = (double*)cc; *d = 12345.7;
cout << "*d=" << *d << endl << endl;
// 把 cc 的内存空间用于结构体。
struct stt
{
int a;
char b[4];
}*st;
st = (struct stt*)cc;
st->a = 38;
strcpy(st->b, "abc");
cout << "st->a=" << st->a << endl;
cout << "st->b=" << st->b << endl << endl;
// void* malloc(size_t size);
//char* cc1 = (char*)malloc(8);
//int* cc1 = (int*)malloc(8);
}
示例 3:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
int main()
{
struct st_girl { // 超女结构体。
int bh;
char name[30];
bool yz;
double weight;
string memo;
} girl;
cout << "超女结构体的大小:" << sizeof(struct st_girl) << endl;
string buffer; // 创建一个空的 string 容器 buffer。
// 生成 10 名超女的信息,存入 buffer 中。
for (int ii = 1; ii <= 10; ii++)
{
// 对超女结构体成员赋值。
memset(&girl, 0, sizeof(struct st_girl));
girl.bh = ii;
sprintf(girl.name, "西施%02d", ii);
girl.yz = true;
girl.weight = 48.5 + ii;
girl.memo = "中国历史第一美女。";
// 把超女结构追加到 buffer 中。
buffer.append((char*)&girl, sizeof(struct st_girl));
}
cout << "buffer.capacity()=" << buffer.capacity() << endl; // 显示容量。
cout << "buffer.size()=" << buffer.size() << endl; // 显示实际大小。
// 用一个循环,把 buffer 容器中全部的数据取出来。
for (int ii = 0; ii < buffer.size() / sizeof(struct st_girl); ii++)
{
memset(&girl, 0, sizeof(struct st_girl)); // 初始化超女结构体。
// 把容器中的数据复制到超女结构体。
memcpy(&girl , buffer.data() + ii * sizeof(struct st_girl), sizeof(struct st_girl));
// buffer.copy((char*)&girl, sizeof(struct st_girl), ii * sizeof(struct st_girl));
// 显示超女结构体成员的值。
cout << "bh=" << girl.bh << ",name=" << girl.name << ",yz=" << girl.yz <<
",weight=" << girl.weight << ",memo=" << girl.memo << endl;
}
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值