char mensagem[100] ;
processa()
{
/* processa */
if( /* uma condição de erro */ )
strcpy( mensagem,"Deu erro 1" );
else
{
/* processa */
if( /* uma condição de erro */ )
strcpy( mensagem,"Deu erro 2" );
else
{
/* processa */
if( /* uma condição de erro */ )
strcpy( mensagem,"Deu erro 3" );
else
strcpy( mensagem,"Funcionou direitinho" );
}
}
}
Antes de prosseguir lendo, pare e pense um pouco.
O programa acima é ingênuo, feito com o conceito de strings em mente, com o conceito de atribuição de strings em mente, e como o C não existe um tipo string formal, então se faz o equivalente, que é copiar. Aliás, linguagens de alto nível fazem isto, copiam a string. Mas a grande pergunta é: "Realmente é necessário copiar?".
A resposta é não.
Qualquer string que exista no programa, seja como parâmetro da printf, na inicialização de um array de char, no strcpy como no exemplo acima etc, será criada e colocada na área de dados do programa, e portanto estará um lugar, uma posição, de memória. O array mensagem usará 100 Bytes da memória. E ainda existem dois riscos. Um, de pouco impacto no caso, de desperdício de memória com um array superdimensionado, e um de grande impacto, o array ser sub-
dimensionado, caso surja uma mensagem maior que ele.
No conceito do tipo de variável string, tal como algumas linguagens trabalham, o programa acima está corretíssimo, mas com forte conceito de ponteiros que a linguagem C tem, e a tipagem fraca e mais livre, o programa pode ser considerado conceitualmente, e em matéria de eficiência, um desastre.
Veja a nova forma abaixo:
char *mensagem ;
processa()
{
/* processa */
if( /* uma condição de erro */ )
mensagem = "Deu erro 1" ;
else
{
/* processa */
if( /* uma condição de erro */ )
mensagem = "Deu erro 2" ;
else
{
/* processa */
if( /* uma condição de erro */ )
mensagem = "Deu erro 3" ;
else
mensagem = "Funcionou direitinho" ;
}
}
}
As chamadas da strcpy gastam código e tempo de processamento empilhando os parâmetros, chamando a função, retornando da função, executando a função etc. Alguns compiladores, com opções de otimização ligadas, inserem a função strcpy no lugar de chamada, poupando muito processamento, mas mesmo assim nem chega perto da atribuição de um valor constante a um ponteiro. Como o endereço onde está a string é fixo (ou resolvido a tempo de carga do programa em alguns sistemas operacionais), só resta um valor constante a ser colocado no ponteiro. Agora não existe mais o gasto de 100 bytes na criação da variável, sendo bem menor com o ponteiro, e nem mais o risco de estar com o tamanho pequeno demais e causar um desastre.
Este caso pode causar estranheza entre os que não estão acostumados à forma com o que o C lida com strings, mas esta é a forma correta e eficiente de tratar strings em C, e é bem mais eficiente do que em muitas outras linguagens.
Só tem um cuidado a tomar. A string apontada pelo ponteiro não pode sofrer alteração, pois assim alterará o conteúdo original em memória.
Nenhum comentário:
Postar um comentário