2013-10-09 46 views
-1

以下是查看不同数据类型在内存中存储方式的代码。访问连续内存位置时出现打印错误

#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表示是0x449a5000,以及用于double 1234.50x40934A0000000000。当它打印floatdouble变量内容时,它显示一个4-byte内容。

即, 0x7fff8a9ab2ca 0xffffff9a0x7fff8a9ab2c6 0xffffff93

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

+0

@EricPostpischil谢谢..我没有找到... – noufal

回答

2

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

如果从焦炭改变某些类型的以无符号的字符你得到正确的结果:

#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 
+0

之前的链接,但是它是如何/为何发生的? – noufal

+0

0x9a和0x93是负数:-)也许编译器将这个值升级为整数或printf做到了这一点.. – pfmaggi

+0

是的,printf正在做这个工作,我可以从这个代码中看到它..'int main(){char i = -3; printf(“%。2x \ n”,i);返回0;}'。但为什么它避免了'%.2x'? – noufal