2010-03-04 15 views
22

मैं एकसी में एक चर की स्मृति सामग्री को मुद्रित करने के लिए कैसे?

double d = 234.5; 

मैं d की स्मृति सामग्री [पूरे 8 बाइट्स]

मैं ऐसा कैसे करते देखना चाहते हो मान लीजिए?

+0

किस रूप में आप इसे देखना चाहते हैं में? – danben

+8

आपको क्यों लगता है कि यह आठ बाइट्स है? –

+3

मुझे विश्वास है कि फ्लोट * आमतौर पर * चार बाइट्स होते हैं, और युगल * आमतौर पर * आठ बाइट होते हैं। – Dolph

उत्तर

20
double d = 234.5; 

/* 1. use a union */ 
union u { 
    double d; 
    unsigned char c[sizeof(double)]; 
}; 
union u tmp; 
size_t i; 
tmp.d = d; 
for (i=0; i < sizeof(double); ++i) 
    printf("%02x\n", tmp.c[i]); 

/* 2. memcpy */ 
unsigned char data[sizeof d]; 
size_t i; 
memcpy(data, &d, sizeof d); 
for (i=0; i < sizeof d; ++i) 
    printf("%02x\n", data[i]); 

/* 3. Use a pointer to an unsigned char to examine the bytes */ 
unsigned char *p = (unsigned char *)&d; 
size_t i; 
for (i=0; i < sizeof d; ++i) 
    printf("%02x\n", p[i]); 

सभी तरीकों आप बाइट्स — दिखाने लेकिन एक ही double मूल्य विभिन्न प्रणालियों, उदाहरण के लिए, विभिन्न एन्कोडिंग (दुर्लभ) की वजह से, या अलग endianness पर अलग ढंग से बाइट्स प्रिंट कर सकते हैं।

+0

मैंने व्यक्तिगत रूप से एक सूचक का उपयोग किया होगा, लेकिन एक संघ भी बेहतर इमो है। अच्छा है। मैं इसके बारे में भूल जाते हैं। – Xorlev

+0

एक्सोलेव: तकनीकी रूप से यूनियन विधि काम करने के लिए गारंटी नहीं है, जबकि अन्य दो विधियां हैं। – caf

+0

@caf: आप क्यों कहते हैं कि संघ विधि को काम करने की गारंटी नहीं है? जब तक संघ में 'हस्ताक्षरित चार' सरणी का उपयोग किया जाता है, तब तक इसे काम करना चाहिए। –

26
unsigned char *p = (unsigned char *)&d; 
int i; 

for (i = 0; i < sizeof d; i++) 
    printf("%02x ", p[i]); 
+3

@ क्रैग: 'आकार डी' सही है, मुझे नहीं पता कि आपने इसे 'sizeof (d)' में क्यों बदल दिया है (यह भी काम करता है, लेकिन 'आकार' डी जैसे कई लोग 'd' एक प्रकार नहीं है)। –

+4

सहमत - मैं यह स्पष्ट रखने के लिए है कि यह एक ऑपरेटर, नहीं एक समारोह है (मैं वापसी नहीं करते '(एक्स),', या तो) पसंद करते हैं – caf

+4

यह आसान है बस हमेशा कोष्ठक का उपयोग करने के लिए इतनी के रूप में एक _more_ स्टोर करने के लिए नहीं करने के लिए उस भूरे पदार्थ के ऊपर की चीज ऊपर की ओर :-) I _ _ _ चर के प्रकार के बदले एक चर के बजाय एक चर का उपयोग करना पसंद करते हैं, इसलिए मुझे जितना अधिक कोड बदलना नहीं है। – paxdiablo

1

आप उस पते से शुरू d और प्रिंट sizeof(d) बाइट्स की पता लेने की कोशिश की?

2

union Plop 
{ 
    double value; 
    char  data[sizeof(double)]; 
}; 

Plop print; 
print.value = 234.5; 

