Curso de C - 6. Estruturas de Decisão
Na aula desta semana veremos como nossos programas poderão tomar decisões, ampliando bastante a capacidade de programação.
Os comandos para tomadas de decisão em C são: if, if ... else, switch e o operador ternário ? :.
6.1. O comando if
O comando if, presente na maioria das linguagens de programação, é usado para a construção de estruturas de decisão simples. A forma
geral do comando é assim:
if (expressão condicional)
{
comandos;
}
OU
if (expressão condicional)
comando único;
O comando if avalia a expressão condicional entre parênteses. Se esta expressão for verdadeira, o(s) comando(s) do bloco de código
será(ão) executado(s). Se for falsa, o bloco de código do if não será executado, isto é, o programa "passa batido".
Para comandos if com apenas UM comando, não é necessário delimitar o bloco de código com chaves ("{}"). O compilador sabe que quando não
existem as chaves naquele if, somente UM comando fará parte do bloco de código.
Agora, vamos ver alguns exemplos:
if (a > b) /* se o a for maior do que o b ... */
printf("a é maior que b"); /* ... imprime mensagem */
if ((num % 2) == 0) /* se o resto da divisão entre num e 2 for 0 ... */
{
printf("Número par"); /* ... faça
return 0; isso */
}
É interessante sempre manter o código indentado, com tabulações, para ficar claro de qual bloco de código é determinado comando.
6.2. O comando if ... else
Esta construção possui duas partes: um comando if, cujo bloco de código será executado se a expressão condicional for verdadeira; e
um comando else, que será executado caso a mesma expressão seja falsa.
Portanto, agora temos uma "bifurcação", e o caminho que o programa trilhará vai depender do resultado da expressão condicional (verdadeiro ou
falso).
Forma geral:
if (expressão condicional)
{
comandos;
}
else
{
comandos;
}
Se os blocos de código tiverem mais que um comando, deve-se delimitá-los com abre e fecha chaves. Vejam alguns exemplos:
if ((num % 2) == 0) /* Se o resto da divisão entre num e 2 for 0... */
printf("Número par."); /* ...imprime mensagem "número par". */
else /* ... Senão... */
printf("Número ímpar."); /* ... imprime mensagem "número ímpar". */
Neste exemplo, se num % 2 for igual a zero (se esta expressão for verdadeira), executa o primeiro printf(). Caso contrário (se for falsa),
executa o segundo printf().
Mais um exemplo:
int *p; /* Um ponteiro para inteiro */
p= (int *) malloc(sizeof(int)); /* Aloca um espaço de memória do tamanho de um int */
if (!p) /* Se o ponteiro p for igual a NULL (nulo) ... */
{
printf("Falha ao alocar memória!"); /* ... alocação falhou */
return 1;
}
else /* ... senão ... */
printf("Memória alocada com sucesso..."); /* alocou direitinho */
Um exemplo de ponteiros, e como usar o if ... else para tratar erros. O comando malloc() tenta alocar memória e, no caso de falhar,
retorna NULL. O comando if (!p) significa "se o conteúdo de p não for diferente de nulo", ou seja, se p for nulo (NULL), executa o
primeiro bloco (trata o erro). Caso contrário, entra no bloco do else.
Dentro de um bloco de código, pode aparecer qualquer comando, até mesmo if's e elses.
Você pode até criar construções para decisões múltiplas, criando uma espécie de escada de if's e elses. Exemplo:
if (n==1) /* se n for igual a 1... */
escolha1(); /* ... executa isto. */
else /* senão...
if (n==2) /* se n for igual a 2... */
escolha2(); /* ... executa isto. */
else /* senão... */
if (n==3) /* se n for igual a 3... */
escolha3(); /* ... executa isto. */
else /* senão... */
if (n==4) /* se n for igual a 4... */
escolha4(); /* ... executa isto. */
else /* senão (se todas as outras condições forem falsas)... */
printf("Opção inválida"); /* ... executa isto. */
Este é um exemplo de decisão múltipla. Como você pode ver, é uma construção um tanto deselegante e que pode tornar o código mais difícil de
entender. A seguir veremos uma construção alternativa à escada de if's e elses.
6.3. O Comando switch
O comando switch é usado como alternativa à escada de if's e elses, e torna o código mais elegante e legível. Forma geral:
switch (expressão constante)
{
case constante1:
comandos;
case constante2:
comandos;
case constante3:
comandos;
case constante4:
comandos;
default:
comandos;
}
Este comando possui algumas restrições. Como expressão constante, ele só aceita valores inteiros e caracteres. Como expressão
condicional, só são aceitas igualdades (se a constante1 for igual a expressão constante, executa comandos; e assim por diante).
Para cada case existe um conjunto de comandos que só serão executados caso a condição seja verdadeira. Se a expressão constante não
casar com nenhum case, então os comandos do bloco default são executados. O bloco de código dos case NÃO PRECISAM ser delimitados
com chaves; basta colocá-los, um após o outro, após o rótulo case :.
Vamos ver um exemplo para poder "clarear":
#include
main()
{
float n1, n2;
char op;
printf("*** Calculadora ***\n");
printf("Digite um número: ");
scanf("%f", &n1);
getchar();
printf("Digite o operador (+ - * /): ");
scanf("%c", &op);
getchar();
printf("Digite outro número: ");
scanf("%f", &n2);
getchar();
switch(op) /* expressão constante: variável op (caractere) */
{
case '+':
printf("Adição: %.2f\n", n1+n2);
break;
case '-':
printf("Subtração: %.2f\n", n1-n2);
break;
case '*':
printf("Multiplicação: %.2f\n", n1*n2);
break;
case '/':
if (n2 == 0)
{
printf("Erro: impossível dividir por zero!\n");
return 1;
}
else
{
printf("Divisão: %.2f\n", n1/n2);
break;
}
default:
printf("Operador inválido: %c\n", op);
return 1;
}
return 0;
}
Tá aí um exemplo do switch na prática. Em cada case, temos o(s) comando(s) e, em seguida, um comando break.
O comando break, quando encontrado, faz o programa sair imediatamente do switch. Se usado em loops, faz o programa parar com o loop
e continuar com a execução. Nas rotinas de tratamento de erros, ao invés de usar o break, encerramos o programa com return 1, o que
manda um valor de retorno diferente de zero para o sistema operacional (erro).
Imagina se, no lugar do switch, tivéssemos que montar uma escada de if's e elses... Ficaria mais ou menos assim:
if (op=='+')
{
printf("Adição: %.2f\n", n1+n2);
break;
}
else
if (op=='-')
{
printf("Subtração: %.2f\n", n1-n2);
break;
}
else
if (op=='*')
{
printf("Multiplicação: %.2f\n", n1*n2);
break;
}
else
if (op=='/')
{
if (n1==0)
{
printf("Erro: impossível dividir por zero!\n");
return 1;
}
else
{
printf("Divisão: %.2f\n", n1/n2);
break;
}
}
else
{
printf("Operador inválido: %c\n", op);
return 1;
}
Usando o switch, neste exemplo, temos 26 linhas de código, enquanto que usando a construção de if's e elses temos 36 linhas... 10 a mais,
além do código ficar menos claro e mais bagunçado.
O switch é bastante usado em menus, quando o usuário tem que digitar o número ou a letra de alguma opção.
6.4. O Operador Ternário ? :
O operador ternário faz a mesma coisa que o if ... else. Forma geral:
expressão condicional ? comando : comando;
Se a expressão condicional for verdadeira, executa-se o comando após o ?; se for falsa, executa-se o comando após o :. Exemplos:
(n>p) ? n-- : n++;
Se n for maior que p, decremente n (n--); senão incremente n (n++).
(num != 5) ? printf("Número diferente de 5") : printf("Número igual a 5");
Se num for diferente de 5, imprime "Número diferente de 5". Se for igual a 5, imprime "Número igual a 5".
Você pode fazer construções assim também:
res= (num>100) ? 200 : 100;
Por exemplo, se num for maior que 100, a variável res recebe 200; caso contrário, recebe 100.
Deve-se zelar pela legibilidade do código. Se essa construção tornar o código ilegível, ou bagunçado, evite usá-la. A não ser que a
otimização seja mais importante do que a legibilidade do código.
Exercícios
1) Escreva um programa que, dadas as constantes a, b e c de uma equação do segundo grau, calcule o delta e, se possível, calcule
as raízes x' e x''.
2) Dada a nota de um aluno, faça um programa que calcule a média e imprima se o aluno foi aprovado sem exame (>= 7), se ficou de exame (>= 4
e < 7) ou se reprovou direto (< 4).
3) Faça um programa que leia o login e a senha de um usuário e imprima se ele está logado ou se tem acesso negado. OBS: Deve-se usar a função
de comparação entre strings, strcmp(string1, string2), que retorna 0 se as duas strings forem iguais. Para poder se logar, o nome de
usuário será "linuxdicas" e a senha "h56yu89".
4) Escreva um programa que leia a velocidade que um carro passou pelo radar e calcule a sua multa. Considere a tabela a seguir:
| Velocidade |
Multa |
| > 100 Km/h |
R$ 600,00 |
| < 100 Km/h e >= 80 Km/h |
R$ 300,00 |
| < 80 Km/h e > 60 Km/h |
R$ 120,00 |
5) Faça um programa de calculadora similar ao exemplo da aula, mas que faça cálculos bit a bit, com operadores and, or, not,
xor, deslocamento para esquerda e para a direita.
Powered by txt2tags