Platnosť dosahu premennej
Aby sme sa dostali k pointerom, ukážeme si program, ktorý má takú menšiu vadu na kráse. Práve efektívnym riešením problému v programe môže byť využitie pointeru.
#include <iostream> using namespace std; void scitaj(int cislo) { cislo += 10; } void odcitaj(int cislo) { cislo -= 5; } void vynasob(int cislo) { cislo *= 2; } void vydel(int cislo) { cislo /= 2; } int main() { int cislo = 7; scitaj(cislo); odcitaj(cislo); vynasob(cislo); vydel(cislo); cout << "Vysledok: "<<cislo<<"\n"; return 0; }
Cieľom programu je po poradí matematickými operáciami spracovať premennú s hodnotu 7. Výsledok, ktorý sme z programu získali je zlý. Kde nastala chyba? Všimnite si, že hodnota premennej cislo
a výsledok je rovnaký. Ani jedna z operácii, ktoré sú definované vo funkciách, neovplyvnila premennú cislo
. Je to kvôli tomu, že premenná cislo
vo funkcii už nemá nič spoločné s pôvodnou premennou definovanej v hlavnej funkcii main
. Takže nech sa stane čokoľvek s premennou cislo
vo funkcii, nemá žiadny vplyv na pôvodnú premennú, z ktorej vznikla skopírovaním. Jedným z riešení môže byť využitie návratovej hodnoty funkcie.
#include <iostream> using namespace std; int scitaj(int cislo) { cislo += 10; return cislo; } int odcitaj(int cislo) { cislo -= 5; return cislo; } int vynasob(int cislo) { cislo *= 2; return cislo; } int vydel(int cislo) { cislo /= 2; return cislo; } int main() { int cislo = 7; cislo = scitaj(cislo); cislo = odcitaj(cislo); cislo = vynasob(cislo); cislo = vydel(cislo); cout << "Vysledok: "<<cislo<<"\n"; return 0; }
Dopracovali sme sa k správnemu výsledku. Čo si môžeme všimnúť, že stále priraďujeme novú hodnotu premennej cislo
. Predstavte si teraz, že máte tisícky premenných a každá z nich bude mať desiatky priradení hodnôt. To by bolo číre zúfalstvo sa orientovať v takomto kóde. Ale nezúfajte, na pomoc prichádzajú pointery, ktoré nás zbavia úmornej práce s priradeniami premenných.
Čo je pointer?
Pointer nie je nič iné, len premenná uchovávajúca adresu inej premennej. Pozrime sa najprv, ako taká adresa premennej vyzerá.
#include <iostream> using namespace std; int main() { int cislo1 = 4; int cislo2 = 10; int cislo3 = 25; cout << "Hodnota premennej cislo1 je: " << cislo1 << " a jej adresa je: " << &cislo1 << "\n"; cout << "Hodnota premennej cislo2 je: " << cislo2 << " a jej adresa je: " << &cislo2 << "\n"; cout << "Hodnota premennej cislo3 je: " << cislo3 << " a jej adresa je: " << &cislo3 << "\n"; return 0; }
Výsledok je nasledovný:
Hodnota premennej cislo1 je: 4 a jej adresa je: 0x6dfefc Hodnota premennej cislo2 je: 10 a jej adresa je: 0x6dfef8 Hodnota premennej cislo3 je: 25 a jej adresa je: 0x6dfef4
Zisťujeme, že adresa premennej pozostáva z identifikátora, ktorý určuje kde sa nachádza premenná v pamätí. Avšak ako zabezpečiť, aby premenná v nejakej funkcii mala priamy vplyv na pôvodnú premennú, z ktorej ako kópia vznikla? Skopírovaním adresy jednej premennej do druhej? To je vylúčené. Nemôžu byť uložené dve premenné na tom istom mieste v pamätí. Čo tak ale vytvoriť odkaz tvorený adresou nejakej premennej a na túto premennú odkazovať? A to je základný princíp pointeru.
Skúsme sa pozrieť na implementáciu nášho problému využitím pointerov.
#include <iostream> using namespace std; void scitaj(int *cislo) { *cislo += 10; } void odcitaj(int *cislo) { *cislo -= 5; } void vynasob(int *cislo) { *cislo *= 2; } void vydel(int *cislo) { *cislo /= 2; } int main() { int cislo = 7; scitaj(&cislo); odcitaj(&cislo); vynasob(&cislo); vydel(&cislo); cout << "Vysledok: "<<cislo<<"\n"; return 0; }
Funkcie v našom programe získavajú ako parameter nie skopírovanú premennú, ale odkaz na ňu. Tak ako máte na pracovnej ploche monitoru odkaz na obľúbenú hru, tak pointer zaisťuje rýchly prístup k premennej. Preto tak môžeme ľahko manipulovať s premennou vo funkciách a práve tu je pointer veľmi využívaným riešením.
V ďalšom dieli sa dozviete, čo znamená znak *
a ukážeme si aj nejaké zaujímavé príklady na pointery.