„Rekord (adatszerkezet)” változatai közötti eltérés

Innen: Programozás Wiki
Ugrás a navigációhozUgrás a kereséshez
(→‎Python: namedtuple megemlítése)
 
(13 közbenső módosítás, amit 7 másik szerkesztő végzett, nincs mutatva)
5. sor: 5. sor:
 
A rekord mezőit a [[programozási nyelv]]ek szintjén általában nevükön keresztül lehet elérni, [[gépi kód]]ra fordítva azonban a rekord kezdőcímét meghatározó báziscímhez képest eltolással kerülnek elérésre.
 
A rekord mezőit a [[programozási nyelv]]ek szintjén általában nevükön keresztül lehet elérni, [[gépi kód]]ra fordítva azonban a rekord kezdőcímét meghatározó báziscímhez képest eltolással kerülnek elérésre.
  
A legtöbb [[Objektumorientált programozás|objektumorientált]] programozási nyelv az objektumokat belsőleg rekordokként kezeli, azzal a különbséggel, hogy az objektumok adatmezői mellett azok metódusainak címet is ez a speciális - a programozó számára nem látható és elérhető - rekord részeként tárolja, az ún. Virtuális Metódus-Táblában (VMT).
+
A legtöbb [[Objektumorientált programozás|objektumorientált]] programozási nyelv az objektumokat belsőleg rekordokként kezeli, azzal a különbséggel, hogy az objektumok adatmezői mellett azok metódusainak címet is ez a speciális - a programozó számára nem látható és elérhető - rekord részeként tárolja, az ún. [[Virtuális Metódus-Tábla (VMT)|Virtuális Metódus-Táblában (VMT)]].
  
 
==Rekordok használata különböző nyelvekben==
 
==Rekordok használata különböző nyelvekben==
===Turbo Pascal==
+
 
Turbo Pascal-ban a rekord logikailag összetartozó adatokat fog össze.
+
===C===
 +
<Source Lang="c">
 +
#include <stdio.h>
 +
 
 +
struct _datum {
 +
    int ev;  // mehetne akár "int ev, ho, nap;" szintaktikával is.
 +
    int ho;
 +
    int nap;
 +
};
 +
 
 +
int main() {
 +
    struct _datum datum = {2010,8,6};
 +
    printf("Ev : %d\n",datum.ev);
 +
    printf("Ho : %d\n",datum.ho);
 +
    printf("Nap: %d\n",datum.nap);
 +
    return 0;
 +
}
 +
</Source>
 +
 
 +
===Go===
 +
<!-- Go szintaxis híján C (hasonló) -->
 +
<Source Lang="c">
 +
package main
 +
import "fmt"
 +
 
 +
type TDatum struct {
 +
    ev, ho, nap int
 +
}
 +
 
 +
func main() {
 +
    datum := TDatum{2010,8,6}
 +
    fmt.Println("Ev :",datum.ev)
 +
    fmt.Println("Ho :",datum.ho)
 +
    fmt.Println("Nap:",datum.nap)
 +
}
 +
</Source>
 +
 
 +
===Pascal===
  
 
<Source Lang="Pascal">
 
<Source Lang="Pascal">
36. sor: 73. sor:
 
   ReadLn;
 
   ReadLn;
 
End.
 
End.
 +
</Source>
 +
 +
===Python===
 +
Ha az [[asszociatív tömb]] (a Python kifejezésével: ''szótár'')  nem jó megoldás számunkra, akkor [[osztály]]t definiálunk, amelyben kötöttek a [[változó]]k.
 +
 +
<Source Lang="python">
 +
#!/usr/bin/python
 +
 +
class datum(object):
 +
    def __init__(self, ev=None, ho=None, nap=None):
 +
        self.ev=ev
 +
        self.ho=ho
 +
        self.nap=nap
 +
 +
ma = datum(2010,8,6)
 +
 +
print ma.ev
 +
print ma.ho
 +
print ma.nap
 +
</Source>
 +
 +
Mivel a nyelv megengedi új [[attribútum]]ok hozzáadását saját [[osztály]]ok példányaihoz, lehetséges megkötés nélküli rekord-szerű osztályt is használni:
 +
<Source Lang="python">
 +
class struct(object):    #üres osztály
 +
    pass
 +
 +
datum = struct()
 +
datum.ev = 2010
 +
datum.ho = 9
 +
datum.nap = 3
 +
 +
szemely = struct()
 +
szemely.nev = "Pista"
 +
szemely.kor = 42
 +
szemely.kutyaja = "Bodri"
 +
szemely.kedvenc_etele = "paprikás krumpli"
 +
</Source>
 +
 +
