结构体成员数组不定长如何实现

Posted 壹点灵异

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了结构体成员数组不定长如何实现相关的知识,希望对你有一定的参考价值。

【目的】

  定义一个结构体类,其中的成员变量数组长度不定,根据实例化的对象指定长度,所以想到用指针实现

【现状】

  指针可以指向任意长度数组,但结构体类只分配指针本身4字节长度,所以无法扩展

 

 

  1 /**
  2 ***************************************************************************************************
  3 *
  4 *    @FileName        Data structure of device
  5 *
  6 *    @Editor          Skullboyer
  7 *
  8 *    @EditTime        2017-12-27 
  9 *
 10 *    @Version         V0.1
 11 *
 12 *    @Note            
 13 *
 14 ***************************************************************************************************
 15 */
 16 
 17 
 18 /* Define the data structure */
 19 typedef struct
 20 {
 21     uint8_t Msg_Head;         /* 消息标识头 */
 22     uint16_t Msg_ID;          /* 消息 ID */
 23     uint16_t Msg_Prop;        /* 消息体属性 */
 24     uint8_t Term_Phone[6];    /* 终端手机号 */
 25     uint16_t Msg_SwiftNum;    /* 消息流水号 */
 26     void *Message;            /* 消息体 */
 27     uint8_t Msg_CRC;          /* 校验码 */
 28     uint8_t Msg_Tail;         /* 消息标识尾 */
 29 }DATA_s;
 30 
 31 /* Instantiated objects ---------------------------------*/
 32 DATA_s sMedia;
 33 
 34 /* GPS structure */
 35 uint8_t uGPS_Data[28];
 36 DATA_s sGPS = 
 37 {
 38     0x7E;
 39     0x0200;
 40     0x****;
 41     0x**, 0x**, 0x**, 0x**, 0x**, 0x**;
 42     0x****;
 43     uGPS_Data;
 44     0x**;
 45     0x7E;
 46 }
 47 
 48 /* TMPS structure */
 49 uint8_t uTMPS_Data[1024];    /* 最大支持1024个轮胎 10bit */
 50 DATA_s sTMPS = 
 51 {
 52     0x7E;
 53     0x0205;
 54     0x****;
 55     0x**, 0x**, 0x**, 0x**, 0x**, 0x**;
 56     0x****;
 57     uTMPS_Data;
 58     0x**;
 59     0x7E;
 60 }
 61 
 62 /* POSE structure */
 63 uint8_t uPOSE_Data[28];    
 64 DATA_s sPOSE = 
 65 {
 66     0x7E;
 67     0x0206;
 68     0x****;
 69     0x**, 0x**, 0x**, 0x**, 0x**, 0x**;
 70     0x****;
 71     uPOSE_Data;
 72     0x**;
 73     0x7E;
 74 }
 75 
 76 /* OBD structure */
 77 uint8_t uOBD_Data[202];    
 78 DATA_s sOBD = 
 79 {
 80     0x7E;
 81     0x0207;
 82     0x****;
 83     0x**, 0x**, 0x**, 0x**, 0x**, 0x**;
 84     0x****;
 85     uOBD_Data;
 86     0x**;
 87     0x7E;
 88 }
 89 
 90 
 91 
 92 
 93 
 94 
 95 
 96 
 97 
 98 
 99 
100 
101 
102 
103 
104 
105 
106 /******************************************^_^\__END__/^_^******************************************/

