C kezdőknek (5)

 

Tömbök

 

A tömbök segítségével azonos elemekből álló adathalmazt tárolhatunk a memóriában és műveleteket hajthatunk végre rajta.

Általános alakjuk:

 

típus tömbnév[elemszam];

 

A típus nem lehet void. A szögletes zárójelek között adjuk meg a tömb elemeinek számát, vagyis méretét.

Ez a tömb egydimenziós tömb, vagy más néven vektor. Általánosan igaz, hogy a tömb elemszam db elemet tud tárolni (micsoda meglepetés :-)). Az elemek számozása nullától kezdődik és (elemszam-1)-ig tart.

 

Példa:

int x[15];

 

Ez a tömb 15 darab int típusú elemet tartalmaz, 0-tól 14-ig számozva.

A tömbök elemeire mindig az indexelés operátorával ([]) hivatkozunk (pl. x[3]). Az elemek egymás utáni elérésére általában az előző részben megismert for ciklust használjuk, melynek ciklusváltozója lesz a tömb indexe.

Az egész tömbre a tömb nevével (példánknál maradva: x) hivatkozhatunk. Mivel a tömb azonos típusú elemeket tartalmaz, ezek mérete is egyenlő. Ebből következik, hogy ha a tömb méretét (sizeof(x)) elosztjuk egy elem méretével (sizeof(x[0])), akkor megkapjuk a tömb elemeinek számát. Ez egy fontos adat, nagyon sok művelet elvégzéséhez szükséges. Ilyen műveletekkel a következő részben foglalkozunk.

 

A tömbökkel kapcsolatosan itt egy példaprogram, amely összeadja a beolvasott számokat.

 

#include <stdio.h>

#define ELEMEK 10

 

int szamok[ELEMEK], osszeg = 0;

/* fontos nullázni, mert különben ismeretlen értékről indul az osszeg változó */

int i;

 

int main()

{

      for (i = 0; i < ELEMEK; i++)

      {

            printf("\nszam[%d]: ", i);

            scanf("%d", &szamok[i]); fflush(stdin);

            osszeg += szamok[i];      

      }

      printf("\nA %d db beolvasott szam osszege: %d", ELEMEK, osszeg);

 

    return 1;

}

 

Hűha, ez kicsit tömény lett, de nem baj, gyakorlat teszi a mestert. A második sor egy előfordító utasítás, egy szimbolikus konstanst deklaráltunk. Ez arra jó, hogy ha megváltozik az ELEMEK értéke, akkor csak egy helyen kell megváltoztatnunk azt, a többi helyre behelyettesítődik automatikusan.

A következő ismeretlen dolog a for ciklus törzsében jelenik meg: "\nszam[%d]: " A \n-t ismerjük, ezzel lépünk új sorba, de a %d-vel még nem találkoztunk. Ez is egy formázási karakter, decimális (azaz tízes számrendszerbeli) egész szám helyét jelzi a szövegben. A szám a printf() következő paramétere, ha több szám is van, akkor sorban követik egymást.

A következő sor teljes egészében ismeretlen. Ezt a scanf() függvényt tulajdonképpen a printf() fordítottjaként lehet felfogni. A standard bemenetről (stdin) olvas be adatokat (a „standard bemenet” többnyire a billentyűzet). Első paramétere egy formátumsztring, ez alapján olvassa be az adatokat. A másodikban adjuk meg, hogy hova kerüljön a beolvasott adat. Ezt mindig a címképző operátor (&) és a változó neve.

Ugyanebben a sorban található az fflush() függvény. Ez kiüríti a beolvasási puffert. Erre azért van szükségünk, mert ha a felhasználó nem megfelelő adatot visz be a programnak (pl. betűket) akkor azt a scanf() nem dolgozza fel, mivel mi csak 1 darab decimális egészre adtunk utasítást. De a feldolgozatlan adat ott marad a pufferben és a következő scanf() nem a billentyűzetről olvas be, hanem a pufferből, bár ez sem tudja feldolgozni és így tovább. Az fflush() kiüríti a paraméterében megadott puffert.

A += operátorral azt hiszem már találkoztunk, az osszeg értékét növeli a szamok[i]-vel.

És ezzel vége is a programnak.

 

Természetesen tömböt bármilyen elemből képezhetünk, így karakterekből is. Ez különösen fontos a C esetében, mert ez a nyelv tulajdonképpen nem ismeri a sztringeket, hanem ezeket is karaktertömbökként kezeli. Így ha a programozásban nagyon gyakori sztringekkel dolgozunk, itt mindig karaktertömböket alkalmazunk.

 

Létrehozhatunk természetesen ennek megfelelően - hiszen bármely típusú elemet tömbbe rendezhetünk - tömbökből álló tömböt, azaz többdimenziós tömböket is, ezek általános alakja egy háromdimenziós tömb esetében:

 

típus tömbnév[12][23][12];

 

Egy többdimenziós tömb (indexek szorzata) darab elemet tud tárolni, tehát esetünkben ez a tömb 3312 elemet képes tárolni. Bár elvileg ennél több dimenziós is lehet egy tömb, a gyakorlatban az áttekinthetőség érdekében háromnál többet ritkán alkalmazunk. Gyakran használt viszont a kétdimenziós tömb karaktertömbök, azaz stringek tárolására.

 

A tömbök a létrejöttük során kezdőértéket nem kapnak, tehát a programozónak kell arról gondoskodni, hogy ne valami "memóriaszemetet" tároljon a tömb. A "nullázások" során ismét csak a már megismert for ciklusok játszanak szerepet, a többdimenziós tömbök esetén természetesen egymásba ágyazott ciklusokat alkalmazunk a kezdőértékkel való feltöltésre.

Van még itt egy speciális tömbalkalmazás és egy gyakran használt feltöltési módszer is. Erre akkor van szükség, ha például bekéréseknél folytonosan változó szövegeket kell tájékoztatónak kíirni.

 

#include <stdio.h>

 

typedef char str[10];  //így definiálunk új típust, esetünkben egy 10 karakterből álló tömböt

 

void main()  // a main függvényhez nem szükséges típust rendelni

{

/* a napok nevei így is megadhatók, a str típusú elemekből álló tömb közvetlen feltöltésével */

str napok[7] = {"hétfő", "kedd", "szerda". "csütörtök", "péntek", "szombat", "vasárnap"};

for (int i = 0; i<7; i++)

printf("\n a hét %d. napja: %s", i+1, napok[i]);

/* és itt ki is íratjuk a napok neveit, természetesen a sorszámok esetében eggyel növeltük i értékét, hogy ne nulláról induljon a számozás */

}

 

Ennyi jutott mára, a következő számban ugyanitt találkozunk!

 

Szelei Tamás - d4mi3n@mail.com