当前位置:首页 > 公众号精选 > 嵌入式基地

struct的作用

一般来说,区别一个开发人员是否具备丰富开发经历的标志在于其会不会使用struct,怎么使用strcut。

在网络协议、通信控制、嵌入式系统的编程中,我们经常要传送的不是简单的字节流(char型数组),而是多种数据组合起来的一个整体,其表现形式是一个结构体。

初级的开发人员往往将所有需要传送的内容依顺序保存在char 型数组中,通过指针偏移的方法传送网络报文等信息。这样做编程复杂,易出错,而且一旦控制方式及通信协议有所变化,程序就要进行非常细致的修改。

一个有经验的开发者则灵活运用结构体,举一个例子,假设网络或控制协议中需要传送三种报文,其格式分别为packetA、packetB、packetC

typedef struct StructA { int a; char b;
} A; typedef struct StructB { chara;
 shortb;
} B; typedef struct StructC { int a; char b; float c;
} C;

报文结构设计

typedef enum PacketType{
 PacketTypeA = 1,
 PacketTypeB,
 PacketTypeC
}; struct CommuPacket { PacketType type; ////< 报文类型 union { ////< 每次传输的是其中的一种,因此使用union A packet_a;
 B packet_b;
 C packet_c;
 }
};

报文传输设计

/* pSendData 发送字节流的首地址
 len 发送数据长度
*/ void Send(char *pSendData, unsigned int len); /* pRecvData 接收缓冲区首地址
 len 接受长度 
 返回值:实际接收长度
*/ unsigned int Recv(char *pRecvData, unsigned int len);

判断报文类型,并作相应处理

switch(type) { case PacketTypeA :
 ... break; case PacketTypeB :
 ... break; case PacketTypeC :
 ... break;
}

struct成员对齐

自然对齐

struct 是一种复合数据类型,其构成元素既可以是基本数据类型(如int、long、float 等)的变量,也可以是一些复合数据类型(如array、struct、union 等)的数据单元。对于结构体,编译器会自动进行成员变量的对齐,以提高运算效率。缺省情况下,编译器为结构体的每个成员按其自然对界(natural alignment)条件分配空间。各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同。


自然对界(natural alignment)即默认对齐方式,是指按结构体的成员中size 最大的成员对齐。

struct Natural { char a; short b; char c;
}

在上面的这个结构体中,size最大的数据类型为short,长度为两个字节。因此,结构体中所有成员变量都以2为单位对齐。
其大小为sizeof(Natural) = 6

指定对界

一般使用预处理指令#pragma pack来改变缺省的对界条件

  • 使用伪指令#pragma pack (n),编译器将按照n 个字节对齐

  • 使用伪指令#pragma pack (),取消自定义字节对齐

  • 如果#pragma pack (n)中指定的n 大于结构体中最大成员的size,则其不起作用,结构体仍然按照size 最大的成员进行对界

#pragma pack (n) struct Natural { char a; int b; char c;
}; #pragma pack () 

当n 为4、8、16 时,其对齐方式均一样,sizeof(naturalalign)的结果都等于12。而当n 为2时,其发挥了作用,使得sizeof(Natural)的结果为6。

  • 通过__attribute((aligned (n)))也可以让所作用的结构体成员对齐在n 字节边界上,但它使用较少

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
关闭