3.4.4 使用数组元素的成员函数
使用数组元素成员函数的方法是写出数组元素,在后面跟上成员选择运算符和成员函数名称。听起来有些复杂,其实不然,如下例所示:
cout << inventory[0].size() << " letters in it.\n";
代码inventory[0].size()的意思是程序调用元素inventory[0]的成员函数size()。因为此处的inventory[0]是"battle axe",所以调用返回该string对象的字符个数10。
3.4.5 数组边界
之前已经介绍过,索引数组时要小心。因为数组的大小是固定的,所以可以创建一个整型常量存储数组的大小。程序的开头部分就采取了这种做法:
const int MAX_ITEMS = 10;
下面代码在给主人公添加物品之前使用MAX_ITEMS进行数组保护:
if (numItems < MAX_ITEMS)
{
inventory[numItems++] = "healing potion";
}
else
{
cout << "You have too many items and can’t carry another.";
}
这段代码首先检测numItems是否小于MAX_ITEMS。如果小于,则可以安全地把numItems当作索引号使用,并赋给数组一个新的string对象。在本例中,numItems为3,所以字符串"healing potion"赋给了数组的位置3。如果不满足小于条件,则显示消息“You have too many items and can't carry another.”。
那么,如果使用数组边界以外的元素会怎样?这要视情况而定,因为这是在使用计算机内存中未知的部分。最坏的情况是,如果试图给数组边界外的元素赋值,将导致程序行为不可预测,甚至程序崩溃。
可以在使用索引号之前对其进行测试,以确保它是合法的数组位置。这种做法叫做边界检查。如果要使用的索引可能不合法,那么边界检查是必不可少的。
3.5 理解C风格字符串
有string对象之前,C++程序员使用以空字符结尾的字符数组表示字符串。这些字符数组现在称为C风格字符串,因为这种表示字符串的习惯是从C程序开始的。声明和初始化C风格字符串的方法和其他数组一样:
char phrase[] = "Game Over!!!";
C风格字符串以一个称为空字符的字符结尾。空字符可以写成'\0'。上面的代码不需要使用空字符,因为它已经存储在字符串的结尾处。所以,从技术上而言,phrase有13个元素(然而,使用C风格字符串的函数则认为phrase的长度为12,这是合理的,并且与string对象的工作原理一致)。
至于其他任意类型的数组,可以在定义时指定数组大小。因此,声明和初始化C风格字符串的另一种方式是:
char phrase[81] = "Game Over!!!";
这行代码创建了一个可以容纳80个可打印字符的C风格字符串(另外还有一个终止空字符)。
C风格字符串没有成员函数,但是作为标准库一部分的cstring文件中包含了各种使用C风格字符串的函数。
string对象的优点在于,它们被设计为可以和C风格字符串很好地结合使用。例如,下面给出的都是C风格字符串和string对象的合法用法:
string word1 = "Game";
char word2[] = " Over";
string phrase = word1 + word2;
if (word1 != word2)
{
cout << "word1 and word2 are not equal.\n";
}
if (phrase.find(word2) != string::npos)
{
cout << "word2 is contained in phrase.\n";
}
string对象可以和C风格字符串连接起来,但结果仍然是一个string对象(所以char phrase2[] = word1 + word2;会产生错误)。可以使用关系运算符比较string对象和C风格字符串,甚至还可以将C风格字符串用作string对象成员函数的实参。
C风格字符串和数组有共同的缺点,其中最大的一个是它们的长度是固定的。因此,应当遵循的原则是:只要可能就使用string对象,但是如果有必要的话,需做好使用C风格字符串的准备。