2010-04-30 19 views
7

Ben bir 32 bit uzunluğunda değişken CurrentPosition var. Bunu en verimli şekilde nasıl yapabilirim? Ben bir 8bit MCU, 8051 mimarisi ile çalışıyorum.Uzun bir değeri (32 bit) C kullanarak dört değişkene (8 bit) ayırırım. Ben 4, 8bit karakterler bölünmüş istediğiniz

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? 

Sadece bir işaretçi ile CurrentPosition başlangıç ​​adresini referans ve daha sonra 8 dört kez ele ikisini eklemek gerekir mi?

O küçük Endian olduğunu.

AYRICA ben CurrentPosition değişmeden kalmasını istiyorlar. Sen işin biraz bir bütün 32 bit değişken değişen bir 8 bitlik MCU kullanıyorsanız

+2

? ___ – kennytm

+0

Küçük Endian biçimi – PICyourBrain

cevap

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

Sen

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

1) Bunları (imzasız char) ile yapmak zorunda mıyım? 2) Bu durum CurrentPosition'ı etkilemiyor mu? – PICyourBrain

+1

1. Birincisi, dökümüne gereksinim duyacaktır. Her iki yöntem de CurrentPosition'ı etkilenmeden bırakır – Saul

+0

Eski, * need * casting yapmaz, ancak bazı derleyiciler, eğer yapmazsanız olası bir hassasiyet kaybı hakkında sahte bir uyarı verir. – caf

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

kullanır SDCC kullanıyorum Bu CurrentPosition sağdaki değeri değiştirir? CurrentPosition'ı değiştirmeden bırakmak istiyorum. – PICyourBrain

+0

Evet, bir seçenek CurrentPosition'ın bir kopyasını yapmak ve kopyasını kopyalamaktır. Ya da nos'un cevabı başka bir seçenek. İşaretçiyi kullanma fikriniz de mümkündür.Bunu yapmanın birçok yolu var. –

2

yanı bir işaretçi üzerinden bayt erişebilir. Bu durumda pointer aritmetiğini kullanarak 4 baytlık CurrentPosition okumak daha iyidir. Dökme:

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

CurrentPosition değişmez ama sen p yazmaya çalışırsanız [0] CurrentPosition en önemli bayt değişecektir. Bir kopyasını istiyorsanız:

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]; 

ve arr ile çalışın. (En önemli baytı istiyorsanız, önce bu ödevlerdeki sırayı değiştirin). Sen 4 değişkenleri tercih ederseniz

Açıkçası yapabilirsiniz:

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

Bir 32 bit int doğrudan değiştiremiyorsanız, bu soln daha iyidir. –

5

Sana bir birlik kullanmayı düşünmelisiniz düşünüyorum:

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

CurrentPosition.position = 7654321; 

bayt artık erişilebilir olarak: CurrentPosition.bytes [0

Şimdi orijinal kod başına NKP
+0

Pratikte iyi bir fikir çünkü derleyici int'nin baytlara ayrışmasını yapabilir. Teorik olarak kötü bir fikir çünkü sendikaların bu kullanımı c-standardı tarafından tanımlanmamıştır .. (çoğu uygulama olmasa bile çoğu uygulama sadece çalışacaktır) –

+0

@Nils C99'dan bu yana sendikalarla yapılan püf noktası iyi tanımlanmıştır. Kod hala endian bağımlıdır. – user694733

0
unsigned char *CP = &CurrentPosition; 

aracılığıyla erişilir [3]], ..., CurrentPosition.bytes.

0

Bu bir süre önce gönderilmiş biliyoruz. Ancak hala iş parçacığını okuyan herkes için: Birçok kişi, orijinal değeri sıralı olarak değiştirme yaklaşımını kullanır. Neden derleyicinin işi sizin için yapmasına izin vermiyorsunuz? aynı yerde değerlerini saklamak için izin vermek için bir birliğe & kullanın. Hem 32 bit uzunluğundaki bir değişkenden (bu, CurrentPosition'ı kaydettiğiniz yer) hem de 4 karakterden oluşan bir yapıdan oluşan bir birlik tanımlayın. Veya sadece basit bir 8 bit tam sayı dizisi. CurrentPosition'ınızı uzun değişkene yazdığınızda, 4 char değişkenini okuduğunuzda erişilen aynı yerde saklanır. Bu yöntem çok daha az emek yoğun ve zaman derleyici & kaynak israf yerine iş yapmak için izin vermez.

endian
+1

Tam olarak bu [en fazla ikinci cevap] (https://stackoverflow.com/a/2747324/2564301) öneridir. – usr2564301