Re: [問題] 走訪 struct member 的問題

看板C_and_CPP作者 (藍影)時間12年前 (2011/11/09 23:23), 編輯推噓2(201)
留言3則, 2人參與, 最新討論串2/2 (看更多)
回個文可能清楚些。 C 語言裡面, 我認為可以玩最久、最深入的就是 struct 。 big / little endian 相關問題, 可先探討這篇 #1EbSpQa6, 然後先回你這段話 : 目前本身的看法, 猜測 struct 本身就不建議這樣操作, : 或者相同 type 要這樣操作就改用 array. : 不知道大家有沒有什麼看法, 感謝. 前提若是 struct 裡面的 data type 都一樣,是不是用 array 較為方便? 答案是否定的。 原因在於很多場合底下,用 struct 較容易定義出屬性, 或抽像化之型別出來,一個最簡單的例子 , 表達二維平面上的一個點 typedef struct tagPoint{ double x, y; }Point; 但比較少人這麼做 typedef double Point[2]; 甚至表達學生的成績 (假設去掉 char*) typedef struct tagGrade{ int ch, eng, math, total; }Grade; 也不會有人做成 typedef int Grade[4]; ----- 以下說明沒翻過規格書,唯曾實作過。 而如果你能夠「非常確定」在你的 struct 裡面,所有的 data type 都一樣的話, 基本上就不用考慮 padding 問題,這時候可以放心使用 memcpy,沒問題。 typedef int stype; // 建議最好重新 typedef typedef struct tags{stype a, b, c, d;}s; s obj; // struct 物件 stype be_copy = 10; // 欲複製之值 stype* ptr = (stype*)&obj; // ptr hook for(int i=0; i<sizeof(s)/sizeof(stype); ++i) memcpy((void*)(ptr+i), &be_copy, sizeof(stype)); 再強調一次,上面只在「型別所佔位元數全一樣時」才可正常執行。 如果 struct 裡面有 int, short, char 的話,就不適用。 但為避開這種問題,一些技巧倒是被應用,假設 typedef struct tags{ char a; // 1byte short b; // 2bytes int c; // 4bytes }s; 實際上 padding 情形是 - 不一定,特別像在 compiler 時,還可以下 #pargma_push / #pragma_pop 之類的指令指定 aligmnent , 使得問題更加複雜,但可看到部份的 code 會寫成這樣 typedef struct tags{ char a; char garbge1[3]; short b; char garbge2[2]; int c; }s; 目的就是要消 padding 所帶來之影響, 沒記錯的話,Win32 裡面有少數 struct 也是用這個在搞。 缺點主要有一個, 若 short / int / unsigned long 這些 POD 佔用 bits 數改變時, char garbge 要重定 (所以 Win32 裡面有一堆自定義的 type 來防)。 至於會不會多佔用其他空間,答案是不確定的,但若不叫 compiler 指定 aligment, 其實不會多吃太多空間。 這麼做有什麼好處?以下程式碼就自己意會了。 #include <stdio.h> typedef struct tags{ unsigned char a; unsigned char garbge1[3]; unsigned short b; unsigned char garbge2[2]; unsigned int c; }s; int main() { s obj; int i, x=10; int y[] = {10,10,10,10}; int *p = (int*)&obj; for(i=0; i<sizeof(obj)/sizeof(int); ++i) // copy memcpy((void*)(p+i), (void*)&x, sizeof(x)); printf("%hhd , %hd , %d", obj.a, obj.b, obj.c); memcpy((void*)&obj, (void*)y, sizeof(y)); printf("%hhd , %hd , %d", obj.a, obj.b, obj.c); return 0; } ----- -- No matter how gifted you are, alone, can not change the world. -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 180.177.78.41

11/10 10:40, , 1F
看到這篇,我就知道我之前的回覆出問題.
11/10 10:40, 1F

11/10 10:43, , 2F
拜謝t神
11/10 10:43, 2F

11/10 21:23, , 3F
感謝!
11/10 21:23, 3F
文章代碼(AID): #1EkfhpwJ (C_and_CPP)
文章代碼(AID): #1EkfhpwJ (C_and_CPP)