next up previous contents
Elõre: Tömbök használata. Többdimenziós tömbök Fel: Mutatók és tömbök Vissza: Mutatók függvényparaméterként

Pointer aritmetika

Pointerekkel különbözõ aritmetikai mûveleteket végezhetünk, ezek a következõ formájúak lehetnek:

illetve az elsõ két mûvelet speciális eseteként Minden mutatóval végzett mûvelet esetén képzeljük el azt, hogy a memória csak olyan típusú adatokból áll, mint amilyet az adott mutató megcímez, és ezek egyesével vannak megszámozva. Tehát például a ptr azonosítójú pointerrel való mûveletvégzés esetén azt tételezzük fel, hogy a memória legkisebb megcímezhetõ egysége a rövid egészt tartalmazó szó. Ha most a mutatóhoz hozzáadunk, vagy belõle levonunk egy egész számot, akkor az a megadott számú adattal való elõre-, vagy hátralépést fogja jelenteni, azaz például a ptr+5 értéke az a cím lesz, ahol az aktuálisan mutatott short utáni 5-dik rövid egész szó elhelyezkedik; a -ptr pedig a megelõzõ short-ra állítja ptr-t. Más szóval, ha egy mutatott adat képzeletbeli sorszáma i, akkor a mutatóhoz való n egész érték hozzáadása után az eredményül kapott mutató az i+n sorszámú adatot fogja megcímezni. A fentieket legkönnyebb egydimenziós tömbök segítségével szemléltetni. Tekintsük az alábbi definíciókat:
            float vekt[20], *pv = &vekt[4];
A pv azonosítójú mutatót egy adott adat címével inicializáltuk. Ez alkalmazható statikus helyfoglalású változókra is, mert csak azt kötöttük ki, hogy ezek inicializátorai nem függhetnek más változók értékétõl, de itt nem az érték, hanem az elfoglalt cím lett felhasználva. A fenti definíciók után a pv, pv + 3, pv - 2, pv + 20 kifejezések sorban a vekt tömb 5-ödik, 8-adik, 3-adik és - nem létezõ - 25-ödik elemének címét adják meg (az utolsó tehát szintaktikailag helyes ugyan, de szemantikailag hibás).

A pointer - pointer alakú kifejezésnek csak akkor van értelme, ha a két mutató által megcímzett típus azonos; ekkor az eredmény a két adat távolsága adat-méretnyi egységben, vagyis itt is alkalmazzuk a fenti feltételezést a memóriáról, és az eredményt a két mutató által kijelölt két adat sorszámainak különbségeként kapjuk. Példaként tekintsük az alábbi függvényt, amely egy karakterlánc hosszát adja vissza:

            int strlen(s)
            char *s;
            {
               register char *p = s;
               while (*p != EOS)
               {
                  p++;
               } /* endw */
               return (p - s);
            } /* end strlen() */
A p mutatót ráállítjuk a sztring elejére, és mindaddig léptetjük elõre egyesével (egy mutatott adattal, jelen esetben egy karakterrel), amíg el nem érjük a karakterlánc végét jelzõ EOS értéket. Eredményül éppen azt adjuk vissza, hogy mennyit léptünk elõre, amíg elértük a sztring végét, vagyis hány "igazi" karakter van a sztringben. A fenti szabványos könyvtári függvény egy felhasználási lehetõsége:
            char hiba[ ] = "Nincs eleg memoria!";
            int  l1, l2;
            ...
            l1 = strlen(hiba[0]);
            l2 = strlen(&hiba[6]);
Ekkor l1 értéke 19, l2-é 13 lesz.

A BORLAND C++ rendelkezik huge mutatókkal, amelyeknél lehetõség van arra, hogy ne csak int mennyiségeket adhassunk hozzájuk, illetve vonhassunk le belõlük, hanem használhatjuk a pointer + long, illetve pointer - long alakú mûveleteket is. Ez nem portábilis lehetõség, ezért használatánál erre legyünk figyelemmel. Hasonlóan, bár két mutató különbsége C nyelvi definíció szerint int, huge pointerek esetén ez az érték meghaladhatja a 16 bites határt. A fordító ezért a következõ formát felismeri és 32 bites különbséget számol (p, q azonos típusú huge pointerek, l pedig long):

            l = (long)(p - q);
A mutatók közötti bármiféle összehasonlítás (<, >, ==, stb.) csak akkor ad garantáltan helyes és portábilis eredményt, ha a mutatók azonos típusúak, és mindkettõ egy, a mutatott típusból felépített tömbre mutat (lásd strlen-nél p és q, mindketten a hiba[ ] tömbre mutatnak). Hasonlóan garantált, hogy minden pointer biztonságosan összevethetõ NULL-lal, annak eldöntésére, hogy a mutató érvényes címet tartalmaz-e, vagy sem.


next up previous contents
Elõre: Tömbök használata. Többdimenziós tömbök Fel: Mutatók és tömbök Vissza: Mutatók függvényparaméterként