本文共 4516 字,大约阅读时间需要 15 分钟。
文章中的文字可能存在语法错误以及标点错误,请谅解;
如果在文章中发现代码错误或其它问题请告知,感谢!
在实际编程过程中,我们希望把一些关联的数据存放在一起,这样方便我们使用,但是这些数据的类型有时候并不一致,例如报文内容以及该条报文长度,报文内容和长度不属于同一类型,报文应该是类似如char*类型的字符串,报文长度应该是类似如int类型的整数。
因为数组只能存放同一类型的数据,所以不适合用数组来保存这些变量。 但在C语言中,结构体允许将不同类型数据组成组合型的数据结构。此时,我们若想要将类型不一样的关联数据存放在一起,就可以使用结构体。
声明一个结构体类型的一般形式如下:
struct 结构体类型名 { 成员表列 };其中,成员表列中的每个成员(Member)是该结构体类型所包含的变量或数组,上面所说的报文内容和报文长度可以是一个结构体的成员,它们组合在一起构成成员表列,举例如下:
struct UDP_Server_Thread_Para{ void *pData; int Len;};
结构体的类型可以有很多种,结构体类型中的成员由开发者自己定义,并且成员不用初始化。
另外,一个结构体成员可以属于另一个结构体类型,例如:struct TIME{ int date; int month; int year; int hour; int min; int sec;};struct nmea_msg{ struct TIME utc; char gpssta; int longitude; int latitude; short speed; short altitude; };
上节所述的结构体类型本身并不会作为数据而被系统分配内存,如果一个结构体类型定义了变量则系统会分配内存空间,每一个结构体变量的所占内存大小,由结构体类型中的每个成员的总和决定。
定义结构体变量的方法有三种: 1.先声明结构体类型,再定义该类型变量:一般形式为:
struct 结构体类型名 { 成员表列 }; struct 结构体类型名 变量名表列;例如:
struct UDP_Server_Thread_Para{ void *pData; int Len;};struct UDP_Server_Thread_Para UDPThreadPara1,UDPThreadPara2;
为了便于理解,可以把struct UDP_Server_Thread_Para 类型类比于 int类型,UDP_Server_Thread_Para UDPThreadPara1,UDPThreadPara2即int UDPThreadPara1,UDPThreadPara2。
一个在该定义方式下的程序例子:
#includestruct UDP_Server_Thread_Para{ void *pData; int len;};int main(){ struct UDP_Server_Thread_Para UDPThreadPara1,UDPThreadPara2; UDPThreadPara1.pData = "hello"; UDPThreadPara1.len = 1; UDPThreadPara2.pData = "world"; UDPThreadPara2.len = 2; printf("UDPThreadPara1: %s, len %d\n", (char*)UDPThreadPara1.pData, UDPThreadPara1.len); printf("UDPThreadPara2: %s, len %d\n", (char*)UDPThreadPara2.pData, UDPThreadPara2.len); return 0;}
运行结果:
2.在声明的同时定义变量:
一般形式为:
struct 结构体类型名 { 成员表列 }变量名表列;例如:
struct UDP_Server_Thread_Para{ void *pData; int Len;}UDPThreadPara1,UDPThreadPara2;
声明和定义变量放在一起比较直观,但在比较大的代码工程中,为了使程序结构清晰,会对类型声明和变量定义放在不同的位置。另外,在此方式下,也可以根据需要在函数中新增该结构体类型变量。
一个在该定义方式下的程序例子:
#includestruct UDP_Server_Thread_Para{ void *pData; int len;}UDPThreadPara1,UDPThreadPara2;int main(){ UDPThreadPara1.pData = "hello"; UDPThreadPara1.len = 1; UDPThreadPara2.pData = "world"; UDPThreadPara2.len = 2; struct UDP_Server_Thread_Para UDPThreadPara3; //新增该结构体类型变量 UDPThreadPara3.pData = "!!!!"; UDPThreadPara3.len = 3; printf("UDPThreadPara1: %s, len %d\n", (char*)UDPThreadPara1.pData, UDPThreadPara1.len); printf("UDPThreadPara2: %s, len %d\n", (char*)UDPThreadPara2.pData, UDPThreadPara2.len); printf("UDPThreadPara3: %s, len %d\n", (char*)UDPThreadPara3.pData, UDPThreadPara3.len); return 0;}
运行结果:
3.不指定类型名直接定义结构体类型变量:
一般形式为:
struct { 成员表列 }变量名表列;struct{ void *pData; int Len;}UDPThreadPara1,UDPThreadPara2;
这种方式只能够定义一次,不能再以此定义其它变量。
一个在该定义方式下的程序例子:
#includestruct{ void *pData; int len;}UDPThreadPara1,UDPThreadPara2;int main(){ UDPThreadPara1.pData = "hello"; UDPThreadPara1.len = 1; UDPThreadPara2.pData = "world"; UDPThreadPara2.len = 2; printf("UDPThreadPara1: %s, len %d\n", (char*)UDPThreadPara1.pData, UDPThreadPara1.len); printf("UDPThreadPara2: %s, len %d\n", (char*)UDPThreadPara2.pData, UDPThreadPara2.len); return 0;}
运行结果:
对于结构体变量的初始化即赋值,可以在定义结构体变量时对其进行成员初始化,例如:
struct UDP_Server_Thread_Para{ void *pData; int Len;}UDPThreadPara1={“I LOVE CHINA”,12},UDPThreadPara2={“I AM CHINESE”,12};
也可以引用 结构体变量时赋值,格式如下:
结构体类型变量名.成员名例如:
struct UDP_Server_Thread_Para{ void *pData; int Len;}UDPThreadPara1,UDPThreadPara2;UDPThreadPara1.pData = "I LOVE CHINA";UDPThreadPara1.Len = 12;UDPThreadPara2.pData = "I AM CHINESE";UDPThreadPara2.Len = 12;
若结构体成员本身又属于另一个结构体类型,则需要运算符“.”逐级找到最低以及的成员赋值。比如上一小节nmea_msg类型结构体中utc属于TIME类型结构体,假设现在要为speed以及month赋值则:
struct TIME{ int date; int month; int year; int hour; int min; int sec;};struct nmea_msg{ struct TIME utc; char gpssta; int longitude; int latitude; short speed; short altitude; } Data;Data.speed = 50;Data.utc.month = 12;
最后,需要注意的是,访问结构体成员需要对齐访问,至于这个概念 ,下篇博文会介绍。
以上。
参考文档: 1. 2. 3. 4. 谭浩强.C程序设计(第四版)[M].北京:清华大学出版社,2010.转载地址:http://mmdzz.baihongyu.com/