A 2.6-os verzió óta lehetséges egy harmadik megközelítés is: a collections modul namedtuple metódusa segítségével olyan osztályokat hozhatunk létre, amelyek a beépített tuple adattípushoz hasonlóan működnek, de az egyes adattagokat rekordszerűen, név szerint is elérhetjük:
 +
<Source Lang="python">
 +
import collections
 +
 +
Datum = collections.namedtuple('Datum', ['ev','ho','nap'])
  
 +
datum = Datum(2010, 8, 6)  #inicializáció a felsorolás sorrendjében
 +
datum = Datum(nap=6, ho=8, ev=2010) #inicializáció tetszőleges sorrendben
 +
print datum.nap #elérés név szerint
 +
#kimenet: 6
 +
print datum[2] #elérés sorrend alapján
 +
#kimenet: 6
 +
print datum #teljes struktúra kiíratása
 +
#kimenet: Datum(ev=2010, ho=8, nap=6)
 
</Source>
 
</Source>
 +
 +
==Rekordok használatának célja, fizikai felépítés==
 +
 +
 +
A rekordok fontos feladatot látnak el, hiszen elemi adatokból (illetve [[rekurzió]]val már korábban létrehozott rekord szerkezetekből) építhetünk összetett adatszerkezeteket ily módon.
 +
A rekordok ezzel jobban modellezik a valós feladatok adatigényét és az elemi tagok összefogásával ez egy kezdeti lépés az [[Objektum|objektum orientált]] szemlélet [[egységbe foglalás]] fogalma felé.
 +
 +
 +
A rekordok használata tipikusan két fő területre osztható.
 +
A programon belüli használat esetén a korábban említett [[szó|szóhatárra]] illesztés nem okoz problémát. Ilyenkor annak használata ill. a használat módja a hatékonyság kérdése. A szóhatárra illesztéssel a [[memória]] igény növekszik, de a használat sebessége növekszik, hiszen a [[CPU]] kevesebb órajellel képes a szóhatáron található elemi adat olvasására/írására. Vagyis a nagyon nagy számban memóriában tárolt rekord esetén célszerű [[byte határra]] igazítani a rekord mezőit, ezzel memóriát takarítani meg.
 +
 +
 +
Mivel a szóhatár fogalom is egy elvonatkoztatás, pl. mást-mást jelent [[32 bites]] és [[64 bites]] környezetben, így a nem kizárólag egyetlen rendszeren belül használt rekordok esetén a mezők byte/egyéb határra illesztése alapvetően fontos döntés, amit dokumentálni kell a helyes használathoz.
 +
Ha pl. fileba írjuk a rekordokat vagy hálózaton át továbbítjuk azokat, akkor az azokat olvasó programnak fontos feladata, hogy a rekordok mezőinek fizikai méretét és formátumát valamint a mezők illesztését egyformán kezeljék.
 +
 +
[[Kategória:Adatszerkezetek]]

A lap jelenlegi, 2013. január 1., 11:48-kori változata

A rekord a legegyszerűbb adatszerkezetek egyike, amely két vagy több egymástól független és potenciálisan eltérő típusú változót (mezőt) foglal egyetlen egységbe. A rekord mezői a memóriában szigorúan egymást követően foglalnak helyet a rekordban történő felsorolásuk sorrendjében, bár szóhatárra igazítás alkalmazása esetén az egyes mezők között kitöltő (filler) adatterületek is jelen lehetnek, amelyek tartalma nem definiált. A rekord méretét a mezők és ezen kitöltő területek összege határozza meg.

A legtöbb programozási nyelv a beépítettek mellett megengedi saját rekordszerkezetek definiálását is a programozó számára, amelyhez tipikusan a rekord mezői nevének és típusának felsorolását követeli meg. A rekordok egymásba ágyazhatók - azaz egy rekord mezője maga is lehet egy rekord -, és egyes nyelvekben (pl. Pascal) lehetőség van alternatív ill. feltételes rekordszerkezet definiálására is, ami a rekord egy részének több eltérő mezőkészletként történő értelmezését is lehetővé teszi. Ebben az esetben a rekord mérete a a fix mezők ill. a legnagyobb alternatív mezőkészlet méretének összegével egyezik.

A rekord mezőit a programozási nyelvek szintjén általában nevükön keresztül lehet elérni, gépi kódra fordítva azonban a rekord kezdőcímét meghatározó báziscímhez képest eltolással kerülnek elérésre.

A legtöbb objektumorientált programozási nyelv az objektumokat belsőleg rekordokként kezeli, azzal a különbséggel, hogy az objektumok adatmezői mellett azok metódusainak címet is ez a speciális - a programozó számára nem látható és elérhető - rekord részeként tárolja, az ún. Virtuális Metódus-Táblában (VMT).

Rekordok használata különböző nyelvekben[szerkesztés]

C[szerkesztés]

