結構體成員數組不定長如何實現


【目的】

  定義一個結構體類,其中的成員變量數組長度不定,根據實例化的對象指定長度,所以想到用指針實現

【現狀】

  指針可以指向任意長度數組,但結構體類只分配指針本身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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM