2011-12-30 22 views
9

मुझे पता है कि एक चर प्रकार द्वारा उपयोग किए गए बाइट्स की संख्या प्राप्त करने के लिए, उदाहरण के लिए आप sizeof(int) का उपयोग करते हैं। जब आप उस चर प्रकार के साथ किसी नंबर को संग्रहीत करते हैं तो आप व्यक्तिगत बाइट्स का मूल्य कैसे प्राप्त करते हैं? (यानी int x = 125।)एक चर के व्यक्तिगत बाइट्स का मूल्य कैसे प्राप्त करें?

उत्तर

14

आप कुछ सूचक अंकगणित का उपयोग करके बाइट्स प्राप्त कर सकते हैं: मेरी मशीन (इंटेल x86-64) पर

int x = 12578329; // 0xBFEE19 
for (size_t i = 0; i < sizeof(x); ++i) { 
    // Convert to unsigned char* because a char is 1 byte in size. 
    // That is guaranteed by the standard. 
    // Note that is it NOT required to be 8 bits in size. 
    unsigned char byte = *((unsigned char *)&x + i); 
    printf("Byte %d = %u\n", i, (unsigned)byte); 
} 

, उत्पादन होता है:

Byte 0 = 25 // 0x19 
Byte 1 = 238 // 0xEE 
Byte 2 = 191 // 0xBF 
Byte 3 = 0 // 0x00 
+1

कैसे 4294967278 एक बाइट है? डिफ़ॉल्ट 'char' प्रकार शायद आपके सिस्टम पर हस्ताक्षरित है और' हस्ताक्षरित 'में कास्टिंग बड़ी संख्या में उत्पादन करता है। –

+0

@Eser Aygün मैं कोड अपडेट करूंगा। टिप्पणी के लिए धन्यवाद। –

+0

अधिक पढ़ने योग्य सरणी पहुंच के बजाय मैन्युअल सूचक अंकगणित का उपयोग करने का कोई कारण? –

3

आप तो उस जानकारी को प्राप्त करना चाहते हैं, इसके लिए कहें:

int value = -278; 

(मैंने उस मान का चयन किया क्योंकि यह बहुत रुचि नहीं है 125 के लिए ing - कम से कम महत्वपूर्ण बाइट 125 है और अन्य बाइट्स सभी 0 कर रहे हैं)

आप पहली बार है कि मूल्य के लिए सूचक की जरूरत है:

int* pointer = &value; 

अब आप एक 'चार' सूचक को टाइपकास्ट सकता है! जो केवल एक बाइट है, और इंडेक्सिंग द्वारा व्यक्तिगत बाइट प्राप्त करें।

for (int i = 0; i < sizeof(value); i++) { 
    char thisbyte = *(((char*) pointer) + i); 
    // do whatever processing you want. 
} 

ध्यान दें कि ints और अन्य डेटा प्रकार के लिए बाइट के आदेश अपने सिस्टम पर निर्भर करता है - बनाम 'छोटी-endian' 'बड़े endian' देखो।

+0

अधिक पढ़ने योग्य सरणी पहुंच के बजाय मैन्युअल सूचक अंकगणित का उपयोग करने का कोई कारण? –

+0

क्योंकि यह उन लोगों को स्पष्ट करता है जो शिक्षित हैं कि हम एक सूचक का उपयोग कर रहे हैं? मैं पॉइंटर अंकगणित गलत या अपठनीय होने पर विचार नहीं करता हूं। – Dan

+1

यह गलत नहीं है लेकिन निश्चित रूप से आप तर्क नहीं देते कि यह सरणी पहुंच के रूप में पठनीय है ...! 'X [i]' '' (x + i) 'की तुलना करें। असल में, सरणी पहुंच वाक्यविन्यास क्यों मौजूद है, अगर हम उचित होने पर इसका उपयोग नहीं करते हैं? –

2

यह काम करना चाहिए:

int x = 125; 
unsigned char *bytes = (unsigned char *) (&x); 
unsigned char byte0 = bytes[0]; 
unsigned char byte1 = bytes[1]; 
... 
unsigned char byteN = bytes[sizeof(int) - 1]; 

लेकिन ध्यान रखें कि पूर्णांकों का बाइट क्रम मंच निर्भर है हो सकता है।

+0

बाइट ऑर्डरिंग सीपीयू निर्भर नहीं है ओएस निर्भर – DipSwitch

+0

@DipSwitch आप सही हैं। सही किया। –

3

आप एक union का इस्तेमाल करते हैं, लेकिन हर "बाइट में यह ध्यान रखें कि बाइट आदेश प्रोसेसर निर्भर है और कहा जाता है endianness http://en.wikipedia.org/wiki/Endianness

#include <stdio.h> 
#include <stdint.h> 

union my_int { 
    int val; 
    uint8_t bytes[sizeof(int)]; 
}; 

int main(int argc, char** argv) { 
    union my_int mi; 
    int idx; 

    mi.val = 128; 

    for (idx = 0; idx < sizeof(int); idx++) 
     printf("byte %d = %hhu\n", idx, mi.bytes[idx]); 

    return 0; 
} 
+0

@WTP आह लॉल, यह भी ध्यान नहीं दिया: पी – DipSwitch

14

आप बिट्स (अक्सर 8) की संख्या पता करने के लिए हो सकता था "। फिर आप उचित मास्क के साथ int को एंडिंग करके बदले में प्रत्येक बाइट निकाल सकते हैं। कल्पना कीजिए कि एक पूर्णांक 32 बिट है कि, तो the_int में से 4 बाइट्स प्राप्त करने के लिए:

int a = (the_int >> 24) & 0xff; // high-order (leftmost) byte: bits 24-31 
    int b = (the_int >> 16) & 0xff; // next byte, counting from left: bits 16-23 
    int c = (the_int >> 8) & 0xff; // next byte, bits 8-15 
    int d = the_int   & 0xff; // low-order byte: bits 0-7 

और वहाँ तुम्हारे पास है: प्रत्येक बाइट कम क्रम में है की एक, ख, ग, और घ 8 बिट।

+0

आप इसे जितना कठिन बना रहे हैं और बाइट निकालने के लिए स्थानांतरण का उपयोग करना सीपीयू गहन है। स्मृति में सीधे प्रत्येक बाइट स्थान तक पहुंचने के लिए यह बहुत आसान और तेज़ होगा ... – DipSwitch

+0

@ डीआईपी - मेरे क्रूर तरीके से यह गुण है कि यह सीपीयू में पोर्टेबल है, जबकि अन्य नहीं हो सकते हैं। लेकिन जैसा कि आप चाहते हैं, ज़ाहिर है। –

+1

+1: मैं स्मृति स्थान के साथ झुकाव से कहीं ज्यादा बेहतर मानता हूं। 1) अगर एंडियन-अज्ञेयवादी है। 2) सीपीयू प्रोसेसर रजिस्टरों में परिचालन कर सकता है, इसलिए यह आमतौर पर कहीं अधिक कुशल है। वास्तव में, कुछ (8-बिट) मशीनों के लिए, यह किसी भी कोड को उत्पन्न नहीं कर सकता है (यदि आपके पास सभ्य कंपाइलर है)। – Lindydancer

संबंधित मुद्दे