background image

Funkcje

Kiedy  ktoś  mówi  o  C++  to  ma  na  myśli  przede  wszystkim  obiekty.  Jednak 
obiekty bazują, na funkcjach, które wykonują niezbędne do działania obiektu 
operacje. 

Każdy  program  w  C++  posiada  przynajmniej  jedną  funkcję,  main ()  .  Kiedy 
uruchamia się program to funkcja main () jest automatycznie uruchamiana. 
Może ona wywoływać inne funkcje, które z kolei mogą wywołać jeszcze inne.

Funkcja jest podprogramem, który może modyfikować dane i zwracać 

wartość.

Każda  funkcja  ma  swoją  nazwę,  a  wywołanie  funkcji  polega  na  wpisaniu  jej 
nazwy  w  programie.  W  momencie  napotkania  wywołania  funkcji  program 
przechodzi do wykonania kodu funkcji. Kiedy funkcja się kończy, to program 
wraca do miejsca jej wywołania (do następnej instrukcji). 

Ilustracja tego procesu

return;

Funkcja
4

Main()
{
  Instrukcja;
  Funkcja1 () ;
  Instrukcja ;
  Funkcja2 () ;
  Instrukcja ;
  Funkcja4 () ;
}

return;

Funkcja
1

return;

Funkcja
3

Instrukcja;
Funkcja3();

return;

Funkcja
2

background image

Deklarowanie funkcji (prototypy)

Deklaracja  funkcji  określa  jej  nazwę,  typ  zwracanej  wartości  i  listę 
parametrów. 

Standardowe funkcje dostarczone razem z kompilatorem posiadają już swoje 
prototypy. Wystarczy dołączyć za pomocą  #include odpowiedni plik 
nagłówkowy (.H)
Prototyp funkcji to typ wartości zwracanej przez tę funkcję, nazwa  i lista 
parametrów. Prototyp kończy się znakiem średnika.
Lista 

parametrów 

to 

wyszczególnienie 

wszystkich 

parametrów 

przekazywanych do funkcji oddzielonych przecinkami. 

unsigned short int PoliczPole ( int nDlugosc, int nSzerokosc);

typ zwracanej 
wartości

nazw
a

parame
try

średn
ik

nazwa 
parametru

typ 
parametru

Przykład: „Elementy prototypu

Żadna  funkcja  nie  może  być  wywołana  przez  inną  bez  uprzedniego 
zadeklarowania. 

Deklaracja funkcji nazywana jest prototypem.

Definicja obejmuje treść funkcji.

background image

Prototyp, pod względem typu wartości zwracanej, nazwy i typów parametrów, 
musi zgadzać się z definicją funkcji. 

Jeśli  wystąpią  różnice,  to  kompilator,  przy  próbie  kompilacji, 
zasygnalizuje błąd. 

Przykład: long 

Pole

 ( int int );

Ten  prototyp  deklaruje  funkcję 

Pole  ()

  zwracającą  wartość  typu  long  i 

posiadającą dwa parametry typu int. Mimo że taka deklaracja jest całkowicie 
prawidłowa,  to  dla  poprawienia  przejrzystości  zalecane  jest  podawanie  w 
prototypie  również  nazw  parametrów.  Deklaracja  z  nazwami  parametrów 
będzie wyglądać następująco:

long 

Pole 

int nDlugosc, int nSzerokosc 

) ;

Zauważmy, że wszystkie funkcje mają określony typ zwracanej wartości. 

Prototyp funkcji mówi kompilatorowi o nazwie funkcji, wartości zwracanej i 
parametrach.

typ_zwracany

 

nazwa_funkcji

 ( [

typ

 [

nazwa_parametru

]]….) 

;

składnia:

background image

Porównajcie prototyp z definicją 
funkcji. 
Zwróćcie  uwagę,  że  typ  wartości 
zwracanej, 

nazwa 

typy 

parametrów są identyczne.
Gdyby  były  jakiekolwiek  różnice  to 
kompilator  wygenerowałby  błąd. 

Praktycznie  jedyna  wymagana 
różnica  polega  na  tym,  ze 
prototyp kończy się średnikiem 
i nie zawiera treści funkcji.

