Goto
GoTo je kontrolna struktura, odnosno direktiva, naredba, "komanda" (engl. statement) koja postoji u mnogim programskim jezicima. Izvršava jednosmjerni prenos kontrole toka (programski skok) do odredjene lokacije u izvornom kôdu 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.[1][2]
Programski jezici koji imaju goto
, na različite načine i s različitim kombinacijama velikih i malih slova (kapitalizacija) su imenovali ovu direktivu, npr:
GO TO
(kapitalno, razdvojene riječi) - Neke stare verzije Basica u Time-sharing sistemima;[3]
goto
,Goto
,GoTo
... (nebitna kapitalizacija) - Pascal i drugi programski jezici koji ne razlučuju kapitalizaciju identifikatora i rezerviranih riječi (engl. keyword).
Sintaksa goto
kontrolne strukture u svim jezicima je uglavnom ista:
goto <Destination>
gdje destinacija može biti označena linijskim brojem (BASIC, FORTRAN 77) ili labelom, posebnom imenovanom "konstantom" (Pascal, C/C++). Direktiva goto
se obično upotrebljava unutar If-Then-Else blokova, na sledeći način:
if <Expression> then
goto <LabelName1>
else
goto <LabelName2>
Programski jezik Pascal zahtijeva deklaraciju labele, kao i bilo koje druge varijable, konstante ili tipa podataka, 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.[4]
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.[5]
{$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.
@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
Osim jednostavne direktive goto
, 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 (integer) 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:[3]
50 GO TO N OF 100, 200, 300, 400
U modernijim, strukturiranim programskim jezicima, umjesto ove razgranate strukture koristi se različito nazvana instrukcija višestrukoga izbora: switch
(C/C++), case
(Pascal), select case
(Fortran 90, QBasic, Visual Basic).
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:[6]
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
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:[3]
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;
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.[7]
- 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 */
- ↑ Edsger W. Dijkstra. „Go To Statement Considered Harmful”.
- ↑ Donald Knuth. „Structured Programming with Go To Statements”. Arhivirano iz originala na datum 2020-05-29. Pristupljeno 2019-11-26.
- ↑ 3,0 3,1 3,2 Željko Reljić, Branimir Makanec (1984). BASIC kompjuterski jezik. Tehnička knjiga, Zagreb.
- ↑ Dijkstra, Edsger W. (March 1968). „Letters to the editor: Go-to statement considered harmful”. Communications of the ACM 11 (3): 147–148.
- ↑ „PHP: goto - Manual”. PHP.net.
- ↑ Željko Reljić, Branimir Makanec (1984). BASIC kompjuterski jezik. Tehnička knjiga, Zagreb. str. 84.
- ↑ Brian W. Kernighan, Dennis M. Ritchie (1988). The C Programming Language (Second Edition). Prentice Hall.