2017-08-12 92 views
-1

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

#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 

我不知道,如果我的機器是小端或大端。我發現某處它應該給出

148 

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

+1

編譯標誌可以將默認字符更改爲有符號/無符號等 –

回答

1

c[4]404。在雙字節小端表示中,這意味着兩個字節的0x940x01或(十進制)1481

b+8解決了c[4]的內存問題。 b是指向char的指針,所以8意味着添加8個字節(即4個雙字節短路)。換句話說,b+8指向c[4]的第一個字節,其中包含148

*(b+8)(也可寫爲b[8])對指針取消引用,因此將值148設爲char。它所做的是實現定義的:在許多常見平臺上,char是帶符號類型(範圍爲-128 .. 127),因此它實際上不能是148。但是,如果它是無符號類型(範圍爲0 .. 255),那麼148就沒有問題。

0123'二進制的位模式是10010100。將此解釋爲二進制補碼可以給你-108

(任一148-108)此char值,因爲它出現在一個可變參數的函數(printf)的參數列表,然後自動轉換爲int。這不會改變價值。

最後,"%d"告訴printf採取int參數並將其格式化爲十進制數。

因此,回顧一下:假設你有一臺機器,其中

  • 一個字節爲8位
  • 負數使用補
  • short int爲2個字節

...那麼這個程序將輸出-108(如果char是簽名類型)或148(如果char是你的nsigned類型)。

1

要了解哪種尺寸的類型在您的系統:

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機器有不同的地址和指針diffe租金類型的數據

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

另一句話:它是唯一,因爲你的程序C [0] == 400個

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來控制默認行爲。