2017-05-25 55 views
1

编我写的作品为一些整数的值,但不是所有...为什么?无法正确提取整数字节

程序输出

int value is abcdef78 
first byte is 78 addr is 2686741 
second byte is ffffffef addr is 2686742 
third byte is ffffffcd addr is 2686743 
fourth byte is ffffffab addr is 2686744 

预期输出

int value is abcdef78 
first byte is 78 addr is 2686741 
second byte is ef addr is 2686742 
third byte is cd addr is 2686743 
fourth byte is ab addr is 2686744 

Process returned 0 (0x0) execution time : 0.015 s 
Press any key to continue. 

代码:

#include <stdio.h> 
#include <stdlib.h> 

int main() 
{ 

    int i=0xabcdef78; 
    int *ip; 

    printf("int value is %x\n",i); // *ip contents of address 

    char c; 
    char *cp; 
    cp=&i; 
    c = *cp; 
    printf("first byte is %x addr is %d\n",*cp++,cp); 
    printf("second byte is %x addr is %d\n",*cp++,cp); 
    printf("third byte is %x addr is %d\n",*cp++,cp); 
    printf("fourth byte is %x addr is %d\n",*cp++,cp); 

    return 0; 
} 
+0

更改'%x'→'%hhx'和'%d'→'%p'。另外,如果您希望程序可靠地工作,您应该在printf语句后增加'cp'。 –

+0

该代码调用*未定义的行为*。在每个输出调用中,您都有无法修改和访问'cp'的情况。 – WhozCraig

+0

也许尝试使用unit_8t数据类型而不是int。 – LethalProgrammer

回答

0

的原因是你的炭获得晋升与符号扩展为int。 0xef二进制形式是:

1110 1111 

并得到提升到一个32位整数,符号扩展这样的:

1111 1111 1111 1111 1111 1111 1110 1111 

虽然0x78以二进制形式是:

0111 1000 

最重要的位是0,所以它得到这样的提升:

0000 0000 0000 0000 0000 0000 0111 1000 

有两个解决方案:

  1. 不要打印字符作为32位值,即使用%HHX代替%×。

  2. 让你的字符无符号,即无符号字符* CP代替字符* CP

0

你应该修改像

#include <stdio.h> 

int main(void) 
{ 
    int i = 0xabcdef78; 

    printf("int value is %x\n", i); // *ip contents of address 

    unsigned char *cp; 
    cp = (unsigned char *)(&i); 

    printf("1st byte is 0x%02X addr is %p\n", cp[0], (void *)(&cp[0])); 
    printf("2nd byte is 0x%02X addr is %p\n", cp[1], (void *)(&cp[1])); 
    printf("3rd byte is 0x%02X addr is %p\n", cp[2], (void *)(&cp[2])); 
    printf("4th byte is 0x%02X addr is %p\n", cp[3], (void *)(&cp[3])); 

    return 0; 
} 

你的代码,你可以看到:

  1. 我更改了地址的格式说明符:必须是%p并且传递参数必须是void *
  2. 我删除了指针增量,因为它是UB。看看this famous SO question。如果你想增加你的指针,你必须在printf之后增加它。
  3. 您必须使用unsigned char指向您的整数的字节,否则,asu您面临的值大于7F将被视为负值。

输出

int value is abcdef78 
1st byte is 0x78 addr is 0x7ffdda43fc8c 
2nd byte is 0xEF addr is 0x7ffdda43fc8d 
3rd byte is 0xCD addr is 0x7ffdda43fc8e 
4th byte is 0xAB addr is 0x7ffdda43fc8f 
-1

删除声明

int *ip; 

因为你从来没有使用它(并不重要)。然后:

而不是

printf("first byte is %x addr is %d\n",*cp++,cp); 
printf("second byte is %x addr is %d\n",*cp++,cp); 
printf("third byte is %x addr is %d\n",*cp++,cp); 
printf("fourth byte is %x addr is %d\n",*cp++,cp); 

使用

printf("first byte is %hhx, addr is %ld\n", *cp++, cp); 
printf("second byte is %hhx, addr is %ld\n", *cp++, cp); 
printf("third byte is %hhx, addr is %ld\n", *cp++, cp); 
printf("fourth byte is %hhx, addr is %ld\n", *cp++, cp); 

为你的程序的逻辑是正确的,但输出坏格式化

+0

这不能解决未定义的行为问题。 –

+0

@squeamis - 你完全正确,谢谢。我想正确的答案,但同时[LP](https://stackoverflow.com/users/3436922/lps)提供了一个正确的答案。 – MarianD