结构体(Struct)是C语言中一种用户自定义的数据类型,用于将多个不同类型的变量组合在一起,形成一个新的数据类型。结构体可以包含各种基本数据类型(如整数、浮点数、字符等)和其他结构体,从而使得在程序中可以更方便地管理和操作复杂的数据结构。
在C语言中,结构体的定义通常如下:
struct 结构体名称 { 数据类型1 成员变量1; 数据类型2 成员变量2; ... };
结构体定义初始化
Eg: //定义结构体_PlayerInfo struct _PlayerInfo { char szName[50]; int nHP; float PosX; float PoxY; }; int main() { //创建PlayerInfo类型的结构体,并使用初始化列表进行初始化(szName="wolven",nHP=500,PosX=50.32f,PosY=100.34f) struct _PlayerInfo PlayObj = { "wolven",500,50.32f,100.34f }; printf("%s\r\n", PlayObj.szName);//打印结果为wolven //对某个成员变量进行修改 PlayObj.nHP = 1000; printf("%d\r\n", PlayObj.nHP);//打印结果为1000 //指针指向结构体 struct _PlayerInfo * pPlayObj; //声明结构体指针 pPlayObj = &PlayObj; //指针指向PlayObj结构体 printf("%f\r\n", pPlayObj->PosX); printf("%f\r\n", pPlayObj->PosY); system("pause"); return 0; }
//指针指向结构体 struct _PlayerInfo * pPlayObj; //声明结构体指针 pPlayObj = &PlayObj; //指针指向PlayObj结构体 printf("%f\r\n", pPlayObj->PosX); printf("%f\r\n", pPlayObj->PosY);
总结:常规结构体访问成员变量使用 ” . “;指针指向结构体的地址进行成员变量访问时使用"->";也可以使用地址的形式进行成员变量的访问。
printf("%d\r\n", PlayObj.nHP); printf("%d\r\n", (&PlayObj)->nHP); printf("%f\r\n", pPlayObj->nHP); //打印的结果都为1000
为结构体变量申请内存(需要用到malloc函数)注意包含malloc.h头文件
Eg: //定义结构体_PlayerInfo struct _PlayerInfo { char szName[50]; int nHP; float PosX; float PoxY; }; int main() { //为空结构体申请内存 struct _PlayerInfo * pPlayerObj_B = malloc(sizeof(struct _PlayerInfo)); 初始化 pPlayerObj_B->nHP = 5000; printf("%d",pPlayerObj_B->nHP);//打印结果为5000 }
在一般情况下,结构体内存是连续分配的。这意味着结构体中的各个成员变量在内存中是按照声明的顺序依次排列的,没有间隔或填充。这样设计的好处是可以通过结构体的首地址和成员变量的偏移量来访问结构体的各个成员。
但是,结构体内存连续与否还受到编译器的影响,编译器可能会在结构体中添加一些填充字节以满足对齐要求,以提高访问速度。这样可能会导致结构体的大小比成员变量的大小之和要大,但结构体的内存仍然是连续分配的。
typedef为结构体定义新名称
typedef 是C语言中的一个关键字,用于为已有的数据类型(包括基本数据类型、结构体、枚举等)定义新的名称(别名)。
它的语法形式为:
typedef 原类型 新类型名;
使用 typedef
可以方便地为复杂的数据类型定义更简洁、易于理解的别名,提高代码的可读性和可维护性。
在结构体定义的时候我们可以使用typedef定义结构体的新名称(包含指针别名):
typedef struct _PlayerInfo { char szName[50]; int nHP; float PosX; float PosY; }PlayerInfo,*pPlayerInfo; //别名1,别名2;
定义完别名后就可以按照如下方式进行结构体的使用:
PlayerInfo 就相当于 typedef struct _PlayerInfo PlayerInfo PlayObj; //声明结构体指针 pPlayerInfo 就相当于 struct _PlayerInfo * pPlayerInfo pPlayObj;
位域结构体
位域结构体(Bit-field struct)是C语言中一种特殊的结构体,它允许将结构体的成员按照位来存储,以实现对内存的更加精细的控制。
案例:
struct { int a : 8; //使用8位存储a int b : 8; //使用8位存储a int c : 8; //使用8位存储a int d : 8; //使用8位存储a }wl; wl.a = 0x78; wl.b = 0x56; wl.c = 0x34; wl.d = 0x12; printf("0x%X", wl); 输出位0x12345678
这段代码定义了一个位域结构体,该结构体包含了四个成员变量 a
、b
、c
和 d
,每个成员变量都被声明为8位宽度的位域,表示每个成员变量只占用一个字节的存储空间。
然后,创建了一个名为 wl
的结构体变量,并为其成员变量赋值:
-
wl.a = 0x78;
:给a
成员赋值为十六进制数0x78
,其二进制表示为0111 1000
。 -
wl.b = 0x56;
:给b
成员赋值为十六进制数0x56
,其二进制表示为0101 0110
。 -
wl.c = 0x34;
:给c
成员赋值为十六进制数0x34
,其二进制表示为0011 0100
。 -
wl.d = 0x12;
:给d
成员赋值为十六进制数0x12
,其二进制表示为0001 0010
。
最后,使用 printf()
函数以十六进制的形式打印整个结构体变量 wl
的值,由于结构体中的成员变量是按照声明顺序依次存储的,因此整个结构体的值可以被隐式地转换为一个整数类型,并打印其十六进制表示。在这个例子中,输出的结果为结构体 wl
中所有成员变量按照顺序组合而成的一个整数值的十六进制表示。
在当前实验平台上,内存中存储的字节序是小端序(Little-Endian)的,即低位字节存储在低地址处,高位字节存储在高地址处。因此,在内存中,这四个字节的排列顺序是从低地址到高地址的,即 0x12 0x34 0x56 0x78
。