Funkcje 65
Mimo że można używać funkcji zwracających wartości jako parametry do innych funkcji, to nie polecamy tego rozwiązania, gdyż prowadzi ono do zbędnego komplikowania kodu.
Jako przykład, załóżmy, że mamy funkcje RazyDwa(), RazyTrzyO, Kwadrat() i Sześcian (), z których każda zwraca wartość. Możesz napisać:
Odpowiedz = (RazyDwa(RazyTrzy(Kwadrat(Sześcian(MojaWartosc)))));
Ta instrukcja pobiera zmienną Mo jaWartosc, przekazuje ją jako argument do funkcji Sześcian (), zwracającą wartość przekazywaną z kolei od funkcji Kwadrat(), której wynik przekazywany jest do funkcji RazyTrzy () na rezultacie której operuje funkcja RazyDwa (). Wynik tego podwajania, potrajania i potęgowania podstawiany jest do zmiennej Odpowiedz.
Trudno na pierwszy rzut okna powiedzieć co ta instrukcja robi (czy wartość była podnoszona do sześcianu zanim była podwojona czy nie?). Również w momencie uzyskania wyniku niezgodnego z oczekiwaniami trudno będzie znaleźć miejsce popełnienia błędu.
Alternatywnym rozwiązaniem jest przypisanie każdego kroku do osobnych zmiennych:
// Przez5 = 8 // Przez4 = 64 // Przez3 = 192 // Przez2 = 384
unsigned long MojaWartosc = 2; unsigned long Potega3 = Sześcian(MojaWartosc); unsigned long Potega2 = Kwadrat(Potega3); unsigned long Przez3 = RazyTrzy(Potega2); unsigned long Przez2 = RazyDwa(Przez3);
Teraz każda pośrednia wartość może zostać przeanalizowana. Jasna jest również kolejność wykonywania operacji.
Argumenty przekazywane do funkcji są w niej lokalne. Zmiana ich wartości jest również lokalna i nie jest widoczna w funkcji wywołującej. Nazywamy to przekazywaniem przez wartość, co oznacza, że w funkcji tworzona jest lokalna kopia każdego argumentu przekazywanego do tej funkcji. Takie kopie są traktowane tak, jak lokalne zmienne. Listing 5.3. ilustruje ten mechanizm.
Mimo że można używać funkcji zwracających wartości jako parametry do innych funkcji, to nie polecamy tego rozwiązania, gdyż prowadzi ono do zbędnego komplikowania kodu.
Jako przykład, załóżmy, że mamy funkcje RazyDwa (), RazyTrzy(), Kwadrat () i Sześcian (), z których każda zwraca wartość. Możesz napisać:
Odpowiedz = (RazyDwa(RazyTrzy(Kwadrat(Sześcian(MojaWartosc)))));
Ta instrukcja pobiera zmienną MojaWartosc, przekazuje ją jako argument do funkcji Sześcian (), zwracającą wartość przekazywaną z kolei od funkcji KwadratO, której wynik przekazywany jest do funkcji RazyTrzy () na rezultacie której operuje funkcja RazyDwa (). Wynik tego podwajania, potrajania i potęgowania podstawiany jest do zmiennej Odpowiedz.
Trudno na pierwszy rzut okna powiedzieć co ta instrukcja robi (czy wartość była podnoszona do sześcianu zanim była podwojona czy nie?). Również w momencie uzyskania wyniku niezgodnego z oczekiwaniami trudno będzie znaleźć miejsce popełnienia błędu.
Alternatywnym rozwiązaniem jest przypisanie każdego kroku do osobnych zmiennych:
// Przez5 = 8 // Przez4 = 64 // Przez3 = 192 // Przez2 = 384
unsigned long MojaWartosc = 2; unsigned long Potega3 = Sześcian(MojaWartosc); unsigned long Potega2 = Kwadrat(Potega3); unsigned long Przez3 = RazyTrzy(Potega2); unsigned long Przez2 = RazyDwa(Przez3);
Teraz każda pośrednia wartość może zostać przeanalizowana. Jasna jest również kolejność wykonywania operacji.
Argumenty przekazywane do funkcji są w niej lokalne. Zmiana ich wartości jest również lokalna i nie jest widoczna w funkcji wywołującej. Nazywamy to przekazywaniem przez wartość, co oznacza, że w funkcji tworzona jest lokalna kopia każdego argumentu przekazywanego do tej funkcji. Takie kopie są traktowane tak, jak lokalne zmienne. Listing 5.3. ilustruje ten mechanizm.