english version while1 - stránky o programování

Funkce

Popis

Funkce a procedury jsou jenom jiná jména pro podprogramy. Požadavek na jejich provedení nazýváme volání.

  • funkce - podprogram s návratovou hodnotou
  • procedura - podprogram bez návratové hodnotou

Podprogramy usnadňují modifikaci a čitelnost programu. Obsahují často (vzácně pouze jednou) používaný úsek kódu pro jehož vykonání stačí daný podprogram zavolat. Z pohledu procesoru proběhne :

  • uložení adresy následující instrukce
  • skok na začátek podprogramu
  • provedení podprogramu
  • návrat do programu - skok na dříve uloženou adresu

Jazyk C a jazyky od něj odvozené nerozlišují mezi procedurami a funkcemi a používají pouze funkce.

Vývojový diagram

Přirozený jazyk

JSA

NASM

  • Aby nedošlo k zničení obsahu registrů, je nutné všechny registry na začátku podprogramu uložit na zásobník a na jeho konci jejich obsah odebráním ze zásobníku opět obnovit.
  • Volání podprogramu instrukcí CALL.
  • Návrat z podprogramu instrukcí RET.


podprogram[ printb.asm ]
; vypis Bajtu 

bits 16
        
segment code 
;----------------------------------------------------------------------------
;  printb : vypis bajtu
;  hodnota pro tisk predana registrem (al)
;----------------------------------------------------------------------------
   printb:
      pushf        ; ulozeni obsahu registru
      pusha
      
      mov si, 2     ; posunuti ve vystupnim retezci
      mov bl, 10    ; zaklad soustavy
      
; opakovane deleni zakladem soustavy (bl)     
; zapis zbytku kazdeho radu do vystupniho retezce
pbdiv: 
      mov ah, 0
      div bl        ; al (div),  ah (mod) 
      add ah, '0'
      mov [strtmp+si], ah
      dec si
      cmp si, 0
      jnz pbdiv
      
      add al, '0'
      mov [strtmp], al
      mov dx, strtmp    ; zacatek retezce do (dx)
      mov si, 0
      
; odstraneni uvodnich nul cisla (001 -> 1)      
pbrem: 
      cmp [strtmp+si], byte '0'
      jne pbprint
      inc dx
      inc si
      cmp si, 2   ; odstranit prvni dve 0, treti nechat (000 -> 0)
      jne pbrem
      
pbprint: 
; vypis retezce
      mov ah, 9 
      int 21h

      popa     ; obnoveni obsahu registru
      popf
      ret      ; navrat do programu
;----------------------------------------------------------------------------	
;  printnl : novy radek
;  prechod na novy radek vystupu
;----------------------------------------------------------------------------
   printnl:
      pushf     ; ulozeni obsahu registru
      pusha
      
      mov dx, strnl ; vypis retezce
      mov ah, 9 
      int 21h

      popa     ; obnoveni obsahu registru
      popf
      ret      ; navrat do programu
;----------------------------------------------------------------------------	
;  press : 
;  cekani na stisk klavesy s vypisem zpravy 'Stisknete klavesu...'
;----------------------------------------------------------------------------
   press:
      pushf     ; ulozeni obsahu registru
      pusha
      
; vypsani zpravy
      mov dx, strwait 
      mov ah, 9 
      int 21h
  
; nacteni klavesy
      mov ah, 8		
      int 21h

      popa     ; obnoveni obsahu registru
      popf
      ret      ; navrat do programu
;----------------------------------------------------------------------------	

..start: 
  mov ax, data	
  mov ds, ax 
  mov ax, stack 
  mov ss, ax 
  mov sp, stacktop


  mov al, 125  ; hodnota pro tisk predana registrem (al)
  call printb  ; volani podprogramu
  
  call printnl ; novy radek
  call press   ; cekej na stisk klavesy


; navrat do OS
  mov ah, 4ch  
  int 21h

segment data 
strwait   	db 'Stisknete klavesu...', 13, 10, '$'
strnl     	db 13, 10, '$'  ; cr lf : '\n'
strtmp      resb 3          ; 3 vyhrazene bajty pro vystup cisla
            db '$'        
            
segment stack stack 
        resb 64 
stacktop:

