31-使用二维数组
5.6.2 使用二维数组
程序清单5.20初始化了一个二维数组,并使用了一个嵌套循环。这一次,循环的顺序相反,将列循环(城市索引)放在外面,将行循环(年份索引)放在里面。另外,它还采用了C++常用的做法,将一个指针数组初始化为一组字符串常量。也就是说,将cities声明为一个char指针数组。这使得每个元素(如cities [0])都是一个char指针,可被初始化为一个字符串的地址。程序将cities [0]初始化为字符串“Gribble City”的地址,等等。因此,该指针数组的行为与字符串数组类似。
程序清单5.20 nested.cpp
// nested.cpp -- nested loops and 2-D array
#include <iostream>
const int Cities = 5;
const int Years = 4;
int main()
{
using namespace std;
const char * cities[Cities] = // array of pointers
{ // to 5 strings
"Gribble City",
"Gribbletown",
"New Gribble",
"San Gribble",
"Gribble Vista"
};
int maxtemps[Years][Cities] = // 2-D array
{
{96, 100, 87, 101, 105}, // values for maxtemps[0]
{96, 98, 91, 107, 104}, // values for maxtemps[1]
{97, 101, 93, 108, 107}, // values for maxtemps[2]
{98, 103, 95, 109, 108} // values for maxtemps[3]
};
cout << "Maximum temperatures for 2008 - 2011\n\n";
for (int city = 0; city < Cities; ++city)
{
cout << cities[city] << ":\t";
for (int year = 0; year < Years; ++year)
cout << maxtemps[year][city] << "\t";
cout << endl;
}
// cin.get();
return 0;
}
下面是该程序的输出:
Maximum temperatures for 2008 - 2011
Gribble City: 96 96 97 98
Gribbletown: 100 98 101 103
New Gribble: 87 91 93 95
San Gribble: 101 107 108 109
Gribble Vista: 105 104 107 108
在输出中使用制表符比使用空格可使数据排列更有规则。然而,制表符设置不相同,因此输出的外观将随系统而异。第17章将介绍更精确的、更复杂的、对输出进行格式化的方法。
在这个例子中,可以使用char数组的数组,而不是字符串指针数组。在这种情况下,声明如下:
char cities[Cities][25] = // array of 5 arrays of 25 char
{
"Gribble City",
"Gribbletown",
"New Gribble",
"San Gribble",
"Gribble Vista"
};
上述方法将全部5个字符串的最大长度限制为24个字符。指针数组存储5个字符串的地址,而使用char数组的数组时,将5个字符串分别复制到5个包含25个元素的char数组中。因此,从存储空间的角度说,使用指针数组更为经济;然而,如果要修改其中的任何一个字符串,则二维数组是更好的选择。令人惊讶的是,这两种方法使用相同的初始化列表,显示字符串的for循环代码页相同。
另外,还可以使用string对象数组,而不是字符串指针数组。在这种情况下,声明如下:
const string cities[Cities] = // array of 5 strings
{
"Gribble City",
"Gribbletown",
"New Gribble",
"San Gribble",
"Gribble Vista"
};
如果希望字符串是可修改的,则应省略限定符const。使用string对象数组时,初始化列表和用于显示字符串的for循环代码与前两种方法中相同。在希望字符串是可修改的情况下,string类自动调整大小的特性将使这种方法比使用二维数组更为方便。