03 字符串 向量 数组

3.1 命名空间的using声明

例子

#include <iostream>
using std::cin;
int main()
{
int i;
cin >> i;
std::cout << i;
return 0;
}

在头文件中一般不要使用using。因为头文件的内容会被拷贝到所有引用它的文件中去,这可能会产生命名冲突。

3.2 标准库类型string

string定义在命名空间std中。

两种初始化

  • 拷贝初始化:用等号,编译器把右侧的值拷贝到新建的对象中。注意string对象的结尾没有空白符

  • 直接初始化

string s1 = "hiya"; // 拷贝初始化
string s2("hiya"); // 直接初始化
string s3(10, 'c'); // 直接初始化

string对象上的操作

操作

说明

os<<s

把s写到输出流os

is>>s

把输出流is的内容读到s,以空白分隔

getline(is, s)

读入一行,返回is

s.empty()

s.size()

返回值的类型是string::size_type,是无符号的

s1+s2

s1=s2

s1==s2

s1!=s2

<, <=, >, >=

字典顺序比较

getline会把输入流中的换行符读进来,但是不会写到string对象中去,需要我们手动换行

#include <iostream>
using namespace std;
int main()
{
string line;
while (getline(cin, line))
cout << line << endl; // 手动加换行符
return 0;
}

处理string对象中的字符

c++标准库兼容c标准库。c中name.h在c++中就是cnamecctypectype.h内容是一样的,只不过命名规范更符合c++的要求。

cctype中有isalnum, isalpha, isdigit等函数。

3.3 标准库类型vector

vector是类模板而非类型。vector被设计为能够高效的添加元素。开始时创建空的vector,在运行时再动态添加是很常见的做法。

3.4 迭代器

string对象不属于容器类型,但是支持很多与容器类型类似的操作,支持迭代器。

迭代器从可变性上可分为const_iteratoriterator。对于常量对象的begin和end函数会返回前者。c++11中新增了cbegincend,不管对象是不是常量,都返回const_iterator

3.5 数组

数组与vector不同之处在于数组大小确定不变,不能随意向数组中增加新元素。

vector和数组的元素都是对象。引用不是对象,所以引用不能作为数组或vector的元素。

理解复杂的数组声明

默认情况下,类型修饰符是从右向左依次绑定的

int *ptrs[10]; // ptrs是包含10个整型指针的数组
int &refs[10]; // 错误,不存在引用的数组
int (*Parray)[10]; // Parray是指针,指向有10个整型元素的数组
int (&arrRef)[10]; // arrRef是引用,引用有10个整型元素的数组

访问数组元素

数组下标通常为size_t类型,这是一个与机器无关的无符号类型。

指针和数组

在使用数组名的很多地方,编译器会自动把数组名替换为指向数组首元素的指针

string nums[] = {"one", "two"};
string *p = nums; // 等价于 string *p = &nums[0];

c++11位数组提供了两个函数begin和end,可以用来获得指向数组首和尾元素的一下个位置的指针

int ia[] = {0,1,2,3};
int *beg = begin(ia);
int *end = begin(ia);
// 用数组初始化vector
vector<int> ivec(begin(ia), end(ia));

c风格字符串

c风格字符串,即以空字符结束的字符数组。头文件cstring即c中string.h的c++版本。

下面一下cstring中的函数必须用c风格的字符串。

  • strlen(p)

  • strcmp(p1, p2)

  • strcat(p1, p2)

  • strcpy(p1, p2)

string对象有c_str()方法,返回一个c风格字符串。返回值的类型是const char *

3.6 多维数组

严格来说c++中没有多维数组,只有数组的数组。

注意基于范围的for循环遍历多维数组时,除了最内层之外都要用引用。不然会转换成指针

for (const auto &row : ia) // 这里的row如果不用引用会报错
for (auto col : row)
cout << col << endl;