[英]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
參數並將其格式化為十進制數字。
因此,回顧一下:假設您有一台機器,
short int
是2個字節 ...然后,此程序將輸出-108
(如果char
是有符號類型)或148
(如果char
是無符號類型)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.