2012-10-03 33 views
0

我正在嘗試使用指針將uint16_t值插入到uint8_t數組中。我會認爲下面會起作用,但一直沒能做到。什麼問題是什麼線索?使用指針將uint16_t值注入到uint8_t數組中?

uint8_t myarray[10]; 
uint16_t value = 10000; 
uint16_t * myptr = (uint16_t *)(myarray+2); 
*myptr = value; 

我知道我可以這樣做,但爲什麼不上面的工作?

uint8_t myarray[10]; 
uint16_t value = 10000; 
uint8_t * myptr = (myarray+2); 
uint8_t * myptr2 =(myarray+3); 
*myptr = value>>8; 
*myptr2 =value; 
+0

究竟是第一個代碼問題? – jplot

+0

沒有太多的細節,似乎你是「別名」,使兩種不同的類型生活在同一個記憶。如果它們是「兼容類型」,那麼只能「左移」左值(*兼容類型僅僅因添加任何有符號,無符號或易失性*的組合而不同)。關於此主題的一些輕讀:http:// dbp-consulting .com/tutorials/StrictAliasing.html – HostileFork

回答

3

第二個版本寫入最顯著字節(具有值39)myarray[2],並且至少顯著(具有值16)myarray[3]

第一個版本將按您的計算機的endianness確定的順序寫入兩個字節。大多數現代計算機是little-endian,這意味着多字節整數值的最低有效字節在內存中首先出現 - 所以這個版本將以與其他版本相反的順序寫入兩個字節。

我假設這是你看到的問題;如果是別的東西,那麼請比「無法做到」更具體。

另外,第一個版本在技術上具有未定義的行爲,並且可能在充分異國情調的計算機上完成一些意想不到的事情。我建議你堅持像第二個版本一樣明確定義的代碼;如果性能分析顯示定義明確的代碼太慢,以及不友好的指針別名代碼更快,則只使用可疑的優化。我也建議使用reinterpret_cast而不是邪惡的C風格演員;它不會改變行爲,但更容易看到有些事情正在發生。

+0

我試圖修改代碼,因此,它似乎工作。這會有什麼問題嗎? uint8_t myarray [10]; uint16_t value = 10000; void * ptr =&myarray; uint16_t * myptr =(((uint16_t *)ptr)+2); * myptr = value >> 8 | value << 8; – renasis

+0

@ user1142327:它依賴於未定義的行爲,並且不可移植。正如我所說的,如果你已經確定了(a)明確定義的版本不夠快,並且(b)狡猾版本確實更快,那麼你應該只使用這種惡意優化。 –

0

你可以這樣說:

uint8_t * value_data = reinterpret_cast<uint8_t*>(&value); // cast to `(unsigned) char*` is allowed by standard 
myarray[0] = value_data[0]; 
myarray[1] = value_data[1];