42-类型组合
4.9 类型组合
本章介绍了数组、结构和指针。可以各种方式组合它们,下面介绍其中的一些,从结构开始:
struct antarctica_years_end
{
int year;
/* some really interesting data, etc. */
};
可以创建这种类型的变量:
antarctica_years_end s01, s02, s03; // s01, s02, s03 are structures
然后使用成员运算符访问其成员:
s01.year = 1998;
可创建指向这种结构的指针:
antarctica_years_end * pa = &s02;
将该指针设置为有效地址后,就可使用间接成员运算符来访问成员:
pa->year = 1999;
可创建结构数组:
antarctica_years_end trio[3]; // array of 3 structures
然后,可以使用成员运算符访问元素的成员:
trio[0].year = 2003; // trio[0] is a structure
其中trio是一个数组,trio[0]是一个结构,而trio[0].year是该结构的一个成员。由于数组名是一个指针,因此也可使用间接成员运算符:
(trio+1)->year = 2004; // same as trio[1].year = 2004;
可创建指针数组:
const antarctica_years_end * arp[3] = {&s01, &s02, &s03};
咋一看,这有点复杂。如何使用该数组来访问数据呢?既然arp是一个指针数组,arp[1]就是一个指针,可将间接成员运算符应用于它,以访问成员:
std::cout << arp[1]->year << std::endl;
可创建指向上述数组的指针:
const antarctica_years_end ** ppa = arp;
其中arp是一个数组的名称,因此它是第一个元素的地址。但其第一个元素为指针,因此ppa是一个指针,指向一个指向const antarctica_years_end的指针。这种声明很容易出错。例如,您可能遗漏const,忘记*,搞错顺序或结构类型。下面的示例演示了C++11版本的auto提供的方便。编译器知道arp的类型,能够正确地推断出ppb的类型:
auto ppb = arp; // C++11 automatic type deduction
在以前,编译器利用它推断的类型来指出声明错误,而现在,您可利用它的这种推断能力。
如何使用ppa来访问数据呢?由于ppa是一个指向结构指针的指针,因此*ppa是一个结构指针,可将间接成员运算符应用于它:
std::cout << (*ppa)->year << std::endl;
std::cout << (*(ppb+1))->year << std::endl;
由于ppa指向arp的第一个元素,因此ppa为第一个元素,即&s01。所以,(ppa)->year为s01的year成员。在第二条语句中,ppb+1指向下一个元素arp[1],即&s02。其中的括号必不可少,这样才能正确地结合。例如,ppa->year试图将运算符应用于ppa->year,这将导致错误,因为成员year不是指针。
上面所有的说法都对吗?程序清单4.23将这些语句放到了一个简短的程序中。
程序清单4.23 mixtypes.cpp
// mixtypes.cpp -- some type combinations
#include <iostream>
struct antarctica_years_end
{
int year;
/* some really interesting data, etc. */
};
int main()
{
antarctica_years_end s01, s02, s03;
s01.year = 1998;
antarctica_years_end * pa = &s02;
pa->year = 1999;
antarctica_years_end trio[3]; // array of 3 structures
trio[0].year = 2003;
std::cout << trio->year << std::endl;
const antarctica_years_end * arp[3] = {&s01, &s02, &s03};
std::cout << arp[1]->year << std::endl;
const antarctica_years_end ** ppa = arp;
auto ppb = arp; // C++11 automatic type deduction
// or else use const antarctica_years_end ** ppb = arp;
std::cout << (*ppa)->year << std::endl;
std::cout << (*(ppb+1))->year << std::endl;
return 0;
}
该程序的输出如下:
2003
1999
1998
1999
该程序通过了编译,并向前面介绍的那样运行。