O comando case serve para facilitar a visualização de vários comandos if-then-else aninhados, com a diferença de que, no lugar de avaliar expressões booleanas, são avaliadas expressões cujo resultado seja de algum tipo enumerado ou ordinal (exceto boolean).
O comando é constituído por uma expressão e por constantes de caso. As constantes devem ser conhecidas em tempo de compilação. Todas as constantes devem ser do mesmo tipo.
O compilador avalia a expressão e, caso haja o casamento de uma das constantes com o valor da expressão, a sentença que segue esta constante é executada. O programa continua então após o end final do comando. Note que este comportamento difere de outras linguagens de programação. Em Pascal, apenas um dos comandos é executado, sem necessidade de inserir breaks.
Na situação em que não há casamento de nenhuma constante com o valor da expressão, executam-se as instruções aninhadas em else. Não confundir este else com aquele do comando if-then-else. Apesar do nome ser o mesmo (else), este é o else do case.
O trecho do else é opcional e executado apenas no caso de não haver qualquer casamento de constante com o valor da expressão. Ainda neste caso, se não houver este trecho, o fluxo de execução seguirá para o comando que sucede o end}. Este end não precisa de um begin, sendo uma das poucas excessões na linguagem Pascal.
Sintaxe:
case <expressao do case> of cte1: comando_1; cte2: comando_2; cte3: comando_3; //... cteN: comando_N; else comando_do_else; end;
Observe que case, of e else são palavras reservadas. As constantes do comando são cte1, cte2, … , cteN. Conforme explicado anteriormente, estas constantes podem ser também de tipos enumeráveis, isto é, da forma A..B. No Free Pascal não é permitido haver duplicidade nas constantes.
Analogamente aos comandos if, aqui somente um único comando é executado em cada caso. Quando necessário mais de um comando, deve-se utilizar os delimitadores de bloco (ver seção Delimitadores de bloco).
Ao contrário do que ocorre com o if, aqui deve existir o ponto-e-vírgula na instrução que precede o else, pois, conforme já mencioado, este é o else do case, não do if.
Em suma, o comando case funciona baseado em casamentos de padrões e não é tão genérico quando o comando if. Este, por sua vez, trabalha com expressões booleanas que podem ser tão complexas quanto se precise. Vale frisar que todo trecho que utilize case pode ser reescrito como um aninhamento de comandos if-then-else, embora o código fique menos legível.
Exemplo:
program exemplo_case_of; var a, b : integer; resposta, escolha : byte; begin writeln('Digite dois inteiros:'); read(a, b); writeln('Escolha a operacao a ser realizada: '); writeln('(1) Soma, (2) Subtracao, (3) Multiplicacao, (4) divisao)'); read(escolha); case escolha of 1 : writeln(a, ' + ', b, ' = ', (a+b)); 2 : writeln(a, ' + ', b, ' = ', (a-b)); 3 : begin resposta := a * b; writeln(a, ' + ', b, ' = ', resposta); end; 4: writeln(a, ' + ', b, ' = ', (a/b)); 5..255: writeln ('Escolha errada!'); else writeln('Entrada incorreta.'); end.
O código anterior, escrito com o case equivale a este outro código, que utiliza if.
program operacoes; var a, b : integer; resposta : integer; escolha : integer; begin writeln('Digite dois inteiros:'); read(a, b); writeln('Escolha a operacao a ser realizada: '); writeln('(1) Soma, (2) Subtracao, (3) Multiplicacao, (4) divisao)'); read(escolha); if escolha = 1 then writeln(a, ' + ', b, ' = ', (a+b)) else if escolha = 2 then writeln(a, ' + ', b, ' = ', (a-b)) else if escolha = 3 then begin resposta := a * b; writeln(a, ' + ', b, ' = ', resposta); end else if escolha = 4 then writeln(a, ' + ', b, ' = ', (a/b)) else if (escolha > 5) and (escolha <= 255) then writeln('Escolha errada!') else writeln('Entrada incorreta.'); end.
O próximo exemplo explora mais as possibilidades do case.
program exemplo_case_sofisticado; var numero : integer; begin writeln('Digite um numero:'); read(numero); case numero of 1 : writeln('Numero um.'); 2..3, 5, 7, 11, 13, 17, 19, 23, 29: writeln('Numero esta entre os 10 primeiros primos.'); 4, 8, 12, 16, 20, 24, 28: writeln('Numero menor do que 30 e divisivel por quatro'); else writeln('Nada de especial com esse numero'); end; end.
No exemplo acima, toda vírgula dentro da especificação das constantes é considerada um or. Sempre que forem encontrados dois pontos entre constantes, lê-se até, pois especifica uma escala de possíveis valores.