Zwróćcie  także  uwagę  na  to,  że 
nazwy parametrów w prototypie to 
nDlugosc  i  nSzerokosc,  a  nazwa 
parametrów w definicji to d i s. Jak 
widać, 

nazwy 

parametrów 

prototypie  nie  są  używane,  służą 
one  jedynie  jako  informacja  dla 
programisty. 

background image

Definiowanie funkcji

Definicja funkcji składa się z nagłówka i treści funkcji. Nagłówek wygląda tak, 
jak  prototyp,  jednak  musi  posiadać  nazwy  parametrów  i  nie  może  być 
zakończony średnikiem.
Treści funkcji to zbiór instrukcji ograniczony klamrami. 

unsigned short int ZnajdzPole ( int nDługosc, int 
nSzerokosc )

{

  // instrukcje

  return ( nDlugosc*nSzerokosc ) ;

} 

Klamra 
zamykająca

Klamra 
otwierająca

słowo 
kluczowe

zwracana 
wartość

typ zwracanej 
wartości

nazw
a

parametry

background image

Definicja mówi kompilatorowi co dana funkcja robi i jak działa.

typ_zwracany 

 

nazwa_funkcji

  ( [

typ

 [

nazwa_parametru

]]…. ) 

{

      instrukcje;

}

Składnia:

Jeżeli funkcja zwraca jakąś wartość, to przed wyjściem z funkcji należy użyć 
instrukcji  return.  Instrukcja  ta  może  zostać  użyta  w  każdym  miejscu  treści 
funkcji.
Dla  każdej  funkcji  określany  jest  typ  wartości  zwracanej.  Jeśli  nie  podamy 
typu, to automatycznie zostanie przypisany typ całkowity –  int. Jeśli funkcja 
nie zwraca żadnej wartości, to typem zwracanym będzie void.
Przykłady prototypów funkcji:

long Pole (long lDlugosc, long lSzerokosc);

Zwraca long, 

ma dwa parametry

void WypiszTekst(int nNumerTekstu); 

Zwraca void, 

ma jeden parametr

int PobierzOpcje (); 

Zwraca int, 

brak parametrów

SpecFunk () ;

Zwraca int, 

brak parametrów

background image

Przykłady poprawnych definicji funkcji:

void WypiszTekst( int nNumerTekstu )
{
  if ( nNumerTekstu == 0)
  {  
   cout << "Czesc.\n";
  }
  if ( nNumerTekstu == 1)
  {   
    cout << "Do widzenia. \n";
  }
  if ( nNumerTekstu > 1)
  {
    cout << "Jestem troche zaklopotany. \n";
  }
}

long Pole ( long d, long s )
{
  return d*s;
}

background image

Zmienne lokalne

Zmienne  można  nie  tylko  przekazywać  do  funkcji.  Można  je  również 
deklarować  wewnątrz  funkcji.  Wykorzystuje  się  w  tym  celu  tzw.  zmienne 
lokalne.  Zmienne  te  są  widoczne  tylko  wewnątrz  funkcji,  w  której  są 
zadeklarowane. Kiedy funkcja się kończy, zmienne przestają być dostępne.
Zmienne  lokalne  definiuje  się  tak  samo  jak  wszystkie  inne.  Parametry 
przekazywane do funkcji również są traktowane jako zmienne lokalne i można 
je wykorzystywać tak, jakby były wewnątrz tej funkcji zadeklarowane. 

background image

Wartość 

przekazywana 

jako 

parametr,  fTempFer,  również 
jest  tylko  lokalną  kopią  zmiennej 
przekazywaną z funkcji main ()

Deklarowana 

jest 

zmienna 

lokalna  fTempCel.  Ta  zmienna 
istnieje  tylko  wewnątrz  funkcji 
Konwertuj ()

Zwróćmy uwagę, że nie jest to ta 
sama zmienna co fTempCel.

background image

Każda  zmienna  ma  swój  zasięg, 
który  mówi  jak  długo  zmienna 
jest dostępna i gdzie można z niej 
korzystać. 

Zmienne 

zadeklarowane  w  osobnym  bloku 
widoczne są tylko wewnątrz niego 
i giną wraz z końcem bloku. 

background image

Zmienne globalne

