Embora as funções em Pawn normalmente retornem apenas valores simples do tamanho de uma célula, a linguagem permite que funções (mesmo nativas) retornem matrizes e, portanto, também strings. No entanto, o mecanismo que permite isso é um pouco mais complexo e pode não ser adequado para alguns casos de uso.
Em primeiro lugar, vamos examinar a maneira padrão de obter uma string de uma função.
Por meio de um parâmetro de saída
Todas as funções SA-MP nativas produzem uma string por meio de um parâmetro de matriz não const padrão. Como os arrays são passados por referência (o que significa que a função obtém acesso à variável real e não apenas ao valor interno), a função nativa pode armazenar facilmente quaisquer dados dentro de:
Código de peão:
novo nome [ MAX_PLAYER_NAME + 1 ] ;
GetPlayerName ( playerid, name, sizeof name ) ;
Essa maneira é especialmente útil para obter arrays de comprimento variável (como strings). A função de formato , por exemplo, só pode ser implementada desta forma, pois o comprimento teórico da string de saída é ilimitado.
Retornando um array diretamente
Se você deseja produzir um tamanho fixo array, você pode retorná-lo de uma função diretamente:
Código de peão:
encaminhar [ MAX_PLAYER_NAME + 1 ] PlayerName ( playerid ) ;
estoque PlayerName ( playerid )
{
novo nome [ MAX_PLAYER_NAME + 1 ] ;
GetPlayerName ( playerid, name, sizeof name ) ; nome de
retorno ;
}
Agora, se você conhece um pouco de outras linguagens como C etc., você deve estar ciente de que, como o nome é alocado na pilha, ele não existe mais quando a função retorna. Pawn supera esse fato usando um truque - quando a função é chamada, um espaço extra para o array é alocado e o endereço dessa variável é fornecido para a função por meio de um parâmetro secreto.
Na realidade, a função é parecida com esta:
Código de peão:
estoque PlayerName ( playerid, saída [ MAX_PLAYER_NAME + 1 ] )
{
novo nome [ MAX_PLAYER_NAME + 1 ] ;
GetPlayerName ( playerid, nome, sizeof nome ) ;
output = name;
}
No entanto, isso tem um custo de desempenho ligeiramente reduzido e bugs em certos casos. Vamos começar com os problemas:
Código de peão:
Selecione ações ( índice, arg [ ] , arg2 [ ] )
{
if ( índice == 0 ) return arg;
return arg2;
}
Código de peão:
avançar [ 4 ] Func1 ( ) ;
estoque Func1 ( )
{
new str [ ] = "abc" ;
return str;
}
encaminhar [ 4 ] Func2 ( ) ;
estoque Func2 ( )
{
retornar Func1 ( ) ;
}
Código de peão:
estoque Func ( ... )
{
new str [ ] = "abc" ;
return str;
}
Em todos esses casos, retornar uma string é uma coisa muito ruim de se fazer, já que o código geralmente compila bem e o problema só se torna aparente em tempo de execução.
Há um pequeno custo de desempenho associado ao retorno de matrizes também: o output = name; sempre acontece se a função é implementada em Pawn e, portanto, o array é copiado pelo menos uma vez. Dê uma olhada neste código:
Código de peão:
novo nome [ MAX_PLAYER_NAME + 1 ] ; // = PlayerName (playerid); não funciona, a atribuição direta não é suportada
name = PlayerName ( playerid ) ;
Como você pode ver, o retorno de matrizes tem algumas desvantagens significativas, mas ainda é útil em alguns casos, quando você é cauteloso.
Código de peão:
format ( string, sizeof string, "Seu nome é% s." , PlayerName ( playerid ) ) ;
O próprio PlayerName pode ser "consertado" para retornar a string diretamente sem cópias desnecessárias, por meio de montagem in-line:
Código de peão:
avançar [ MAX_PLAYER_NAME + 1 ] PlayerName ( playerid ) ;
estoque PlayerName ( playerid )
{
#assert MAX_PLAYER_NAME + 1 == 25
#emit PUSH.C 25 // parâmetro de tamanho de GetPlayerName
#emit PUSH.S 16 // parâmetro de retorno secreto de PlayerName no endereço 16 (& playerid + 4)
#emit PUSH .S playerid // igual a 12
#emit PUSH.C 12 // número de bytes passados para a função (4 * 3 argumentos)
#emit SYSREQ.C GetPlayerName // chamando a função
#emit STACK 16 // limpeza dos argumentos da pilha
#emit RETN
}
PawnPlus Strings
dinâmicas em PawnPlus oferecem a flexibilidade e conveniência dos valores normais, uma vez que são passados como referências.
Código de peão:
estoque String : Func ( )
{
return str_new ( "abc" ) ;
}
Strings constantes
Todos os métodos anteriores são adequados para strings que são produzidas em tempo de execução, mas para strings constantes, eu desaconselho o uso de qualquer um deles. Em vez disso, use macros.
Código de peão:
new const _tips [ ] [ ] = {
"Dica um" ,
"Dica dois" ,
"Dica três" ,
"Dica quatro"
} ;
#define RandomTip () (_tips [random (sizeof _tips)])

0 Comentários