在我的筆記本電腦,運行下面的代碼:爲什麼對char應用按位不產生int?
#include <iostream>
using namespace std;
int main()
{
char a;
cout << sizeof(~a) << endl;
}
打印4
。
我預計~a
的結果是char
,但顯然它是一個int
。
這是爲什麼?
在我的筆記本電腦,運行下面的代碼:爲什麼對char應用按位不產生int?
#include <iostream>
using namespace std;
int main()
{
char a;
cout << sizeof(~a) << endl;
}
打印4
。
我預計~a
的結果是char
,但顯然它是一個int
。
這是爲什麼?
~
是arithemtic運營商(按位NOT),並a
正在從signed char
晉升爲int
(並且在許多實現中sizeof(int) == 4
)。參閱下面的解釋:
http://en.cppreference.com/w/cpp/language/implicit_conversion#integral_promotion小積分類型(如炭)的
Prvalues可被轉換成較大的整數類型的 prvalues(如int)。特別是, 算術運算符不接受類型小於int的類型作爲 自變量,並且積分提升會在 左值到右值轉換後自動應用(如果適用)。此轉換始終保留該值。
謝謝您的回答!我想我已經明白了。但我想知道爲什麼它在C++中以這種方式實現。 –
@HanQiu因爲C也是這樣,所以C++應該是廣泛兼容的。現在爲什麼C做它我不知道。也許有些*「'int'是最快的整數類型原因」*。 –
@BaummitAugen關於'int'的任何證明是最快的?我們大多數人現在使用64位機器,32位'int'仍然是最快的? –
的標準說(§[expr.primary]/10):
的〜應具有一體或無作用域枚舉類型的操作數;結果是它的操作數的補碼。積分促銷被執行。結果的類型是提升操作數的類型。
「整體狀況」 是指(§[conv.prom]/1):
以外的整數類型的prvalue
bool
,char16_t
,char32_t
,或wchar_t
其整數轉換秩(4.13 )低於排名int
可以轉換爲int
類型的預值如果int
可以表示源類型的所有值;否則,源值可以轉換爲unsigned int
類型的值。
在你的情況,a
具有類型char
,其中有一個轉換等級小於int
軍銜,所以它被晉升要麼int
或unsigned int
,兩者具有相同的尺寸(顯然4
在你的實現中)。至於爲什麼要這樣做:我認爲很重要的一點是它只是簡化了語言定義和編譯器。不必爲幾乎所有類型分別生成代碼,它最好將所有內容都摺疊成幾種類型,而且大多數代碼僅針對這些類型生成。現在情況並非如此(現在我們有多種類型,大於int
),但當C小時,整數類型爲:char
,short
,int
(以及它們的未簽名版本),所以所有其他類型被提升爲int
,並且所有操縱任何東西的代碼都是用int
s完成的。
注意,這適用於函數調用和這樣太:用C的早期版本中沒有的函數原型,所以char
類型或short
的任何參數傳遞給函數之前也被晉升爲int
。
相同的基本想法是,隨後用浮點類型:在大多數情況下(包括將它們傳遞給函數)float
小號晉升爲double
,並double
S(之後你可以轉換回做所有的實際處理。float
,如果必要的話
1.3除了bool,char16_t,char32_t或wchar_t以外的整數轉換等級(4.13)小於int等級的整數類型的值可以轉換爲int類型的值,如果int可以表示所有的值源類型;否則,可以將源prvalue轉換爲unsigned int類型的prvalue。
[...]
1.6 char的等級應等於signed char和unsigned char的等級。
雖然這可能是一個騙局(找一個),我不會得到downvote。如果不瞭解整體促銷規則,這對於尋找我來說並不容易。 –
[This](https://stackoverflow.com/questions/30473958/what-is-going-on-with-bitwise-operators-and-integer-promotion)一開始並不壞。 OP:你認爲這夠好嗎? –
糟糕,沒有注意到'sizeof'。 – Barmar