Zmienne  zadeklarowane  poza  wszystkimi  funkcjami  mają  globalny  zasięg  i 
widoczne są wewnątrz wszystkich funkcji, łącznie z  main ().  Gmatwają one 
bardzo program. 

W  profesjonalnie  napisanych  programach,  są  bardzo  rzadko 
spotkane.

Argumenty funkcji

Argumenty  funkcji  nie  muszą  być  tego  samego  typu.  Nie  ma  żadnych 
przeciwwskazań, żeby argumentami funkcji były np.: jedna zmienna typu int
dwie typu float i jedna typu char.
Każde poprawne wyrażenie może być argumentem funkcji. Mam tu na myśli 
również  stałe,  wyrażenia  matematyczne  i  logiczne  oraz  inne  funkcje 
zwracające wartość.

background image

Funkcje jako parametry innych funkcji

Mimo że można używać funkcji zwracających wartości jako parametry do 
innych funkcji, to prowadzi ono do zbędnego komplikowania kodu. 

Przykład: 

Załóżmy, że mamy funkcje RazyDwa (), RazyTrzy (), Kwadrat () i Szescian () , 
z których każda zwraca wartość. Można napisać:

lOdp = ( RazyDwa( RazyTrzy( Kwadrat( Szescian( lWartosc )))));

Ta  instrukcja  pobiera  zmienną  lWartosc,  przekazuje  ją  jako  argument  do 
funkcji  Szescian  (),  zwracana  wartość  przekazywana  jest  z  kolei  od  funkcji 
Kwadrat(),  której  wynik  przekazywany  jest  do  funkcji  RazyTrzy  ()  w 
rezultacie  której  operuje  funkcja  RazyDwa  ()  .  Wynik  tego  podwajania, 
potrajania i potęgowania podstawiany jest do zmiennej lOdp.

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. 

background image

Alternatywnym  rozwiązaniem  jest  przypisanie  każdego  kroku  do  osobnych 
zmiennych:

unsigned long lWartosc = 2 ;

unsigned long lPotega3 = Szescian( lWartosc );// lPotenga3 =  
8

unsigned long lPotega2 = Kwadrat( lPotega3 ); // lPotenga2 = 
64

unsigned long lPrzez3  = RazyTrzy( lPotega2 );// lPrzez3  = 
192

unsigned long lPrzez2  = RazyDwa( lPrzez3 );  // lPrzez2  = 
384

Teraz  każda  pośrednia  wartość  może  zostać  przeanalizowana.  Jasna  jest 
również kolejność wykonywania operacji. 

background image

Parametry są zmiennymi lokalnymi

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. 

Ten  program,  w  funkcji  main()  , 
inicjalizuje 

dwie 

zmienne 

przekazuje  je  do  funkcji  Zamien()
która teoretycznie je zamienia. 

Jak 

widać, 

zmienne 

zostały 

przekazane  do  funkcji  tylko  przez 
wartość.  Zostały  stworzone  ich 
lokalne  kopie,  i  na  tych  kopiach 
były 

wykonywane 

wszelkie 

operacje.  Były  to  lokalne  zmienne 
funkcji  Zamien().  Zamiana  została 
dokonana  tylko  na  kopiach  i  nie 
miała  żadnego  wpływu  na  wartości 
zmiennych w funkcji main().

Jednak po przetestowaniu wyniku w 
funkcji  main()  okazuje  się,  że  nic 
się nie zmieniło! 

background image

Zwracanie wartości

Funkcje mogą zwracać albo jakąś wartość albo  voidvoid to informacja dla 
kompilatora, że funkcja nie będzie zwracać wartości. Żeby zwrócić wartość z 
funkcji,  należy  użyć  słowa  kluczowego  return,  a  następnie  podać  wartość, 
która ma zostać zwrócona. Równie dobrze może być to wyrażenie zwracające 
wartość. 

Przykład:

return 5 ;

return ( x > 5 ) ;

return (MojaFunkcja() );

Po napotkaniu słowa kluczowego return wartość wymieniona po return jest 
zwracana  jako  wartość  funkcji,  a  program  wraca  do  funkcji  wywołującej. 
Krótko mówiąc, instrukcja return, kończy wykonywanie danej funkcji. 

