Re: [問題] 走訪 struct member 的問題
回個文可能清楚些。
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
11/10 10:43, 2F
推
11/10 21:23, , 3F
11/10 21:23, 3F
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):