#include <stdio.h>

struct _datum {
    int ev;  // mehetne akár "int ev, ho, nap;" szintaktikával is.
    int ho;
    int nap;
};

int main() {
    struct _datum datum = {2010,8,6};
    printf("Ev : %d\n",datum.ev);
    printf("Ho : %d\n",datum.ho);
    printf("Nap: %d\n",datum.nap);
    return 0;
}

Go[szerkesztés]

package main
import "fmt"

type TDatum struct {
    ev, ho, nap int
}

func main() {
    datum := TDatum{2010,8,6}
    fmt.Println("Ev :",datum.ev)
    fmt.Println("Ho :",datum.ho)
    fmt.Println("Nap:",datum.nap)
}

Pascal[szerkesztés]

Program Rekord;

Type TDatum = Record
                ev:String;
                ho:1..12;
                nap:1..31;
              End;

Var datum:TDatum; {egy TDatum típusú rekord létrehozása}

Begin
  {hivatkozás a rekord egyes mezőire}
  datum.ev:=2010;
  datum.ho:=7;
  datum.nap:=11;

  {illetve lekérdezés}
  With datum Do Begin
    WriteLn('Ev : ',ev);
    WriteLn('Ho : ',ho);
    WriteLn('Nap: ',nap);
  End;
  ReadLn;
End.

Python[szerkesztés]

Ha az asszociatív tömb (a Python kifejezésével: szótár) nem jó megoldás számunkra, akkor osztályt definiálunk, amelyben kötöttek a változók.

#!/usr/bin/python

class datum(object):
    def __init__(self, ev=None, ho=None, nap=None):
        self.ev=ev
        self.ho=ho
        self.nap=nap

ma = datum(2010,8,6)

print ma.ev
print ma.ho
print ma.nap

Mivel a nyelv megengedi új attribútumok hozzáadását saját osztályok példányaihoz, lehetséges megkötés nélküli rekord-szerű osztályt is használni:

class struct(object):    #üres osztály
    pass

datum = struct()
datum.ev = 2010
datum.ho = 9
datum.nap = 3

szemely = struct()
szemely.nev = "Pista"
szemely.kor = 42
szemely.kutyaja = "Bodri"
szemely.kedvenc_etele = "paprikás krumpli"

A 2.6-os verzió óta lehetséges egy harmadik megközelítés is: a collections modul namedtuple metódusa segítségével olyan osztályokat hozhatunk létre, amelyek a beépített tuple adattípushoz hasonlóan működnek, de az egyes adattagokat rekordszerűen, név szerint is elérhetjük:

import collections

Datum = collections.namedtuple('Datum', ['ev','ho','nap'])

datum = Datum(2010, 8, 6)  #inicializáció a felsorolás sorrendjében
datum = Datum(nap=6, ho=8, ev=2010) #inicializáció tetszőleges sorrendben
print datum.nap #elérés név szerint
#kimenet: 6
print datum[2] #elérés sorrend alapján
#kimenet: 6
print datum #teljes struktúra kiíratása
#kimenet: Datum(ev=2010, ho=8, nap=6)

Rekordok használatának célja, fizikai felépítés[szerkesztés]

A rekordok fontos feladatot látnak el, hiszen elemi adatokból (illetve rekurzióval már korábban létrehozott rekord szerkezetekből) építhetünk összetett adatszerkezeteket ily módon. A rekordok ezzel jobban modellezik a valós feladatok adatigényét és az elemi tagok összefogásával ez egy kezdeti lépés az objektum orientált szemlélet egységbe foglalás fogalma felé.


A rekordok használata tipikusan két fő területre osztható. A programon belüli használat esetén a korábban említett szóhatárra illesztés nem okoz problémát. Ilyenkor annak használata ill. a használat módja a hatékonyság kérdése. A szóhatárra illesztéssel a memória igény növekszik, de a használat sebessége növekszik, hiszen a CPU kevesebb órajellel képes a szóhatáron található elemi adat olvasására/írására. Vagyis a nagyon nagy számban memóriában tárolt rekord esetén célszerű byte határra igazítani a rekord mezőit, ezzel memóriát takarítani meg.


Mivel a szóhatár fogalom is egy elvonatkoztatás, pl. mást-mást jelent 32 bites és 64 bites környezetben, így a nem kizárólag egyetlen rendszeren belül használt rekordok esetén a mezők byte/egyéb határra illesztése alapvetően fontos döntés, amit dokumentálni kell a helyes használathoz. Ha pl. fileba írjuk a rekordokat vagy hálózaton át továbbítjuk azokat, akkor az azokat olvasó programnak fontos feladata, hogy a rekordok mezőinek fizikai méretét és formátumát valamint a mezők illesztését egyformán kezeljék.