Wartość zwrócona będzie równa zero 
jeżeli  x  będzie  nie  większe  niż  5,  w 
przeciwnym  wypadku  będzie  równa 
1.  To  co  jest  zwracane  to  wartość 
wyrażenia, 0 (fałsz) lub 1 (prawda), a 
nie wartość zmiennej x.

W jednej funkcji można wielokrotnie wykorzystywać instrukcję return
Wykonanie instrukcji return powoduje zakończenie funkcji. 

background image

Funkcja  Denominator()  sprawdza,  czy  podana 
liczba 

nie 

jest 

większa 

od 

stałej 

GRANICAGORNA

.  Jeżeli  nie,  to  funkcja  zwraca 

jej 

wartość 

pomnożoną 

przez 

stałą 

DEWALUACJA

.  Jeżeli  jednak  liczba  jest  większa 

od  1000,  to  funkcja  zwraca  stałą 

ERROR

  jako 

wartość błędną.

Instrukcja    nigdy  nie  zostanie  wykonana, 
ponieważ  niezależnie  od  wartości  parametru 
(większy  od  1000  czy  nie)  funkcja  zawsze  wróci 
albo       albo        . 

Dobry kompilator zasygnalizuje, że ta 

instrukcja

 

nigdy  nie  zostanie  osiągnięta  w  trakcie 
wykonywania  programu.  Niektóre  kompilatory 
zwrócą  nawet  komunikat  błędu.  Można  tę  linię 
programu wykomentować.

background image

Parametry domyślne

Do  każdego  zadeklarowanego  w  prototypie  i  definicji  funkcji  parametru, 
funkcja wywołująca musi pobrać wartość zgodną z zadeklarowanym typem. 
Przykład:
Jeżeli funkcję zadeklarowaną w następujący sposób:

long Funkcja ( int ) ;

to  trzeba  przekazywać  do  niej  wartość  całkowitą.  Jeżeli  definicja  jest 
niezgodna  z  prototypem,  lub  jeżeli  wartość  przekazywana  nie  będzie 
całkowita  to  kompilator  zasygnalizuje  błąd. 

Od  tej  reguły  jest  jeden 

wyjątek

. Jeżeli w prototypie zadeklarujemy domyślną wartość dla parametru, 

to  gdy  nie  określimy  danego  argumentu,  zostanie  mu  przypisana 
automatycznie wartość domyślna. Odpowiednia deklaracja powinna wyglądać 
następująco:

long Funkcja ( int x = 10 ) ;

Definicja funkcji nie zmienia się. Nagłówek definicji nadal będzie miał postać:

long Funkcja ( int x )

Teraz,  gdy  wywoła  się  funkcję  bez  określenia  wartości  argumentu  to 
kompilator  automatycznie  nada  mu  wartość  10.  Nazwa  parametru  z 
wartością domyślną nie musi być taka sama jak w nagłówku definicji, wartość 
domyślna jest przypisywana na podstawie pozycji w liście parametrów, a nie 
według nazwy.

background image

Wartości domyślne można nadawać kilku parametrom funkcji. Jest tu jednak 
pewne ograniczenie, jeżeli parametr nie ma określonej wartości domyślnej, to 
żaden  z  poprzedzających  go  parametrów,  również  nie  może  posiadać 
wartości domyślnej. 

Jeżeli prototyp funkcji wygląda w następujący sposób:

long Funkcja ( int nParam1, int nParam2, int nParam3 ) ;

Przykład:

to  parametrowi  nParam2  można  przypisać  wartość  domyślną  wtedy  i  tylko 
wtedy  gdy  przypisze  się  również  wartość  domyślną  do  nParam3.  Podobnie, 
gdy chce się przypisać wartość domyślną do nParam1 to trzeba uwzględnić 
parametry nParam2 i nParam3 i również nadać im wartości domyślne. 

background image

Deklaracja  funkcji  ObjProstopadłościanu() 
jako funkcję mającą trzy parametry. Dla dwóch 
ostatnich są zadane wartości domyślne.

Jeżeli nie poda się nSzerokosci i nWysokosci 
to  program  wykorzysta  podane  wartości:  10  i 
3. 

Zdeklarowane i zainicjalizowane zmienne 
przekazywane są do funkcji 
ObjProstopadlościanu(). 

Wywołujemy 