Pascal

  • Procedury procedure print(a:integer); bez návratové hodnoty a funkce function max(a,b:integer):integer; s návratovou hodnotou.
  • Procedury i funkce (podprogramy) umožňují lokální deklarace a definice : konstant, typů, proměnných, funkcí a procedur.
  • Ukazatel na funkci

C/C++

Přetížení jmen

Přetížení jmen pro funkce vykonávající stejnou úlohu na různých typech. Při volání jména funkce bude z deklarovaných vybrána ta, jejíž typy formálních parametrů jsou neblíže předaným parametrům tak aby došlo k minimální ztrátě informací.



pretizeni jmena funkce[ pretizeni.cpp ]
/* pretizeni jmen funkci */ 

#include <stdio.h>

 double plus(double a, double b) { 
     printf("double plus(double %.1f, double %.1f)\n", a, b);
     return a+b; 
 }
 int plus(int a, int b) { 
     printf("int plus(int %d, int %d)\n", a, b);
     return a+b;
 }
 
int main(int argc, char *argv[]) {
    plus(1,   2  );
    plus(1,   (int)2.2);    /* explicitni konverze */     
    plus(1.0, (double)2  ); /* explicitni konverze */
    plus(1.0, 2.2);    
    return 0;
}

Ukazatel na funkci

void (*p)(int);

Proměnná (p) je typu ukazatel na funkci s jedním celočíselným parametrem.



ukazatel na funkci[ fptr.cpp ]
/* ukazatel na funkci */

#include <stdio.h>

int plus  (int a, int b)  { return a+b; }
int minus (int a, int b)  { return a-b; }

int main(int argc, char argv[]) {
    /* promenna (p) je typu ukazatel na funkci int id(int,int) */
    int (*p)(int,int);  
    
    int c; 
    
    p = &plus;     /* prirazeni adresy funkce plus */
    c = (*p)(1,2); /* A: volani funkce pres ukazatel */
    printf(" plus %d \n", c); 
    
    p = &minus;    
    c = (*p)(1,2); /* B: stejny zapis volani (jako A) */
    printf(" minus %d \n", c);    
    
    return 0;
}

Inline funkce

inline int plus(int a, int b) { return a+b };

Kód inline funkce a+b se překladač pokusí dosadit na všechna místa volání funkce plus. Inline nelze použít pro rekurzivní funkce kde k (opakovanému) volání dojít musí.

Java

  • Funkce nelze zapisovat samostatně, ale pouze v rámci tříd. Taková funkce se potom nazývá metodou a tvoří rozhraní třídy.

JavaScript

  • Delší funkce se ukládají do externích souborů (.js).
  • Kratší funkce se definují přímo do HTML kódu.

Matlab

  • Uložené do samostatných souborů (.m) se stejným jménem jako identifikátor funkce.
  • Funkce lze také vytvářet příkazovým řádkem Matlabu (dočasné).
  • Přetěžování jmen funkcí ukládáním do adresářů podle typu parametrů: \@double, \@int32.
  • Privátní funkce s omezením přístupu vzniknou uložením do nového podadresáře private. Privátní funkce jsou dostupné pouze z funkcí uložených v nadřazeném adresáři.
  • Soubor s funkcí (.m) může obsahovat více podfunkcí, přístupných pouze v rámci tohoto souboru.
  • Předčasný návrat z funkce příkazem return.


přidání nové funkce[ euklid.m ]
function max = euklid(a, b);
% funkce euklid (Eukliduv algoritmus)
% nejvetsi spolecny delitel cisel a,b
% ------------------------------------------------
% vstup   a,b ... povinne
% vystup  max ... nejvetsi spolecny delitel
% ------------------------------------------------
while b~=a      %dokud je b ruzne od a
   if a>b       %a je vetsi nez b
      a = a-b;  %sniz a o b
   else         %a je mensi nez b
      b = b-a;  %sniz b o a
   end
end
max = a;  %vysledek (a == b)

PHP

function plus($a, $b) { return $a+$b; }
  • Nemá přetěžování jmen. Funkce stejného jména nelze bez typovaných parametrů rozlišit.
Kontakt
Prohlášení o dostupnosti
Tisk stránky
Autor: Václav Bubník © 2005
vbubnik@post.cz
XHTML 1.0| CSS