2010-04-30 66 views
7

我有一個32位長的變量,CurrentPosition,我想分裂成4,8位字符。我如何在C中最有效地做到這一點?我正在使用8位MCU,8051架構。如何使用C將長整型值(32位)分解爲四個char變量(8位)?

unsigned long CurrentPosition = 7654321; 
unsigned char CP1 = 0; 
unsigned char CP2 = 0; 
unsigned char CP3 = 0; 
unsigned char CP4 = 0; 
// What do I do next? 

我應該只是用指針引用CurrentPosition的起始地址,然後添加8個兩個地址四次?

這是小端。

我也想讓CurrentPosition保持不變。

+2

哪個endian? ___ – kennytm 2010-04-30 19:47:18

+0

我正在使用SDCC並使用Little Endian格式 – PICyourBrain 2010-04-30 19:50:22

回答

13
CP1 = (CurrentPosition & 0xff000000UL) >> 24; 
    CP2 = (CurrentPosition & 0x00ff0000UL) >> 16; 
    CP3 = (CurrentPosition & 0x0000ff00UL) >> 8; 
    CP4 = (CurrentPosition & 0x000000ffUL)  ; 

你可以如果您使用的是8位MCU移位整個32位變量是一些工作通過一個指針訪問的字節,以及,

unsigned char *p = (unsigned char*)&CurrentPosition; 
//use p[0],p[1],p[2],p[3] to access the bytes. 
+0

1)我是否需要使用(無符號字符)來施放它們? 2)這是否使CurrentPosition不受影響? – PICyourBrain 2010-04-30 19:52:57

+1

1.前者需要鑄造 2.兩種方法都不會影響CurrentPosition – Saul 2010-04-30 19:56:08

+0

前者不需要*鑄造,但是如果不這樣做,某些編譯器會給出關於可能的精度損失的虛假警告。 – caf 2010-05-01 05:16:56

0
CP1 = (unsigned char)(CurrentPosition & 0xFF); 
CurrentPosition >>= 8; 
CP2 = (unsigned char)(CurrentPosition & 0xFF); 
... 
+0

這會改變CurrentPosition中的值嗎?我想離開CurrentPosition不變。 – PICyourBrain 2010-04-30 19:50:02

+0

是的,一種選擇是製作CurrentPosition的副本並對副本進行裁剪。或者nos的答案是另一種選擇。使用指針的想法也是可能的。有很多方法可以做到這一點。 – 2010-04-30 19:52:33

2

。在這種情況下,最好使用指針算術來讀取4個字節的CurrentPosition。演員:

unsigned char *p = (unsigned char*)&CurrentPosition; 

不改變CurrentPosition,但如果你試圖寫入P [0],將更改CurrentPosition的至少顯著字節。如果您想要一個副本,請執行以下操作:

unsigned char *p = (unsigned char*)&CurrentPosition; 
unsigned char arr[4]; 
arr[0] = p[0]; 
arr[1] = p[1]; 
arr[2] = p[2]; 
arr[3] = p[3]; 

並使用arr。 (如果你想要最重要的字節首先改變這些分配的順序)。

,如果你喜歡4個變量可以明顯地做到:

unsigned char CP1 = p[0]; 
unsigned char CP2 = p[1]; 
unsigned char CP3 = p[2]; 
unsigned char CP4 = p[3]; 
+0

如果你不能直接移動一個32位的int,這個soln會更好。 – 2010-04-30 20:43:21

5

我想你應該考慮使用一個聯盟:

union { 
    unsigned long position; 
    unsigned char bytes[4]; 
} CurrentPosition; 

CurrentPosition.position = 7654321; 

的字節現在可以訪問如:CurrentPosition.bytes [0 ],...,CurrentPosition.bytes [3]

+0

實踐中的一個好主意,因爲編譯器可以將int分解爲字節。理論上不好的主意,因爲這種聯合使用方式是c標準未定義的(大多數情況下,即使不是所有的實現都可以正常工作) – 2010-04-30 20:55:48

+0

@Nils自C99以來,已經很好地定義了使用聯合的類型雙關聯。儘管如此Code仍然依賴於Endian。 – user694733 2018-01-05 10:11:04

0
unsigned char *CP = &CurrentPosition; 

現在您的原始代碼的CPn可通過CP[n]

0

我知道這是前段時間發佈的。但對於任何人仍然閱讀的線程: 許多人採取順序移動原始值的方法。爲什麼不讓編譯器爲你做這項工作。 使用聯合&可讓您將值存儲在同一位置。定義由32位長變量(這將是您保存CurrentPosition的位置)和由4個char變量組成的結構組成的聯合。或者只是一個簡單的8位整數數組。當你將你的CurrentPosition寫入long變量時,當你讀取4個char變量時,它將被存儲在相同的位置。這種方法勞動密集程度低很多,不允許編譯器做這項工作,而不是浪費時間資源。

+1

這正是[第二最upvoted答案](https://stackoverflow.com/a/2747324/2564301)建議。 – usr2564301 2018-01-05 09:56:21

相關問題