funkcję 

ObjProstopadloscianu(), lecz tym razem bez 
parametru nWysokosc. Program wykorzystuje 
wartość domyślną (3). 

Trzecie 

wywołanie 

funkcji 

ObjProstopadloscianu()  Tym  razem  podany 
jest 

tylko 

jeden 

parametr 

nDlugosc

Pozostałym 

parametrom 

nadawane 

są, 

wartości domyślne. 

background image

Przeciążanie funkcji

C++  pozwala  na  stworzenie  więcej  niż  jednej  funkcji  o  tej  samej  nazwie. 
Możliwość  ta  określana  jest  jako  przeciążanie  funkcji.  Funkcje  takie 
muszą różnić się listą parametrów, typami parametrów lub ich liczbą. 

Przykład:

int FunkcjaNew ( intint ) ; 

int FunkcjaNew ( longlong ) ; 

int FunkcjaNew ( long ) ; 

FunkcjaNew  ()  jest  przeciążona  z  użyciem  trzech  rożnych  list  parametrów. 
Dwie pierwsze różnią się typem parametrów, trzecia ma inną ich liczbę. 

W  przypadku  przeciążanych  funkcji,  typ  wartości  zwracanej  może  być 
inny lub taki sam. Nie można przeciążać funkcji opierając się jedynie na 
typie wartości zwracanej. Trzeba wykorzystać różne listy parametrów. 

Przeciążanie  funkcji  określane  jest  również  mianem 

polimorfizmu 

funkcji

.

 

background image

Polimorfizm  pozwala  na  przeciążanie  funkcji  za  pomocą  różnych  ich  treści. 
Zmieniając  liczbę  lub  typ  parametrów,  można  nadać  funkcjom  te  same 
nazwy. W momencie wywołania, parametry będą decydować, która z funkcji 
zostanie wykonana. 

Załóżmy,  że  potrzebujemy  funkcję  podwajającą  dowolną  podaną  wartość. 
Chcielibyśmy  mieć  możliwość  podania  zmiennej  typu  int,  long,  float  i 
double

Przykład:

Bez 

przeciążania 

funkcji 

musiałoby  się  napisać  cztery 
funkcje o różnych nazwach:

int PodInt ( int ) ;

long PodLong ( long ) ;

float PodFloat ( float ) ;

doube PodDouble ( double ) ;

Natomiast 

użyciem 

przeciążenia 

można 

użyć 

następującej deklaracji:

int Pod ( int ) ;

long Pod ( long ) ;

float Pod ( float ) ;

double Pod ( double ) ;

background image

Funkcje wewnętrzne (inline)

Gdy  definiuje  się  funkcję,  kompilator  tworzy  w  pamięci  jeden  zestaw 
instrukcji. W momencie wywołania funkcji, program przechodzi do wykonania 
tych  instrukcji.  Gdy  funkcja  kończy  swoje  działanie,  program  wraca  do 
następnej instrukcji po wywołaniu.

Jeżeli  funkcja  jest  zadeklarowana  ze  słowem  kluczowym  inline,  to 
kompilator  nie  tworzy  prawdziwej  funkcji.  Kopiuje  natomiast  jej  kod  w 
każde miejsce wywołania. Nie jest wykonywany żaden skok. Wygląda to 
tak, jakby fizycznie wpisać treść funkcji zamiast ją wywoływać.

gdy funkcję wywołuje się 10 razy

program tyle samo razy "skoczy" do instrukcji danej 

funkcji. 

w pamięci istnieje tylko jedna kopia funkcji, (a nie 

10).

Prędkość 
wykonywania 
programu 
zwiększa  się  gdy 
unikniemy skoków 
do funkcji.

background image

Kiedy zatem stosować funkcje inline? 

Wtedy gdy ma się małą funkcję (dwie, trzy linie), to można pomyśleć o 

zamienieniu jej na wewnętrzną.

Jeżeli  wywoła  się  taką  funkcję  dziesięciokrotnie  to  treść  funkcji  zostanie 
skopiowana  w  każde  z  dziesięciu  miejsc  wywołania.  Niewielki  wzrost 
wydajności  może  okazać  się  nieopłacalny  w  stosunku  do  wzrostu  rozmiaru 
kodu wynikowego. 

