1. struct的巨大作用
  面对一个人的大型C/C++程序时,只看其对struct的使用情况我们就可以对其编写者的编程经验进行评估。因为一个大型的C/C++程序,势必要涉及一些(甚至大量)进行数据组合的结构体,这些结构体可以将原本意义属于一个整体的数据组合在一起。从某种程度上来说,会不会用struct,怎样用struct是区别一个开发人员是否具备丰富开发经历的标志。


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

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

  一个有经验的开发者则灵活运用结构体,举一个例子,假设网络或控制协议中需要传送三种报文,其格式分别为
packetA、packetB、packetC:
  1. struct structA    
  2. {   
  3.  int a;   
  4.  char b;   
  5. };   
  6.   
  7. struct structB    
  8. {   
  9.  char a;   
  10.  short b;   
  11. };   
  12.   
  13. struct structC   
  14. {   
  15.  int a;   
  16.  char b;   
  17.  float c;   
  18. }   


  1. //  优秀的程序设计者这样设计传送的报文:   
  2.   
  3. struct CommuPacket   
  4. {   
  5.  int iPacketType;  //报文类型标志   
  6.  union      //每次传送的是三种报文中的一种,使用union   
  7.  {   
  8.   struct structA packetA;   
  9.   struct structB packetB;   
  10.   struct structC packetC;   
  11.  }   
  12. };   

  在进行报文传送时,直接传送struct CommuPacket一个整体。

  假设发送函数的原形如下:
  1. // pSendData:发送字节流的首地址,iLen:要发送的长度   
  2. Send(char * pSendData, unsigned int  iLen);   
  3. //发送方可以直接进行如下调用发送struct CommuPacket的一个实例sendCommuPacket:   
  4. Send( (char *)&sendCommuPacket , sizeof(CommuPacket) );   
  5. //假设接收函数的原形如下:   
  6. // pRecvData:发送字节流的首地址,iLen:要接收的长度   
  7. //返回值:实际接收到的字节数   
  8. unsigned int Recv(char * pRecvData, unsigned int  iLen);   
  9.   
  10.   //接收方可以直接进行如下调用将接收到的数据保存在struct CommuPacket的一个实例recvCommuPacket中:   
  11.   
  12. Recv( (char *)&recvCommuPacket , sizeof(CommuPacket) );   
  13.   
  14.   //接着判断报文类型进行相应处理:   
  15.   
  16. switch(recvCommuPacket. iPacketType)   
  17. {   
  18.     case PACKET_A:   
  19.     …    //A类报文处理   
  20.     break;   
  21.     case PACKET_B:   
  22.     …   //B类报文处理   
  23.     break;   
  24.     case PACKET_C:   
  25.     …   //C类报文处理   
  26.     break;   
  27. }   
  28.   
  29. //  以上程序中最值得注意的是   
  30.   
  31. Send( (char *)&sendCommuPacket , sizeof(CommuPacket) );   
  32. Recv( (char *)&recvCommuPacket , sizeof(CommuPacket) );   

  中的强制类型转换:(char *)&sendCommuPacket、(char *)&recvCommuPacket,先取地址,再转化为char型指针,这样就可以直接利用处理字节流的函数。

  利用这种强制类型转化,我们还可以方便程序的编写,例如要对sendCommuPacket所处内存初始化为0,可以这样调用标准库函数memset():

  1. memset((char *)&sendCommuPacket,0, sizeof(CommuPacket));   

posted on 2008-02-26 16:53  大鱼  阅读(264)  评论(0编辑  收藏  举报