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

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