7. gyakorlat: tömbök és sztringek
A lenti programokban gyakran tömböt adunk át egy függvénynek. Az alapvető különbség a sima tömbök és a nullával lezárt sztringek között az, hogy az utóbbiaknál a tömb tartalma (karakterek és lezáró nulla) alapján tudjuk azt, hogy hol van vége annak. Ebben a speciális esetben nem kell átadni a tömb méretét a függvényeknek, máskor viszont mindig igen! Érdemes ilyen szemmel összehasonlítani a programokat.
Másrészről: a paraméterként kapott tömböt a függvény tudja módosítani, hiszen cím szerint kapja meg azt. Az eredeti memóriát látja, nem a tömb egy másolatát! Ezt is kihasználjuk a függvényekben.
1 Cím szerinti paraméterátadás
Írjunk egy függvényt, amelyik kiszámolja és visszaadja két szám összegét és szorzatát!
Megoldás
Mivel két adatot is vissza kell adnia, cím szerinti átadást kell használnunk. A visszatérési érték helyett átvesszük cím szerint a két változót, amelybe írni kell.
void szamol(int a, int b, int *osszeg, int *szorzat) { *osszeg=a+b; *szorzat=a*b; } int o, s; szamol(9, 11, &o, &s);
Természetesen
ilyenkor is érték szerinti átadás történik, csak az
az érték a memóriacím. A függvény belsejében az osszeg
típusa int
-re mutató pointer, a szorzat
változóé ugyanaz.
2 Tömb átadása függvénynek
Írjunk függvényt, amelyik átvesz paraméterben egy egészekből álló tömböt, és
- visszatér az elemek összegével!
- visszatér a legkisebb elem indexével,
- megszorozza kettővel mindegyik elemet!
- kiírja mindegyik elemet!
Megoldás
#include <stdio.h> /* nullarol indul, es minden elemet hozzaad */ int osszeg(int *tomb, int meret) { int osszeg, i; osszeg=0; for (i=0; i<meret; ++i) osszeg+=tomb[i]; return osszeg; } /* legkisebb elem indexet adja vissza. * at kell vennie a tomb meretet! */ int legkisebb(int *tomb, int meret) { int lk, i; /* feltetelezett legkisebb, utana hatha van meg kisebb */ lk=0; for (i=1; i<meret; ++i) if (tomb[i]<tomb[lk]) lk=i; return lk; } /* kiirja egy sorban az osszes elemet */ void kiir(int *tomb, int meret) { int i; for (i=0; i<meret; ++i) printf("%d ", tomb[i]); printf("\n"); } /* megduplazza minden elemet a tombnek */ void megduplaz(int *tomb, int meret) { int i; for (i=0; i<meret; ++i) tomb[i]*=2; } int main() { int tomb[10]={4, 9, 1, 3, 7, 9, 3, 2, 8, 3}; kiir(tomb, 10); printf("Legkisebb: %d. indexu.\n", legkisebb(tomb, 10)); printf("Osszeg: %d.\n", osszeg(tomb, 10)); megduplaz(tomb, 10); kiir(tomb, 10); return 0; }
3 Sztringek: bemelegítő
Hozzunk létre egy sztringet! Változtassunk meg benne néhány
karaktert! Írjunk ciklust, amelyik megszámolja az 'l'
betűket a sztringben!
Megoldás
#include <stdio.h> int main() { char sz[20]="Hello, vilag!"; int i, db; printf("|%s|\n", sz); sz[0]='h'; /* sztring: "idezojel", karakter: 'h' aposztrof! */ printf("|%s|\n", sz); sz[7]='\0'; /* 0 is lehetne, ugyanaz. */ printf("|%s|\n", sz); /* tekintsünk a sztringre, mint tömbre. hol van vége? ahol sz[i]==0, nem pedig i=19-nél, ami a tömb méretéből adódna! */ db=0; for (i=0; sz[i]!='\0'; i++) if (sz[i]=='l') db++; printf("[%s] sztring %d darab l betűt tartalmaz.\n", sz, db); return 0; }
4 Sztring átadása függvénynek
Írjunk függvényt, amelyik egyik sztring végére másol egy
másikat, vagyis hozzáfűzi a paraméterként kapott első sztringhez a
másodikat! (Ezt csinálja a könyvtári strcat()
függvény
is.)
Megoldás
#include <stdio.h> void sztringhozzafuz(char *mihez, char *honnan) { int folytat, i; i=0; while (mihez[i]!='\0') i++; /* ezzel megkeressuk, az elobbinek hol van vege */ folytat=i; /* es oda masoljuk a masikat, folytatolagosan */ i=0; /* nezzuk a masik sztringet az elejetol */ while (honnan[i]!='\0') { mihez[folytat]=honnan[i]; i++; folytat++; } mihez[folytat]=0; /* lezaro nulla eddig nem - most megtesszuk. */ } /* peldak, hogyan kell meghivni a fuggvenyeket */ int main() { /* mit a mizujs[]? azt, hogy a fordito kitalalja a tomb meretet. */ /* a hello[] sztringhez hozzafuzunk, ezert az nagyobb kell legyen. */ char hello[50]="Hello, vilag!", mizujs[]="Mizujs?"; printf("Sztring: [%s] es [%s]\n", hello, mizujs); sztringhozzafuz(hello, " "); sztringhozzafuz(hello, mizujs); printf("Osszefuzve: [%s].\n", hello); return 0; }
5 Fordítva
Írjunk függvényt, amelyik megfordít egy sztringet! Pl. "Hello, mizujs?" sztringből keletkezzen "?sjuzim ,olleH" sztring!
Megoldás
#include <stdio.h> #include <string.h> void megfordit(char *t) { int hossz, i; hossz=strlen(t); /* csak a feléig forgatunk, különben visszafordítanánk */ for (i=0; i<hossz/2; ++i) { char temp=t[i]; /* három lépéses csere */ t[i]=t[hossz-1-i]; t[hossz-1-i]=temp; } /* lezáró nulla? van, mert maradt a helyén. */ } int main() { char str[] = "Hello, mizujs?"; printf("Eredeti: %s\n", str); megfordit(str); printf("Forditott: %s\n", str); return 0; }
6 Mindentegybevéve
Írjunk függvényt, amelyik paraméterként kap egy sztringet. Változtassuk meg olyan módon, hogy a szóközöket kiszedi belőle! Dolgozzunk a megadott sztringen! (A keletkező sztring ne egy másik memóriaterületen legyen, hanem az eredetit változtassuk meg!)
Megoldás
Gondoljuk végig:
- Bele fog férni? Igen, mert ettől csak rövidülhet.
- Belül kell ideiglenes sztring? Nem, mert menet közben is csak rövidül.
- Le kell írni egymás alá egy példa bemenetet és kimenetet, abból jól látszik a megoldás: két változónk van, honnan másolunk (hányadik karaktert) és hova másolunk (hányadik helyre a tömbben).
#include <stdio.h> void spacetelenit(char *t) { int honnan, hova; hova=0; /* végigmegyünk az összes karakteren */ /* "honnan" mindig nő, "hova" csak néha */ for (honnan=0; t[honnan]!='\0'; honnan++) /* és ami nem space, másoljuk */ if (t[honnan]!=' ') { /* NEM 32, hanem ' '! */ t[hova]=t[honnan]; hova++; } t[hova]='\0'; /* lezáró nulla! */ } int main() { char hello[]="H e l l o, vilag!"; spacetelenit(hello); printf("Mindentegybeirok: [%s]\n", hello); return 0; }