std::copy(print.data,print.data+sizeof(double),std::ostream_iterator<int>(std::cout)," "); 
std::cout << std::endl; 
+0

जबकि समाधान दिलचस्प है, आपको इसे इस मामले में सी में परिवर्तित करना चाहिए। –

+0

और पूरी तरह से पोर्टेबल होने के लिए आपको 'अहस्ताक्षरित चार डेटा का उपयोग करना चाहिए [sizeof (डबल)];' –

+0

जब तक मैं गलत कर रहा हूँ, दो अलग अलग सदस्यों के माध्यम से एक संघ तक पहुँचने अपरिभाषित व्यवहार की ओर जाता है। फिर फिर, मुझे लगता है कि अगर नए सदस्य के पास जाल मूल्य हैं, लेकिन चार में कोई नहीं है। – GManNickG

2

प्रयास करें आप gdb से देखने पर देख रहे हैं आप जारी कर सकते हैं:

x /gx d 

जी एक विशाल के रूप में मूल्य प्रिंट होगा (8 बाइट्स)

1

अपने दोस्ताना डीबगर का उपयोग स्मृति स्थान के मूल्य को देखने का सबसे अच्छा तरीका है, यह है कि यदि आप बस देखना चाहते हैं।

2

यदि आप बिट्स में डबल मान मुद्रित करना चाहते हैं तो इसे आजमाएं। मैंने फ्लोट वैल्यू के लिए प्रयास किया है। यदि आपने इसे बदल दिया है तो आप 64 बिट्स में डबल मान देखने में सक्षम हो सकते हैं। उपयोगी के टुकड़े के अपने पुस्तकालय की

#include <stdio.h> 

int main (void) 
{ 
     float f = 10.0f; 

     struct Float { 
       unsigned char bit01:1; 
       unsigned char bit02:1; 
       unsigned char bit03:1; 
       unsigned char bit04:1; 
       unsigned char bit05:1; 
       unsigned char bit06:1; 
       unsigned char bit07:1; 
       unsigned char bit08:1; 
       unsigned char bit09:1; 
       unsigned char bit10:1; 
       unsigned char bit11:1; 
       unsigned char bit12:1; 
       unsigned char bit13:1; 
       unsigned char bit14:1; 
       unsigned char bit15:1; 
       unsigned char bit16:1; 
       unsigned char bit17:1; 
       unsigned char bit18:1; 
       unsigned char bit19:1; 
       unsigned char bit20:1; 
       unsigned char bit21:1; 
       unsigned char bit22:1; 
       unsigned char bit23:1; 
       unsigned char bit24:1; 
       unsigned char bit25:1; 
       unsigned char bit26:1; 
       unsigned char bit27:1; 
       unsigned char bit28:1; 
       unsigned char bit29:1; 
       unsigned char bit30:1; 
       unsigned char bit31:1; 
       unsigned char bit32:1; 
     }; 

     struct Float *F; 

     F = (struct Float *) &f; 

     printf("\nMSB -->1 bit for sign bit; 8 bit for exponent; 23 bit for mantisa<-- LSB\n"); 
     printf("%d ", F->bit32); 
     printf("%d", F->bit31); 
     printf("%d", F->bit30); 
     printf("%d", F->bit29); 
     printf("%d", F->bit28); 
     printf("%d", F->bit27); 
     printf("%d", F->bit26); 
     printf("%d", F->bit25); 
     printf("%d ", F->bit24); 
     printf("%d", F->bit23); 
     printf("%d", F->bit22); 
     printf("%d", F->bit21); 
     printf("%d", F->bit20); 
     printf("%d", F->bit19); 
     printf("%d", F->bit18); 
     printf("%d", F->bit17); 
     printf("%d", F->bit16); 
     printf("%d", F->bit15); 
     printf("%d", F->bit14); 
     printf("%d", F->bit13); 
     printf("%d", F->bit12); 
     printf("%d", F->bit11); 
     printf("%d", F->bit10); 
     printf("%d", F->bit09); 
     printf("%d", F->bit08); 
     printf("%d", F->bit07); 
     printf("%d", F->bit06); 
     printf("%d", F->bit05); 
     printf("%d", F->bit04); 
     printf("%d", F->bit03); 
     printf("%d", F->bit02); 
     printf("%d\n", F->bit01); 
} 
7

