# Subprogramo

|  |  |
| --- | --- |
|  | *Ĉi tiu artikolo temas pri parto de programo. Por funkcio en matematiko rigardu la paĝon Funkcio (matematiko).* |

En programlingvoj, **subprogramo** aŭ **proceduro** aŭ **funkcio** estas grupo da ordonoj (programpeco), plenumebla per vokoj el diversaj partoj de komputila programo.

## Terminologia noto

Estas pluraj programadaj skoloj, estiĝintaj ĉirkaŭ pluraj familioj programlingvaj, kaj por la koncepto pri kiu temas ĉi tiu artikolo ili uzas malsamajn terminojn.

En Fortrano kaj ĝia familio oni preferas la terminon *subprogramo* (angle *subroutine*). La termino estas intuicie klara kaj radikŝpara; bedaŭrinde, ĝi povas esti misgvida, ĉar ekzistas ankaŭ aliaj programpartoj (ekz-e la programmoduloj, la kunprogramoj), kiuj rajtus pretendi je tiu nomo. Krome, pro la Fortrana deveno, iuj supozas, ke *subprogramoj* ne povas esti rekursiaj.

En la tradicio de la Algola skolo la koncepton oni nomas **proceduro** (angle *procedure*); oni parolas pri *deklaro de proceduro*, pri *procedurvoko* — tamen se oni vokas proceduron liverantan rezulton ene de esprimo, tiam oni nomas la vokon *funkcia* (angle *function designator*).

En Paskalo (kiu ja devenas el la Algola familio) la proceduroj senrezultaj restis *proceduroj*, dum la proceduroj liverantaj rezulton ricevis la nomon **funkcio**.

Aliflanke, en la programlingvo C la supernocia termino estas **funkcio**; se C-funkcio ne liveras rezulton (kiel la Paskalaj *proceduroj*), oni nomas ĝin **senrezulta funkcio** (angle *void function*).

Ĉi-sube ni, laŭ la Algola tradicio, uzos supernocie la terminon *proceduro*.

## Procedurdeklaro

Por ebligi uzadon de proceduro oni devas ĝin *deklari*. Procedurdeklaro entenas la algoritmon realigatan de la proceduro (ĝuste tion, kio pravigas la nomo *subprogramo*), kaj la interfacon, difinantan la manieron, kiel oni voku la proceduron.

La algoritman parton oni nomas **korpo de proceduro**; la interfacon, **ĉapo de proceduro**.

### Ekzemplo

Jen estas ekzempla programpeco en esprantigita Paskala pseŭdokodo, entenanta deklaron de funkcio `Maks`:

```
 01  **konst** n = 1000;
 02  **tipo** Vektoro = **tabelo** [1..n] **el** reelaj;

```

```
 03  **funkcio** Maks(**var** A: Vektoro; m: entjera): reela;
 04     **var** x: reela; i: entjera;
 05     **starto**
 06        x := A[1];
 07        **por** i := 1 **supre** n **faru**
 08           **se** A[i] < x **tiam** x := A[i];
 09        Maks := x;
 10     **fino** {Maks};

```

### Ĉapo de proceduro

En la ĉi-supra ekzemplo la ĉapo de proceduro (ĉi-okaze, de *funkcio*) okupas la linion 03. Ĝi indikas:

1. specon de proceduro (*funkcio*),
2. ĝian nomon (*Maks*),
3. la du *formalajn parametrojn* (*A* kaj *m*),
4. la manierojn de ilia *pasigo* (variable por *A*, per valoro por *i*),
5. iliajn datumtipojn (*Vektoro, entjera*) kaj la tipon de la liverota rezulto (*reela*).

### Korpo de proceduro

La korpo (linioj 04–10) entenas la deklarojn de la lokaj variabloj (04) kaj la ordonojn. La valorizo en la linio 09 estas maniero indiki la rezulton liverotan de la funkcio.

## Voko de subprogramo

### Voko de funkcio

*Voko de funkcio* (aŭ *funkcivoko*) havas tradician sintakson matematikan; ĝi povas aperi en esprimo:

```
 q := Maks(V, k **div** 2);

```

### Voko de proceduro

*Voko de proceduro* senrezulta (aŭ *procedurvoko*) kutime havas la saman «funkcian» sintakson, tamen aperas en la pozicio de ordono — ĉu nude (kiel en Paskalo kaj plimulto da altnivelaj programlingvoj):

```
  **se** k < n **tiam** Transponu(M, k, n);

```

aŭ kun anoncvorto `call` (voku), `gosub` (iri al sub[programo]) aŭ simile (tiel en Fortrano, BASIC kaj asemblaj lingvoj):

```
   **call** Transponu(M, k, n)

```