Informacje o nowych artykułach oraz akcjach edukacyjnych prosto na Twojej skrzynce e-mail!

Funkcje i wskaźniki w C++ cz. II

W pierwszej części artykułu poświęconemu funkcją w C++ pisałem, że kiedy w danej funkcji operujemy na jakiejś zmiennej globalnej to tak naprawdę nie modyfikujemy jej danych, ale kopię, którą robi kompilator podczas kompilacji kodu. W tym artykule pokarzę, w jaki sposób można to obejść przy pomocy wskaźników opisanych w poprzednim wpisie.

Jak już wspomniałem wcześniej wskaźniki tak naprawdę nie przechowują danych lecz adresy pamięci na które wskazują. Jeżeli na przykład mamy wskaźnik typu zmiennoprzecinkowego czyli taki, który wskazuje na obiekty double to kiedy przypiszemy do niego jakąś wartość – czyli ustawimy go tak aby wskazywał na jakiś adres pamięci, gdzie mamy coś zapisane, to należy pamiętać iż w rzeczywistości nie będzie on miał przypisanych żadnych danych lecz tylko adres pamięci.

Wykorzystując powyżej opisaną własność wskaźnika, zróbmy sobie globalny wskaźnik, który będzie wskazywał na obiekty typu double, a następnie przekażmy go do funkcji jako argument:

#include <iostream>

using namespace std;

double liczba = 4;
double *c = &liczba;

double pole(double a, double b)
{
    double dzialanie = 2 * b; //do dzialanie przypisz 2 * b czyli 2 * 4 = 8
    c = &dzialanie; //do wskaźnika c przypisujemy 8
    return a * a;
}

int main()
{

    pole(5, 4);

    cout << *c; //jak widać zamiast 4 mamy 8

    return 0;
}

Jak widać, kompilator oczywiście wykonał „kopię” tego wskaźnika tak jak zrobił to w naszym poprzednim programie (patrz niżej) ale tutaj kopią nie były dane, na które wskazywał nasz wskaźnik lecz adres pamięci jaki przechowywał. W efekcie po modyfikacji zawartości jaka znajdowała się pod tym adresem, po wyjściu z funkcji dane te zostały zmienione dla dalszego kodu programu.

#include <iostream>
 
using namespace std;
 
int c = 4;
 
int pole(int a, int b)
{
    c = 2 * b; //do c przypisz 2 * b czyli 2 * 4 = 8
    return a * a;
}
 
int main()
{
 
    pole(5, 4);
 
    cout << c; //zamiast 8 mamy dalej 4
 
    return 0;
}

Przypominam, że w przypadku zwykłych zmiennych aplikacja ta działała w ten sposób iż w przypadku podania do funkcji danych w argumentach kompilator zrobił sobie kopię wskazanych przez nas zmiennych obliczył co ma obliczyć i zwrócił bądź też nie jakąś daną. Jeżeli funkcja zmodyfikowała liczbę (na przykład pomnożyła 5 przez 2) w dowolnej zmiennej to ta zmodyfikowana liczba była dostępna tylko do momentu kiedy dana funkcja nie zakończy działania.

Spodobało się?

Jeśli tak, to zarejestruj się do newslettera aby otrzymywać informacje nowych artykułach oraz akcjach edukacyjnych. Gwarantuję 100% satysfakcji i żadnego spamowania!

, , , ,

Dodaj komentarz

Komentarze (1)

  • akolikol pisze:

    Stary temat ale mimo wszystko, wydaje mi się, że w pierwszym kodzie jest błąd, dzialanie2 jest zmienna lokalną wypisanie wskaźnika do niej poza funkcją jest jak rzut kością, rezultat będzie nieznany. Gdy spróbujesz odczytać ją bardzo szybko może trafisz w 8, jeżeli się coś zdąży wstrzelić przed cout’a i nadpisze komórkę pamięci to kicha.

Odpowiedz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Pin It on Pinterest