सौजन्य, यहाँ परीक्षण दोहन के साथ सी में एक समाधान, पूरी हो चुकी है, और दोनों हेक्स और ASCII डेटा उपलब्ध कराने के:

#include <stdio.h> 

void hexDump (char *desc, void *addr, int len) { 
    int i; 
    unsigned char buff[17];  // stores the ASCII data 
    unsigned char *pc = addr;  // cast to make the code cleaner. 

    // Output description if given. 

    if (desc != NULL) 
     printf ("%s:\n", desc); 

    // Process every byte in the data. 

    for (i = 0; i < len; i++) { 
     // Multiple of 16 means new line (with line offset). 

     if ((i % 16) == 0) { 
      // Just don't print ASCII for the zeroth line. 

      if (i != 0) 
       printf (" %s\n", buff); 

      // Output the offset. 

      printf (" %04x ", i); 
     } 

     // Now the hex code for the specific character. 

     printf (" %02x", pc[i]); 

     // And store a printable ASCII character for later. 

     if ((pc[i] < 0x20) || (pc[i] > 0x7e)) 
      buff[i % 16] = '.'; 
     else 
      buff[i % 16] = pc[i]; 
     buff[(i % 16) + 1] = '\0'; 
    } 

    // Pad out last line if not exactly 16 characters. 

    while ((i % 16) != 0) { 
     printf (" "); 
     i++; 
    } 

    // And print the final ASCII bit. 

    printf (" %s\n", buff); 
} 

int main (int argc, char *argv[]) { 
    double d1 = 234.5; 
    char s1[] = "a 15char string"; 
    char s2[] = "This is a slightly longer string"; 
    hexDump ("d1", &d1, sizeof d1); 
    hexDump ("s1", &s1, sizeof s1); 
    hexDump ("s2", &s2, sizeof s2); 
    return 0; 
} 

अपने सिस्टम पर उत्पादन होता है:

d1: 
    0000 00 00 00 00 00 50 6d 40       [email protected] 
s1: 
    0000 61 20 31 35 63 68 61 72 20 73 74 72 69 6e 67 00 a 15char string. 
s2: 
    0000 54 68 69 73 20 69 73 20 61 20 73 6c 69 67 68 74 This is a slight 
    0010 6c 79 20 6c 6f 6e 67 65 72 20 73 74 72 69 6e 67 ly longer string 
    0020 00            . 

के बाद से इस सवाल का टैग है सी ++ भी, यहाँ तुलना करने के लिए एक iostream संस्करण है। भले ही आप iostreams का एक विशेष प्रशंसक नहीं हैं, फिर भी यदि आप पहले से ही उनका उपयोग कर रहे हैं तो यह अभी भी फिट बैठता है। hexdump(any_obj) का उपयोग करने में सक्षम होने के नाते भी अच्छा है, लेकिन निश्चित रूप से सीटीओआर के समान एक प्रतिनिधि समारोह टेम्पलेट के साथ किया जा सकता है।

#include <iomanip> 
#include <ostream> 
#include <string> 

struct hexdump { 
    void const* data; 
    int len; 

    hexdump(void const* data, int len) : data(data), len(len) {} 

    template<class T> 
    hexdump(T const& v) : data(&v), len(sizeof v) {} 

