Dúvida avançada switch [RESOLVIDO]

1. Dúvida avançada switch [RESOLVIDO]

Nick Us
Nick-us

(usa Slackware)

Enviado em 10/03/2019 - 19:24h

É possível fazer um switch usando uma variável char? Em C claro!
Exemplo:
char Texto[] = "Posicao 1";
switch(Texto){

O primeiro problema que encontrei é que o compilador reclama de não ser integer:
error: switch quantity not an integer
switch(Texto){

Depois claro problemas ainda piores para colocar isso nos cases.
Procurei formas na Internet mas as que encontrei são verdadeiras gambiarras para isso funcionar! Motivo que gostaria de saber se é possível ou não. Pq se for possível não estou conseguindo fazer! :(


  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 11/03/2019 - 03:42h

Isso é parte da linguagem, mesmo.

O comando switch() não é uma maneira mais bonita de reescrever uma tripa de if/else if/else if/.../else. O valor passado ao switch() tem de ser um valor inteiro e produzido por uma expressão, e provoca um desvio da execução para o valor passado como rótulo de algum case (ou do caso default), de modo semelhante ao funcionamento de goto, podendo usar uma tabela de possíveis locais de desvio, em lugar de testar cada valor sequencialmente até encontrar o valor correto, como ocorreria com a tripa de if/else if/else if/.../else.

Um paralelo dele em outras linguagem seria, no BASIC, o comando ON expressão GOTO endereço0, endereço1[, ...], endereçoN, em que o fluxo de execução desviaria para endereço0 se expressão valesse 0, para endereço1 se ela valesse 1, e assim por diante, até endereçoN se ela valesse N.

Para você ter uma ideia, o seguinte programa em C padrão produz um código executável muito semelhante ao segundo programa seguinte (que usa extensões do GCC para obtenção do endereço de labels e para usar um valor não-constante para goto).
int main(int argc, char **argv){
switch(argc){
default:
return -1;
case 10:
return 1;
case 20:
return 2;
case 30:
return 3;
case 40:
case 50:
return 4;
case 60:
return 6;
}
}

/* Usa extensões do GCC -- não é C padrão. */
int main(int argc, char **argv){
static void *const labels[51]={
&&lb10, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf,
&&lb20, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf,
&&lb30, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf,
&&lb40, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf,
&&lb50, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf, &&lbdf,
&&lb60
};

if(argc>=10 && argc<=60)
goto *labels[argc-10];

lbdf:
return -1;
lb10:
return 1;
lb20:
return 2;
lb30:
return 3;
lb40:
;
lb50:
return 4;
lb60:
return 6;
}


Em outras linguagens, pode ser que elementos relativamente parecidos com o switch() do C, como o SELECT CASE do Visual Basic, não possam ser implementados dessa maneira, mas tenham de recorrer ao funcionalmente equivalente à tripa de if/else if/else if/.../else, especialmente quando o tipo que está sendo avaliado for algo complexo, como strings, ou quando os próprios valores das expressões de cada caso distinto não forem constantes. Por exemplo, o seguinte código em Visual Basic não tem como ter correspondente visual direto em C.
Dim Str1, Str2 as String
' ...
Select Case Str1
Case "Paulo", "Nick"
Debug.WriteLine("Usuário do VoL.")
Case Str2
Debug.WriteLine("Sei quem é "+Str2+", mas não sei se usa o VoL.")
Case Else
Debug.WriteLine("Não conheço nenhum "+Str1+".")
End Select


A conversão do código acima para C teria de usar uma tripa de ifs explícita.
char *str1, *str2;
/* ... */
if(strcmp(str1, "Paulo")==0 || strcmp(str1, "Nick")==0)
puts("Usuário do VoL.");
else if(strcmp(str1, str2)==0)
printf("Sei quem é %s, mas não sei se usa o VoL.\n", str2);
else
printf("Não conheço nenhum %s.\n", str1);


Note, aliás, que o próprio fato de não haver um tipo nativo para strings em C dificulta a criação de algo como uma versão de switch que saiba manipular tais dados.

Por fim, vale ressaltar que é possível que o compilador C, em algumas situações, produza código equivalente às tripas de ifs. Seria muito caro, por exemplo, gerar um array de ponteiros com milhares ou milhões de índices para uma construção tão simples como a seguinte.
switch(valor){
case -100000000: puts("Muito negativo."); break;
case 100000000: puts("Muito positivo."); break;
case 0: puts("Zero."); break;
default: puts("Sei lá!");
}



... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)





Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts