【问题标题】:Printing error while accessing consecutive memory locations [duplicate]访问连续内存位置时出现打印错误[重复]
【发布时间】:2013-10-16 06:47:50
【问题描述】:

以下是查看不同数据类型如何存储在内存中的代码。

#include <stdio.h>

void newline(void)
{
    putchar('\n');
}

void showbyte(char *string, int len)
{
    int i;
    for (i = 0; i < len; i++)
    printf("%p\t0x%.2x\n", string+i, *(string+i));
}

int main()
{
    int i = 12345;
    float f = 1234.5;
    double d = 1234.5;
    char name[] = "12345";
    showbyte((char *)&i, sizeof i);
    newline();
    showbyte((char *)&f, sizeof f);
    newline();
    showbyte((char *)&d, sizeof d);
    newline();
    showbyte((char *)&name, sizeof name);
    return 0;
}

输出

0x7fff8a9ab2cc  0x39
0x7fff8a9ab2cd  0x30
0x7fff8a9ab2ce  0x00
0x7fff8a9ab2cf  0x00

0x7fff8a9ab2c8  0x00
0x7fff8a9ab2c9  0x50
0x7fff8a9ab2ca  0xffffff9a
0x7fff8a9ab2cb  0x44

0x7fff8a9ab2c0  0x00
0x7fff8a9ab2c1  0x00
0x7fff8a9ab2c2  0x00
0x7fff8a9ab2c3  0x00
0x7fff8a9ab2c4  0x00
0x7fff8a9ab2c5  0x4a
0x7fff8a9ab2c6  0xffffff93
0x7fff8a9ab2c7  0x40

0x7fff8a9ab2b0  0x31
0x7fff8a9ab2b1  0x32
0x7fff8a9ab2b2  0x33
0x7fff8a9ab2b3  0x34
0x7fff8a9ab2b4  0x35
0x7fff8a9ab2b5  0x00

float 1234.5 的 IEEE-754 表示是 0x449a5000double 1234.5 的 IEEE-754 表示是 0x40934A0000000000。当它打印floatdouble 变量内容时,它会显示4-byte 内容。

即, 0x7fff8a9ab2ca 0xffffff9a0x7fff8a9ab2c6 0xffffff93

但是每个内存位置只能存储1-byte的数据,那为什么会这样呢?

【问题讨论】:

  • @EricPostpischil 谢谢.. 我之前没找到那个链接...

标签: c pointers memory floating-point ieee-754


【解决方案1】:

unsigned 在这种情况下是你的朋友,因为char is by default a signed type

如果您将某些类型从 char 更改为 unsigned char,您会得到正确的结果:

#include <stdio.h>

void newline(void)
{
    putchar('\n');
}

void showbyte(unsigned char *string, int len)
{
    int i;
    for (i = 0; i < len; i++)
      printf("%p\t0x%.2x\n", string+i, *(string+i));
}

int main()
{
    int i = 12345;
    float f = 1234.5;
    double d = 1234.5;
    char name[] = "12345";
    showbyte((unsigned char *)&i, sizeof i);
    newline();
    showbyte((unsigned char *)&f, sizeof f);
    newline();
    showbyte((unsigned char *)&d, sizeof d);
    newline();
    showbyte((unsigned char *)&name, sizeof name);
    return 0;
}

在这种情况下,您会得到:

0x7fff5d5a98b8  0x39
0x7fff5d5a98b9  0x30
0x7fff5d5a98ba  0x00
0x7fff5d5a98bb  0x00

0x7fff5d5a98b4  0x00
0x7fff5d5a98b5  0x50
0x7fff5d5a98b6  0x9a
0x7fff5d5a98b7  0x44

0x7fff5d5a98a8  0x00
0x7fff5d5a98a9  0x00
0x7fff5d5a98aa  0x00
0x7fff5d5a98ab  0x00
0x7fff5d5a98ac  0x00
0x7fff5d5a98ad  0x4a
0x7fff5d5a98ae  0x93
0x7fff5d5a98af  0x40

0x7fff5d5a98a2  0x31
0x7fff5d5a98a3  0x32
0x7fff5d5a98a4  0x33
0x7fff5d5a98a5  0x34
0x7fff5d5a98a6  0x35
0x7fff5d5a98a7  0x00

【讨论】:

  • 但它是如何/为什么发生的?
  • 0x9a 和 0x93 是负数 :-) 也许编译器将此值升级为整数或 printf 做到了..
  • 是的,printf 正在做这项工作,我可以从这段代码中看到它..int main() {char i = -3; printf("%.2x\n", i); return 0;}。但是为什么会避开%.2x呢?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-05
  • 1970-01-01
  • 2018-05-15
  • 2016-09-27
  • 2011-02-12
  • 2017-04-29
  • 1970-01-01
相关资源
最近更新 更多