SA-MP Forums Archive
[Ajuda] Por que nгo se deve usar o goto ? - Printable Version

+- SA-MP Forums Archive (https://sampforum.blast.hk)
+-- Forum: Non-English (https://sampforum.blast.hk/forumdisplay.php?fid=9)
+--- Forum: Languages (https://sampforum.blast.hk/forumdisplay.php?fid=33)
+---- Forum: Português/Portuguese (https://sampforum.blast.hk/forumdisplay.php?fid=34)
+---- Thread: [Ajuda] Por que nгo se deve usar o goto ? (/showthread.php?tid=584183)



Por que nгo se deve usar o goto ? - Detoria - 02.08.2015

Eu estava dando uma olhada na wiki do SA-MP,e notei o goto,a wiki diz que nгo se deve usa-lo,mas nгo diz por que..

Caso alguйm puder explicar o motivo disso,eu ficaria grato.

E caso nгo seja incomodo,peзo tambйm alguns exemplos de uso do mesmo. (sem ser em loops,por favor)


Re: Por que nгo se deve usar o goto ? - Dolby - 02.08.2015

Boa leitura.


Re: Por que nгo se deve usar o goto ? - Detoria - 02.08.2015

Entгo nгo passa de um mito...

O uso do goto nгo traz prejuнzos,mais pode confundir programadores mais desatentos..

No caso,eu usei o goto para checagens,nгo hб como fechar um label,pelo menos,nгo de cara,entгo,eu suponho que,todos os labels devem ser colocados no final da callback para evitar conflitos e confusхes dentro do cуdigo:

PHP код:
public OnPlayerText(playeridtext[])
{
        
/*
            Let's try the basics,QUESTIONS.
        */
        
if(!strcmp(text[0],"How",true) && !strcmp(text[2],"can",true)) goto question_Handler;
        else if(!
strcmp(text,"Pilar",true) || !strcmp(text[0],"Pilar",true) && !strcmp(text[1],".",true)) goto conversation_Handler;
        
//Labels - Yes,I'm gonna try it.
        
question_Handler:printf("Pilar: %s made a question to me,can't answer because I'm not able to do that now."GetPlayerExactlyName(playerid));
        
conversation_Handler:printf("Pilar: %s is starting a conversation with me,I'm so nervous.."GetPlayerExactlyName(playerid));
        return 
1;

Ok,mas,e se eu passar pra uma outra linha e tentar continuar meu cуdigo fora da label ?

PHP код:
public OnPlayerText(playeridtext[])
{
        
/*
            Let's try the basics,QUESTIONS.
        */
        
if(!strcmp(text[0],"How",true) && !strcmp(text[2],"can",true)) goto question_Handler;
        else if(!
strcmp(text,"Pilar",true) || !strcmp(text[0],"Pilar",true) && !strcmp(text[1],".",true)) goto conversation_Handler;
        
//Labels - Yes,I'm gonna try it.
        
question_Handler:printf("Pilar: %s made a question to me,can't answer because I'm not able to do that now."GetPlayerExactlyName(playerid));
        
conversation_Handler:printf("Pilar: %s is starting a conversation with me,I'm so nervous.."GetPlayerExactlyName(playerid));
        
SendClientMessage(playerid, -1"Pilar: That's me,how can I help ?");
        return 
1;

No caso,ele vai continuar dentro da label,ou jб era ?
Porque se for,eu teria que fazer tudo inline,e isso nгo й uma boa coisa..


Re: Por que nгo se deve usar o goto ? - Dolby - 02.08.2015

Nesse caso, nгo й necessбrio usar goto. Vocк sу faz dar saltos desnecessбrios, o que pode consumir mais tempo de execuзгo.

PHP код:
if(!strcmp(text[0],"How",true) && !strcmp(text[2],"can",true)) printf("Pilar: %s made a question to me,can't answer because I'm not able to do that now."GetPlayerExactlyName(playerid));
        else if(!
strcmp(text,"Pilar",true) || !strcmp(text[0],"Pilar",true) && !strcmp(text[1],".",true)) printf("Pilar: %s is starting a conversation with me,I'm so nervous.."GetPlayerExactlyName(playerid)); 
Fora o que vocк chegou a ler no tуpico que linkei, eu recomendaria evitar o uso de goto. Nгo que ele traga malefнcios, mas que seu mal uso pode gerar problemas, fora a velocidade. Estamos tratando de uma linguagem imperativa, e dar "saltos" no cуdigo pode fugir um pouco deste conceito.


Re: Por que nгo se deve usar o goto ? - Detoria - 02.08.2015

Sim mas,se caso eu procure usar o goto em algo,como eu saberia que tudo que digitei depois do cуdigo que fora planejado para a label estaria fora da mesma ?

Й por isso que eu digo que pode ser melhor deixar as labels para o final da callback para garantir pelo menos que,elas serгo fechadas quando vocк fechar a callback.

PHP код:
public OnPlayerText(playeridtext[]) 

        if(!
strcmp(text[0],"How",true) && !strcmp(text[2],"can",true)) goto question_Handler
        else if(!
strcmp(text,"Pilar",true) || !strcmp(text[0],"Pilar",true) && !strcmp(text[1],".",true)) goto conversation_Handler;
        
question_Handler:
        
printf("Pilar: %s made a question to me,can't answer because I'm not able to do that now."GetPlayerExactlyName(playerid));
        
//Code stays on that label     -    O cуdigo abaixo deve continuar nessa label
        
SendClientMessage(playerid, -1"Pilar: That's me,how can I help ya ?");
        
//Another label to close the question label
        
conversation_Handler:
        
printf("Pilar: %s is starting a conversation with me,I'm so nervous.."GetPlayerExactlyName(playerid));
        
SendClientMessage(playerid, -1"Pilar: Yes ?");
        
//The next code can't be a part of the actual label
       //code...

EDIT: Serб que iria ser necessбrio fazer outra label para o resto do cуdigo ?

PHP код:
public OnPlayerText(playeridtext[]) 

        if(!
strcmp(text[0],"How",true) && !strcmp(text[2],"can",true)) goto question_Handler
        else if(!
strcmp(text,"Pilar",true) || !strcmp(text[0],"Pilar",true) && !strcmp(text[1],".",true)) goto conversation_Handler;
        else goto 
continueCode;    // <-----   No,just...no.
        
question_Handler:
        
printf("Pilar: %s made a question to me,can't answer because I'm not able to do that now."GetPlayerExactlyName(playerid));
        
//Code stays on that label     -    O cуdigo abaixo deve continuar nessa label
        
SendClientMessage(playerid, -1"Pilar: That's me,how can I help ya ?");
        
//Another label to close the question label
        
conversation_Handler:
        
printf("Pilar: %s is starting a conversation with me,I'm so nervous.."GetPlayerExactlyName(playerid));
        
SendClientMessage(playerid, -1"Pilar: Yes ?");
        
//The next code can't be a part of the actual label
        
continueCode:
       
//code...




Re: Por que nгo se deve usar o goto ? - Dolby - 02.08.2015

Eu nгo entendi muito bem onde deseja chegar, mas tenha em mente que goto serve para dar saltos no cуdigo.

Vejamos... Vocк tem todo um cуdigo estruturado, e deseja pular todo ele, ir direto para o final, vocк pode usar goto. No entanto, nгo й a melhor forma de se fazer isto. Vocк pode fazer com if, com switch(default), etc.


Re: Por que nгo se deve usar o goto ? - Detoria - 02.08.2015

Vamos dizer que,alguйm se interesse pelo goto,um scripter novato (ou um scripter cleo,eles tambйm usam goto,sу que lб,a funзгo se chama jump,mas isso nгo importa no momento),esse cara vai lб e usa o goto,cria suas labels normalmente,mas deixa todas elas no inнcio do script:

PHP код:
public OnPlayerConnect(playerid)
{
    new 
playerName[MAX_PLAYER_NAME];
    
GetPlayerName(playeridplayerNameMAX_PLAYER_NAME);
    
//Labels
    
PLAYER_ADMIN:
    new 
clientMessage[144];
    
format(clientMessage,sizeof clientMessage,"Administrador %s entrou no servidor.",playerName);
    
SendClientMessageToAll(-1,clientMessage);
    
    
PLAYER_NORMAL:
    new 
clientMessage[144];
    
format(clientMessage,sizeof clientMessage,"%s entrou no servidor.",playerName);
    
SendClientMessageToAll(-1,clientMessage);
    
    
//Checagens
    
if(IsPlayerAdmin(playerid)) goto PLAYER_ADMIN;//Pelo que sei,vocк pode entar como administrador inserindo a senha direto no launcher
    
else goto PLAYER_NORMAL;
    return 
1;

Esse й o problema Dolby,se vocк tentar compilar esse cуdigo,o compilador vai te dizer que a variavel clientMessage jб foi criada,mas como ela foi criada,sendo que a outra label nгo foi chamada para criar essa variavel antes ?

Isso pode ser um erro de interpretaзгo do compilador ou o goto nгo deve funcionar direito no caso,nгo hб como fecha-lo,e isso й um problema..


Re: Por que nгo se deve usar o goto ? - Dolby - 02.08.2015

Como as labels estгo acima do goto, o fluxo de execuзгo vai executa-las normalmente. Como eu disse, o goto faz apenas um pulo, ou seja, volta ou avanзa pra um determinado local do cуdigo, e nгo cria um "bloco de cуdigo".

Quem cria bloco de cуdigo й if.