A kulcsszavak mellett az operátorok alkotják minden programozási nyelv gerincét. Ezek a szimbólumok műveleteket határoznak meg. A műveletek nem minden típus esetén értelmezettek.
Alap műveleti operátorok
Az alap műveleti operátorok szám típusok (egészek, float, decimal, double) esetén értelmezettek.
- + összeadás, összefűzés
- – kivonás
- * szorzás
- / osztás
- % maradékos osztás. Eredménye az osztás elvégzésekor keletkező maradék.
Bitenkénti logikai operátorok
A bitenkénti operátorok a Boole algebra alapműveletei szerinti műveleteket valósítanak meg. A műveletek csak egész számok esetén értelmezhetőek. Lebegőpontos és Decimal típus esetén fordítási hibát fogunk kapni.
- ~ bitenkénti negáció. Előjeles számtípusok esetén, ha a szám pozitív, akkor érdekes eredményt ad vissza negálás után, mivel az előjelbitet is negálja.
A negatív előjelű számokat pedig a program kettes komplemens alaknak érzékeli. - | bitenkénti VAGY (OR)
- & bitenkénti ÉS (AND)
- ^ bitenkénti KIZÁRÓ VAGY (XOR)
- << Biteltolás balra. A kifejezés jobb oldalán álló szám határozza meg az eltolás mértékét.
- >> Biteltolás jobbra. A kifejezés jobb oldalán álló szám határozza meg az eltolás mértékét.
Logikai operátorok
A logikai operátorok a program futásának logikai szervezésében vesznek részt. Ezen operátorok jellemzője, hogy bool típust adnak vissza eredményként.
- ! tagadás, negáció
- == egyenlőség
- != egyenlőség tagadása
- || VAGY művelet
- && ÉS művelet
- < Kisebb, mint művelet
- > Nagyobb, mint művelet
Értékadó operátorok
A C-szerű nyelvek esetén a sima egyenlőségjeles értékadás mellett vannak speciális értékadó operátorok, melyek segítségével időt spórolhatunk meg. Ezek az operátorok: *= /= %= += -= <<= >>= &= ^= |= Ezen operátorok azt teszik, hogy az előttük lévő művelet elvégzésével értéket adnak a változónak.
int x = 1;
x += 3;
A fenti kódrészlet azt eredményezi, hogy az eredetileg 1 kezdőértékkel ellátott x változó értékét megnöveli 3-mal. Lényegében az alábbi kódrészletet egyszerűsíti le a fenti példában a += operátor használata:
int x = 1;
x = x + 3;
Értéknövelő-és csökkentő operátorok
Más szóval inkrementáló és dekrementáló operátorok. A ++ operátor eggyel növeli, míg a — operátor eggyel csökkenti a kifejezés értékét. Állhatnak a kifejezés előtt és után is, azonban így módosul a hatásuk. Amennyiben az operátorok valamelyike egy kifejezés előtt áll, az azt jelenti, hogy a további műveletek elvégzése előtt fog megtörténni a növelés vagy a csökkenés. Amennyiben kifejezés után áll, akkor a csökkentés vagy növelés lesz utoljára végrehajtva.
A kérdőjel kettőspont operátor
A C-szerű nyelvek egyetlenegy három operandusú operátora. Működését tekintve leginkább egy egyutasításos if elágazásra hasonlít(lásd feltételes vezérlési szerkezeteken belül az if szerkezet).
Ez az operátor azt csinálja, hogy amennyiben a kérdőjel előtt meghatározott kifejezés értéke igaz, akkor a kérdőjel után lévő utasítás fog végrehajtódni. Amennyiben hamis, akkor a kettőspont után lévő rész fog végrehajtódni.
int a = 1;
int b = 2;
//a változóba a "b nagyobb, mint a" szöveg kerül, mivel a feltétel nem igaz
string nagyobb = a > b ? "a nagyobb, mint b" : "b nagyobb, mint a";
Tagkiválasztó operátor
C# esetén osztályok és névterek tagjainak kiválasztására a . operátor használatos. Ezt nevezzük tagkiválasztó operátornak.
Sizeof operátor
Megjelenését tekintve a sizeof operátor könnyen összekeverhető egy függvénnyel, azonban operátorról van szó. Ezen operátor a paraméterként kapott típusnak a méretét adja vissza byte-ban. Csak érték típusok esetén használható, eredetileg csak unsafe kontextusban volt elérhető, azonban a C# 2.0-ás változatától használható unsafe kontextuson kívül is.
Typeof operátor
A typeof operátor egy adott változó típusát kérdezi le és egy Type objektumot ad vissza. Ezen információk igen hasznosak tudnak lenni, mivel komoly önismereti képességekkel lehet vele felruházni a programjainkat. Erről a későbbi fejezetek kapcsán részletesen lesz szó.
Az alábbi példakód néhány operátor használatát mutatja be:
using System;
namespace PeldaOperatorok
{
class Program
{
static void Main(string[] args)
{
//17 lesz az eredmény
var kifejezes = 3 * 6 - 2 + 1 % 2;
Console.WriteLine(kifejezes);
//így már helyes és az eredmény 1
var kifejezes2 = (3 * 6 - 2 + 1) % 2;
Console.WriteLine(kifejezes2);
Console.Write("A long tipus merete byte-ban: ");
//8
int bytes = sizeof(long);
Console.WriteLine(bytes);
//binárisan
// 0000_0001 << 6 => 0100_0000
int kettohat = 1 << 6;
Console.WriteLine(kettohat);
//binárisan
//1111_0000 >> 2 => 0011_1100
int balra = 240 >> 2;
Console.WriteLine(balra);
//true
bool logika = 33 > 22;
//false
bool logika2 = (33 / 2) == 0;
Console.WriteLine(logika);
Console.WriteLine(logika2);
string szoveg = "ez egy";
szoveg += " szép mondat.";
Console.WriteLine(szoveg);
int x = 3;
//4 lesz, mert inkrementálás után ír ki
Console.WriteLine(++x);
x = 3;
//3 lesz, mert kiír és csak utána inkrementálja a változót
Console.WriteLine(x++);
//4 lesz, mert itt már a növelt értéket látjuk
Console.WriteLine(x);
Console.ReadKey();
}
}
}
A program kimenete:
17
1
A long tipus merete byte-ban: 8
64
60
True
False
ez egy szép mondat.
4
3
4
Zárójelek
- A kapcsos
{ }
zárójeleket C-szerű nyelvek esetén blokk zárójeleknek nevezik, mivel minden egynél több utasítást tartalmazó vezérlési blokk esetén a használatuk kötelező. - A tömb adattípusok és az objektum indexelők jelölésére a szögletes
[]
zárójelek használatosak. - A sima zárójelek
()
C# esetén kifejezések zárójelezésén kívül vezérlési ciklusokban is használtak.
Idézőjelek
Az aposztróf ''
jelek karakterek megadására használtak, míg az idéző ""
jelek szövegek megadására szolgálatosak.
Műveleti sorrend
Az operátorok alkalmazásánál fontos tudni, hogy a kifejezések kiértékelése esetén adódhat, hogy két operátor azonos precedencia szinttel bír. Ekkor a fordító nem tudja eldönteni helyesen, hogy melyiket kellene előbb végrehajtania a generált kódban, így előfordulhat olyan eset, hogy nem a helyes kimenetet kapjuk. Az ilyen esetek elkerülése végett ajánlott alkalmazni a komplex, összetett kifejezések esetén a zárójeleket.
Az operátorok kiértékelése a szokványos balról jobbra helyett, jobbról balra sorrendben történik, mint C/C++ programozási nyelvek esetén.
A fenti kifejezes változó kiértékelésénél az eredmény azért lesz 17, mivel precedencia szerint elvégzi a fordító a műveleteket, azonban a maradékos osztás a művelet végzés szabályai miatt hamarább lefut, így az egy maradékosan osztva kettővel egyet ad vissza. Majd ehhez jön hozzá a többi művelet eredménye precedencia szerint.
A kifejezés2 kiértékelésekor zárójelekkel a fordító rá van kényszerítve, hogy a zárójelben szereplő kifejezést értékelje ki a maradékos osztás második operandusának. Így az eredmény egy lesz, mivel a 17 maradéka kettővel osztás után egy lesz.
Az operátor kiértékelési sorrendet az alábbi táblázat foglalja össze:
Szint | Művelettípus | Műveletek |
---|---|---|
1 | Elsődleges | x.y f(x) a[x] x++ x– new typeof checked unchecked |
2 | Egyváltozós | + – ! ~ ++x –x (T)x |
3 | Multiplikatív | * / % |
4 | Additív | + – |
5 | Shift | << >> |
6 | Viszonyító | < > <= >= is as |
7 | Egyenlőségi | == != |
8 | Bitenkénti ÉS | & |
9 | Bitenkénti KIZÁRÓ VAGY | ^ |
10 | Bitenkénti VAGY | | |
11 | Logikai ÉS | && |
12 | Logikai VAGY | || |
13 | Feltételes | ? : |
14 | Értékadás | = *= /= %= += -= <<= >>= &= ^= |= |