1、结构(struct)简介
假如需要存储一个篮球运动员的信息,那么可能需要存储他的姓名、工资、身高、体重、平均得分、命中率、助攻次数等信息。这些数据的格式各不相同,像姓名是字符串类型,身高和体重是整型,为了将这一个运动员作为一个整体把他的所有信息打包在一块,结构体就是应这个需求产生的。(数组是无法满足上例要求的,数组虽然可以存储多个元素,但是每个数组的元素类型必须是相同的)
C++中的结构体可以满足要求(存储篮球运动员的信息)。结构是一种比数组更加灵活的数据格式,因为同一个结构中可以存储多种类型的数据,这使得可以将有关篮球运动员的信息放在一个结构中,从而使数据的表示合并在一起。如果要跟踪整个球队,则可以使用结构数组。类的设计正是在结构体的基础上建立起来的。
结构是用户自己定义的类型,用户可以用自己定义的这个结构体类型声明一个数据的属性。定义了类型之后就可以创建这个类型的变量。因此,创建结构体包括两步。首先,定义结构描述---描述并标记了能够存储在结构中的各种数据类型。然后,按描述创建结构变量(结构数据对象)。感觉抽象看下面的例子:
例如,假设Bloataire公司要创建一种类型来描述其生产线上充气产品的成员。具体点说,这种类型应该存储产品名称、容量和售价。下面就是创建结构体的过程:
struct inflatable
{
char name[20];
flaot volume;
double price;
};
上面这段代码创建的就是一个结构体。关键字struct就表明这是一个结构体。标识符inflatable是这种数据格式的名称,因此新类型的名称为inflatable(类似于整型名称是int,以后就可以直接用这个名称来声明变量了,如inflatable a;)。接下来的大括号中包含的是结构存储的数据类型的列表,其中每个列表项都是一条声明语句。因此,inflatable结构中有3个成员。
在定义了结构体之后,就可以像使用int或char那样使用结构体创建变量了:
inflatable hat;
这里与C语言有些区别,C语言中要求声明时必须带着struct,但是C++允许在声明结构变量时省略关键字struct。
struct inflatable goose; //C语言中带着struct
inflatable vincent; //C++中可以不带struct
对于类型为结构体的变量,可以使用成员运算符(.)来访问各个成员。例如,上面例子中就可以这么访问vincent.volume指的是结构中的volume成员,vincent.price指的是price成员。因为price成员声明的是double类型,因此,vincent.price相当于double类型的变量,可以跟以前使用变量时一样使用就行了。
下面我们通过一个程序来了解一下结构体的具体用法:
#include <iostream>
struct inflatable //声明一个结构体类型
{
char name[20];
float volume;
double price;
};
int main()
{
using namespace std;
inflatable guest =
{
"Glorious Gloria", //姓名值
1.88, //volume 值
29.99 //price值
}; //guest是一个inflatable类型的变量
//这是结构体初始化的一种方式
inflatable pal =
{
"Audacious Arthur",
3.12,
32.99
};
cout << "Expand your guest list with"<<guest.name;
cout << " and "<<pal.name << "!\n";
cout << " You can have both for $";
cout << guest.price + pal.price << " !\n"
return 0;
}
程序输出:Expand your guest list with Glorious Gloria and Audacious Arthur !
You can have both for $62.98!
上面程序需要说明的地方:
结构声明的位置很重要。可以有两种声明位置:一种是可以将声明放在main()函数中,紧跟在开始括号的后面。另一种是将声明放在main()函数的前面,这里采用的就是这种方式,位于函数外面的声明称为外部声明。对于只有一个主函数的程序来说放在外面和里面没有区别,但是如果有多个函数,外部声明可以被其后面的任何函数使用,而内部声明只能被该声明所属的函数使用。所以对于结构体通常应使用外部声明,这样所有的函数都可以使用这种类型的结构。
变量也同样可以在函数内部和外部定义,外部变量由所有的函数共享。但是C++不提倡使用外部变量,但提倡使用外部结构声明。另外,符号常量也一般在外部声明。
还需要注意上面初始化结构体的方式。也可以只用逗号隔开。如inflatable duck = { "Daphne", 0.12 , 9.98};
2、结构体的一些属性
C++尽量使用户自定义的的类型和内置类型相似。比如,可以将结构体作为参数传递给函数,可以让函数返回一个结构体,另外,还可以使用赋值运算符(=)将结构赋给另一个同类型的结构,这样结构中的每一个成员都将被设置成另一个结构中相应成员的值,即使成员是数组。这种赋值被称为成员赋值。
下面的例子介绍了结构赋值:
#include <iostream>
struct inflatable
{
char name[20];
float volume;
double price;
};
int main()
{
using namespace std;
inflatable bouquet =
{
"sunflowers",
0.20,
12.49
};
infilatable choice;
cout << "bouquet: "<<bouquet.name << " for $";
cout << bouquet.price << endl;
choice = bouquet; //直接结构体赋值
cout << "choice: "<< choice.name << " for $";
cout << choice.price << endl;
return 0;
}
程序输出:
bouquet: sunflowers for $12.49
choice: sunflowers for $12.49
结构体的第二个属性是可以同时完成定义结构和创建结构变量的工作。只需将变量名放在结束括号的后面即可:
struct perks
{
int key_number;
char car[12];
} mr_smith, ms_jones; //两个perks类型的结构变量
3、结构数组
可以创建元素为结构的数组,方法和创建基本类型的数组完全相同。例如:创建一个包含100个inflatable结构的数组 inflatable gifts[100];
这样,gifts将是一个inflatable数组,其中每一个元素(如gifts[0]或gifts[99])都是inflatable对象,可以与成员运算符一起使用:
cin>>gifts[0].volume;
但是注意,gifts本身是一个数组,而不是结构,因此像gifts.price这样的表述是无效的。
初始化结构数组,可以按照如下格式:
inflatable guests[2] =
{
{"Bambi", 0.5 ,21.99},
{"Godzilla", 2000, 565.99}
};
4、结构体中的位字段
与C语言一样,C++也允许指定占用特定位数的结构成员,这使得创建与某个硬件设备上的寄存器对应的数据结构非常方便。字段的类型应为整型或枚举,接下来是冒号,冒号后面是一个数字,它指定了使用的位数。可以使用没有名称的字段来提供间距。每个成员都被称为位字段。
struct torgle_register
{
unsigned int SN : 4;
unsigned int : 4;
bool goodIn : 1;
bool goodTorgle : 1;
};
可以像通常那样初始化这些字段,还可以使用标准结构表示法来访问位字段:
torgle_register tr = { 14, true ,false };
if( tr.goodIn)
位字段通常用在低级编程中。一般来说,可以使用整型或按位运算符代替这种方式。