B blokk · Változók és típusok · 2. tananyag
Az int
csak egy tagja egy nyolcfős családnak. Minden doboznak mérete van —
és ami nem fér bele, az nem „kilóg”, hanem körbefordul. 2014-ben
a YouTube számlálója pont így tört el a Gangnam Style alatt — a fejezet végén
pontosan érted majd, mi történt.
byte…long) és a tartományukat.int az alapértelmezés./) és a maradékot (%).+=, ++, …).checked.A memória rekeszekből (bájtokból) áll, és minden változó annyi rekeszt foglal, amekkora a típusa. Egy bájt 8 bit — 8 darab 0/1 —, ami összesen 2⁸ = 256 különböző értéket tud megkülönböztetni. Több bájt = több bit = nagyobb tartomány:
| Bitek | Hány érték fér el? |
|---|---|
| 8 (1 bájt) | 256 |
| 16 (2 bájt) | 65 536 |
| 32 (4 bájt) | kb. 4,3 milliárd |
| 64 (8 bájt) | kb. 18 trillió |
A kérdés csak az: a rendelkezésre álló értékkészletet hova tesszük a számegyenesen? Ha csak nemnegatív számok kellenek, mehet 0-tól felfelé; ha negatívak is, a készlet fele a nulla alá kerül. Ebből születik a típuscsalád.
| Típus | Méret | Tartomány | Előjeles? | .NET-név |
|---|---|---|---|---|
sbyte | 1 bájt | −128 … 127 | igen | System.SByte |
byte | 1 bájt | 0 … 255 | nem | System.Byte |
short | 2 bájt | −32 768 … 32 767 | igen | System.Int16 |
ushort | 2 bájt | 0 … 65 535 | nem | System.UInt16 |
int | 4 bájt | −2 147 483 648 … 2 147 483 647 | igen | System.Int32 |
uint | 4 bájt | 0 … 4 294 967 295 | nem | System.UInt32 |
long | 8 bájt | kb. ±9,2 trillió | igen | System.Int64 |
ulong | 8 bájt | 0 … kb. 18,4 trillió | nem | System.UInt64 |
Az u előtag (unsigned — előjel nélküli) azt jelenti:
ugyanannyi rekesz, máshová tolva. A byte
és az sbyte egyaránt 256 értéket tud — csak máshogy
osztja be:
A pontos határokat sosem kell fejből tudni — a típus maga megmondja:
Console.WriteLine(int.MaxValue); // 2147483647 Console.WriteLine(int.MinValue); // -2147483648 Console.WriteLine(byte.MaxValue); // 255 Console.WriteLine(long.MaxValue); // 9223372036854775807
A MaxValue-t a típus nevén keresztül érjük el,
nem egy változón. Hogy ez pontosan miért így működik, a H blokkban áll össze
(statikus tagok) — most elég a minta: típus.MaxValue.
Döntsd el: az adott érték elfér-e az adott típusban? A táblázat segít!
Alapértelmezés: int. Gyors, kényelmes,
a C# minden egész literált eleve int-nek tekint — és
±2,1 milliárd az esetek túlnyomó részére elég.
| Mikor térj el? | Mire? | Példa |
|---|---|---|
| az érték túlnőhet ±2,1 milliárdon | long | fájlméret bájtban, ezredmásodperces időbélyeg, világnépesség |
| nyers bájtadatot kezelsz | byte | fájl tartalma, színkomponens (0–255) |
| minden más | int | pontszám, életkor, darabszám, számláló |
Kezdő hiba osztálylétszámhoz byte-ot választani, mert
„úgyis elég”. Ne tedd: az int a bevett alapértelmezés,
a többi típus indoklással kerül elő. A memóriaspórolásnak majd
tömböknél (E blokk) lesz értelme — egyetlen változónál soha.
Az alapműveletek: +, -,
*, / — és egy ötödik, amely
csak itt, az egészek világában igazán érdekes: a %.
Egész osztva egésszel egészet ad — a törtrész nem kerekedik, hanem levágódik:
Console.WriteLine(7 / 2); // 3 — nem 3.5! Console.WriteLine(9 / 10); // 0 Console.WriteLine(100 / 7); // 14
A % (maradékképzés, angolul modulo) azt adja meg,
mennyi marad az osztás után:
Console.WriteLine(7 % 2); // 1 Console.WriteLine(100 % 7); // 2
A / és a %
párban hihetetlenül hasznos — klasszikus példa az átszámítás:
int osszesPerc = 127; int ora = osszesPerc / 60; // 2 — hány TELJES óra int perc = osszesPerc % 60; // 7 — mennyi marad percben Console.WriteLine(ora); Console.WriteLine(perc);
A „vedd elő, változtasd meg, tedd vissza” minta olyan gyakori, hogy a C# rövid alakot ad rá:
| Rövidítés | Ugyanaz, mint | Jelentése |
|---|---|---|
a += 5; | a = a + 5; | növeld 5-tel |
a -= 2; | a = a - 2; | csökkentsd 2-vel |
a *= 3; | a = a * 3; | szorozd 3-mal |
a /= 2; | a = a / 2; | oszd 2-vel (egészosztás!) |
a++; | a = a + 1; | növeld eggyel (increment) |
a--; | a = a - 1; | csökkentsd eggyel (decrement) |
Az a++-t a C blokkban, a ciklusoknál fogod naponta
látni — barátkozz vele már most.
Mi történik, ha a legnagyobb tárolható értékhez hozzáadunk egyet? A doboz nem tud „kicsit nagyobb lenni” — az érték átfordul a tartomány másik végére, mint a régi kilométeróra 999 999 után:
int szamlalo = int.MaxValue; Console.WriteLine(szamlalo); // 2147483647 szamlalo = szamlalo + 1; // csendben körbefordul! Console.WriteLine(szamlalo); // -2147483648
Ez a túlcsordulás (overflow) — és a legveszélyesebb benne, hogy alapbeállításban néma: se hibaüzenet, se kivétel, a program vidáman számol tovább az értelmetlen értékkel.
YouTube, 2014: a Gangnam Style nézettsége átlépte a
2 147 483 647-et — a 32 bites számláló nem bírta, a YouTube 64 bitesre
(long) váltott.
Pac-Man, 256. pálya: a pályaszámláló 8 bites; a 255. után
körbefordul, és a képernyő fele szeméthalommá esik szét — ez a híres
„kill screen”.
Ha a túl nagy érték már a kódban látszik, a fordító elkapja:
byte kicsi = 300; // ⛔ CS0031: Constant value '300' cannot // be converted to a 'byte'
Ha viszont az érték futás közben csordul túl (mint fent a
szamlalo), a fordító nem láthatja előre — az már a
te felelősséged.
A checked blokkon belül a túlcsordulás nem néma többé:
checked { int szamlalo = int.MaxValue; szamlalo = szamlalo + 1; // 💥 OverflowException — a program jelez! }
A kivételekről (mi ez a 💥, és hogyan kapjuk el) a K blokkban tanulunk — most annyi a lényeg: van mód rá, hogy a néma körbefordulás helyett hangos hibát kérj.
| Tünet | Mi történt? | Mit tegyél? |
|---|---|---|
7 / 2 eredménye 3, „pedig 3,5-nek kéne lennie” | egészosztás: egész / egész = egész | ha törtrész kell, az a B3 témája (lebegőpontos típusok) |
CS0031: Constant value '300' cannot be converted to a 'byte' | a literál nem fér a típus tartományába | nagyobb típus kell — vagy tényleg ekkora az érték? |
| A számláló hirtelen hatalmas negatív szám | néma túlcsordulás futás közben | gondold át a tartományt (long?), vagy kérj checked-et |
DivideByZeroException futás közben | egész osztás nullával | a nevezőt ellenőrizni kell — az eszközt a C blokk (feltételek) adja |
Egeszek, .NET 10.int.MaxValue,
int.MinValue, byte.MaxValue,
long.MaxValue. Nézd meg, tényleg akkorák-e, mint a
2. szakasz táblázatában!szamlalo = szamlalo + 1;
sorra, és a Locals ablakban (B1!) nézd végig, ahogy a
2147483647-ből −2147483648 lesz. F10 — és megtörtént.checked { } blokkba, futtasd újra —
most kivételt kapsz. Olvasd el az üzenetét!osszesPerc = 4321 értékből
számold ki /-vel és %-kal,
hány óra és hány perc. (Ellenőrzés fejben: 4321 / 60 = 72 óra, marad 1 perc.)Egesz tipusok es tulcsordulas gyakorlat).Láttad a Locals-ban a körbefordulást, a checked
kivételt dobott, és a perc-átszámítód 72 órát és 1 percet írt ki.
⭐ alap · ⭐⭐ haladó · ⭐⭐⭐ kihívás
Írd le fejből: melyik egésztípus hány bájt, és mettől meddig tart? Utána
ellenőrizd géppel a MinValue/MaxValue
kiírásával — hol tévedtél?
Mit ír ki? Előbb papíron (fejben futtatás!), aztán géppel:
17 / 5 · 17 % 5 ·
100 / 7 · 100 % 7 ·
5 / 10 · 5 % 10
Másodperc-átszámító: a masodperc = 3671 változóból
számold ki, hány óra, hány perc és hány másodperc. (Tipp: kétszer kell
osztani és maradékot képezni. Ellenőrzés: 1 óra 1 perc 11 másodperc.)
Számold ki papíron, mit ír ki — aztán ellenőrizd:
int a = 2147483645; a += 4; Console.WriteLine(a);
Mi történne ugyanezzel checked blokkban? És ha az
a long lenne?
Nézz utána az egyik valós esetnek (YouTube-számláló vagy Pac-Man kill screen), és írd le 4-5 mondatban: milyen típus volt a számláló, mekkora volt a tartománya, és pontosan mi történt, amikor betelt. Melyik C#-típussal előzted volna meg?
Minden kérdésnél egy válasz helyes. A végén pontszámot kapsz.
| Fogalom | Jelentés |
|---|---|
| bit / bájt | a memória legkisebb egysége (0/1) / 8 bit együtt — 256 lehetséges érték |
| tartomány (range) | a típusban tárolható legkisebb és legnagyobb érték közötti sáv |
| előjeles / előjel nélküli (signed/unsigned) | a tartomány a nulla körül / a nullától felfelé helyezkedik el |
MinValue / MaxValue | a típus beépített határértékei: int.MaxValue |
| egészosztás | egész / egész = egész; a törtrész levágódik (7 / 2 → 3) |
maradékképzés (%, modulo) | az osztás maradéka (7 % 2 → 1) |
| összetett értékadás | rövidítés: a += 5 ⟺ a = a + 5; a++ ⟺ a = a + 1 |
| túlcsordulás (overflow) | a tartomány átlépésekor az érték körbefordul — alapból némán |
checked | blokk, amelyben a túlcsordulás kivételt dob (kivételek: K blokk) |
u
előtag: ugyanannyi érték, 0-tól tolva.int (±2,1 milliárd).
long-ot nagy értékekhez,
byte-ot nyers adathoz — mást csak indokkal.int.MaxValue,
byte.MaxValue — nem kell fejből.% a maradék. A / +
% páros az átszámítások (óra/perc) svájcibicskája.a += 5, a++ —
a C blokk ciklusaiban napi eszköz lesz.checked — vagy te.