2017-05-25 111 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