Funkcje inline kosztują (pamięć).

background image

Deklaracja 

wygląda 

jak 

zwykły 

prototyp,  jedyna  różnica  polega  na 
użyciu  słowa  kluczowego  inline.  Taka 
deklaracja  funkcji  powoduje,  że  w 
tych miejscach:

nLiczba = 2 * nLiczba ;

nLiczba = 2 * nLiczba ;

nLiczba = 2 * nLiczba ;

background image

Przed 

wykonaniem 

programu, 

kompilator 

umieszcza  instrukcje  funkcji 
w  kodzie.  Oszczędza  się  w 
ten 

sposób 

na 

liczbie 

skoków wewnątrz kodu, lecz 
traci 

na 

rozmiarze 

programu.

background image

Bliższe spojrzenie na działanie funkcji

Wywołując funkcję, program przechodzi do wykonania instrukcji danej funkcji 
i  przekazuje  parametry.  Kiedy  funkcja  się  kończy,  zwracana  jest  wartość 
(ewentualnie  void)  i  program  wraca  do  miejsca,  z  którego  funkcja  została 
wywołana. 

 

Jak to zadanie jest zorganizowane? 

 Skąd program wie, dokąd ma przejść? 

 Gdzie są przechowywane zmienne przekazywane do funkcji? 

 Co się dzieje ze zmiennymi deklarowanymi wewnątrz funkcji? 

 W jaki sposób jest przekazywana wartość zwracane przez funkcję? 

 Skąd program wie, dokąd ma wrócić po wykonaniu funkcji?

Stos

Kiedy program rozpoczyna działanie, to kompilator tworzy stos. 

Stos  to  specjalny  obszar  pamięci  (struktura  danych)  służąca  do 
przechowywania  danych  wymaganych  przez  wszystkie  funkcje  w 
programie.  Określenie  stos  wynika  z  działania  tej  struktury,  wartość, 
która  została  położona  na  stos  jako  ostatnia  zostanie  zdjęta  jako 
pierwsza (LIFO ang. Last-in first-out). 

background image

Lepiej  jest  wyobrażać  sobie  stos  jako  odpowiedni  ciąg  komórek  pamięci 
ustawiony "do góry nogami". Szczyt jest tam gdzie wskazuje wskaźnik stosu. 

100

101

102

103

104

105

106

107

108

109

110

80

50

37

Stos

Zmienna

nMojaKasa

nTwojaKasa

poza stosem

na stosie

102

Wskaźnik 
stosu

Każda  komórka  stosu  ma  swój 
adres.  Jeden  z  tych  adresów  jest 
przechowywany 

rejestrze 

stosu.  Wszystko  poniżej  tego 
adresu,  nazywanego  szczytem 
stosu,  jest  traktowane  jako 
położone  na  stosie.  Wszystko 
powyżej jest poza stosem. 

background image

100

101

102

103

104

105

106

107

108

109

110

80

50

37

Stos

Zmienna

nMojaKasa

nTwojaKasa

poza stosem

na stosie

108

Wskaźnik 
stosu

Kiedy  wartość  jest  odkładana  na  stos,  to  jest  umieszczana  w  komórce 
powyżej  wskaźnika  stosu.  Wskaźnik  stosu  jest  przesuwany  na  tą  komórkę. 
Kiedy  wartość  jest  zdejmowana,  to  faktycznie  zmieniany  jest  tylko  wskaźnik 
stosu. 

background image

Stos i funkcje

Kiedy program wywołuje funkcję to tworzy dla niej ramkę stosu. Ramka stosu 
to  obszar  na  stosie,  przeznaczony  dla  danej  funkcji.  Jest  to  bardzo  ogólne  i 
rożnie  wykonywane  na  rożnych  komputerach.  Można  jednak  wyróżnić  kilka 
podstawowych kroków:

Umieść na stosie adres powrotny. Kiedy funkcja się skończy, to 

program wróci do tego adresu.

Zrób na stosie miejsca dla zadeklarowanej wartości zwracanej 

przez funkcję. 

Umieść na stosie argumenty funkcji.

Przejdź do wykonywania funkcji.

Umieść na stosie zmienne lokalne funkcji według ich definicji.


Document Outline