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