Username: Password:

.Condições (nível 2)

Sequências de ifs e a instrução switch

Há situações onde a é necessário testar uma sequência de condições para efectuar diferentes processamentos. Podemos imaginar o caso de um programa de jogo onde no fim queremos imprimir no ecrão um comentário ao jogador conforme a sua performance. Vamos admitir que existe uma variável score (de tipo inteiro) que contém um valor entre 1 e 10. Conforme o valor do score vamos mostrar uma mensagem diferente :

if (score >= 9) 
   printf("Excelente !\n");
else 
   if (score >= 7)
      printf("Muito bom !\n");   
   else 
      if (score >= 4)
         printf("Pode tentar fazer melhor apróxima vez !\n");
      else 
         if (score >= 2) 
            printf("Fraco !\n");
         else 
            printf("Muito fraco !\n");

Quando o score vale 9 ou 10, a mensagem «Excelente !» é escrita no ecrã caso contrário uma segunda instrução if é executada : se o valor do score for maior ou igual a 7 (ou seja, igual a 7 ou 8), a mensagem «Muito bom !» aparece no ecrã. Assim sucessivamente o «else» de um «if» consiste num novo teste até ter esgotado todos os casos possíveis. Este padrão encontra-se muitas vezes na programação. Embora a indentação do exemplo anterior faça todo o sentido, como pode haver uma sequência longa de condições a indentação pode levar a ultrapassar a largura do ecrã (ou do papel) o que prejudica francamente a legibilidade. Por essa razão uma sequência de condições é geralmente apresentada de forma mais compacta :

if (score >= 9) 
   printf("Excelente !\n");
else if (score >= 7)
   printf("Muito bom !\n");   
else if (score >= 4)
   printf("Pode tentar fazer melhor a próxima vez !\n");
else if (score >= 2) 
   printf("Fraco !\n");
else 
   printf("Muito fraco !\n");

A linguagem C possui uma instrução que facilita a escrita de condições multiplas como descritas no exemplo anterior. Esta instrução é chamada switch. A sequência de «if» anterior pode ser substituida por uma instrução switch :

switch (score) {
   case 10: printf("O melhor !\n")
   case 9: printf("Excelente !\n");
           break;
   case 8:
   case 7: printf("Muito bom !\n");
           break; 
   case 6:
   case 5:
   case 4: printf("Pode tentar fazer melhor a próxima vez !\n");
           break;
   case 3:
   case 2: printf("Fraco !\n");
           break;
   default: printf("Muito fraco !\n");
}
A instrução switch é seguida de uma expressão aritmética, entre parentesis. Neste caso é apenas o valor do score : (score). A expressão é avaliada e o seu valor é comparado aos valores especificados pelos vários casos (um caso é descrito pela paravra reservada case seguido de uma constante seguida de dois pontos). Se o valor igual a um dos casos, a instrução correspondente é executada. A execução das instruções dos casos seguintes prosegue até ser interrompida pela instrução break (ou chegar ao fim do switch) Por exemplo, se o valor do score for 10, o programa vai imprimir no ecrã :
O melhor !
Excelente !
Se o valor for 9 imprimirá apenas :
Excelente !
A instrução break provoca uma interrupção na análise dos diferentes casos e um salto para a intrução que vier a seguir ao switch.

O exemplo escrito com a instrução switch não é completamente igual à sequência de «if» anterior. A instrução switch permite a enumeração de vários casos e disponibilisa uma clausúla especial : default. Esta clausúla corresponde a «todos os outros casos». No caso da sequência de «if» se o valor do score for 1000 o programa imprimirá «Excelente !» enquanto no caso do switch imprimirá «Muito fraco !» porque o valor não se encontra em nenhum dos casos previstos.

Existe uma restrição no uso da instrução switch : a expressão testada deve ser de tipo inteiro. Caso deseja comparar valores decimais, a única solução é usar uma sequência de «if» como ilustrado no início desta secção. Os valores indicados para cada casos devem ser constantes, não podem ser variáveis. Como os caracteres são representados internamente por valores inteiros, o switch pode ser usado com valores de tipo char, aqui reposta é uma variável de tipo char :

switch (resposta) {
   case 'a' : /* fazer alguma coisa */
              break;
   case 'b' : /* fazer outra coisa */
              break;
   case 'c' : /* fazer uma coisa diferente */
}

Valores lógicos e operadores = e ==

Falamos brevemente de algumas caracteristicas da representação dos valores inteiros, decimais e caracteres mas ainda não falamos da representação dos valores lógicos (Booleanos). Os valores lógicos verdadeiro e falso são representados internamente por números inteiros. O valor falso é representado pelo valor 0 (zero) e todos os valores diferentes de zero correspondem ao valor verdadeiro. Uma consequência infeliz desta representação é que um valor inteiro pode erradamente ser interpretado como um valor lógico.

Como já foi referido na secção «Condições», não se deve confundir o símbolo de atribuição com o operador lógico de igualidade ==. Quais são as consequências de uma tal confusão ? Sabemos [> section 9.14 ] que = é um operador. Por exemplo a expressão x = 4 tem o valor 4. Se, erradamente escrevemos :

if (x = 4) {
   /* efectuar processamento 1 */
else {
   /* efectuar processamento 2 */
}
é como escrever if (4) ... Porque 4 é diferente de 0, é interpretado como «verdadeiro» logo o processamento 1 será sempre efectuado e o processamento 2 nunca.