vector类型为内置数组提供了一种替代表示,通常建议使用vector。为了使用vector类型必须引入相关头文件:
include <vector>
使用vector有两种不同的形式,即所谓的数组习惯和STL习惯。在数组习惯用法中,我们模仿内置数组的用法定义一个已知长度的vector:
vector <int> v_array(10); //v_array中的所有元素已经被初始化为0
上面的用法与定义一个包含十个数组元素的内置数组类似:
int array[10];
我们可以使用下标操作符来访问vector元素,与访问内置数组的方式一样:
int a = v_array[2];
我们可以使用size()方法来查询vector的大小,也可以使用empty()方法来判断vector是否为空:
if(v_array.empty())
return;
for(int i = 0,i < v_array.size();i++){
cout << v_array[i] << " ";
}
我们也可以为每个元素提供一个显式的初始值来完成初始化,但是我们不能为vector中的元素初始化为一组常量值,但是可以将vector初始化为一个已有的数组的全部或是一部分,只需指定希望被用来初始化vector的数组元素起始地址以及最后一个元素的下一个地址:
vector<int> v_array(10,2); //vector中的每一个元素都被初始化为2
int array [] = {0,1,2,3}; //正确,可以通过一组常量值初始化数组
vector<int> vv_array(4,0,1,2,3); //错误,没有这种初始化的定义
vector<int> vvv_array(array,array + 2); //正确,初始化vector为array的前两个元素
也内置数组不同,vector可以被另一个vector初始化,也可以赋值给另一个vector:
vector<int> v_array(10);
vector <int> v_array2(v_array);
vector <int > v_array3 = v_array2;
在STL中对vector的习惯用法完全不同,我们不是定义一个已知大小的vector,而是定义一个空的vector:
vector<string> v_string;
我们想vector中插入元素,而不是索引元素,以及向元素赋值,例如:push_back()操作就是在vector的后面插入一个元素:
v_string.push_back("hello");
v_string.push_back("world");
v_string.push_back("!");
但是我们仍然可以利用下标操作符访问vector元素:
for(int i = 0;i <v_string.size();i ++){
cout << v_string[i] <<" ";
}
但是,更典型的做法是利用vector的begin()和end()所返回的迭代器:
for(vector<string> :: iterator it = v_string.begin();it != v_string.end();it++){
cout << *it << " ";
}
iterator是标准库中的类,它具有指针的功能。不要混用这两种习惯用法,例如:
vector<int> v_array;
v_array[0] = 1; //错误,v_array中还没有元素
类似地当我们用一个给定了大小的vector时,任何一个插入操作都将在vector的后面加入一个元素来增加vector的大小:
vector<int> v_array(5);
v_array.push_back(1);
v_array.push_back(1);
v_array.push_back(1);
v_array.push_back(1);
v_array.push_back(1); //执行到这里,v_array的大小为10,前五个元素为0,后五个元素为1
另外,在STL惯用方法中,可以删除一个或多个vector元素。
命名空间的using声明
:: 操作符:
该操作符是作用域操作符,它的含义是右操作数的名字可以在左操作数的作用域中找到。因此,std::cin 的意思是说 所需要名字 cin 是在命名空间 std 中定义的。
使用 using 声明可以在不需要加前缀 namespace_name:: 的情况下访问命名空间中的名字。using 声明的形式如下: using namespace::name; 一旦使用了 using 声明,我们就可以直接引用名字,而不需要再引用该名字的命名空间。
#include <string> #include <iostream> // using declarations states our intent to use these names from the namespace std
using std::cin;
using std::string;
int main() {
string s; // ok: string is now a synonym for std::string
cin >> s; // ok: cin is now a synonym for std::cin
cout << s; // error: no using declaration; we must use full name
std::cout << s; // ok: explicitly use cout from namepsace std
}
——————————————————————————————————————
string 类型支持长度可变的字符串,C++ 标准库将负责管理与存储字符相关的内存,以及提供各种有用的操作。标准库 string 类型的目的就是满足对字符串的一般应用。 与其他的标准库类型一样,用户程序要使用 string 类型对象,必须包含相关头文件。如果提供了合适的 using 声明,那么编写出来的程序将会变得简短些: #include <string> using std::string;
string 对象的定义和初始化
几种初始化string 对象的方式 string s1; 默认构造函数 s1 为空串 string s2(s1); 将 s2 初始化为 s1 的一个副本 string s3("value"); 将 s3 初始化为一个字符串字面值副本 string s4(n, 'c'); 将 s4 初始化为字符 'c' 的 n 个副本
使用getline 读取整行文本
有一个有用的 string IO 操作:getline。这个函数接受两个参数:一个输入流对象和一个 string 对象。getline 函数从输入流的下一行读取,并保存读取的内容到string 对象中,不包括换行符。和输入操作符不一样的是,getline 并不忽略行开头的换行符。只要 getline 遇到换行符,即便它是输入的第一个字符,getline 也将停止读入。
string 对象的操作
常用的 string 操作。 s.empty(): 如果 s 为空串,则返回 true,否则返回 false。 s.size(): 返回 s 中字符的个数。 s[n] :返回 s 中位置为 n 的字符,位置从 0 开始计数。 s1 + s2: 把 s1 和s2 连接成一个新字符串,返回新生成的字符串。 s1 = s2 :把 s1 内容替换为 s2 的副本。 v1 == v2 :比较 v1 与 v2 的内容,相等则返回 true,否则返回 false。 !=, <, <=, >, and >= :保持这些操作符惯有的含义。
string::size_type 类型
size 操作返回的是 string::size_type 类型的值。任何存储 string 的 size 操作结果的变量必须为 string::size_type 类型。
string 关系操作符
string 对象比较操作是区分大小写的,即同一个字符的大小写形式被认为是两个不同的字符。在多数计算机上,大写的字母位于小写之前:任何一个大写之母都小于任意的小写字母。
== 操作符比较两个 string 对象,如果它们相等,则返回 true。两个 string 对象相等是指它们的长度相同,且含有相同的字符。标准库还定义了 != 操作符来测试两个 string 对象是否不等。关系操作符 <,<=,>,>= 分别用于测试一个 string 对象是否小于、小于或等于、大于、大于或等于另一个 string 对象。
如果两个 string 对象长度不同,且短的 string 对象与长的 string 对象的前面部分相匹配,则短的 string 对象小于长的 string 对象。 如果 string 对象的字符不同,则比较第一个不匹配的字符。
从string 对象获取字符 string 类型通过下标操作符([ ])来访问 string 对象中的单个字符。下标操作符需要取一个 size_type 类型的值,来标明要访问字符的位置。这个下标中的值通常被称为“下标”或“索引”(index)。
string 对象的下标从 0 开始。如果 s 是一个 string 对象且 s 不空,则 s[0] 就是字符串的第一个字符, s[1] 就表示 第二个字符(如果有的话),而 s[s.size() - 1] 则表示 s 的最后一个字符。
string 对象中字符的处理
各种字符操作函数,适用于 string 对象的字符(或其他任何 char 值)。这些函数都在 cctype 头 文件中定义。 cctype 中的函数: isalnum(c) :如果 c 是字母或数字,则为 True。 isalpha(c) :如果 c 是字母,则为 true。 iscntrl(c) :如果 c 是控制字符,则为 true isdigit(c) :如果 c 是数字,则为 true。 isgraph(c): 如果 c 不是空格,但可打印,则为 true。 islower(c) :如果 c 是小写字母,则为 true。 isprint(c) :如果 c 是可打印的字符,则为 true。 ispunct(c) :如果 c 是标点符号,则为true。 isspace(c) :如果 c 是空白字符,则为 true。 isupper(c) :如果 c 是大写字母,则为 true。 isxdigit(c) :如果是 c 十六进制数,则为 true。 tolower(c): 如果 c 大写字母,返回其小写字母形式,否则直接返回 c。 toupper(c): 如果 c 是小写字母,则返回其大写字母形式,否则直接返回 c。
——————————————————————————————————————
标准库 vector 类型
vector 是同一种类型的对象的集合,每个对象都有一个对应的整数索引值。和 string 对象一样,标准库将负责管理与存储元素相关的内存。我们把 vector称为容器,是因为它可以包含其他对象。一个容器中的所有对象都必须是同一种 类型的。
使用 vector 之前,必须包含相应的头文件,并作相应的 using 声明: #include <vector> using std::vector;
vector 不是一种数据类型,而只是一个类模板,可用来定义任意多种数据类型。vector 类型的每一种都指定了其保存元素的类型。因此,vector<int> 和 vector<string> 都是数据类型。
vector 对象的定义和初始化
初始化vector vector<T> v1:vector 保存类型为 T 对象。默认构造函数 v1 为空。 vector<T> v2(v1):v2 是 v1 的一个副本。 vector<T> v3(n, i):v3 包含 n 个值为 i 的元素。 vector<T> v4(n):v4 含有值初始化的元素的 n 个副本。
若要创建非空的 vector 对象,必须给出初始化元素的值。当把一个 vector对象复制到另一个 vector 对象时,新复制的 vector 中每一个元素都初始化为原 vectors 中相应元素的副本。但这两个 vector 对象必须保存同一种元素类 型: vector<int> ivec1; // ivec1 holds objects of type int vector<int> ivec2(ivec1); // ok: copy elements of ivec1 intoivec2 vector<string> svec(ivec1); // error: svec holds strings, not ints 可以用元素个数和元素值对 vector 对象进行初始化。构造函数用元素个数来决定 vector 对象保存元素的个数,元素值指定每个元素的初始值: vector<int> ivec4(10, -1); // 10 elements, each initialized to -1 vector<string> svec(10, "hi!"); // 10 strings, each initialized to "hi!"
vector 对象动态增长
vector 对象(以及其他标准库容器对象)的重要属性就在于可以在运行时高效地添加元素。
值初始化
如果没有指定元素的初始化式,那么标准库将自行提供一个元素初始值进行值初始化(value initializationd)。这个由库生成的初始值将用来初始化容器中的每个元素,具体值为何,取决于存储在 vector 中元素的数据类型。
如果 vector 保存内置类型(如 int 类型)的元素,那么标准库将用 0 值创建元素初始化式: vector<string> fvec(10); // 10 elements, each is initialized to 0 如果 vector 保存的是含有构造函数的类类型(如 string)的元素,标准库将用该类型的默认构造函数创建元素初始化式: vector<string> svec(10); // 10 elements, each is an empty string
还有第三种可能性:元素类型可能是没有定义任何构造函数的类类型。这种情况下,标准库仍产生一个带初始值的对象,这个对象的每个成员进行了值初始化。
vector 对象的操作
几种最重要的 vector 操作。 v.empty(): 如果 v 为空,则返回 true,否则返回 false。 v.size() :返回 v 中元素的个数。
v.push_back(t) :在 v 的末尾增加一个值为 t 的元素。 v[n] :返回 v 中位置为 n 的元素。 v1 = v2 :把 v1 的元素替换为 v2 中元素的副本。 v1 == v2: 如果 v1 与 v2 相等,则返回 true。 !=, <, <=,>, and >=:保持这些操作符惯有的含义。
vector 对象的 size empty 和 size 操作类似于 string 的相关操作。成员函数size 返回相应 vector 类定义的 size_type 的值。使用 size_type 类型时,必须指出该类型是在哪里定义的。vector 类型总是包括 vector 的元素类型: vector<int>::size_type // ok vector::size_type // error
向 vector 添加元素 push_back 操作接受一个元素值,并将它作为一个新的元素添加到 vector对象的后面,也就是“插入(push)”到 vector 对象的“后面(back)”: // read words from the standard input and store them as elements in a vector string word; vector<string> text; // empty vector
while (cin >> word) { text.push_back(word); // append word to text }
vector 的下标操作 vector 中的对象是没有命名的,可以按 vector 中对象的位置来访问它们。通常使用下标操作符来获取元素。vector 的下标操作类似于 string 类型的下标操作。
vector 的下标操作符接受一个值,并返回 vector 中该对应位置的元素。vector 元素的位置从 0 开始。下例使用 for 循环把 vector 中的每个元素值都重置为 0: // reset the elements in the vector to zero for (vector<int>::size_type ix = 0; ix != ivec.size(); ++ix) ivec[ix] = 0;
在上例中,即使 ivec 为空,for 循环也会正确执行。ivec 为空则调用 size 返回 0,并且 for 中的测试比较 ix 和 0。第一次循环时,由于 ix 本身就是 0 就是 0,则条件测试失败,for 循环体一次也不执行。
初学 C++ 的程序员可能会认为 vector 的下标操作可以添加元素,其实不然: vector<int> ivec; // empty vector for (vector<int>::size_type ix = 0; ix != 10; ++ix) ivec[ix] = ix; // disaster: ivec has no elements
上述程序试图在 ivec 中插入 10 个新元素,元素值依次为 0 到 9 的整数。但是,这里 ivec 是空的 vector 对象,而且下标只能用于获取已存在的元素。这个循环的正确写法应该是: for (vector<int>::size_type ix = 0; ix != 10; ++ix) ivec.push_back(ix); // ok: adds new element with value ix 必须是已存在的元素才能用下标操作符进行索引。通过下标操作进行赋值时,不会添加任何元素。
——————————————————————————————————————
C++ 中有些函数可以声明为内联(inline)函数。编译器遇到内联函数时就会直接扩展相应代码,而不是进行实际的 函数调用。像 size 这样的小库函数几乎都定义为内联函数,所以每次循环过程中调用它的运行时代价是比较小的。
——————————————————————————————————————
迭代器简介
除了使用下标来访问 vector 对象的元素外,标准库还提供了另一种访问元素的方法:使用迭代器(iterator)。迭代器是一种检查容器内元素并遍历元素的数据类型。
标准库为每一种标准容器(包括 vector)定义了一种迭代器类型。迭代器类型提供了比下标操作更通用化的方法:所有的标准库容器都定义了相应的迭代器类型,而只有少数的容器支持下标操作。因为迭代器对所有的容器都适用,现 代 C++ 程序更倾向于使用迭代器而不是下标操作访问容器元素,即使对支持下标操作的 vector 类型也是这样。
容器的iterator 类型 每种容器类型都定义了自己的迭代器类型,如 vector: vector<int>::iterator iter; 这符语句定义了一个名为 iter 的变量,它的数据类型是 vector<int> 定义的 iterator 类型。每个标准库容器类型都定义了一个名为 iterator 的成员,这里的 iterator 与迭代器实际类型的含义相同。
begin 和 end 操作 每种容器都定义了一对命名为 begin 和 end 的函数,用于返回迭代器。如果容器中有元素的话,由 begin 返回的迭代器指向第一个元素:vector<int>::iterator iter = ivec.begin();上述语句把 iter 初始化为由名为 vector 操作返回的值。假设 vector 不空,初始化后,iter 即指该元素为 ivec[0]。
由 end 操作返回的迭代器指向 vector 的“末端元素的下一个”。“超出末端迭代器”(off-the-end iterator)。表明它指向了一个不存在的元素。如果 vector 为空,begin 返回的迭代器与 end 返回的迭代器相同。由 end 操作返回的迭代器并不指向 vector 中任何实际的元素,相反,它只是起一个哨兵(sentinel)的作用,表示我们已处理完vector 中所有元素。
vector 迭代器的自增和解引用运算 迭代器类型定义了一些操作来获取迭代器所指向的元素,并允许程序员将迭代器从一个元素移动到另一个元素。迭代器类型可使用解引用操作符(dereference operator)(*)来访问迭代器所指向的元素: *iter = 0; 解引用操作符返回迭代器当前所指向的元素。假设 iter 指向 vector 对象 ivec 的第一元素,那么 *iter 和 ivec[0] 就是指向同一个元素。上面这个语句的效果就是把这个元素的值赋为 0。
迭代器使用自增操作符向前移动迭代器指向容器中下一个元素。从逻辑上说,迭代器的自增操作和 int 型对象的自增操作类似。对 int 对象来说,操作结果就是把 int 型值“加 1”,而对迭代器对象则是把容器中的迭代器“向前移动一个位置”。因此,如果 iter 指向第一个元素,则 ++iter 指向第二个元素。由于 end 操作返回的迭代器不指向任何元素,因此不能对它进行解引用或自增操作。
另一对可执行于迭代器的操作就是比较:用 == 或 != 操作符来比较两个迭代器,如果两个迭代器对象指向同一个元素,则它们相等,否则就不相等。
const_iterator 前面的程序用 vector::iterator 改变 vector 中的元素值。每种容器类型还定义了一种名为 const_iterator 的类型,该类型只能用于读取容器内元素,但不能改变其值。
把 iter 定义为 const_iterator 类型。当对 const_iterator 类型解引用时,返回的是一个 const 值。不允许用 const_iterator进行赋值: for (vector<string>::const_iterator iter = text.begin();iter != text.end(); ++ iter) *iter = " "; // error: *iter is const
不要把 const_iterator 对象与 const 的 iterator 对象混淆起来。声明一个 const 迭代器时,必须初始化迭代器。一旦被初始化后,就不能改变它的值: vector<int> nums(10); // nums is nonconst const vector<int>::iterator cit = nums.begin(); *cit = 1; // ok: cit can change its underlying element
++cit;// error: can't change the value of cit
const_iterator 对象可以用于 const vector 或非 const vector,因为不能改写元素值。const 迭代器这种类型几乎没什么用处:一旦它被初始化后,只能用它来改写其指向的元素,但不能使它指向任何其他元素。
迭代器的算术操作 除了一次移动迭代器的一个元素的增量操作符外,vector 迭代器(其他标准库容器迭代器很少)也支持其他的算术操作。这些操作称为迭代器算术操作(iterator arithmetic),包括: iter + n iter - n 可以对迭代器对象加上或减去一个整形值。这样做将产生一个新的迭代器,其位置在 iter 所指元素之前(加)或之后(减) n 个元素的位置。加或减之后的结果必须指向 iter 所指 vector 中的某个元素,或者是 vector 末端的后一个元素。加上或减去的值的类型应该是 vector 的 size_type 或 difference_type 类型。
iter1 - iter2 该表达式用来计算两个迭代器对象的距离,该距离是名为 difference_type 的 signed 类型 size_type 的值,这里 的 difference_type 是 signed 类型,因为减法运算可能产生负数的结果。该类型可以保证足够大以存储任何两个迭代器对象间的距离。
iter1 与 iter2 两者必须都指向同一 vector 中的元素,或者指向 vector 末端之后的下一个元素。可以用迭代器算术操作来移动迭代器直接指向某个元素,例如,下面语句直接定位于 vector 中间元素: vector<int>::iterator mid = vi.begin() + vi.size() / 2; 上述代码用来初始化 mid 使其指向 vi 中最靠近正中间的元素。这种直接计算迭代器的方法,与用迭代器逐个元素自增操作到达中间元素的方法是等价的,但前者的效率要高得多。任何改变 vector 长度的操作都会使已存在的迭代器失效。例如,在调用 push_back 之后,就不能再信赖指向 vector 的迭代器的值了。
——————————————————————————————————————
标准库 bitset 有些程序要处理二进制位的有序集,每个位可能包含 0(关)1(开)值。位是用来保存一组项或条件的 yes/no 信息(有时也称标志)的简洁方法。标准库提供的 bitset 类简化了位集的处理。要使用 bitset 类就必须包含相关的头文件和使用 std::bitset 的 using 声明: #include <bitset> using std::bitset;
bitset 对象的定义和初始化 类似于 vector,bitset 类是一种类模板;而与 vector 不一样的是 bitset 类型对象的区别仅在其长度而不在其类 型。在定义 bitset 时,要明确 bitset 含有多少位,须在尖括号内给出它的长度值: 初始化bitset 对象的方法: bitset<n> b:b 有 n 位,每位都 0。 bitset<n> b(u): b 是 unsigned long 型 u 的一个副本。 bitset<n> b(s): b 是 string 对象 s 中含有的位串的副本。 bitset<n> b(s, pos, n): b 是 s 中从位置 pos 开始的&nbps;n 个位的副本。 bitset<32> bitvec; // 32 bits, all zero 给出的长度值必须是常量表达式。正如这里给出的,长度值必须定义为整型字面值常量或是已用常量值初始化的整型的 const 对象。这条语句把 bitvec 定义为含有 32 个位的 bitset 对象。和 vector 的元素一样,bitset 中的位是没有命名的,程序员只能按位置来访问。位集合的位置编号从 0 开始,因此,bitvec 的位序是从 0 到 31。以 0 位开始的位串是低阶位(low-order),以 31 位结束的位串是高阶位(high-order)。
用unsigned 值初始化 bitset 对象 当用 unsigned long 值作为 bitset 对象的初始值时,该值将转化为二进制的位模式。而 bitset 对象中的位集作为这种位模式的副本。如果 bitset 类型长度大于 unsigned long 值的二进制位数,则其余的高阶位将置为 0;如果 bitset 类型长度小于 unsigned long 值的二进制位数,则只使用 unsigned 值中的低阶位,超过 bistset 类型长度的高阶位将被丢弃。
用string 对象初始化 bitset 对象 当用 string 对象初始化 bitset 对象时,string 对象直接表示为位模式。从 string 对象读入位集的顺序是从右向左(from right to left): string strval("1100"); bitset<32> bitvec4(strval); bitvec4 的位模式中第 2 和 3 的位置为 1,其余位置都为 0。如果 string 对象的字符个数小于 bitset 类型的长度,则高阶位置为 0。
string 对象和 bitsets 对象之间是反向转化的:string 对象的最右边字符(即下标最大的那个字符)用来初始化 bitset 对象的低阶位(即下标为 0 的位)。当用 string 对象初始化 bitset 对象时,记住这一差别很重要。
bitset 对象上的操作 多种 bitset 操作用来测试或设置 bitset 对象中的单个或多个二进制位。 bitset 操作 b.any() :b 中是否存在置为 1 的二进制位。 b.none(): b 中是否不存在置为 1 的二进制位。
b.count() :b 中置为 1 的二进制位的个数。 b.size() :b 中二进制位的个数。 b[pos] :访问 b 中在 pos 处二进制位。 b.test(pos): 是否把b 中在 pos 处的二进制位置为 1。
b.set() :把 b 中所有二进制位都置为 1。 b.set(pos) :把 b 中在 pos 处的二进制位置为 1。
b.reset() :把 b 中所有二进制位都置为 0。 b.reset(pos) :把 b 中在 pos 处的二进制位置为 0。 b.flip() :把 b 中所有二进制位逐位取反。 b.flip(pos) :把 b 中在 pos 处的二进制位取反。 b.to_ulong() :用 b 中同样的二进制位返回一个 unsigned long 值。 os << b :把 b 中的位集输出到 os 流。
——————————————————————————————————————
术语 abstract data type(抽象数据类型) 隐藏其实现的数据类型。使用抽象数据类型时,只需要了解该类型所支持的操作。
bitset 一种标准库类型,用于保存位置,并提供地各个位的测试和置位操作。
cctype header(cctype 头文件)
从 C 标准库继承而来的头文件,包含一组测试字符值的例程。
class template(类模板) 一个可创建许多潜在类类型的蓝图。使用类模板时,必须给出实际的类型和值。例如,vector 类型是保存给定类型对象的模板。创建一个 vector对象是,必须指出这个 vector 对象所保存的元素的类型。vector<int>保存 int 的对象,而 vector<string> 则保存 string 对象,以此类推。
container(容器) 一种类型,其对象保存一组给定类型的对象的集合。
difference_type 一种由 vector 类型定义的 signed 整型,用于存储任意两个迭代器间的距离。
empty 由string 类型和vector 类型定义的成员函数。empty 返回布尔值,用于检测string 是否有字符或vector 是否有元素。如果string 或vector的size 为0,则返回true,否则返回false。
getline string 头文件中定义的函数,该函数接受一个istream 对象和一个string对象,读取输入流直到下一个换行符,存储读入的输入流到string 对象中,并返回istream 对象。换行符被读入并丢弃。
high-order(高阶) bitset 对象中索引值最大的位。
index(索引) 下标操作符所使用的值,用于表示从string 对象或vector 对象中获取的元素。也称“下标”。
iterator(迭代器) 用于对容器类型的元素进行检查和遍历的数据类型。
iterator arithmetic(迭代器的算术操作) 应用于一些(并非全部)迭代器类型的算术操作。迭代器对象可以加上或减去一个整型数值,结果迭代器指向处于原迭代器之前或之后若干个元素的位置。两个迭代器对象可以相减,得到的结果是它们之间的距离。迭代器算术操作只适用于指向同一容器中的元素或指向容器末端的下一元素迭代器。
low-order(低阶) bitset 对象中索引值最小的位。
off-the-end iterator(超出末端的迭代器) 由end 操作返回的迭代器,是一种指向容器末端之后的不存在元素的迭代器。
push_back 由vector 类型定义的成员函数,用于把元素追加到vector 对象的尾部。
sentinel(哨兵) 一种程序设计技术,使用一个值来控制处理过程。在本章中使用由end操作返回的迭代器作为保护符,当处理完vector 对象中的所有元素后,用它来停止处理vector 中的元素。
size 由库类型string、vector 和bitset 定义的函数,分别用于返回此三个类型的字符个数、元素个素、二进制位的个数。string 和vector 类的size成员函数返回size_type 类型的值(例如,string 对象的size 操作返回string::size_type 类型值)。bitset 对象的size 操作返回size_t 类型值。
size_t 在cstddef 头文件中定义的机器相关的无符号整型,该类型足以保存最大数组的长度。
size_type 由string 类类型和vector 类类型定义的类型,用以保存任意string 对象或vecotr 对象的长度。标准库类型将size_type 定义为unsigned 类型。
using declarations(using 声明) 使命名空间的名字可以直接引用。比如: using namespace::name; 可以直接访问name 而无须前缀namespace::。
value initialization(值初始化) 当给定容器的长度,但没有显式提供元素的初始式时,对容器元素进行的初始化。元素被初始化为一个编译器产生的值的副本。如果容器保存内置类型变量,则元素的初始值将置为0。如果容器用于保存类对象,则元素的初始值由类的默认构造函数产生。只有类提供了默认构造函数时,类类型的容器元素才能进行值初始化。
++ operator(++操作符) 迭代器类型定义的自增操作符,通过“加1”移动迭代器指向下一个元素。
:: operator(::操作符) 作用域操作符。::操作符在其左操作数的作用域内找到其右操作数的名字。用于访问某个命名空间中的名字,如std::cout,表明名字cout 来自命名空间std。同样地,可用来从某个类取名字,如string::size_type,表明size_type 是由string 类定义的。
[] operator([]操作符) 由string, vector 和bitset 类型定义的重载操作符。它接受两个操作数:左操作数是对象名字,右操作数是一个索引。该操作符用于取出位置与索引相符的元素,索引计数从0 开始,即第一个元素的索引为0,最后一个元素的索引为obj.size() -1。下标操作返回左值,因此可将下标操作作为赋值操作的左操作数。对下标操作的结果赋值是赋一个新值到相应的元素。
* operator(*操作符) 迭代器类型定义了解引用操作符来返回迭代器所指向的对象。解引用返回左值,因此可将解引用操作符用作赋值操作的左操作数。对解引用操作的结果赋值是赋一个新值到相应的元素。
<< operator(<< 操作符) 标准库类型string 和bitset 定义了输出操作符。string 类型的输出操作符将输出string 对象中的字符。bitset 类型的输出操作符则输出bitset 对象的位模式。
>> operator(>> 操作符) 标准库类型string 和bitset 定义了输入操作符。string 类型的输入操作符读入以空白字符为分隔符的字符串,并把读入的内容存储在右操作数(string 对象)中。bitset 类型的输入操作符则读入一个位序列到其bitset 操作数中。