Vezérlőpult
B2. Egész típusok és a túlcsordulás · Változók és típusok

B blokk · Változók és típusok · 2. tananyag

Egész típusok és a túlcsordulás

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.

2 tanóraEgészosztás és maradékTúlcsordulás élőben

Tanulási célok

1Miért nem elég egyetlen számtípus?

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:

BitekHá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.

2Az egésztípusok családja

TípusMéretTartományElőjeles?.NET-név
sbyte1 bájt−128 … 127igenSystem.SByte
byte1 bájt0 … 255nemSystem.Byte
short2 bájt−32 768 … 32 767igenSystem.Int16
ushort2 bájt0 … 65 535nemSystem.UInt16
int4 bájt−2 147 483 648 … 2 147 483 647igenSystem.Int32
uint4 bájt0 … 4 294 967 295nemSystem.UInt32
long8 bájtkb. ±9,2 trillióigenSystem.Int64
ulong8 bájt0 … kb. 18,4 trilliónemSystem.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:

UGYANAZ A 256 REKESZ — KÉTFÉLE BEOSZTÁS sbyte −128 0 127 negatív fél pozitív fél byte 0 128 255 az egész készlet a nulla fölött
256 érték mindkettőben — az sbyte a nulla köré, a byte a nullától felfelé 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
ℹ️ MINDEN OBJEKTUM (folytatás)

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.

Belefér vagy nem fér bele?

Döntsd el: az adott érték elfér-e az adott típusban? A táblázat segít!

1 / 8Pontszám: 0
…

3Melyiket mikor? — az ökölszabály

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árdonlongfájlméret bájtban, ezredmásodperces időbélyeg, világnépesség
nyers bájtadatot kezelszbytefájl tartalma, színkomponens (0–255)
minden másintpontszám, életkor, darabszám, számláló
💡 NE SPÓROLJ!

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.

4Műveletek egészekkel

Az alapműveletek: +, -, *, / — és egy ötödik, amely csak itt, az egészek világában igazán érdekes: a %.

Az egészosztás

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ék (%)

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);

Rövidítések

A „vedd elő, változtasd meg, tedd vissza” minta olyan gyakori, hogy a C# rövid alakot ad rá:

RövidítésUgyanaz, mintJelenté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.

5A túlcsordulás — amikor a doboz körbefordul

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.

ℹ️ KÉT VALÓS ESET

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”.

Mikor szól a fordító, és mikor nem?

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 — védőháló kérésre

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.

6Gyakori hibák

TünetMi 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észha 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ábanagyobb típus kell — vagy tényleg ekkora az érték?
A számláló hirtelen hatalmas negatív számnéma túlcsordulás futás közbengondold át a tartományt (long?), vagy kérj checked-et
DivideByZeroException futás közbenegész osztás nullávala nevezőt ellenőrizni kell — az eszközt a C blokk (feltételek) adja

7Gyakorlat — túlcsordulás a szemed előtt

  1. Új projekt: Console App, név: Egeszek, .NET 10.
  2. Írasd ki a határokat: int.MaxValue, int.MinValue, byte.MaxValue, long.MaxValue. Nézd meg, tényleg akkorák-e, mint a 2. szakasz táblázatában!
  3. Gépeld be a túlcsordulás-példát az 5. szakaszból. Tegyél töréspontot a 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.
  4. Tedd az egészet checked { } blokkba, futtasd újra — most kivételt kapsz. Olvasd el az üzenetét!
  5. Írj perc-átszámítót: az 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.)
  6. Commitold a kész gyakorlatot (Egesz tipusok es tulcsordulas gyakorlat).
✅ ELLENŐRZŐ PONT

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.

8Feladatok

Gyakorló feladatok

⭐ alap · ⭐⭐ haladó · ⭐⭐⭐ kihívás

B2.1⭐

Í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?

B2.2⭐

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

B2.3⭐⭐

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.)

B2.4⭐⭐

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?

B2.5⭐⭐⭐

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?

9Önellenőrző kvíz

Ellenőrizd magad!

Minden kérdésnél egy válasz helyes. A végén pontszámot kapsz.

10Fogalomtár

FogalomJelentés
bit / bájta 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 / MaxValuea típus beépített határértékei: int.MaxValue
egészosztásegé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ásrö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
checkedblokk, amelyben a túlcsordulás kivételt dob (kivételek: K blokk)

11Összegzés

  1. Az egésztípus doboz mérettel: 1–8 bájt, és a bitek száma szabja meg a tartományt (8 bit = 256 érték). Az u előtag: ugyanannyi érték, 0-tól tolva.
  2. Alapértelmezés: int (±2,1 milliárd). long-ot nagy értékekhez, byte-ot nyers adathoz — mást csak indokkal.
  3. A határokat a típus tudja: int.MaxValue, byte.MaxValue — nem kell fejből.
  4. Egész / egész = egész — a törtrész levágódik; a % a maradék. A / + % páros az átszámítások (óra/perc) svájcibicskája.
  5. Rövidítések: a += 5, a++ — a C blokk ciklusaiban napi eszköz lesz.
  6. A túlcsordulás némán körbefordítja az értéket (kilométeróra-effektus); a konstans hibát a fordító fogja (CS0031), a futásidejűt a checked — vagy te.