验证相关代码 

 

  1 #include "stdio.h"
  2 #include "stdlib.h"
  3 
  4 /* 类别名 */ 
  5 typedef unsigned char    uint8_t;
  6 typedef unsigned short int    uint16_t;
  7 typedef unsigned int    uint32_t;
  8  
  9 /* 单字节对齐 */
 10 #pragma pack(1) 
 11 
 12 /* Define the data structure ------------------------------*/
 13 typedef struct
 14 {
 15     uint8_t Msg_Head;         /* ???¢±êê?í· */
 16     uint16_t Msg_ID;          /* ???¢ ID */
 17     uint16_t Msg_Prop;        /* ???¢ì?ê?D? */
 18     uint8_t Term_Phone[6];    /* ????ê??úo? */
 19     uint16_t Msg_SwiftNum;    /* ???¢á÷??o? */
 20     uint8_t *Message;         /* ???¢ì? */
 21 //    void *Message;          /* void*在下边打印出错 */
 22     uint8_t Msg_CRC;          /* D£?é?? */
 23     uint8_t Msg_Tail;         /* ???¢±êê??2 */
 24 }DATA_s;
 25 
 26 #pragma pack()
 27 
 28 typedef union
 29 {
 30     DATA_s sObj;
 31     uint8_t uByte[];    /* 以不指定长度的数组来控制数据按字节输出,其长度由 DATA_s 类长度决定 */        
 32 //    uint8_t *uByte;        /* 愿望以字节指针控制数据按字节输出,但愿望失败,经测试无法控制到字节地址,只能控制字地址 */ 
 33 }DATA_u;
 34 
 35 /* Instantiated objects ---------------------------------*/
 36 DATA_s sMedia;
 37 
 38 /* GPS structure */
 39 uint8_t uGPS_Data[28];
 40 DATA_u uGPS ;
 41 DATA_s sGPS =                              
 42 {                                           
 43     0x7E,                                      
 44     0x0200,                                    
 45     0x1234,                                    
 46     0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC,        
 47     0x5A5A,                                    
 48     uGPS_Data,                      
 49     0x12,                                      
 50     0x7E                                       
 51 };
 52 
 53 /* TMPS structure */
 54 uint8_t uTMPS_Data[1024];    /* ×?′ó?§3?1024????ì¥ 10bit */
 55 DATA_s sTMPS =                              
 56 {                                           
 57     0x7E,                                      
 58     0x0205,                                    
 59     0x5678,                                    
 60     0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78,        
 61     0xA5A5,                                    
 62     uTMPS_Data,                                
 63     0x34,                                      
 64     0x7E                                       
 65 };
 66 
 67 /* POSE structure */
 68 uint8_t uPOSE_Data[28];                                                
 69 DATA_s sPOSE =                              
 70 {                                           
 71     0x7E,                                     
 72     0x0206,                                    
 73     0x9ABC,                                    
 74     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54,        
 75     0x55AA,                                    
 76     uPOSE_Data,                                
 77     0x56,                                      
 78     0x7E                                       
 79 };
 80 
 81 /* OBD structure */
 82 uint8_t uOBD_Data[202];    
 83 DATA_s sOBD =                               
 84 {                                           
 85     0x7E,                                      
 86     0x0207,                                    
 87     0xDEF0,                                    
 88     0x32, 0x10, 0xFE, 0xDC, 0xBA, 0x98,        
 89     0xAA55,                                    
 90     uOBD_Data,                                 
 91     0x78,                                      
 92     0x7E                                       
 93 };
 94 
 95 int main(void)
 96 {
 97     
 98     uint16_t i, j;
 99     uint16_t GPS_Len;
100     DATA_s *p;
101     
102     /* 类型大小 */
103     printf("\n----------------类型大小--------------------\n");
104     printf("\nsizeof(uint8_t)= %d\n", sizeof(uint8_t)); 
105     printf("sizeof(uint16_t)= %d\n", sizeof(uint16_t)); 
106     printf("sizeof(DATA_s)= %d\n", sizeof(DATA_s)); 
107     printf("\n--------------------------------------------\n");                                      
108         
109     /* 数组初始化 */ 
110     for(i = 0; i < 28; i++)
111         uGPS_Data[i] = i;
112         
113     for(i = 0; i < 1024; i++)
114         uTMPS_Data[i] = i;
115         
116     for(i = 0; i < 28; i++)
117         uPOSE_Data[i] = i;
118         
119     for(i = 0; i < 202; i++)
120         uOBD_Data[i] = i;
121     
122     DATA_s sGPS =                              
123 {                                           
124     0x7E,                                      
125     0x0200,                                    
126     0x1234,                                    
127     0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC,        
128     0x5A5A,                                    
129     uGPS_Data,                      
130     0x12,                                      
131     0x7E                                       
132 };
133     
134     /* 联合体赋值 */
135     GPS_Len = sizeof(DATA_s) + sizeof(uGPS_Data) - 4;        /* sGPS所占字节数(指针成员初始化后) */ 
136     printf("\n----------------GPS对象大小--------------------\n");
137     printf("\nGPS_Len= %d\n", GPS_Len);
138     printf("\n-----------------------------------------------\n");
139 //    uGPS.uByte = (uint8_t *)malloc(GPS_Len);    /* 联合体中的指针分配必须在其结构体赋值之前,否则后分配的指针对应的值是乱码,将冲掉已正确赋值的结构体 */    
140     uGPS.sObj = sGPS;
141 //     uGPS.uByte = &uGPS.sObj.Msg_Head;    /* 将结构体第一个变量地址赋给共用体指针,导致地址与实际变化了,为什么要赋地址,因为调试发现共用体的成员之间地址不统一 */
142     
143     /* 结构体对象间赋值 */
144     sMedia = sGPS;
145     printf("\n----------------结构体对象整体赋值--------------------\n");
146     printf("\nsMedia.Msg_Head= %#X\n", sMedia.Msg_Head);
147     printf("\n------------------------------------------------------\n");
148         
149     p = &sGPS;
150     printf("\n----------------sizeof对象大小--------------------\n");
151     printf("\nsizeof(uGPS_Data)= %d\n", sizeof(uGPS_Data));
152     printf("sizeof(sGPS)= %d\n", sizeof(sGPS));
153     printf("\n--------------------------------------------------\n");
154     
155     printf("\n----------------sizeof指针成员大小--------------------\n");
156     printf("\nsizeof(p->Message)= %d\n", sizeof(p->Message));
157     printf("sizeof(sGPS.Message)= %d\n", sizeof(sGPS.Message));
158     printf("\n------------------------------------------------------\n");
159     
160 #if 0 
161     printf("%#X\n", p->Msg_Head);
162     printf("%#X\n", p->Msg_ID); 
163     printf("%#X\n", p->Msg_Prop); 
164     printf("%#X\n", p->Term_Phone); 
165     printf("%#X\n", p->Msg_SwiftNum); 
166     printf("%#X\n", p->Message); 
167     printf("%#X\n", p->Msg_CRC);
168     printf("%#X\n", p->Msg_Tail); 
169 #endif
170     
171     /* 联合体输出 */ 
172     printf("\n----------------联合体对象--------------------\n");    
173     printf("\nuGPS.sObj.Msg_Head= %#X\n", uGPS.sObj.Msg_Head); 
174     printf("&uGPS.sObj.Msg_Head= %#X\n", &uGPS.sObj.Msg_Head);
175     printf("uGPS.uByte= %#X\n", uGPS.uByte); 
176     printf("*uGPS.uByte= %#X\n", *uGPS.uByte); 
177     printf("\n----------------------------------------------\n");    
178      
179          
180     
181     
182     /* 愿望以联合体的字节变量输出 */
183     printf("\n----------------以联合体的字节变量输出--------------------\n"); 
184     for(i = 0; i < GPS_Len; i++)
185     {
186         printf("%#X\t", uGPS.uByte[i]);    /*  */ 
187     }
188     printf("\n----------------------------------------------------------\n");
189     
190     
191     printf("\n----------------以传统之法输出--------------------\n");
192     /* 上边愿望失败,改此补之,失败在指针成员处 */
193     /* 除去指针,其余以联合体的字节变量输出 */    
194     for(i = 0; i < sizeof(DATA_s); i++)    /**/ 
195     {
196         if(i == 13)    /* 到达指针 Message 处 */ 
197         {
198             for(j = 0; j < 28; j++)
199             {
200                 printf("%d\t", p->Message[j]);    /* 以传统方法输出 */    
201             }
202             i += 4;    /* 跨过结构体成员指针 Message 占据的4Bytes */    
203         }
204         printf("%#X\t", uGPS.uByte[i]);    
205     }
206     printf("\n--------------------------------------------------\n");
207         
208     return 0;
209 }

 

以上是关于结构体成员数组不定长如何实现的主要内容,如果未能解决你的问题,请参考以下文章

STL初步不定长数组:vector + 集合:set + 映射:map

数组实现多叉树

C#调用C++的dll库怎么传递结构体中不定长度的char数组

如何将结构数组里的两个成员位置交换

分享几个实用的代码片段(第二弹)

分享几个实用的代码片段(第二弹)