第四章 复合类型之结构、共用体和枚举

原创
2015/05/03 17:25
阅读数 60

        今天比昨天晚一点,因为马刺VS快船的比赛太精彩也太感人了,我支持的马刺遗憾出局,但虽败犹荣。只怨保罗太逆天!

        今天要看的是结构、共用体和枚举,其实都很简单,但是也有很多细节需要认真阅读。还是框架图!

结构

1.定义结构布局和创建结构变量以及初始化

        我们使用关键字struct定义一个结构的布局,可以像下面一样定义一个结构的布局:

struct inflatable
{
    char name[20];
    float volume;
    double price;
};

标识符 inflatable是这种数据格式新的名称,可以使用它来创建这种数据格式的变量,如下所示:

inflatable hat;    //hat is a structure variable of type inflatable
inflatable woopie_cushion;    //type inflatable variable
inflatable mainframe;    //type inflatable variable

以上语句声明了3个 inflatable类型的结构变量,都具有 name、volume、price 3个成员变量。值得注意的是, 在声明结构变量时,C语言需要使用关键字struct,但是C++可以省略。

        结构变量的初始化和数组差不多,如下:

inflatable guest=
{
    "Glorious Gloria",    //name value
    1.88,                //volume value
    29.99                //price value
};
inflatable duck{"Daphne",0.12,9.98};  //can omit the = in C++11
inflatable mayor{};  //volume和price被设置为0,且name的每个字节都被设置为0

         可以将定义结构布局与创建结构变量结合起来,像这样:

struce perks
{
    int key_number;
    char car[12];
}mr_smith,ms_jones;    //two perks variables

        如果你觉得还不够方便,我们还 可以把初始化也加进来,像这样:

struct perks
{
    int key_number;
    char car[12];
}mr_glitz=
{
    7,
    "Packard"
};

        不过看起来不太好看, 最好还是把3者都分开,让程序更容易阅读和理解。我们还可以省略结构名直接定义结构变量,像这样:

struct         //no tag
{
    int x;
    int y;
}position;     //a structrue variable

2.使用结构

        说了这么多,我们该使用结构了,来个程序:

程序清单4.11        strucur.cpp
#include <iostream>
struct inflatable
{
	char name[20];
	float volume;
	double price;
} ;
int main()
 {
	using namespace std;
	
	inflatable guest=
	{
    	"Glorious Gloria",    //name value
    	1.88,                //volume value
    	29.99                //price value
	};	
	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;
}

        主要说明访问结构的成员变量要使用点运算符(.)。下面是运行结果:

        再来一个案例:

程序清单4.12        assgn_st.cpp
#include <iostream>
struct inflatable
{
	char name[20];
	float volume;
	double price;
} ;
int main()
 {
	using namespace std;
	
	inflatable bouquet=
	{
		"sunflower",
		0.20,
		12.49
	};
	inflatable choice;
	cout<<"bouquet: "<<bouquet.name<<" for $";
	cout<<bouquet.price<<endl;
	
	choice=bouquet;		//assign one structrue to another
	cout<<"choice: "<<choice.name<<" for $";
	cout<<choice.price<<endl;
	
	return 0;
}

        运行结果如下:

        这说明结构变量是可以直接赋值的,和数组不同。

3.结构数组

        可以这样定义一个结构数组变量:

inflatable guest[2]=    //initializing an array of structs
{
    {"Bambi",0.5,21.99},    //first structure in array
    {"Godzilla",2000,565.99}    //next structure in array
};

        看下面的程序:

#include <iostream>
struct inflatable
{
	char name[20];
	float volume;
	double price;
} ;
int main()
 {
	using namespace std;
	
	inflatable guests[2]=    //initializing an array of structs
	{
    	{"Bambi",0.5,21.99},    //first structure in array
   		{"Godzilla",2000,565.99}    //next structure in array
	};
	
	cout<<"The guests "<<guests[0].name<<" and "<<guests[1].name
		<<"\nhave a combined volume of "
		<<guests[0].volume+guests[1].volume<<" cubic feet.\n";
		
	return 0;
}

