Programozás

Verzió: 1.0
Perényi Zsigmond
2000. február 28.

1. Bevezetés

1.1 A hardver és a szoftver jelentőségének változása

 
A számítástechnika hajnalában (1950-es évek) a hardvernek sokkal nagyobb volt a jelentősége, hiszen akkoriban magának a számítógépnek, mint szerkezetnek az öszzeállítása és működtetése jelentette a legnagyobb problémát. Akkoriban csak a hozzáértő szakemberek jutottak számítógép közelébe, így nem is volt cél, hogy kimondottan felhasználóbarát programokat írjanak.

Ahogy a technológia fejlődött, úgy a számítógép (a hardver) egyre megbízhatóbbá és olcsóbbá vált, így fokozatosan eljutott a kisebb cégekhez, s mára a hétköznapi emberig. Tehát a felhaszánlók köre megváltozott: profi szakemberek helyett most gyermekek, tanárok, orvosok, titkárnők, pékek, és takarítónők ülnek a gépek előtt, és minden joggal elvárják, hogy a számítógépet a saját különböző céljaikra a lehető legkényelmesebben lehessen felhasználni, a legkevesebb tanulással.

De mivel a számítógép hardvere csupán egy halom vas és műanyag, ami önmagától semmi értelmes dologra nem képes, a fent említett hatalmas felhasználói igényeket a programoknak (szoftvereknek) kell biztosítani. A számítástechnika története során tehát a hangsúly áthelyeződött a hardverről a szoftverre. Mára a szoftvergyártás (vagyis a programozás) jelentős iparággá nőtt.


1.2 A hardver és a szoftver kapcsolata: a számítógépek működése

1.2.1 Számítógépek

A számítástechnika fejlődése során számtalan különböző próbálkozás született arra, hogy miként lehetne a számításokat valamilyen géppel elvégeztetni. Mindközűl a Neumann-elvű gépek bizonyultak a legsikeresebbnek, a modern elektronika pedig megteremtette a digitális technológia alkalmazásának műszaki feltételeit.

A Neumann-elvű számítógépek lényege, hogy mind az adatok, mind az elvégzendő feladat (kódolt utasítások formájában) a memóriában van eltárolva. A digitális szó azt jelenti, hogy mindent számokként ábrázolunk, és azokat dolgozzuk fel.

A ma körülöttünk lévő számítógépek mind ilyen elven működnek, legyen az PC, Macintosh, nagygép, laptop, palmtop, vagy akár mobiltelefon, CD játszó, vagy mikrohullámú sütő processzora. Ezért ettől a ponttól számítógépen Neumann-elvű digitális számítógépet értünk.

1.2.2 A programvégrehajtás menete

A memória
minden rekesze sorszámmal (címmel) rendelkezik, így a memória bármely rekesze megcímezhető, és így a processzor által közvetlenül elérhető.
A CPU (központi feldolgozó és vezérlő egység, a ,,processzor'')
feladata, hogy végighaladjon a program utasításain, és az előírt sorrendben végrehajtsa azokat. Az utasítások műveleteket végeznek az adatokon.
  1. a soron következő utasítás gépi kódja lehívódik a memórióból a CPU-ba
  2. dekódolás: megállapítja, hogy milyen adatokkal milyen műveletet kell elvégezni
  3. beolvassa a memóriából a szükséges adatokat, végrehajtja az előírt utasítást,

  4. az eredményt pedig visszaírja a memóriába 


1.3 A programozás alapjai

1.3.1 A gépi kód

A memóriában az utasítások kódolva tárolódnak, az adott processzor ,,nyelvén'' (a különböző processzoroknak különböző utasításai vannak. Utasítás alatt itt egyszerű, elemi utasítást kell érteni, pl. 2 szám összeadása, szorzása, egy szám másolása egyik memóriarekeszből a másikba... ). Minden utasításnak van egy kódja (ez lényegében egy szám). Az adott utasításhoz meg kell adni, hogy milyen adatokkal számol, pl. az általa használt adatok memóriacímét (azt a sorszámot, amely memória rekeszben elhelyezkedik). Így lehet a programot számokkal kódolni. Az így kapott kód a gépi kód. A programozás tehát lényegében ennek a gépi kódnak a megalkotása.

1.3.2 Programozási nyelvek, fordító/értelmező

