如何在C中打印出变量的内存内容?

Laz*_*zer 24 c c++ memory double

假设我做了

double d = 234.5;
Run Code Online (Sandbox Code Playgroud)

我想看d[整个8字节] 的内存内容

我怎么做?

caf*_*caf 27

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

for (i = 0; i < sizeof d; i++)
    printf("%02x ", p[i]);
Run Code Online (Sandbox Code Playgroud)

  • 同意 - 我更喜欢明确它是一个操作符,而不是一个函数(我不做`return(x);`,或者) (4认同)
  • 总是使用括号更容易,以便不必在楼上的灰质中存储一个_more_东西:-)我喜欢使用变量而不是类型,以防变量的类型发生变化,所以我不这样做必须改变尽可能多的代码. (4认同)
  • @Craig:`sizeof d`是正确的,我不知道为什么你把它改成`sizeof(d)`(这也有效,但很多人喜欢`sizeof d`当`d`不是一个类型). (3认同)

Alo*_*hal 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]);
Run Code Online (Sandbox Code Playgroud)

所有方法都显示了字节 - 但是相同的double值可能会在不同系统上以不同方式打印字节,例如,由于编码不同(罕见)或不同的字节序.


pax*_*blo 8

由我的有用片段库提供,这是C语言的解决方案,包含测试工具,并提供十六进制和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;
}
Run Code Online (Sandbox Code Playgroud)

我系统的输出是:

d1:
  0000  00 00 00 00 00 50 6d 40                          .....Pm@
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                                               .
Run Code Online (Sandbox Code Playgroud)

由于这个问题也被标记为C++,这里有一个iostream版本可供比较.即使你不是iostreams的特别粉丝,如果你已经在使用它们,它仍然适合.能够使用hexdump(any_obj)也很好,但当然可以使用类似于ctor的委托功能模板来完成.

#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;
}
Run Code Online (Sandbox Code Playgroud)