Pular para o conteúdo principal

Palavras-chave: Declarações

assert

Aborta a execução com um erro em tempo de execução se a expressão for avaliada como logicamente falsa. Parece funcionar apenas no bloco main(). A declaração assert deve ser usada para indicar um erro lógico (do programador), nunca um erro em tempo de execução (do usuário).

main()
{
assert (MAX_PLAYERS == GetMaxPlayers()); // garante que a definição de MAX_PLAYERS é igual ao número real de slots do servidor em uso
}

break

Sai de um loop instantaneamente, saindo apenas do loop de nível superior, não de todos os loops atuais.

for (new i = 0; i < 10; i++)
{
printf("%d", i);
if (i == 5)
{
break;
}
}

Produzirá:

0
1
2
3
4
5

Enquanto:

for (new i = 0; i < 10; i++)
{
if (i == 5)
{
break;
}
printf("%d", i);
}

Produzirá:

0
1
2
3
4

Como o loop é instantaneamente encerrado, nenhum dos loops chega a 10 e o segundo termina antes do número 5 ser impresso.

case

Trata um resultado específico em uma declaração switch. O resultado pode ser um único número, uma seleção de números ou um intervalo de números:

new
switchVar = 10;
switch (switchVar)
{
case 1:
{
printf("switchVar é 1");
}
case 4:
{
printf("switchVar é 4");
}
case 2, 3, 5:
{
printf("switchVar é 2, 3 ou 5");
}
case 7 .. 11:
{
printf("switchVar está entre 7 e 11 inclusive (7, 8, 9, 10 ou 11)");
}
default:
{
printf("switchVar não é 1, 2, 3, 4, 5, 7, 8, 9, 10 ou 11");
}
}

continue

Similar ao break, mas apenas avança para a próxima iteração do loop. É importante notar que o ponto para o qual ele pula varia dependendo do tipo de loop que você usa.

for (new i = 0; i < 10; i++)
{
if (i == 5)
{
continue;
}
printf("%d", i);
}

Produzirá:

0
1
2
3
4
6
7
8
9

Um continue após o print basicamente não fará nada. Em um loop for, continue pula para a terceira declaração na instrução for (neste exemplo, a parte "i++;"), isso é diferente de como se comporta em um loop while:

new
i = 0;
while (i < 10)
{
if (i == 5)
{
continue;
}
printf("%d", i);
i++;
}

Isso produzirá um loop infinito, pois continue pulará para DEPOIS do "i++;" e voltará para a parte "while (i < 10)". Nesse momento, "i" ainda será 5, pois "i++;" nunca foi chamado, e então continue será chamado novamente e "i" ficará preso em 5 para sempre.

default

default trata resultados de declarações switch que não são tratados explicitamente por declarações case. Veja o exemplo do case para um exemplo.

do

do é um tipo de loop que pode ser usado com while para produzir um loop que sempre será executado pelo menos uma vez. Note o ponto e vírgula após o while () no exemplo a seguir:

new
i = 10;
do
{
printf("%d", i);
i++;
}
while (i < 10);

"i" claramente não é menor que 10, mas este loop produzirá:

10

de qualquer forma. O loop while similar:

new
i = 10;
while (i < 10)
{
printf("%d", i);
i++;
}

Não dará nenhuma saída, pois a condição falha instantaneamente.

Estes também são úteis para evitar verificações duplas:

new
checkVar = 10;
if (checkVar == 10)
{
new
i = 0;
while (checkVar == 10)
{
checkVar = someFunction(i);
i++;
}
}

Isso não é obviamente um grande problema, mas você está verificando checkVar duas vezes em rápida sucessão no início do loop, o que é bastante inútil, porém o if é necessário pois você precisa executar código se a condição for verdadeira, mas fora do loop (esta é uma situação bastante comum). Isso pode ser melhorado fazendo:

new
checkVar = 10;
if (checkVar == 10)
{
new
i = 0;
do
{
checkVar = someFunction(i);
i++;
}
while (checkVar == 10);
}

Neste caso, o resultado será exatamente o mesmo, mas crucialmente com uma verificação inútil a menos.

else

else é chamado quando uma declaração if falha (assumindo que está presente):

new
checkVar = 5;
if (checkVar == 10)
{
printf("Isso nunca será chamado");
}
else
{
printf("A declaração if falhou, então isso será exibido");
}

else também pode ser combinado com if:

new
checkVar = 2;
if (checkVar == 1)
{
printf("Isso não será chamado"):
}
else if (checkVar == 2)
{
printf("O primeiro if falhou, então o segundo foi verificado e é verdadeiro");
}
else
{
printf("Isso não será chamado, pois um dos ifs era verdadeiro");
}

