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(playerid, text[])
{
/*
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(playerid, text[])
{
/*
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(playerid, text[])
{
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(playerid, text[])
{
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(playerid, playerName, MAX_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.