2017-05-23 57 views
1

保留的內存位置我有一個結構:如何編寫爲結構

struct foo{ 
    uint8_t i1 : 4; 
    uint8_t i2 : 4; 
    uint8_t i3 : 4; 
    uint8_t i4 : 4; 
} 

現在,我有一個16位整數(叫它),我想寫的內存位置,對於這個結構,而不必這樣做:

foo1.i1 = (uint8_t)a>>12; 
foo1.i2 = (uint8_t)a>>8; 
foo1.i3 = (uint8_t)a>>4; 
foo1.i4 = (uint8_t)a; 

是否有一個選項可以將16位寫入foo1的內存位置。喜歡的東西:

*(*uint16_t)&foo1 = a; 
+1

第一個問題:你爲什麼要使用位域? –

+2

體面的編譯器意識到你在做什麼 - 這可能是過早的優化。當然,如果編譯器反轉佈局(字節中的位順序未指定),那麼您的投射就是錯誤的。 – MSalters

+0

@Neil使用位域有什麼問題? –

回答

2

首先,你應該確保這是你需要做的優化 - 操作不當,你可能會遇到關於對齊,字節順序等。這樣的問題,你我們希望使用分析器來檢查代碼的性能,並確定這是否會消耗大量處理器時間。記住what Donald Knuth wrote

程序員浪費大量的時間思考,也不必擔心,他們的節目非關鍵部分的速度,而這些嘗試的效率居然有當調試和維護被認爲是一個強烈的負面影響。我們應該忘記小效率,大約97%的時間:過早優化是所有邪惡的根源。但我們不應該在這個關鍵的3%中放棄我們的機會。

一旦您確認這是一個有用的優化,那麼您應該可以通過幾種方式來完成。其中之一是使用memcpy ...

memcpy(&foo1, &a, sizeof(foo1)); 

或者,你可以做一個foo1unionuint16_t成員和寫入...

union { 
    struct foo f; 
    uint16_t u; 
} foo1; 
foo1.u = a; 
+2

請注意,通過C++中的聯合進行類型雙擊是未定義的行爲。 – NathanOliver

+0

@NathanOliver這是真的,但它不僅僅是'union'方法的問題 - 基本上任何涉及「我將忽略這些對象的C++類型並將它們當作原始內存」的任何事情都會有類似的可移植性問題(因此,爲什麼你應該更喜歡便攜式,非優化版本,除非你有充分的理由相信手工優化它會產生有意義的差異)。 –

+0

添加註釋,我們應該使用分析器來衡量*最重要的瓶頸*;這些是我們在優化程序時應該瞄準的目標,這意味着我們需要*一個實際的解決方案*來優化...然後,一旦我們應用了優化,我們應該再次重新分析*以確保我們實際進行了優化。任何其他方法僅僅是* guesswork *,* guesswork *會導致*較慢的代碼! – Sebivor