    friend 
    std::ostream& operator<<(std::ostream& s, hexdump const& v) { 
    // don't change formatting for s 
    std::ostream out (s.rdbuf()); 
    out << std::hex << std::setfill('0'); 

    unsigned char const* pc = reinterpret_cast<unsigned char const*>(v.data); 

    std::string buf; 
    buf.reserve(17); // premature optimization 

    int i; 
    for (i = 0; i < v.len; ++i, ++pc) { 
     if ((i % 16) == 0) { 
     if (i) { 
      out << " " << buf << '\n'; 
      buf.clear(); 
     } 
     out << " " << std::setw(4) << i << ' '; 
     } 

     out << ' ' << std::setw(2) << unsigned(*pc); 
     buf += (0x20 <= *pc && *pc <= 0x7e) ? *pc : '.'; 
    } 
    if (i % 16) { 
     char const* spaces16x3 = "            "; 
     out << &spaces16x3[3 * (i % 16)]; 
    } 
    out << " " << buf << '\n'; 

    return s; 
    } 
}; 

int main() { 
    std::cout << "double:\n" << hexdump(234.5); 
    std::cout << "string 1:\n" << hexdump("a 15char string"); 
    std::cout << "string 2:\n" << hexdump("This is a slightly longer string"); 

    return 0; 
} 
+0

चूंकि इस प्रश्न को सी ++ भी टैग किया गया है, iostream संस्करण की तुलना करने के लिए: http://codepad.org/trVz9mlQ। मैं iostreams का एक विशेष प्रशंसक नहीं हूं, लेकिन अगर आप पहले से ही उनका उपयोग कर रहे हैं तो यह फिट बैठता है। 'हेक्सडम्प (any_obj)' का उपयोग करने में सक्षम होने के नाते भी अच्छा है (लेकिन निश्चित रूप से उस सीटीआर के समान एक प्रतिनिधि समारोह टेम्पलेट के साथ किया जा सकता है)। –

+0

@ रोगर, मैं इस कोड को इस उत्तर में शामिल करने जा रहा था (पाठ्यक्रम की विशेषता के साथ, और सुझाव है कि यदि आपने अपना उत्तर पोस्ट किया है, तो मैं इसे अपने से हटा दूंगा)। ऐसा इसलिए है क्योंकि मैं अभी भी उपयोगी होने के लिए एसओ पसंद करता हूं भले ही ग्रह पर हर दूसरी साइट (जैसे कोडेपैड) गायब हो जाए। हालांकि, आपके एसओ यूजर पेज पर आपकी कॉपीराइट पॉलिसी को देखते हुए मुझे रोक दिया गया - अगर आप कॉपीराइट बनाए रखते हैं तो कोई भी आपके कोड का उपयोग नहीं कर सकता है, यह शिक्षा के अलावा बेकार है। इसके कारण, मैं आपको एक लिंक के साथ टिप्पणी के बजाय इसे उचित उत्तर के रूप में पोस्ट करना पसंद करूंगा, लेकिन यह पूरी तरह से आपके ऊपर है। – paxdiablo

+0

यह एक अलग व्यक्ति के मुकाबले आपके उत्तर से अधिक संबंधित था, और टिप्पणी स्थान सीमित है इसलिए मैं केवल कोडपैड के लिए reflexively पहुंचे। मैं इसे शामिल करने के लिए प्रश्न संपादित करूंगा, फिर मैं इसे एसओ लाइसेंस के तहत रखूंगा। जैसा आप चाहें पुन: संपादित करें। - एफडब्ल्यूआईडब्लू, हालांकि मुझे लगता है कि अब आप इसे महसूस कर रहे हैं, मैं केवल अपने जैव में उल्लेख करके "डिफ़ॉल्ट" को बहाल कर रहा हूं कि कहीं और पोस्ट किया गया कोड एसओ के लाइसेंस द्वारा कवर नहीं किया गया है, लेकिन मेरा इरादा था कि लंबे समय तक, कम छोटे codepad.org पेस्ट के बारे में तुच्छ कोड। –

0

मुझे लगता है कि आप वास्तविक बिट्स को "मास्क आउट" करने के लिए शिफ्ट ऑपरेशन और मास्क का उपयोग कर सकते हैं।

पूर्णांक टी = 128;

के लिए (int i = 0; मैं < 8; ++ i) { printf ("% d", पी & टी);

पी = >> 1;

टी = >> 1; }

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

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