exit

Isso encerra o programa atual instantaneamente.

main()
{
exit;
return 0;
}

for

Um loop for é um tipo de loop que envolve três estágios: inicialização, comparação e atualização. Cada um é separado por ponto e vírgula e cada um pode ser excluído simplesmente deixando um espaço em branco. O loop for mais básico é:

for ( ; ; ) {}

Este não tem inicialização, nem comparação e nem atualização e, como resultado, continuará para sempre (a comparação, sendo ausente, assume o valor verdadeiro por padrão).

Um dos loops mais comuns é:

for (new i = 0; i < MAX_PLAYERS; i++)
{
printf("%d", i);
}

A inicialização neste loop é:

new i = 0;

O ponto e vírgula marca o fim da inicialização. Isso declara uma nova variável, chamada i, que só pode ser usada dentro deste loop. Em seguida, a comparação é feita. Ela compara i com MAX_PLAYERS (padrão 500 - veja #define) e se for menor, continua. Então, o conteúdo do loop é executado. Inicialmente, isso imprimirá "0". Finalmente, a atualização é feita "i++", isso aumenta o valor de i. Agora, uma iteração completa está concluída, o loop volta, como o nome indica, e retorna ao estágio de comparação (a inicialização é feita apenas uma vez por chamada).

O resultado deste loop é todos os números de 0 a 499 inclusive sendo impressos. O loop while equivalente (ignorando os efeitos do continue) seria:

new
i = 0;
while (i < MAX_PLAYERS)
{
printf("%d", i);
i++;
}

Os três estágios podem ser tornados muito mais complexos se necessário, usando vírgulas para a primeira e última seções e comparações padrão para a seção do meio:

for (new i = 0, j = 200; i < MAX_PLAYERS && j > 10; i++, j -= 2)
{
printf("%d %d", i, j);
}

Isso criará duas novas variáveis e as definirá como 0 e 200, então fará um loop enquanto uma for menor que 200 e a outra for maior que 10, aumentando uma a cada vez e diminuindo a outra em dois a cada vez.

Como dito antes, o escopo das variáveis é geralmente limitado ao loop:

for (new i = 0; i < MAX_PLAYERS; i++)
{
printf("%d", i);
}
printf("%d", i);

Isso produzirá um erro, pois "i" não existe após o loop terminar. No entanto:

new
i = 0;
for ( ; i < MAX_PLAYERS; i++)
{
printf("%d", i);
}
printf("%d", i);

Está correto, pois "i" não é declarado no loop. Você também poderia inicializar "i" no loop, mas não declará-lo lá:

new
i;
for (i = 0; i < MAX_PLAYERS; i++)
{
printf("%d", i);
}
printf("%d", i);

goto

goto e rótulos são geralmente desencorajados na comunidade de programação, pois o que eles fazem geralmente pode ser feito melhor reestruturando seu código adequadamente. No entanto, basicamente um goto é um salto:

goto my_label;
printf("Isso nunca será impresso");
my_label:
printf("Isso será impresso");

O compilador, no entanto, não lida muito bem com goto, então isso não será otimizado de forma alguma e coisas como:

{
new
i = 5;
if (i == 5)
{
goto my_label;
}
else
{
my_label:
return 0;
}
}

Darão um aviso sobre tipos de retorno inconsistentes, pois ele pensa que o ramo verdadeiro não retorna nada quando na verdade retorna, apenas de uma forma muito indireta. Além disso:

MyFunction()
{
new
i = 5;
if (i == 5)
{
goto my_label;
}
return 0;
my_label:
return 1;
}

Dará um aviso de código inalcançável, apesar de que ele é de fato alcançável.

A sintaxe básica é:

label:

goto label;

O rótulo deve estar em uma linha sozinha e terminar com dois pontos, NÃO com ponto e vírgula. Rótulos seguem as mesmas restrições de nomenclatura que variáveis e funções etc.

if

If é um dos operadores mais importantes. Ele determina se algo deve ser feito ou não e age de acordo, ele, junto com goto, é a base de quase todas as outras estruturas de controle:

for (new i = 0; i < 10; i++)
{
}

É equivalente a:

new
i = 0;
for_loop:
if (i < 10)
{
i++;
goto for_loop;
}

As condições que if pode aceitar são muitas demais para este post, porém algumas estão listadas abaixo:

Operador Explicação Exemplo Resultado quando a=1, b=0 Resultado quando a=1, b=1 Resultado quando a=0, b=1 Resultado quando a=0, b=0 == Verifica se uma coisa é igual a outra if (a == b) falso verdadeiro falso verdadeiro != Verifica se uma coisa não é igual a outra if (a != b) verdadeiro falso verdadeiro falso < Verifica se uma coisa é menor que outra if (a < b) falso falso verdadeiro falso > Verifica se uma coisa é maior que outra if (a > b) verdadeiro falso falso falso <= Verifica se uma coisa é menor ou igual a outra if (a <= b) falso verdadeiro verdadeiro verdadeiro >= Verifica se uma coisa é maior ou igual a outra if (a >= b) verdadeiro verdadeiro falso verdadeiro && Verifica se duas coisas são verdadeiras (não 0) if (a && b) falso verdadeiro falso falso || Verifica se pelo menos uma de duas coisas é verdadeira (não 0) if (a || b) verdadeiro verdadeiro verdadeiro falso ! Verifica se algo é falso if (!(a == b)) verdadeiro falso verdadeiro falso

Obviamente, com estes você pode construir condicionais complexas:

if (a == b && (c != d || f < g))

Isso será verdadeiro se a for igual a b e f for menor que g ou c não for igual a d (ou ambos).

return

Isso sai de uma função e pode retornar dados para a função que a chamou:

MyFunction()
{
new
someVar = OtherFunction();
}

OtherFunction()
{
return 5;
}

someVar agora será 5.

MyFunction()
{
if (SomeFunction())
{
printf("Retornou 1");
}
}

SomeFunction()
{
return random(2);
}

Isso retornará 1 ou 0 para a declaração if da função que chamou. 1 é verdadeiro e 0 é falso, então o texto só será impresso se 1 for retornado. No entanto:

MyFunction()
{
if (SomeFunction())
{
printf("Retornou algo entre 1 e 10");
}
}

SomeFunction()
{
return random(11);
}

Isso retornará 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ou 10. Qualquer coisa que não seja 0 é verdadeiro, então o texto será exibido se qualquer coisa entre 1 e 10 for retornada.

Você também pode usar return com strings:

MyFunction()
{
printf("%s", SomeFunction());
}

SomeFunction()
{
new
str[10] = "Hello";
return str;
}

Imprimirá "Hello" (sem as aspas).

Você também não precisa retornar nada:

MyFunction()
{
SomeFunction();
}

SomeFunction()
{
return;
}

No entanto, se você fizer isso, deve garantir que o retorno da função nunca seja usado:

MyFunction()
{
if (SomeFunction())
{
printf("Problema");
}
}

SomeFunction()
{
return;
}

Aqui SomeFunction não está retornando nada, porém MyFunction está verificando se o valor retornado de SomeFunction é verdadeiro ou não - não é nenhum dos dois, pois simplesmente não existe, então você receberá um erro do compilador. Nenhum retorno é o padrão, então:

SomeFunction()
{
return;
}

E:

SomeFunction()
{
}

São a mesma coisa.

Por fim, você não pode misturar valores de retorno:

MyFunction()
{
SomeFunction();
}

SomeFunction()
{
if (random(2))
{
return 1;
}
else
{
return;
}
}

Isso dará um erro porque não sabe o que fazer.

SomeFunction()
{
if (random(2))
{
return 1;
}
}

Também não é permitido, pois o retorno padrão é nada.

sleep

sleep é uma pseudo-função que faz a execução pausar por um determinado número de milissegundos:

printf("Tempo 0s");
sleep(1000);
printf("Tempo 1s");

Isso só funciona em main(), não em callbacks, pois é executado na thread PAWN.

state

state faz parte do sistema de máquina de estados e autômatos do PAWN, veja este tópico para mais informações.

switch

switch é basicamente um sistema estruturado de if/else if/else:

switch (someVar)
{
case 1:
{
printf("um");
}
case 2:
{
printf("dois");
}
case 3:
{
printf("três");
}
default:
{
printf("outro");
}
}

É apenas uma forma um pouco mais eficiente (e muito mais limpa) de fazer:

if (someVar == 1)
{
printf("um");
}
else if (someVar == 2)
{
printf("dois");
}
else if (someVar == 3)
{
printf("três");
}
else
{
printf("outro");
}

while

while é um tipo de loop similar ao for e do..while. A operação básica é uma declaração if que, se verdadeira, executa algum código e volta para o if. Se for falsa, vai para depois do código do loop - não há else. Voltando ao exemplo do goto:

new
i = 0;
for_loop:
if (i < 10)
{
i++;
goto for_loop;
}

Isso também pode ser escrito como:

new
i = 0;
while (i < 10)
{
i++;
}

Veja do e for para mais informações.