1.结构体的定义:结构体(struct)简称“结构”,是一种用户自定义的构造类型。结构由若干“成员”(member)组成,每一个成员可以是一个基本数据类型或者其他构造类型。结构在使用前需要先定义,声明结构体由哪些成员组成。
2.注意:结构体最后的分号必不可少。
3.定义结构体的三种方法
1)结构名 结构体变量名;
2)在定义结构类型的同时说明结构变量。即在结构类型定义后添加变量名直接定义变量。
3)直接说明结构变量,可以不指定结构名。又称为无名结构体。
注意:第三种方法与第二种方法的区别在于第三种方法中省去了结构名,而直接给出结构变量。由于此结构没有名字所以此结构在程序的其他地方也就无法再创建新的变量。
4.在程序中使用结构变量时,既可以把它作为一个整体来使用,也可以访问结构体变量中的成员。
5.结构体赋值的两种方式:
1)结构变量的赋值就是给结构体中的成员赋值,可用输入语句或赋值语句来完成。
2)可对结构变量作初始化赋值,初始化时用结构成员值的列表逐个初始化各个成员。
6.结构体数组:数组的元素也可以是结构类型的,因此可以构成结构数组。
7.结构体指针:当使用一个指针变量指向一个结构变量时,称之为结构指针变量。结构指针变量的值是所指向的结构变量的首地址。通过结构指针即可访问该结构变量.
8.通过结构指针变量访问结构变量成员:(*结构指针变量).成员名或者结构指针变量->成员名
应该注意(*)两侧的括号不可少,因为成员符“.”的优先级高于间接引用符“*”。
9.结构体的内存对齐:各类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排列,这就是字节对齐。如果不按照适合其平台要求对数据存放进行对齐,会在存取效率上带来损失。
10.结构体的总大小为结构体最宽基本类型成员大小的整数倍。
11.字节对齐按照从小到大的顺序对齐。
12.举例:在程序中,可以通过#pragma pack关键字来控制对应结构的结构字节对齐方式。
13.在Microsoft Visual Studio 2005中也可以通过C++项目的属性设置来设置结构字节对齐的方式。
14.结构体内存字节对齐举例说明一下:
struct
{
bool a;
short b;
char c;
int d;
double e;
}S1;
先存一个字节为1存a,第二个为2字节,1不能存下来2,失去1个字节,存short2个字节,
现在为四个字节,下个char为1字节,2能整除1,分配2字节,现在为6字节,2又不能整除下个字节数4,失去字节,存4字节现在字节数为12,4又不能整除8,丢失4字节,存8字节,依次类推。
15.代码如下:
//#include <iostream>
//using namespace std;
//
///*
//结构体
//
//定义格式:
//struct 结构体名
//{
//若干个结构体成员
//...
//};//该分号必不可少
//*/
//
//struct stItem//物品
//{
//unsigned int ID;//物品的ID
//char cName[30];//物品的名字
//unsigned int uiBuyPrice;//买入价格
//unsigned int uiSellPrice;//卖出价格
//}objectA;//定义结构体同时声明了2个结构体的变量
匿名结构体,特点:只能在定义结构体的同时声明该结构体的变量
//struct
//{
//char cName[10];
//int iAge;
//}zhangSan,liSi;
//void main()
//{
////结构体的普通变量:
//stItem xiaoXuePing = {1001,"小血瓶",100,60};
//
//stItem taoMuJian;
//taoMuJian.ID = 2001;
//strcpy_s(taoMuJian.cName,"桃木剑");
//taoMuJian.uiBuyPrice = 1000;
//taoMuJian.uiSellPrice = 500;
//
////访问结构体成员的方式1: 普通变量名.成员
//cout<<taoMuJian.cName<<"的ID = "<<taoMuJian.ID<<",买入价为:"
//<<taoMuJian.uiBuyPrice<<",卖出价为:"<<taoMuJian.uiSellPrice<<endl;
////结构体的指针变量:
//stItem * pDaXuePing = NULL;
//pDaXuePing = new stItem;
//pDaXuePing->ID = 1002;
//strcpy_s(pDaXuePing->cName,"大血瓶");
//pDaXuePing->uiBuyPrice = 200;
//pDaXuePing->uiSellPrice = 100;
////访问结构体成员的方式2: 指针变量->成员
//cout<<pDaXuePing->cName<<"的ID = "<<pDaXuePing->ID<<",买入价为:"
//<<pDaXuePing->uiBuyPrice<<",卖出价为:"<<pDaXuePing->uiSellPrice<<endl;
//delete pDaXuePing;
//pDaXuePing = NULL;
////-----结构体的数组-----
//stItem stArray1[100];
//memset(stArray1,0,sizeof(stArray1));
//stItem stArray2[100] = { {1001,"aaa",100,20} };
//cout<<stArray2[0].cName<<endl;
//cout<<stArray2[0].ID<<endl;
//cout<<stArray2[0].uiBuyPrice<<endl;
//cout<<stArray2[0].uiSellPrice<<endl;
//for(int i = 1 ; i < 100 ; ++i)
//{
////对结构体数组动态赋值......
//}
//system("pause");
//}
//-------结构体的内存对齐-------
#include <iostream>
using namespace std;
//#pragma pack(1)//设置内存字节对齐方式为:1字节对齐
struct stObject1
{
bool a;
short b;
char c;
int d;
double e;
};
//#pragma pack(pop)//恢复默认字节对齐方式
struct stObject2
{
bool a;
char b;
short c;
int d;
double e;
};
/*
规则:我们在构建一个结构体的成员时:
按照从大到小的顺序书写结构体成员
*/
void main()
{
cout<<"stObject1所占的字节数为:"<<sizeof(stObject1)<<endl;
cout<<"stObject2所占的字节数为:"<<sizeof(stObject2)<<endl;
system("pause");
}
16.联合体(union):联合类型是将多个数据项组织为一个整体,它们在内存中占用同一段存储单元,联合类型的变量所占用的字节长度为最长的成员的长度。
17.联合体的作用:可以使用联合在同一块内存块存储程序中不同时期的不同变量,可以使用联合以两种或更多种不同的方式来解释相同的数据。
18.联合体在同一个时期只能存储其成员当中的一个数据。
19.联合体中不能用string类型的数据,因为string类型的数据不确定其内存的大小,不能分配内存,可用字符数组来代替。
20.枚举:如果一个变量只有几种可能的值,可以定义为枚举(enumeration)类型。所谓“枚举”是指将变量的值列举出来,变量的值只能在列举出来的值的范围内。声明枚举类型用enum开头。
21.枚举元素本身由系统定义了一个表示序号的数值,在缺省情况下,第一个枚举成员被赋值为0,后面的每个枚举成员的值依次增加1。
22.也可以显式地把一个值赋给一个枚举成员,它后边的成员如果没有赋值,那么值依次增加1,这个值不必是惟一的。
23.枚举值是常量,不是变量,不能在程序中用赋值语句再对它赋值。
24.枚举经常和switch连用。
25.typedef 原类型名 新类型名。
26.Typedef的三种用途:
1)定义一种类型的别名,而不只是简单的宏替换。
2)用typedef来定义与平台无关的类型。
3)为复杂的声明定义一个新的简单的别名。
27.与define写法上的区别:原类型和新类型的位置相反。
28.#define后不用加分号typedef后面需要加上分号。
29.数字用枚举可以进行强转,得到对应的枚举类型。如:在图形渲染中各个元素对应的不同的二维数组中的数字。
28.代码如下:
//#include <iostream>
//using namespace std;
联合体
//
//union uObject
//{
//bool a;
//int b;
//};
//
//union uData
//{
//char a;
//int b;
//};
//void main()
//{
//uObject objectA = {true};
//cout<<objectA.a<<endl;
//uObject objectB;
//objectB.b = 1000;
//cout<<objectB.b<<endl;
//cout<<objectB.a<<endl;
//uData dataA = {'A'};
//cout<<dataA.a<<endl;
//cout<<dataA.b<<endl;
//dataA.b = 97;
//cout<<dataA.b<<endl;
//cout<<dataA.a<<endl;
//
//system("pause");
//}
枚举
//#include <iostream>
//using namespace std;
枚举定义格式:enum 枚举类型名{枚举值};
// // 0 1 2
//enum GameState{ GS_VEDIO ,GS_LOGIN ,GS_LOADING ,
//GS_RUNNING,GS_PAUSING,GS_QUIT };
//
//GameState gameState = GS_VEDIO;
GameState gameState = 0;//此0(int)非彼0(GameState)
//int iState = 0;// 0 - 视频播放, 1-登陆,2-读条
//void main()
//{
//cout<<"游戏开始"<<endl;
//while(1)
//{
////解析游戏状态
//switch(gameState)
//{
//case GS_VEDIO:
//cout<<"play CG!!!!!"<<endl;
//gameState = GS_LOGIN;
//break;
//case GS_LOGIN:
//cout<<"验证帐号名、密码!!!!!!"<<endl;
//gameState = GS_LOADING;
//break;
//case GS_LOADING:
//cout<<"正在读条......"<<endl;
//gameState = GS_RUNNING;
//break;
//case GS_RUNNING:
//cout<<"游戏的主逻辑、渲染"<<endl;
////gameState = GS_PAUSING;
//gameState = GS_QUIT;
//break;
//case GS_PAUSING:
//cout<<"暂停!!!"<<endl;
//gameState = GS_RUNNING;
//break;
//}
//if(gameState == GS_QUIT)
//break;
//}
//cout<<"游戏结束......"<<endl;
//system("pause");
//}
//类型定义符 typedef
#include <iostream>
using namespace std;
//typedef:类型重命名
//格式:typedef 原类型名 新类型名
typedef unsigned short LEVEL;
LEVEL level = 20;
typedef unsigned short WROD ;
typedef unsigned long DWROD;
typedef struct
{
char cName[30];
unsigned int HP;
}HERO,*LPHERO;
typedef char * LPSTR;
#define WIN32_PLATFORM_
#ifdef WIN32_PLATFORM_
typedef int int32;
#else
typedef long int32;
#endif
void main()
{
HERO IronMan={"IronMan",20000};
LPHERO pSpiderMan = new HERO;
LPSTR pName = "asdkfhasd";
system("pause");
}