运行结果:

4.结构中的位字段

  1. 共用体

        共用体(union)是一种数据格式,能够存储不同的数据类型,但只能同时存储其中的一种。例如:

union one4all
{
    int int_val;
    long long_val;
    double double_val;
};

        句法和结构类似,只是关键字变成 union 但含义不同。

one4all pail;
pail.int_val=15;        //store an int
cout<<pail.int_val;
pail.double_val=1.38;    //store a double, int value is lost
cout<<pail.double_val;

         pail有时可以是 int变量,又可以是 double变量。 由于每次只能存储一个变量,因此它必须有足够的空间来存储最大的成员,所以,共用体的长度为其最大成员的长度。


        结构中含有匿名共用体,可以直接用结构的名称直接访问共用体的成员,如下所示:

struct widget
{
	char brand[20];
	int type;
	union 
	{
		long id_num;
		char id_char[20];
	 } ;
};
widget prize;
if(prize.type==1)
    cin>>prize.id_num;
else
    cin>>prize.id_char;
        共用体常用于节省内存,例如将C++用于嵌入式系统编程的时候。此外,共用体常用于操作系统数据结构或者硬件数据结构。

  1. 枚举

        enum 工具提供了另一种创建符号常量的方式,可以用来代替const 。使用句法也与结构相似,例如:

enum spectrum{red,orange,yellow,green,blue,violet,indigo,ultraviolet};

         这条语句完成了两项工作,一是让spectrum 成为枚举(enumeration),就像结构一样;二是将red、orange、yellow等作为符号常量,对应的值为0~7可以显式地指定整数来覆盖默认值,如:

enum bits{one=1,two=2,four=4,eitht=8};

指定的值必须是整数,也可以显式地定义其中的一些枚举量的值,如:

enum bigstep{first,second=100,third};

        在这里,first的值为0,而third的值为101,这是需要注意的。 

1.赋值

        我们可以声明一个枚举类型的变量:spectrum band; 不进行强制转换的话有:

band=blue;    //valid,blue is an enumeration
band=2000;    //invalid,2000 not an enumeration

        变量band只能有8个可能的值。如果试图将一个非法值赋给它,有些编译器会出现错误,有的会发出警告。为了获得最大限度地可移植性,应将把非enum值赋给enum变量视为错误。 

        枚举只定义了赋值运算符,没有其他的算术运算符

band=orange;        //valid
++band;         //not valid
band=orange+red        //not valid,but a little triky

        枚举量是整型,可被提升为int类型,但int类型不能自动转换为枚举类型

int color=blue;     //valid
band=3;             //invalid,int not converted to spectrum
color=3+red;        //valid

        我们再来看这个语句为什么错误:

band=orange+red;        //not valid,but a little triky

        orange+red 这个表达式将被转化成1+0,是合法的,但是被转换成了int类型,将int类型再赋给spectrum类型为非法的,可以利用强制类型转换来得到想要的结果

band=spectrum(orange+red);        
band=spectrum(3);

        上面两条语句都是可以的,但如果是这样呢?

band=spectrum(4003);

        将4003转换以后在spectrum里面找不到定义,即超出了定义范围。但是编译器不会报错也不会警告。

2.取值范围

        取值范围的定义如下:

        首先,要找出上限,即枚举量的最大值,找到最大值的最小的2次幂,然后将2次幂的值减1,得到的值便是上限。如bigstep的最大值为101,比这个数大的最小2次幂为128,因此取值上限为127.计算下限值则需要知道枚举量的最小值,如果不小于0则下限为0;否则采用相同的方式寻找,不过最后的结果要加上符号。 如最小值为-6,计算比6大的最小二次幂为8,所以最后的下限为-7。





展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部