該代碼可以執行的幾種可能的方式。
char
在你的編譯器上沒有簽名。然後該表達式將被評估爲0x80<<8 | 0x00
,其給出0x8000
。如果這適合您系統中的int
,則結果將爲32768.否則,它將以某種實現定義的方式轉換爲帶符號格式。在二進制補碼計算機上,您可能會得到結果-32768。
或char
在您的編譯器上簽名。然後0x80
不適合它,但在某些實現定義的方式中轉換爲負數。在二進制補碼計算機上,它可能會得到-128的值。然後,您左移這個負值 - 這會調用未定義的行爲(來源:C11 6.5.7/4)。這反過來可能導致任何事情發生:你的程序可能會崩潰或打印廢話,或者編譯器可能存在一些特定的非標準行爲,如將結果視爲-32768。
這裏的關鍵是,你不應該寫這樣的代碼,它依賴於許多形式不明確的行爲。這是不好的做法。之所以最終這樣做,是因爲您使用的是原始的C原始數據類型,如char
和int
,這些數據類型指定不準確,因此很難用於位操作。
你的代碼應該被固定到安全的東西,這將使一個確定性的結果,不管系統或編譯器:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
int main()
{
uint8_t *buffer = malloc(sizeof(uint8_t[2]));
buffer[0] = 0x80;
buffer[1] = 0x00;
uint16_t address = ((uint16_t)buffer[0]<<8) | (buffer[1]);
printf("%" PRIu16 "\n", address);
free(buffer);
return 0;
}
由於緩衝區[0]爲-128 – immibis
哇哦,應該是無符號的不應該是 – danielmhanover
的「int」是一個有符號的數字。如果高位被設置爲有符號整數,則表示它爲負。也許你應該谷歌「二補」。 – TonyB