左移位和右移位運算子:<<
和 >>
位元移位運算子是右移位運算子 (>>
),會將整數或列舉型別運算式的位元向右移,另外還有左移位運算子 (<<
),會將位元向左移。 1
語法
shift-expression
:
additive-expression
shift-expression
<<
additive-expression
shift-expression
>>
additive-expression
備註
重要
下列說明和範例適用於 x86 和 x64 結構的 Windows。 左移位和右移位運算子在適用於 ARM 裝置的 Windows 上實作非常不同。 如需詳細資訊,請參閱 Hello ARM 部落格文章中的<移位運算子>一節。
左移位
左移位運算子會使 shift-expression
中的位元向左移動 additive-expression
所指定的位置數目。 移位作業空出的位元位置以零填補。 左移是邏輯移位 (會捨棄移出結尾的位元,包括正負號位元)。 如需此類位元移位的詳細資訊,請參閱位元移位。
下列範例示範使用不帶正負號數字的左移位作業。 此範例以值代表 bitset 說明位元的行為。 如需詳細資訊,請參閱位元組類別。
#include <iostream>
#include <bitset>
using namespace std;
int main() {
unsigned short short1 = 4;
bitset<16> bitset1{short1}; // the bitset representation of 4
cout << bitset1 << endl; // 0b00000000'00000100
unsigned short short2 = short1 << 1; // 4 left-shifted by 1 = 8
bitset<16> bitset2{short2};
cout << bitset2 << endl; // 0b00000000'00001000
unsigned short short3 = short1 << 2; // 4 left-shifted by 2 = 16
bitset<16> bitset3{short3};
cout << bitset3 << endl; // 0b00000000'00010000
}
如果將帶正負號的數字左移,以影響正負號位元,結果會是未定義。 下列範例示範將一個 1 位元左移位到帶正負號位元位置時的情況。
#include <iostream>
#include <bitset>
using namespace std;
int main() {
short short1 = 16384;
bitset<16> bitset1(short1);
cout << bitset1 << endl; // 0b01000000'00000000
short short3 = short1 << 1;
bitset<16> bitset3(short3); // 16384 left-shifted by 1 = -32768
cout << bitset3 << endl; // 0b10000000'00000000
short short4 = short1 << 14;
bitset<16> bitset4(short4); // 4 left-shifted by 14 = 0
cout << bitset4 << endl; // 0b00000000'00000000
}
右移位
右移位運算子會使 shift-expression
中的位元模式向右移動 additive-expression
所指定的位置數目。 若是不帶正負號的數字,移位作業空出的位元位置以零填補。 若是帶正負號的數字,會使用正負號位元填補空出的位元位置。 換句話說,如果是正數就會使用 0,負數則使用 1。
重要
將帶正負號負數向右移的結果與實作相關。 雖然 Microsoft C++ 編譯器使用正負號位元填補空出來的位元位置,但不保證其他實作也會如此。
此範例示範使用不帶正負號數字的右移位作業:
#include <iostream>
#include <bitset>
using namespace std;
int main() {
unsigned short short11 = 1024;
bitset<16> bitset11{short11};
cout << bitset11 << endl; // 0b00000100'00000000
unsigned short short12 = short11 >> 1; // 512
bitset<16> bitset12{short12};
cout << bitset12 << endl; // 0b00000010'00000000
unsigned short short13 = short11 >> 10; // 1
bitset<16> bitset13{short13};
cout << bitset13 << endl; // 0b00000000'00000001
unsigned short short14 = short11 >> 11; // 0
bitset<16> bitset14{short14};
cout << bitset14 << endl; // 0b00000000'00000000
}
下一個範例示範使用正號數字的右移位作業。
#include <iostream>
#include <bitset>
using namespace std;
int main() {
short short1 = 1024;
bitset<16> bitset1(short1);
cout << bitset1 << endl; // 0b00000100'00000000
short short2 = short1 >> 1; // 512
bitset<16> bitset2(short2);
cout << bitset2 << endl; // 0b00000010'00000000
short short3 = short1 >> 11; // 0
bitset<16> bitset3(short3);
cout << bitset3 << endl; // 0b00000000'00000000
}
下一個範例示範使用帶負號整數右移位作業。
#include <iostream>
#include <bitset>
using namespace std;
int main() {
short neg1 = -16;
bitset<16> bn1(neg1);
cout << bn1 << endl; // 0b11111111'11110000
short neg2 = neg1 >> 1; // -8
bitset<16> bn2(neg2);
cout << bn2 << endl; // 0b11111111'11111000
short neg3 = neg1 >> 2; // -4
bitset<16> bn3(neg3);
cout << bn3 << endl; // 0b11111111'11111100
short neg4 = neg1 >> 4; // -1
bitset<16> bn4(neg4);
cout << bn4 << endl; // 0b11111111'11111111
short neg5 = neg1 >> 5; // -1
bitset<16> bn5(neg5);
cout << bn5 << endl; // 0b11111111'11111111
}
移位和提升
移位運算子兩邊的運算式都必須是整數類型。 整數提升會根據標準轉換中描述的規則執行。 結果的類型與提升之 shift-expression
的類型相同。
下列範例會將屬於類型 char
的變數提升為 int
。
#include <iostream>
#include <typeinfo>
using namespace std;
int main() {
char char1 = 'a';
auto promoted1 = char1 << 1; // 194
cout << typeid(promoted1).name() << endl; // int
auto promoted2 = char1 << 10; // 99328
cout << typeid(promoted2).name() << endl; // int
}
詳細資料
如果 additive-expression
是負數或 additive-expression
大於或等於 (已提升) shift-expression
中的位元數,則移位作業的結果會是未定義。 如果 additive-expression
為 0,則不會進行移位作業。
#include <iostream>
#include <bitset>
using namespace std;
int main() {
unsigned int int1 = 4;
bitset<32> b1{int1};
cout << b1 << endl; // 0b00000000'00000000'00000000'00000100
unsigned int int2 = int1 << -3; // C4293: '<<' : shift count negative or too big, undefined behavior
unsigned int int3 = int1 >> -3; // C4293: '>>' : shift count negative or too big, undefined behavior
unsigned int int4 = int1 << 32; // C4293: '<<' : shift count negative or too big, undefined behavior
unsigned int int5 = int1 >> 32; // C4293: '>>' : shift count negative or too big, undefined behavior
unsigned int int6 = int1 << 0;
bitset<32> b6{int6};
cout << b6 << endl; // 0b00000000'00000000'00000000'00000100 (no change)
}
註腳
1 以下說明 C++11 ISO 規格 (INCITS/ISO/IEC 14882-2011[2012]) 第 5.8.2 和 5.8.3 節的移位運算子。
E1 << E2
的值是向左移位 E1
的 E2
位元位置;空出的位元會以零填補。 如果 E1
具有不帶正負號的類型,結果的值會是 E1 × 2E2,比結果類型中可顯示的最大值少一個餘數。 否則,如果 E1
的類型帶正負號,且具有非負數值,且結果類型之對應不帶正負號類型可以顯示 E1 × 2E2,則轉換為結果類型的值即為結果值,否則該行為即為未定義。
E1 >> E2
的值是 E1
向右移位 E2
個位元位置。 如果 E1
的類型不帶正負號,或者 E1
的類型帶正負號且具有非負數值,則結果的值會是 E1/2E2 商數的整數部分。 如果 E1
的類型帶正負號,且具有負數值,結果產生的值由實作決定。
另請參閱
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應