Ez természetesen nagy odafigyelést igénylő, fáradtságos munka, amit nehéz megtanulni, könnyű elhibázni. Ezért már korán rájöttek, hogy a programozó munkáját minél jobban meg kell könnyíteni. Ennek érdekében programozási nyelveket dolgoztak ki, hogy ne számokkal kelljen programozni, hanem sokkal emberközelibb módon, olyan nyelven, amelyben számok (kódok és címek) helyett angol szavak szerepelnek. Egy ilyen nyelvet azonban nem ,,ért meg'' a gép, ezért ezt le kell fordítani a gép nyelvére. Ehhez szükség van egy olyan segédprogramra, amely az általunk megírt programot gépi kóddá alakítja (ez a fordító, compiler), vagy lépésenként végrehajtja (ez az értelmező, interpreter).
 
 
fordító (compiler) értelmező (interpreter)
jellemzője a program forrásszövegéből egy gépi kódú, futtatható programot (pl. EXE) állít elő, vagyis a programot lefordítja a gép nyelvére a program forrásszövegét sorról sorra értelmezi, ellenőrzi, és (ha tudja) végrehajtja
szintaktikai (alaki) hibák kiszűrése fordítási időben (+) futási időben (-)
az elkészült program végrehajtási sebessége gyorsabb (+) lassabb (-)
a program hordozhatósága rosszabb (-) jobb (+)
a fejlesztés körülményessége nehézkesebb (-) egyszerűbb (+)

1.3.3 Programozási hibák, hibakeresés

Természetesen egy magas szintű nyelven írt program írása közben is véthetünk hibákat. Ez lehet:


1.4 A programozás módszereinek változása

A számítástechnika története során a programok készítésének módszerei és eszközei is fejlődtek - könnyebbé váltak.
A főbb állomások:


1.5 Programozási nyelvek

1.5.1 Csoportosításuk, jellemzésük

