1. 結構變數初值給定
首先,先宣告一個結構型態, 接下來再介紹兩種初值給定方法(C99/C89):
+ struct test
+ {
+ const char* cap;
+ unsigned char data_0;
+ int data_1;
+ };
support C99 mode (現在新版本的GCC都有support C99 mode 的結構變數初值給定方法。 這種方法的優點是未來如果結構調整變數的位置,宣告變數初值不用跟著調整):
+ struct test node =
+ {
+ .cap="first",
+ .data_0=10,
+ .data_1=5
+ };
以下是傳統(C89 mode)的寫法 (很可惜的是目前Watcom C版本(1.9)尚未支援C99 mode結構變數的初值給定方法),所以還是用舊有的寫法:
+ struct test node =
+ {
+ "first", // cap
+ 10, // data_0
+ 5 // data_1
+ };
2. 結構內變數對齊(alignment)的問題
寫程式的技巧常會將結構直接位址對應到某塊MMIO/Memory上,如果編譯時沒特別宣告,那麼結構裡面變數的變數位址會對齊到"最大變數的size"造成讀錯位址,範例如下
+ #include <stdio.h>
+
+ struct test
+ {
+ unsigned int cap_0;
+ unsigned char data_0;
+ unsigned int cap_1;
+ unsigned char data_1;
+ };
+
+ int main()
+ {
+
+ struct test node;
+
+ printf("node size: %d\n", sizeof(node));
+ printf("node.cap_0 address : 0x%X\n", &(node.cap_0));
+ printf("node.data_0 address: 0x%X\n", &(node.data_0));
+ printf("node.cap_1 address : 0x%X\n", &(node.cap_1));
+ printf("node.data_1 address: 0x%X\n", &(node.data_1));
+ return 0;
+ }
應該要加上#pragma pack()這個前置處理,參考如下
+ #include <stdio.h>
+
+ //#pragma pack(push) // 先將原本的對齊方式暫存
+ //#pragma pack(1) // 設定1個Byte為單位對齊
+ #pragma pack(push, 1)
+ struct test
+ {
+ unsigned int cap_0;
+ unsigned char data_0;
+ unsigned int cap_1;
+ unsigned char data_1;
+ };
+ #pragma pack(pop) // 回復原本對齊方式
+
+ int main()
+ {
+
+ struct test node;
+
+ printf("node size: %d\n", sizeof(node));
+ printf("node.cap_0 address : 0x%X\n", &(node.cap_0));
+ printf("node.data_0 address: 0x%X\n", &(node.data_0));
+ printf("node.cap_1 address : 0x%X\n", &(node.cap_1));
+ printf("node.data_1 address: 0x%X\n", &(node.data_1));
+ return 0;
+ }
沒有留言:
張貼留言