Nie obrażaj więc mojej inteligencji poprzez czynione na pokaz zaniżanie własnej.
Przekazywanie argumentów – wskaźniki
• klasyczne wywołanie – wyliczenie i zwrotne przekazanie tylko jednej wielkości • moŜliwość uŜycia zmiennych globalnych – niebezpieczeństwa z tym związane • wyjście – wywołanie funkcji z adresami zmiennych Przykład: // adresy (wskaźniki) jako argumenty funkcji #include <iostream> using namespace std; const double PI=3.1415926; void kula(double r, double *pow, double *obj); main() { double r,s,v,*p; p=&v; r=1.0; kula(r, &s, p); cout << "Pole powierzchni = " << s << endl; cout << "Objetosc = " << *p << endl; return 0; } void kula(double r, double *pow, double *obj) { *pow=4*PI*r*r; *obj=4*PI*r*r*r/3; } _____________________________________ Pole powierzchni = 12.5664 Objetosc = 4.18879 • bardzo częste stosowane • gdy przekazujemy tabelę, to przekazujemy adres jej początku Jak to działa? int a, *wa; cout << "adres a : " << &a << " wartosc a : " << a << endl; cout << "adres wa : " << &wa << " wartosc wa : " << wa <<endl;wa=&a; *wa=1; adres a : 0x22ff74 wartosc a : 2 adres wa : 0x22ff70 wartosc wa : 0x7 1. Definicja zmiennych: int a, *wa; a 0x74 wa 0x70 2. Podstawienie: wa=&a; a 0x74 wa 0x74 0x70 3. Podstawienie: *wa=1; a 1 0x74 wa 0x74 0x70 Poprzez odwołanie pośrednie moŜemy za pomocą wskaźnika zmieniać wartość innych zmiennych (tych, na które pokazuje wskaźnik). To jest kluczowe przy wykorzystaniu wskaźników jako argumentów funkcji. W naszym przykładzie: 1. Definicja zmiennych: double r, s, v, *p; r 0x70 s 0x68 v 0x60 p 0x5c 2. Podstawienie: p=&v; r 0x70 s 0x68 v 0x60 p 0x60 0x5c 3. Podstawienie: r=1.0; r 1.000000 0x70 s 0x68 v 0x60 p 0x60 0x5c 4.Wywołanie funkcji: kula(r,&s,p); ã kula(r,*pow,*obj); r 1.000000 0x70 r 1.000000 0x30 s 0x68 pow 0x68 0x38 v 0x60 obj 0x60 0x3c p 0x60 0x5c 4.Wyliczenia w funkcji: *pow=4*PI*rr*rr; *obj=4*PI*rr*rr*rr/3; r 1.000000 0x70 r 1.000000 0x30 s 12.566 0x68 pow 0x68 0x38 v 4.1888 0x60 obj 0x60 0x3c p 0x60 0x5c 5. Zakończenie funkcji kula – zmienne r, pow, obj są kasowane, ale zawartość komórek pamięci na króre wskazywały pow, obj (czyli komórek s oraz v – zmiennych lokalnych main) pozostaje!!! 6.Wydruk zawartości komórek s, v – drukuje wyliczone w funkcji kula wartości • kluczowy punkt – mając adres jakiegoś obiektu (wskaźnik) moŜemy nim manipulować mimo tego, Ŝe punkt manipulacji jest (formalnie rzecz biorąc) – poza zakresem waŜności tego obiektu • ta metoda pozwala obliczyć i wycofać z funkcji obliczone wartości dowolnej ilości zmiennych • poprawny sposób komunikacji pomiędzy funkcjami w C/C++ - patrząc tylko na miejsce wywołania funkcji moŜemy z góry powiedzieć, które argumenty mogą być zmieniane przez operacje wewnątrz funkcji tak, by zmiany te były aktualne po zakończeniu działania funkcji – to umoŜliwia/ułatwia analizę programu. Zmienne referencyjne • w C++ moŜna tworzyć zmienne referencyjne do istniejących juŜ zmiennych • zmienne takie to aliasy (przezwiska) innych zmiennych – zarówno zmienna jak i alias odpowiadają temu samemu miejscu w pamięci int a=5; // definicja i inicjalizacja a int &b=a; // b jest referencją do a, wartosc b=5 int &c; // nielegalna definicja, referencja musi być // zainicjowana b=10; // a=10, b=10 a=20; // a=20, b=20 • w C++ referencje uŜywane najczęściej w funkcjach, które zmieniają swoje argumenty (alternatywa dla wskaźników) #include <iostream> using namespace std; void podwoj(int a, int &b) { a *= 2; b *= 2; } int main() { int a=1, b=2; podwoj(a,b); cout << "a=" << a << " b=" << b << endl; } a=1 b=4 • argument przesłany przez wartość – bez zmian; przesłany przez referencję – zmodyfikowany • powód – przez referencję przesyłamy adres argumentu (a nie jego wartość) |
Menu
|