Goto naredba

(Preusmjereno sa Goto)

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.[1][2]

NazivUredi

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:

  • GO TO (kapitalno, razdvojene riječi) - Neke stare verzije Basica u Time-sharing sistemima;[3]
  • goto (samo verzalna slova) - C, C++, C#;
  • goto, Goto, GoTo ... (nebitna kapitalizacija) - Pascal i drugi programski jezici koji ne razlučuju kapitalizaciju identifikatora.

UpotrebaUredi

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.[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]

PrimjeriUredi

PascalUredi

{$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 CMDUredi

@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

VarijacijeUredi

Razgranati GotoUredi

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:[3]

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 naredbeUredi

GoSubUredi

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

On ... GoSubUredi

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;

Break & ContinueUredi

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 */

IzvoriUredi

  1. Edsger W. Dijkstra. „Go To Statement Considered Harmful”. http://bioinfo.uib.es/~joemiro/teach/material/escritura/gotoharmfulCol.pdf. 
  2. Donald Knuth. „Structured Programming with Go To Statements”. Arhivirano iz originala 2020-05-29. https://web.archive.org/web/20200529091416/http://www.cs.sjsu.edu/~mak/CS185C/KnuthStructuredProgrammingGoTo.pdf. 
  3. 3,0 3,1 3,2 Ž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. https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf. 
  5. „PHP: goto - Manual”. PHP.net. http://php.net/manual/en/control-structures.goto.php. 
  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.