Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A bitenkénti és a shift operátorok közé tartoznak a nem bitenkénti kiegészítések, a bináris bal és jobb eltolás, az aláíratlan jobb eltolás, valamint a bináris logikai ÉS, OR és kizárólagos VAGY operátorok. Ezek az operátorok az integrál numerikus típusok vagy a karaktertípus operandusait veszik fel.
- Unary
~(bitenkénti kiegészítés) operátor - Bináris
<<(bal shift),>>(jobb shift), és>>>(nem aláírt jobb műszak) operátorok - Bináris
&(logikai ÉS),|(logikai VAGY) és^(logikai kizáró VAGY) operátorok
Ezek az operátorok a int, uint, long, ulong, nintés nuint típusokhoz vannak definiálva. Ha mindkét operandus más integrál típusú (sbyte, , , bytevagy shortushort) típusú, charakkor az értékek a int típusra lesznek konvertálva, ami szintén egy művelet eredménytípusa. Ha az operandusok különböző integráltípusok, az értékek a legközelebbi integrált típusra lesznek konvertálva. További információkért tekintse meg a C#-nyelv specifikációjának Numerikus promóciók szakaszát. Az összetett operátorok (például >>=) nem konvertálják az argumentumaikat int az eredménytípusra, vagy az eredmény típusa a következő int.
A &, |és ^ operátorok is definiálva vannak a bool típus operandusaihoz. További információ: Logikai operátorok.
A bitenkénti és a váltási műveletek soha nem okoznak túlcsordulást, és ugyanazokat az eredményeket eredményezik a ellenőrzött és a nem ellenőrzött környezetekben.
Bitenkénti komplementer operátor ~
Az ~ operátor az operandus bitenkénti kiegészítését állítja elő az egyes bitek megfordításával:
uint a = 0b_0000_1111_0000_1111_0000_1111_0000_1100;
uint b = ~a;
Console.WriteLine(Convert.ToString(b, toBase: 2));
// Output:
// 11110000111100001111000011110011
A szimbólummal ~ véglegesítőket is deklarálhat. További információ: Finalizers.
Bal shift operátor <<
Az << operátor a bal oldali operandusát balra tolja a jobb oldali operandus által meghatározott bitek számával. Arról, hogy a jobb oldali operandus hogyan határozza meg a műszakszámot, tekintse meg a shift operátorok szakaszának Shift count (Műszakok száma) szakaszát.
A bal oldali eltolásos művelet elveti az eredménytípus tartományán kívül eső nagy értékű biteket, és nullára állítja az alacsony sorrendű üres bitpozíciókat, ahogy az alábbi példa mutatja:
uint x = 0b_1100_1001_0000_0000_0000_0000_0001_0001;
Console.WriteLine($"Before: {Convert.ToString(x, toBase: 2)}");
uint y = x << 4;
Console.WriteLine($"After: {Convert.ToString(y, toBase: 2)}");
// Output:
// Before: 11001001000000000000000000010001
// After: 10010000000000000000000100010000
Mivel a shift operátorok csak a int, uint, longés ulong a típusok esetében vannak definiálva, a művelet eredménye mindig legalább 32 bitet tartalmaz. Ha a bal oldali operandus egy másik integráltípusú (sbyte, byte, , shortvagy ushortchar), akkor az értéke a típusra int lesz konvertálva, ahogyan az alábbi példa mutatja:
byte a = 0b_1111_0001;
var b = a << 8;
Console.WriteLine(b.GetType());
Console.WriteLine($"Shifted byte: {Convert.ToString(b, toBase: 2)}");
// Output:
// System.Int32
// Shifted byte: 1111000100000000
Jobb műszakos operátor >>
Az >> operátor a jobb oldali operandus által meghatározott bitek számával jobbra tolja el a bal oldali operandusát. Arról, hogy a jobb oldali operandus hogyan határozza meg a műszakszámot, tekintse meg a shift operátorok szakaszának Shift count (Műszakok száma) szakaszát.
A jobb oldali shift művelet elveti az alacsony sorrendű biteket, ahogy az alábbi példa is mutatja:
uint x = 0b_1001;
Console.WriteLine($"Before: {Convert.ToString(x, toBase: 2), 4}");
uint y = x >> 2;
Console.WriteLine($"After: {Convert.ToString(y, toBase: 2).PadLeft(4, '0'), 4}");
// Output:
// Before: 1001
// After: 0010
A magas sorrendű üres bitpozíciók a bal oldali operandus típusától függően vannak beállítva az alábbiak szerint:
Ha a bal oldali operandus típusa
intvagylong, akkor a jobb műszak operátora aritmetikai eltolást hajt végre: a bal oldali operandus legjelentősebb bitjének (jelbitjének) értékét propagálja a rendszer a nagy sorrendű üres bitpozíciókba. Ez azt jelenti, hogy a magas sorrendű üres bitpozíciók nullára vannak állítva, ha a bal oldali operandus nem negatív, és negatív értékre van állítva.int a = int.MinValue; Console.WriteLine($"Before: {Convert.ToString(a, toBase: 2)}"); int b = a >> 3; Console.WriteLine($"After: {Convert.ToString(b, toBase: 2)}"); // Output: // Before: 10000000000000000000000000000000 // After: 11110000000000000000000000000000Ha a bal oldali operandus típusú
uint, vagyulongha a jobb oldali shift operátor logikai eltolást hajt végre: a nagy sorrendű üres bitpozíciók mindig nullára vannak állítva.uint c = 0b_1000_0000_0000_0000_0000_0000_0000_0000; Console.WriteLine($"Before: {Convert.ToString(c, toBase: 2), 32}"); uint d = c >> 3; Console.WriteLine($"After: {Convert.ToString(d, toBase: 2).PadLeft(32, '0'), 32}"); // Output: // Before: 10000000000000000000000000000000 // After: 00010000000000000000000000000000
Feljegyzés
Az aláíratlan jobb shift operátorral logikai műszakot hajthat végre aláírt egész szám típusú operandusokon. A logikai eltolódás előnyben részesített. Kerülje a bal oldali operandus hozzárendelés nélküli típusra történő átírását, majd a shift művelet eredményét egy aláírt típusra.
Nem aláírt jobb műszakos operátor >>>
Az >>> operátor a jobb oldali operandus által meghatározott bitek számával jobbra tolja el a bal oldali operandusát. Arról, hogy a jobb oldali operandus hogyan határozza meg a műszakszámot, tekintse meg a shift operátorok szakaszának Shift count (Műszakok száma) szakaszát.
Az >>> operátor mindig logikai eltolódást hajt végre. Ez azt jelenti, hogy a magas sorrendű üres bitpozíciók mindig nullára vannak állítva, függetlenül a bal oldali operandus típusától. Az >> operátor aritmetikai eltolódást hajt végre (azaz a legjelentősebb bit értékét propagálja a rendszer a nagy sorrendű üres bitpozíciókba), ha a bal oldali operandus aláírt típusú. Az alábbi példa a negatív bal oldali operandus és >> operátorok közötti >>> különbséget mutatja be:
int x = -8;
Console.WriteLine($"Before: {x,11}, hex: {x,8:x}, binary: {Convert.ToString(x, toBase: 2), 32}");
int y = x >> 2;
Console.WriteLine($"After >>: {y,11}, hex: {y,8:x}, binary: {Convert.ToString(y, toBase: 2), 32}");
int z = x >>> 2;
Console.WriteLine($"After >>>: {z,11}, hex: {z,8:x}, binary: {Convert.ToString(z, toBase: 2).PadLeft(32, '0'), 32}");
// Output:
// Before: -8, hex: fffffff8, binary: 11111111111111111111111111111000
// After >>: -2, hex: fffffffe, binary: 11111111111111111111111111111110
// After >>>: 1073741822, hex: 3ffffffe, binary: 00111111111111111111111111111110
Logikai ÉS operátor >
Az & operátor kiszámítja a bitenkénti logikai ÉS annak integrál operandusait:
uint a = 0b_1111_1000;
uint b = 0b_1001_1101;
uint c = a & b;
Console.WriteLine(Convert.ToString(c, toBase: 2));
// Output:
// 10011000
Az operandusok esetében bool az operátor kiszámítja & az operandusok logikai ÉS operandusait. Az unary & operátor az operátor címe.
Logikai kizárólagos VAGY operátor ^
Az ^ operátor kiszámítja az integrál operandusainak bitenkénti logikai kizárólagos vagy más néven bitenkénti logikai XOR-ját:
uint a = 0b_1111_1000;
uint b = 0b_0001_1100;
uint c = a ^ b;
Console.WriteLine(Convert.ToString(c, toBase: 2));
// Output:
// 11100100
Az operandusok esetében bool az operátor kiszámítja ^ az operandusok logikai kizárólagosságát vagy operandusait.
Logikai VAGY operátor |
Az | operátor kiszámítja a bitenkénti logikai VAGY annak integrál operandusait:
uint a = 0b_1010_0000;
uint b = 0b_1001_0001;
uint c = a | b;
Console.WriteLine(Convert.ToString(c, toBase: 2));
// Output:
// 10110001
Operandusok esetén bool az operátor kiszámítja | az operandusok logikai VAGY operandusait.
Összetett hozzárendelés
Bináris operátor opesetén az űrlap összetett hozzárendelési kifejezése
x op= y
Egyenértékű azzal, hogy
x = x op y
Kivéve, hogy a x csak egyszer lesz kiértékelve.
Az alábbi példa az összetett hozzárendelés bitenkénti és shift operátorokkal való használatát mutatja be:
uint INITIAL_VALUE = 0b_1111_1000;
uint a = INITIAL_VALUE;
a &= 0b_1001_1101;
Display(a); // output: 10011000
a = INITIAL_VALUE;
a |= 0b_0011_0001;
Display(a); // output: 11111001
a = INITIAL_VALUE;
a ^= 0b_1000_0000;
Display(a); // output: 01111000
a = INITIAL_VALUE;
a <<= 2;
Display(a); // output: 1111100000
a = INITIAL_VALUE;
a >>= 4;
Display(a); // output: 00001111
a = INITIAL_VALUE;
a >>>= 4;
Display(a); // output: 00001111
void Display(uint x) => Console.WriteLine($"{Convert.ToString(x, toBase: 2).PadLeft(8, '0'), 8}");
Numerikus előléptetések miatt előfordulhat, hogy a művelet eredménye implicit módon nem konvertálható a típusra opT.x Ilyen esetben, ha op egy előre definiált operátor, és a művelet eredménye explicit módon átalakítható a típusraTx, az űrlap x op= y összetett hozzárendelési kifejezése egyenértékűx = (T)(x op y), kivéve, ha x csak egyszer lesz kiértékelve. Az alábbi példa ezt a viselkedést mutatja be:
byte x = 0b_1111_0001;
int b = x << 8;
Console.WriteLine($"{Convert.ToString(b, toBase: 2)}"); // output: 1111000100000000
x <<= 8;
Console.WriteLine(x); // output: 0
Operátorok műveleti sorrendje
Az alábbi lista bitenkénti sorrendbe sorolja a operátorokat, és a legmagasabb prioritástól a legalacsonyabbig vált:
- Bitenkénti komplementer operátor
~ - Shift operátorok
<<,>>és>>> - Logikai ÉS operátor
& - Logikai kizárólagos VAGY operátor
^ - Logikai VAGY operátor
|
Zárójelek ()használatával módosítsa az operátorok elsőbbsége által előírt kiértékelési sorrendet:
uint a = 0b_1101;
uint b = 0b_1001;
uint c = 0b_1010;
uint d1 = a | b & c;
Display(d1); // output: 1101
uint d2 = (a | b) & c;
Display(d2); // output: 1000
void Display(uint x) => Console.WriteLine($"{Convert.ToString(x, toBase: 2), 4}");
A C#-operátorok elsőbbségi szint szerint rendezett teljes listájáért tekintse meg a C# operátorok cikkének Operátorok elsőbbsége című szakaszát.
A műszak operátorainak műszakszáma
A x << count, x >> countés x >>> count kifejezések esetében a tényleges műszakszám az alábbi típustól x függ:
Ha a
xtípusaintvagyuint, akkor a jobb oldali operandus öt alacsonyrendű bitje határozza meg az eltolási számot. Ez azt jelent, hogy a műszakok száma (vagycount & 0x1F) alapjáncount & 0b_1_1111lesz kiszámítva.Ha a típus
xvagylongvagyulongaz, a jobb oldali operandus alsó hat bitje adja meg az eltolás számát. Ez azt jelent, hogy a műszakok száma (vagycount & 0x3F) alapjáncount & 0b_11_1111lesz kiszámítva.
Az alábbi példa ezt a viselkedést mutatja be:
int count1 = 0b_0000_0001;
int count2 = 0b_1110_0001;
int a = 0b_0001;
Console.WriteLine($"{a} << {count1} is {a << count1}; {a} << {count2} is {a << count2}");
// Output:
// 1 << 1 is 2; 1 << 225 is 2
int b = 0b_0100;
Console.WriteLine($"{b} >> {count1} is {b >> count1}; {b} >> {count2} is {b >> count2}");
// Output:
// 4 >> 1 is 2; 4 >> 225 is 2
int count = -31;
int c = 0b_0001;
Console.WriteLine($"{c} << {count} is {c << count}");
// Output:
// 1 << -31 is 2
Feljegyzés
Ahogy az előző példa is mutatja, a műszakművelet eredménye nem lehet nulla akkor is, ha a jobb oldali operandus értéke nagyobb, mint a bal oldali operandus bitjeinek száma.
Logikai operátorok számbavétele
Minden enumerálási típus támogatja a ~, &, |és ^ operátorokat. Az azonos enumerálási típusú operandusok esetében a rendszer logikai műveletet hajt végre az alapul szolgáló integráltípus megfelelő értékein. Például egy mögöttes típusú xenumerálási típus y esetén TU a x & y kifejezés ugyanazt az eredményt adja, mint a (T)((U)x & (U)y) kifejezés.
Általában bitenkénti logikai operátorokat használ a Flags attribútummal definiált enumerálási típussal. További információkért tekintse meg az Enumerálási típusok az Enumerálástípusok cikk bitjelölők szakaszát.
Operátorok túlterhelése
A felhasználó által definiált típus túlterhelheti a ~, <<, >>, >>>, &, |és ^ operátorokat. Ha egy bináris operátor túlterhelt, a megfelelő összetett hozzárendelési operátor is implicit módon túlterhelt. A C# 14-től kezdve a felhasználó által definiált típus explicit módon túlterhelheti az összetett hozzárendelési operátorokat a hatékonyabb megvalósítás érdekében. Egy típus általában túlterheli ezeket az operátorokat, mert az érték frissíthető a helyén, és nem kell új példányt kiosztani a bináris művelet eredményének tárolásához. Ha egy típus nem biztosít explicit túlterhelést, a fordító implicit túlterhelést hoz létre.
Ha egy felhasználó által definiált típus T túlterheli a <<, >>vagy >>> operátort, a bal oldali operandus típusának kell lennie T. A C# 10-es és korábbi verzióiban a jobb operandus típusának kell lennie int; a túlterhelt műszak operátorának jobb operandusának típusa bármelyik lehet.
C# nyelvspecifikáció
További információt a C# nyelvspecifikációjának alábbi szakaszaiban talál:
- Bitenkénti komplementer operátor
- Shift operátorok
- Logikai operátorok
- Összetett hozzárendelés
- Numerikus promóciók
- Nyugodt műszakra vonatkozó követelmények
- Logikai jobb műszakos operátor
- Felhasználó által definiált összetett hozzárendelés