通訊中,用過的非常多。給你乙個我的例子
typedef union
complex;
float64 dfval;
prot_time time;
}protevent_valtype;
//不同型別的數值
typedef
struct
head;
uint8 name[var_comm_size];
}protmsg_event_par;
對於那種乙個整數和幾個位元組取值的問題,建議不要用結構聯合來實現。如:
union bits32
byte;};
這個在不同的cpu架構變現不相同,就是cpu的高低次序問題。在普通的pc即x86cpu上,是小頭在前,即c1對應的num的第乙個位元組,但是在其它一些如powerpc、sun的sparc架構cpu上,是大頭在前,c1就對應num的第4個位元組。
在網路傳輸中,對這個問題很敏感,就是發生的位元組次序問題。在tcp/ip中,規定是網路次序,具體參考一下tcp/ip的資料。裡面有不少網路次序資料和本機資料的轉換問題。
為了避免這種問題,我們一般在通訊中,採用的是移位操作。如
/*****整數和單位元組數轉換操作,通過移位避開次序問題****
*/#define
byte0(intval) ( (uint8)( 0x000000ff&(intval)) )
#define
byte1(intval) ( (uint8)(( 0x0000ff00&(intval))>>8) )
#define
byte2(intval) ( (uint8)(( 0x00ff0000&(intval))>>16) )
#define
byte3(intval) ( (uint8)((0x0ff000000&(intval))>>24) )
/*******************位元組組合定義******************
*/#define
uint16comb(b1,b0) ( (uint16)(b0) | (((uint16)(b1))<<8) )
#define
int16comb(b1,b0) uint16comb(b1,b0)
#define
uint32comb(b3,b2,b1,b0) /
( (uint32)(b0) /
|(((uint32)(b1))
<<
8) /
|(((uint32)(b2))
<<
16) /
|(((uint32)(b3))
<<
24) )
#define
int32comb(b3,b2,b1,b0) uint32comb(b3,b2,b1,b0)
使用時,可以用:
c1=byte0(num);c2=
byte1(num);
...num
=uint32comb(c3,c2,c1,c0);
實際上移位操作,對於cpu來說,基本上是乙個指令週期,比你直接用struct和union還要快。這個問題涉及到32位cpu的整字對齊和整字操作處理問題和cpu的指令優化,具體可以去參考cpu指令的書籍。
對齊規則由編譯選項決定的,一般編譯器採用預設的編譯選項。一般儲存單元按照cpu的字長對齊,對於目前32位主流系統,基本的資料型別char、short、int、float,對齊在整字的開始。
如struct
;c占用第乙個字長的第乙個位元組,而後面的3個位元組變長儲存空洞;i和f各佔1個字長。
struct
;這種情況下,c1將分配在c之後,佔乙個位元組,而c1後面就留出來2各空洞。
所以在組織struct或者class時,注意一下成員分布的合理,綜合一下儲存分配情況。但是從cpu的指令操作上看,cpu一般按照乙個字長來執行,操作乙個int數要比乙個char效率高。也就說說,當cpu讀取乙個char數時,cpu先從記憶體中讀取一整個字長值到暫存器中,然後將相應char所在的那個位元組提取出來,從而完成乙個char的取值。
另外:程式設計時千萬注意float *pfval;指標的使用,浮點數指標一定要指向乙個整字起始的記憶體位置,如上面的&c1位址,否則在一些特定的cpu或微控制器中,對非對齊的浮點指標操作,會發生崩潰問題,這個和浮點指令的相容性問題。典型的是在sun的sparc、powerpc的一些cpu上就會發生崩潰問題。
想改變編譯器的對齊規則,可以在**中加入:
#pragma pack(push, 1)
.....//**
#pragma pack(pop)
聯合體,位域, 結構體對齊
聯合體union 當多個資料需要共享記憶體或者多個資料每次只取其一時,可以利用聯合體 union 在c programming language 一書中對於聯合體是這麼描述的 1 聯合體是乙個結構 2 它的所有成員相對於基位址的偏移量都為0 3 此結構空間要大到足夠容納最 寬 的成員 1下面解釋這四...
結構體聯合體
在c中,結構也是一種資料型別,可以使用結構變數,因此,象其它型別的變數一樣,在使用結構變數時要先對其定義。定義結構變數的一般格式為 struct 結構名 結構變數 結構名是結構的識別符號不是變數名。型別為第二節中所講述的五種資料型別 整型 浮點型 字元型 指標型和無值型 構成結構的每乙個型別變數稱為...
聯合體加結構體的應用
因為最近設計到通訊協議。而通訊協議中為了減少資料量,常常用乙個位元組的八個位分別代表八種不同的狀態。這就涉及到位的操作和分解。過程可能比較麻煩而且如果位數多的表示可能不是很明了,比如我乙個位元組的前三個位元組表示狀態,後面的分別乙個位元組表示其他情況 所以這邊利用了聯合體和結構體的綜合應用。用乙個結...