A számítástechnikában használatos nyelveket a nyelv által megoldandó probléma alapján 2 nagy csoportra oszthatjuk: A nyelv absztrakciós szintje alapján:
  • alacsony szintű nyelvek

  • nehezebb a programírás, de a lefordítandó program közelebb áll az gép nyelvéhez (a gépi kódhoz), így nehezen hordozható (más típusú gépekre), viszont  több beleszólásunk van a gépközeli dolgokba… pl. assembly
  • magas szintű nyelvek

  • könnyebb programot írni (pontosabban egy emberközeli probléma megfogalmazása könnyebb). A nyelv által nyújtott kényelm és az gép utasításkészlete közötti űrt a fordító/értelmező programnak kell áthidalnia. pl. Java

    1.5.2 A fontosabb programnyelvek


    A ma is élő, legelterjedtebb általános nyelvek: Érdekességképpen néhány régebbi programnyelv, amelyek elterjedtek voltak, de ma már csak elvétve találkozni velük:

    2. Adatok

    Mivel a programok utasításai adatokon dolgoznak, ismerkedjünk meg először ezekkel!

    Minden adattípusnál meg kell nézni, hogy milyen értékeket képes tárolni, hogyan ábrázolja a számítógép, és végül milyen műveleteket végezhetünk velük.

    2.1 Elemi (egyszerű) adattípusok

    2.1.1 Logikai (boolean) típus

    2.1.2 Numerikus (számok) típusok

    2.1.2.1 Egész, (fixpontos,) integer típus

    Ábrázolása kettes számrendszerben történik. Egy kettes számrendszerbeli számjegy - egy bit.
    Az ábrázolható számtartomány attól függ, hogy hány biten (n) történik a tárolás: Például egy n=16 bites előjeles egész esetében ez -215..215-1, vagyis -32768..32785.
    A mai gépek általában 8, 16, 32, 64 biten tárolják az egész számokat.

    2.1.2.2 Valós (lebegőpontos) típus

    Gépi ábrázolása normál alakban:  Például:  0.00123 = 0.123 * 10-2  (megadása 0.123e-2)

     Műveletek: +  -  *  /
    Összehasonlítás: a kerekítések és az ábrázolási pontatlanságok miatt használjuk az |a - b| < epsilon formulát!

    2.1.3 Alfabetikus (betű alapú) típusok

    2.1.3.1 Karakter (character) típus

    Karakterkonstans: aposztrófok között, pl. : 'c', '\n' (az utóbbi az új sor karakter)

    2.1.3.2 String (szöveg) típus

    Ábrázolása: karaktertömb/karakterfüzér.

    Stringkonstans: dupla aposztrófok között: "Ez itt egy sor\n"

     
    2.2 Összetett adatok

    2.2.1 Tömb

    Adott számú (általában azonos típusú) adat együttese.

    Dimenzió szerint:

    Például:

    Indexelés:

    A tömb minden elemének van egy sorszáma (ezt indexnek nevezzük). A indexelés (vagyis a sorszámozás) általában 0-val kezdődik. Az egyes elemeket úgy érhetjük el, ha a tömb neve után szögletes zárójelben megadjuk indexüket: a t tömb második eleme t[2] (a fenti példában t[2] értéke 0). Tehát egy t nevű n elemű tömb első eleme t[0], utolsó eleme t[n-1]. Az indexeléssel a tömbelemek úgy használhatók, mint a közönséges változók.

    2.2.2 Rekord/struktúra

    Több, különböző títpusú adat együttese. Az összegyűjtött adatok a rekord/struktúra mezőit képzik.

    Például egy személy adatai:
    mező neve típus
    nev string
    szuletesiEv integer
    vanErettsegije boolean

    Az egyes mezőkre általában ponttal elválasztva hivatkozunk, pl. ha az ember egy fenti személy típusú változó, akkor az adott ember nevét jelentő mező: ember.nev

    2.2.3 Objektum

    A rekordok/struktúrák továbbfejlesztése: az adattagokon (adatmezőkön) kívül tagfüggvényeket (metódusokat) is tartalmaznak.


    3. Algoritmikus programozás

    3.1 Algoritmus

    Az algoritmus olyan pontos előírás, amely megmondja, hogy egy adott típushoz tartozó összes feladat (problémaosztály) megoldásához milyen műveleteket kell meghatározott sorrendben elvégezni (vagyis pontosan megmondja, hogy miként kell megoldani a problémát).
    Kívánalmak: Az egyes lépésekben elvégezhető műveletek Neumann-elvű számítógépek esetében: Leírása:


    3.2 Az értékadás

    Elemi művelet, amely általában azonos típusú adatok között használható. Segítségével valamely változóhoz új értéket rendelhetünk. Általános alakja:
    változó = kifejezés
    Olvasd: változó legyen egyenlő kifejezés.
    Jelentése: először a jobb oldali kifejezés kiértékelődik, majd az eredmény betöltődik a bal oldalon lévő változóba. A kiértékelendő kifejezés általában tetszőlegesen bonyolult lehet, és tartalmazhat: Pl:
    z = y + 2*tan(x)
    jelentése: számítsd ki az y + 2*tan(x) kifejezés aktuális értékét, és az eredményt tedd bele az z változóba!

    Ha az egyenlőség jel (pontosabban az értékadás operátor) két oldala eltérő típusú, az alábbi dolgok történhetnek:

    Különböző nyelvek eltérő szigorral kezelik a típusok keveredését. Ezek alapján beszélhetünk


    3.3 Függvények

    A programozásban a függvények a matematikában használt függvények kiegészítései. Egy függvény jellemzői: Például: Függvényeket magunk is készíthetünk. Pl: kör kerületét kiszámító függvény (algoritmus leíró nyelven):
    függvény KörKerület ( sugár: Valós )
    kerület = 2 * sugár * 3.14;
    visszatérés: kerület
    vége


    Fejlesztői könyvtárak (library-k, lib-ek)

    Hasonló témájú függvényeket gyakran helyeznek el együtt, úgynevezett programozói könyvtárakban, library-kben.
    A könyvtárak (mint külön elkészített modulok) eredetük szerint: téma szerint például: Természetesen nem lehet minden könyvtárat minden nyelvből elérni. Minden nyelvhez általában külön könyvtárak tartoznak.


    3.4 Vezérlési szerkezetek

    3.4.1 Elágazás (if)

    A leggyakrabban használt elágazás az "if" (ha-különben típusú elágazás):
     
    blokkdiagram stuktogram algoritmus leíró nyelv JavaScript
    ha (feltétel)
    utasítások
    különben
    utasítások
    if (feltétel)
    utasítások
    else
    utasítások

    3.4.2 Ciklusok

    3.4.2.1 Hátultesztelős ciklus (do-while)

    Először végrehajtja a ciklusmagban lévő utasításokat, majd megvizsgálja a feltételt (bennmaradási feltétel), és ha ez igaz, akkor újra végrehajtja a ciklustörzset. Vegyük észre, hogy ha ez az első lefutásnál már hamis, attól még a cikosmag mindenképp lefut egyszer.
     
    blokkdiagram stuktogram algoritmus leíró nyelv JavaScript
    ciklus
    ciklusmag
    amíg (feltétel)
    do
    ciklusmag
    while (feltétel)

    3.4.2.2 Elöltesztelős ciklus (while)

    Először megvizsgálja a feltételt (belépési feltétel), és csak akkor hajtja végre a ciklusmagban lévő utasításokat, ha a feltétel igaz. Vegyük észre, hogy ha kiinduláskor már hamis a belépési feltétel, akkor egyszer sem fut le a ciklustörzs.
     
    blokkdiagram stuktogram algoritmus leíró nyelv JavaScript
    ciklus amíg (feltétel)
    ciklusmag
    while (feltétel)
    ciklusmag

    3.4.2.3 For ciklus

    Az elöltesztelős ciklus egy speciális esete, amikor a megadott ciklusváltozó (gyakran i-nek nevezik) értéke minden lépés után automatikusan nő eggyel, a kezdőértéktől (k.é.) a végértékig (v.é.).
     
    blokkdiagram stuktogram algoritmus leíró nyelv JavaScript
     
    ciklus i = k.é. től v.é. -ig
    ciklusmag
    amíg (feltétel)
    (ez egy kicsit több annál)

    for (i = k.é. ; i<v.é. ; i++)

    ciklusmag


    4. JavaScritp