簡體   English   中英

以下C代碼的輸出

[英]Output of the following C code

以下C代碼的輸出是什么。 假設它在Little endian機器上運行,其中short int需要2字節,而char需要1字節。

#include<stdio.h>
int main() {
    short int c[5];
    int i = 0;
    for(i = 0; i < 5; i++)
        c[i] = 400 + i;
    char *b = (char *)c;
    printf("%d", *(b+8));
    return 0;
}

在我的機器上

-108

我不知道我的機器是Little Endian還是Big Endian。 我發現應該給的地方

148

作為輸出。 因為404(即元素c [4])的低8位是148。但是我認為由於“%d”,它應該從c [4]的地址開始從內存中讀取2個字節。

該代碼在不同的計算機上提供不同的輸出,因為在某些平台上, char類型默認情況下是帶符號的,而在其他平台上則默認情況下是不帶符號的。 這與字節序無關。 嘗試這個:

    char *b = (char *)c;
    printf("%d\n", (unsigned char)*(b+8)); // always prints 148 
    printf("%d\n", (signed char)*(b+8));   // always prints -108 (=-256 +148)

默認值取決於平台和編譯器設置。 您可以使用GCC選項-fsigned-char-funsigned-char來控制默認行為。

要查看系統中有哪些尺寸類型:

printf("char = %u\n", sizeof(char));    
printf("short = %u\n", sizeof(short));    
printf("int = %u\n", sizeof(int));    
printf("long = %u\n", sizeof(long));    
printf("long long = %u\n", sizeof(long long));  

更改程序中的行

unsigned char *b = (unsigned char *)c;
printf("%d\n", *(b + 8));

和簡單的測試(我知道不能保證,但是我知道的所有C編譯器都是這樣做的,而且我並不關心具有不同地址和指向不同類型數據的指針的舊CDC或UNISYS計算機

printf(" endianes test: %s\n", (*b + (unsigned)*(b + 1) * 0x100) ==  400? "little" : "big");

另一句話:這僅僅是因為在您的程序中c [0] == 400

c[4]存儲404 在兩字節的Little-endian表示中,這意味着兩個字節0x94 0x01或(十進制) 148 1

b+8尋址c[4]的內存。 b是指向char的指針,因此8表示添加8個字節(這是4個2個字節的短褲)。 換句話說, b+8指向c[4]的第一個字節,其中包含148

*(b+8) (也可以寫為b[8] )取消引用指針,因此將值148作為char 這是由實現定義的:在許多常見平台上, char是帶符號的類型(范圍為-128 .. 127 ),因此實際上不能為148 但是,如果它是無符號類型(范圍為0 .. 255 ),則148很好。

二進制148的位模式是10010100 將此解釋為二進制補碼可以得到-108

然后,此char值(為148-108 )將自動轉換為int因為它出現在變量參數函數( printf )的參數列表中。 這不會更改值。

最后, "%d"告訴printf使用int參數並將其格式化為十進制數字。

因此,回顧一下:假設您有一台機器,

  • 一個字節是8位
  • 負數使用二進制補碼
  • short int是2個字節

...然后,此程序將輸出-108 (如果char是有符號類型)或148 (如果char是無符號類型)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM