**GoTo** je kontrolna struktura, odnosno naredba (komanda, engl. *statement*) koja postoji u mnogim programskim jezicima. Izvršava jednosmjerni prenos kontrole toka (*programski skok*) do odredjene lokacije u kodu programa. Lokacija se uglavnom identificira imenovanom *labelom*, ili rednim brojem linije. U današnje vrijeme ova naredba se u programiranju uglavnom izbjegava, te postoji kritički odnos prema uporebi ove naredbe u strukturiranim programskim jezicima.

Naziv
-----

Programski jezici koji imaju `goto`, na različite načine i s različitim kombinacijama velikih i malih slova (*kapitalizacija*) su imenovali ovu naredbu, npr:

* `GOTO` (samo kapitalna slova) - FORTRAN, BASIC;

* `GO TO` (kapitalno, razdvojene riječi) - Neke stare verzije Basica u *Time-sharing* sistemima;

* `goto` (samo verzalna slova) - C, C++, C#;

* `goto`, `Goto`, `GoTo` ... (nebitna kapitalizacija) - Pascal i drugi programski jezici koji ne razlučuju kapitalizaciju identifikatora.

Upotreba
--------

Sintaksa komande u svim jezicima je uglavnom ista:

`**goto** <dest>`

gdje destinacija može biti označena linijskim brojem (*BASIC*, *FORTRAN 77*) ili *labelom*, posebnom imenovanom "konstantom" (*Pascal*, *C/C++*). Naredba `goto` se obično upotrebljava unutar If-Then-Else blokova, na sledeći način:

`if <expr> then **goto** <label>`

Programski jezik Pascal zahtijeva deklaraciju labele, kao i bilo koje druge varijable, konstante ili tipa, dok se destinacija obilježava imenom labele iza koje slijedi dvotočka:

```
label DstX;
{ ... }

goto DstX;
{ ... }

DstX:
{ ... }

```

Upotreba naredbe `goto` naročito je bila česta u starijim programskim jezicima sekvencijalnoga karaktera, umjesto pozivanja *podprograma* (*funkcija* ili *procedura*), kako se to inače radi u proceduralnim i funkcijskim jezicima. Za razliku od poziva funkcije, koji vraća kontrolu toka programa natrag nakon izvršenja, naredba `goto` prenosi kontrolu toka samo u jednom smjeru. Zbog toga nije pogodna za strukturirano programiranje i pisanje pregledna, uredna programskoga koda, što je dovelo do kritika protiv upotrebe naredbe još 60-ih godina 20. stoljeća.

Neki programski jezici ne podržavaju ovu naredbu, kao npr. Java, iako je u Javi `goto` rezervirana riječ (engl. *keyword*), što znači da se ne može koristiti za imenovanje identifikatora. Proceduralni programski jezici *Pascal* i *C/C++* podržavaju `goto`, ali ne dopuštaju skakanje izvan dosega funkcije ili procedure. PHP nije imao `goto` sve do verzije 5.3.

Primjeri
--------

### Pascal

```
{$id: ALGMD-20100530}
unit Harmful;

interface(\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*)

function ProdOfInts(Op1, Op2: LongInt): LongInt;
function PowerOfInt(Base: LongInt; Exp: LongInt): LongInt;

implementation(\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*)

var
  Result: LongInt;

function ProdOfInts(Op1, Op2: LongInt): LongInt;
label
  0, 1;
begin
0:
  Result := 0;
1:
  Result := Result + Op1;
  Op2 := Op2 - 1;

  if Op2 <> 0 then
 goto 1
  else if Op2 = 0 then
    ProdOfInts := Result;
end;

function PowerOfInt(Base: LongInt; Exp: LongInt): LongInt;
begin
  Result := 1;

  while Exp <> 0 do
  begin
    Exp := Exp - 1;
    Result := ProdOfInts(Base, Result);
  end;

  PowerOfInt := Result;
end;

begin(\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*)end.

```

### Windows CMD

```
@echo off

setlocal
set project=Harmful
set options=-Sg -WN -Xs -XX

call :main
endlocal
goto :eof

:main
fpc %project%.pp %options%

if exist %project%.pp* (
 goto :eof
) else (
	call :error
)

goto :eof

:error
echo:
echo Compilation error.
pause

:eof

```

Varijacije
----------

### Razgranati Goto

Osim jednostavne naredbe, još u starijim, nestrukturiranim verzijama *Fortrana* i *Basica* postojala je i složenija kontrolna struktura - **izračunati goto** ili **razgranati goto**. Za razliku od obične *goto* instrukcije, *razgranati goto* omogućuje više od jedne destinacije za programski skok, u ovisnosti o vrijednosti kondicionalne varijable ili izraza (ekspresije) unutar razgranate strukture. U Fortranu sintaksa izgleda ovako:

`**goto** (l1, l2, ... ln) <expr>`

Na primjer:

```
GOTO (20, 30, 40) i

```

U ovom primjeru programski skok će se izvršiti na osnovi vrijednosti cjelobrojne varijable `i`. Za svako `i = n`, `GOTO` skače do one destinacije u listi (navedene u zagradi), za koju vrijedi da je njezin redni broj u listi jednak vrijednosti varijable `i`. Dakle:

```
? (i = 1) -> goto 20
? (i = 2) -> goto 30
? (i = 3) -> goto 40
```

Za bilo koju drugu vrijednost `i` različitu od `1, 2, 3`, ne će se izvršiti nijedan od skokova.

Basic je imao sličnu razgranatu strukturu s istom funkcionalnošću, `ON ... GOTO`, odnosno `GO TO ... OF ...` (u ovisnosti o verziji Basica). Primjer upotrebe:

```
50 ON i GOTO 100, 200, 300, 400

```

Starija, manje poznata varijanta:

```
50 GO TO N OF 100, 200, 300, 400

```

U modernijim, strukturiranim programskim jezicima, umjesto ove razgranate strukture koristi se različito nazvana *naredba višestrukoga izbora*: `switch` (*C/C++*), `case` (*Pascal*), `select case` (*Fortran 90*, *QBasic*, *Visual Basic*).

Slične naredbe
--------------

### GoSub

`GOSUB` ili `GO SUB` je naredba u Basicu za pozivanje **podprograma**. Za razliku od `GOTO` naredbe u Basicu, koja vrši jednosmjeran transfer kontole toka, `GOSUB` omogućuje povratak na mjesto pozivanja, nakon izvršenja podprograma, pomoću ključne riječi `RETURN`.

`**GOSUB** <expr> <...> **RETURN**`

Kako je `GOSUB ... RETURN` konstrukcija u Basicu riješena na posve nestrukturiran način, iza koda glavnoga programa i prije početka pisanja podprograma mora se navesti ključna riječ `STOP`, da bi se osiguralo da program nakon izvršenja glavnoga dijela ne nastavi izvršavanje svih navedenih podprograma onim redom kojim su upisani.

Primjer:

```
10 REM \*\*\* Rješavanje kvadratne jednačbe \*\*\*
20 PRINT "Koliki su koeficijenti a, b, c? "
30 INPUT A, B, C
40 GOSUB 500
45 IF (B^2 - 4\*A\*C) < 0 THEN 10
50 PRINT "Korijeni ove jednačbe su: "
60 PRINT "x1 = "; X1 "x2 = "; X2
70 STOP
500 REM \*\*\* Podprogram za determinantu \*\*\*
510 IF (B^2 - 4\*A\*C) < 0 THEN 600
520 X1 = (-B + (B^2 - 4\*A\*C)^(1/2)) / (2\*A)
530 X2 = (-B + (B^2 - 4\*A\*C)^(1/2)) / (2\*A)
540 GOTO 610
600 PRINT "Determinanta je manja od nule. "
610 RETURN
620 END

```

### On ... GoSub

Slično kao razgranati `GOTO`, i `GOSUB` ima svoju razgranatu varijantu.
`GOSUB` instrukcija koja odlučuje o programskom skoku na osnovi evaluacije izraza, ima sledeći oblik:

`**ON** <expr> **GOSUB** <d1, d2, d3, ... dn>`

Manje popularna varijanta u nekim starijim *BASIC* interpreterima / *Time-sharing* sistemima:

`**GO SUB** <expr> **OF** <d1, d2, d3, ... dn>`

Npr:

```
50 GOSUB X OF 110, 210, 320, 1400

```

Izvršenje:

```
x = 1 : GOTO 110;
x = 2 : GOTO 210;
x = 3 : GOTO 320;
x = 4 : GOTO 1400;
x < 1 : GOSUB se ne izvršava;
x > 4 : GOSUB se ne izvršava, jer su zadane samo 4 destinacije;
```

### Break & Continue

U programskom jeziku C, osim `goto` postoje i naredbe za skok iz petlje. Naredba `break` prekida izvršavanje petlje unutar koje je pozvana vraćajući tok programa na lokaciju prije pojavljivanja petlje, dok `continue` ponovno testira brojač (ako je u pitanju `for` iteracija) ili uslov iteracije (kod `while` petlji). Primjeri korištenja `break` i `continue` skokova preuzeti su iz knjige *Programski jezik C* autora Dennisa Ritchieja i Briana Kernighana.

* **Break**

```
/\* trim: remove trailing blanks, tabs, newlines \*/
int trim(char s[])
{
 int n;

 for (n = strlen(s)-1; n >= 0; n--)
 if (s[n] != ' ' && s[n] != '\t' && s[n] != '\n')
 break;

 s[n+1] = '\0';
 return n;
}

```

* **Continue**

```
for (i = 0; i < n; i++)
 if (a[i] < 0) /\* skip negative elements \*/
 continue;

 /\* do positive elements \*/

```

Izvori
------

1. ↑  Edsger W. Dijkstra. „Go To Statement Considered Harmful".
2. ↑  Donald Knuth. „Structured Programming with Go To Statements". Arhivirano iz originala na datum 2020-05-29. Pristupljeno 2019-11-26.
3. 1 2 3  Željko Reljić, Branimir Makanec (1984). *BASIC kompjuterski jezik*. Tehnička knjiga, Zagreb.
4. ↑  Dijkstra, Edsger W. (March 1968). „Letters to the editor: Go-to statement considered harmful". *Communications of the ACM* **11** (3): 147–148.
5. ↑  „PHP: goto - Manual". PHP.net.
6. ↑  Željko Reljić, Branimir Makanec (1984). *BASIC kompjuterski jezik*. Tehnička knjiga, Zagreb. str. 84.
7. ↑  Brian W. Kernighan, Dennis M. Ritchie (1988). *The C Programming Language (Second Edition)*. Prentice Hall.