碎碎念
- 很明显能看出来C++在努力地做去指针化和去C化又想做好兼容,但是,拿这个string类型来说,真的是个半残啊,连跟以前对应的
sprintf
对应的格式化方式都没有。 - 关于下标越界,有一个专用名词叫缓冲区溢出(buffer overflow)。
3.5.4 C风格字符串
- C风格字符串不是一种类型,是为了表达和使用字符串弄巧成拙 一种约定俗成的写法。
- 一般用char类型的数组进行存放,最后以**空字符(’\0’)**结束。注意这一条非常关键,如下面这个例子:
char chars_1[] = {'1','2'};
char chars_2[] = {'3','4'};
char chars_3[] = {'5','\0','6'};
cout << chars_2 << endl; //输出3412
cout << chars_3 << endl; //输出5
cout << strlen(chars_2) << endl; //输出4
cout << strlen(chars_3) << endl; //输出1
- 一般使用指针来操作这些字符。
- 几个常用的C风格字符串函数,在使用时要非常注意数组的大小:
函数 | 说明 |
---|---|
strlen§ | 返回p的长度,空字符不计算在内 |
strcmp(p1,p2) | 比较两个字符串相等性,p1<p2返回负值,p1==p2返回0,p1>p2返回正值 |
strcat(p1,p2) | 将p2连接到p1之后 |
strcpy(p1,p2) | 将p2拷给p1 |
- 关于空字符的一点理解:
从练习3.37可以看到,空字符在进行bool判断时会被判断为负,而在实际使用中,可以将
0
直接写到字符串数组中,说明在C++编译器中很大可能性还是将空字符直接与0
相等。
3.5.4练习
练习3.37
下面的程序是何含义,程序的输出结果是什么 ?
const char ca[] = {'h','e','l','l','o'};
const char *cp = ca;
while (*cp)
{
cout << *cp << endl;
++cp;
}
最后输出
h
e
l
l
o
练习3.38
在本节中我们提到,将两个指针相加不但是非法的,而且也没什么意义 。请问为什么两个指针相加没什么 意义 ?
因为指针的本质是两个地址的和,这两个地址相加没有意义。
如果需要将一个指针移动指定长度,那应该与某个int值相加。
练习3.39
编写一段程序 ,比较两个string对象。再编写一段程序 ,比较 C风格字符串的内容 。
string a("aaa"),b("bbb");
char ac[]("aaa"),bc[]("bbb");
auto str_result = a == b;
auto c_result = strcmp(ac,bc);
cout << "string:" << str_result << endl; //输出string:0
cout << "c_string:" << c_result << endl; //输出c_string :-1
练习3.40
编写一段程序 ,定义 两个字符 数组,并用字符 串字面 值 初始化它们;接着再定义 一个字符 数组存放 前两个数组 连接后的结果 。使用strcpy和strcat把前两个数组的内容拷贝到第三个数组中。
char ac[]("aaa"),bc[]("bbb"),c[128](""),d[128]("");//注意如果c\d不进行初始化,可能会出现乱码
strcat(c,ac);
strcat(c,bc);
cout << "strcat:" << c << endl; //输出strcat:aaabbb
strcpy(d,c);
cout << "strcpy:" << c << endl;//strcpy:aaabbb
3.5.5 与旧代码的接口
- 可以使用字符串数组直接进行string的初始化或者为string赋值,注意反过来操作不可以。
- 对于string类型的变量,可以调用
c_str()
方法获取它的字符串数组指针。要注意这个指针解析后的值会因为string的变化而跟随变化。 - 可以使用字符数组进行vector的初始化,注意写法(见下面练习3.41)。
3.5.5练习
练习3.41:
编写一段程序 ,用整型 数组 初始化一个vector对象 。
char chars_3[] = {'5','\0','6'};
vector<char> v (begin(chars_3),end(chars_3));
for (auto &&i : v)
{
cout << i <<endl;
}
//最后会输出
5
6
练习3.42
编写一段程序 ,将含有 整数 元素的vector对象拷贝给一个整型 数组
vector<int> v = {1,2,3,4,5,6,7};
int a[v.size()];
for(int i = 0;i < v.size();i++)
{
a[i] = v[i];
}
for (auto &&i : a)
{
cout << i <<endl;
}