温习至string部分,做如下记录。
我们知道,string是可变长度的字符串。
实现原理
这里我们只做初步介绍,不做详细探讨.
在IDE中找到string类定义,依次查看相关文件。(个人使用vs2017,对string进行F12操作-找到其定义)
文件xstring:
using string = basic_string<char, char_traits<char>, allocator<char>>;
using wstring = basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>>;
template<class _Elem,
class _Traits = char_traits<_Elem>,
class _Alloc = allocator<_Elem>>
class basic_string
: public _String_alloc<_String_base_types<_Elem, _Alloc>>
{
//内部函数和变量不做详解
}
可以看出basic_string继承于类_String_alloc,现在来看类_String_alloc的定义
template<class _Alloc_types>
class _String_alloc
{
//对很多成员变量和函数进行省略,只关注我们需要的.
union _Bxty
{
// storage for small buffer or pointer to larger one
value_type _Buf[_BUF_SIZE];
pointer _Ptr;
char _Alias[_BUF_SIZE]; // retained for /clr bincompat; unused
} _Bx;
size_type _Mysize; // current length of string
size_type _Myres; // current storage reserved for string
};
//注:_BUF_SIZE为16
好,现在我们找到我们需要的东西了。string类中有3点需要了解
- _Mysize : string字符串的当前长度,size()操作便是返回该值,初始值为0
- _Myres :string字符串当前分配的最大空间长度,capcity()操作便是返回该值,初始值是_BUF_SIZE-1
内存分配 : 查看Bx可知,它为一联合体。查看内部代码(具体不讨论了,太深入了)。当元素个数小于_BUF_SIZE时不用分配内存,直接使用_Buf数组,_Myptr返回_Buf。否则就要分配内存了,_Myptr返回_Ptr。
至于 内存的分配策略,最开始_Myres每次增加_BUF_SIZE,当值达到一定大小时每次增加一半。
具体值为:
char:15,31,47(从这里开始,增加自己的一半),70,105,157,235,352,528,792,1188,1782。。
各位看官可以自行用依次增加string长度,查看对应的capcity().
好了,关于内部的实现目前暂时先了解这些。后续需要的话再行深入了解。
操作
- empty
- []
- ==
- +=
- !=
- >
- c_str:注意该函数返回的是const指针,并且其内容随str改变,一般用strcpy赋值.
string str = "123";
const int MAX_SIZE = 100;
char *pStr1 = new char[MAX_SIZE];
const char *pStr2 = str.c_str();
strcpy(pStr1, str.c_str());
str = "456";
cout << pStr1 << endl; //输出123
cout << pStr2 << endl; //输出456
- size:返回string::size_type类型,最好不要int,int和机器相关。 一般用法如下:
string str;
size_t i = str.size(); //cstddef定义
string::size_type j = str.size(); //容器相关的
构造和赋初值
string s1 = "1234";
string s2("abcdefg");
string s3("123456789", 3); //123
string s4(s2, 1, 3); //bcd
string s5(s1);
其他字符处理函数
考虑到string中存储的都是字符,同时对一些基本的字符处理函数做回顾.
- isdigit : 判断数字
- islower : 判断小写字母
- isupper : 判断大写字母
- ispunct : 判断标点符号
- toupper : 转为大写字母
- tolower : 转为小写字母
使用细节
关于string定义,有一点注意,空string不能随意用[]
string str;
str[0] = 'a'; //错误
str[1] = 'b'; //错误
若向string中依次赋值,可以+=
string str;
str += 'a';
str += 'b';