Uma estrutura de decisão permite decidir por executar ou não certo conjunto de comandos, de acordo com uma determinada condição. Em C existem duas formas de representar um processo de decisão, usando a estrutura if - else
ou a estrutura switch - case
.
if-else
A palavra chave if
é utilizada para codificar uma tomada de decisão em C com base em uma condição (expressão booleana). A seguir é exemplificado o uso do if
em um algoritmo que verifica se um número inteiro lido da entrada é positivo.
#include <stdio.h>
int main() {
int n1;
scanf("%d",&n1);
if(n1 > 0) {
printf("valor positivo");
}
return 0;
}
Após a palavra chave if
deve-se colocar a condição entre parênteses. O escopo da estrutura de decisão pode ser delimitado usando abertura e fechamento de chaves. Isso quer dizer que todos os comandos que ficarem dentro do escopo da estrutura de decisão if
apenas serão executados se a condição for verdadeira. O uso de abertura e fechamento de chaves pode ser dispensado quando existe apenas um comando dentro do escopo da decisão. Se houver dois ou mais comandos dentro do escopo é obrigatório o uso de abertura e fechamento de chaves. Lembrando que diferente de Python, em C o uso de identação não implica em definição de escopo.
A palavra chave else
pode ser utilizada para executar um conjunto de comandos alternativos aos definidos dentro do if
. Ou seja, caso a condição definida no if
seja falsa, os comandos colocados dentro do escopo do else
serão executados. No exemplo a seguir, é mostrado um código que verifica e informa ao usuário se um determinado número inteiro é positivo ou não, usando if-else
.
#include <stdio.h>
int main() {
int n1;
scanf("%d",&n1);
if(n1 > 0) {
printf("valor positivo");
}
else {
printf("valor negativo ou igual a zero");
}
return 0;
}
Ao usar o if-else
como no exemplo mostrado, pode-se definir duas opções de fluxo de processamento no código. Caso a condição definida no if
seja verdadeira, os comandos colocados dentro do seu escopo serão executados, caso contrário os comandos colocados dentro do escopo do else
serão executados. Caso seja necessário definir mais de duas opções de fluxo de processamento, pode-se combinar as palavras chaves else
e if
para definir condições alternativas. Considere o exemplo a seguir, em que é verificado e informado ao usuário se um número é positivo, negativo ou igual a zero.
#include <stdio.h>
int main() {
int n1;
scanf("%d",&n1);
if(n1 > 0) {
printf("valor positivo");
}
else if (n1 < 0){
printf("valor negativo");
}
else {
printf("valor igual a zero");
}
return 0;
}
Diferença em relação a Python: em Python existe uma palavra chave que representa a combinação de um else
com um if
, denominada elif
. Em C essa palavra chave não existe.
switch-case
Outra forma de modelar uma decisão é por meio da estrutura switch-case
. Nesse tipo de estrutura de decisão, o fluxo de código a ser executado depende do valor de uma expressão que retorna um valor inteiro (ou um tipo com representação inteira direta). Cada valor de interesse da expressão é denominado de "caso" (case
). Considere o exemplo de código a seguir, que informa ao usuário qual a opção escolhida, de acordo com o número digitado.
#include <stdio.h>
int main () {
int op;
printf("Digite o valor de op: ");
scanf("%d",&op);
switch(op) {
case 1 :
printf("Op. 1 escolhida\n" );
break;
case 2 :
printf("Op. 2 escolhida\n" );
break;
case 3 :
printf("Op. 3 escolhida\n" );
break;
default :
printf("Op. invalida\n" );
}
return 0;
}
A variável do tipo int
denominada op
é utilizada como a condição no switch
e três casos (case
) possíveis são definidos, que são executados quando a variável op
possui os valores 1, 2 e 3, respectivamente. Caso um valor menor que 1 ou maior que 3 seja digitado, é informado ao usuário que a opção é inválida. O valor de cada caso deve ser sucessido por :
e os comandos que fazem parte do caso devem ser colocados em seguida. Os comandos são então executados até que se encontre uma palavra chave break
.
É importante notar que se não for colocado um break
, todos os comandos posteriores ao case
correspondente ao valor da condição serão executados, inclusive os comandos definidos nos casos posteriores. Por exemplo, caso seja retirado o break
da linha 13 do exemplo mostrado, se o valor da variável op
for igual a 2, a seguinte saída será mostrada na tela:
Op. 2 escolhida
Op. 3 escolhida
O caso default
sempre deve ser definido (mesmo que sem comandos) e é executado quando o valor da variável de condição é diferente dos valores definidos em todos os case
.
Resolver os seguintes problemas no beecrowd, usando a linguagem de programação C:
Durante a construção de algoritmos é comum aparecer casos em que um comando ou um determinado conjunto de comandos deve ser repetido uma certa quantidade de vezes ou repetidos de acordo com alguma condição. Portanto, é necessário algum mecanismo para se representar a repetição de comandos em um algoritmo. Na linguagem C existem três estruturas de repetição: while
, do while
e for
.
A primeira estrutura de repetição a ser apresentada é a estrutura while
. Essa estrutura permite repetir a execução de um conjunto de comandos de acordo com alguma condição. Se a condição for verdadeira, o bloco de comandos definido dentro do escopo do while
será executado. Ao final da execução de todos os comandos do escopo, a condição é avaliada novamente. Caso ela permaneça verdadeira, o bloco de comandos é executado novamente. Esse processo se repete até que a condição seja falsa, e nesse caso o bloco de comandos não é executado e o fluxo de execução do algoritmo continua a partir do primeiro comando depois do fechamento de chaves (}
) do while
. Caso a condição nunca fique falsa, o programa entrará em uma condição de loop infinito. Considere o exemplo a seguir, que usa uma estrutura de repetição while
.
#include <stdio.h>
int main() {
int N;
printf("Digite um valor para N\n");
scanf("%d",&N);
while(N != 5) {
printf("Digite um novo valor para N\n");
scanf("%d",&N);
}
printf("Finalmente foi digitado 5\n");
return 0;
}
No código mostrado é lido um valor inteiro da entrada, que é atribuído à variável N
. Após isso, são lidos novos valores para N
de forma contínua enquanto o valor lido for diferente de 5. É importante notar que se o primeiro valor lido para N
for igual a 5 (fora do while
) nenhuma repetição é realizada. Dessa forma, a condição que define se uma repetição vai ocorrer ou não é a verificação se N
é diferente de 5 (N != 5
).
A estrutura de repetição do while
é muito semelhante à estrutura while
. A única diferença é que no do while
o bloco de comandos no interior da estrutura de repetição é executado pelo menos uma vez. Apenas após uma iteração o teste da condição é realizado. Se a condição for verdadeira ocorre a repetição dos comandos. O exemplo a seguir mostra um algoritmo similar ao descrito no exemplo anterior, mas agora utilizando o do while
.
#include <stdio.h>
int main() {
int N;
do {
printf("Digite um novo valor para N\n");
scanf("%d",&N);
} while(N != 5);
printf("Finalmente foi digitado 5\n");
return 0;
}
A terceira estrutura de repetição definida na linguagem C é a estrutura for
. Em C a definição do for
é muito mais flexível do que em Python, uma vez que a repetição também ocorre com base em uma condição e não com base em uma lista de valores a serem percorridos. No entanto, esse tipo de estrutura de repetição é geralmente a melhor escolha quando se sabe de antemão a quantidade de repetições a serem realizadas. O modo mais comum de uso da estrutura for
é por meio do uso de uma variável de controle, que geralmente serve para contar a quantidade de repetições já realizadas e também é útil para construção de algoritmos que manipulam Arrays, como será melhor discutido em um capítulo posterior. O exemplo de código a seguir mostra como repetir 100 vezes um conjunto de comandos usando for
.
#include <stdio.h>
int main() {
int i;
for(i = 0; i < 100; i++) {
printf("Valor de i: %d\n", i);
}
return 0;
}
Ao executar o programa gerado por esse código são mostradas 100 frases na saída, no formato mostrado a seguir.
Valor de i: 0
Valor de i: 1
Valor de i: 2
Valor de i: 3
Valor de i: 4
Valor de i: 5
...
Valor de i: 99
O código mostrado nesse exemplo é equivalente ao seguinte código que usa while
:
#include <stdio.h>
int main() {
int i = 0;
while(i < 100) {
printf("Valor de i: %d\n", i);
i++;
}
return 0;
}
Em geral, tudo que se pode fazer com um for
, é possível de se fazer com um while
, e vice-versa. A estrutura for
, entretanto, é mais compacta e mais fácil de ser usada em situações em que já se sabe a quantidade de repetições de antemão e quando é necessário o uso de uma variável de controle, que conta a quantidade de repetições.
Dentro do for
são definidas três partes: a inicialização da variável de controle (i = 0
), a condição de repetição (i < 100
) e por último o incremento da variável de controle (i++
). Nenhuma das três partes é obrigatória, mas é necessário colocar de toda forma os ;
dividindo as três partes [ex: for( ; i < 100; )
]. Tanto a condição de repetição como o incremento podem ser escritos de forma diferente do que foi mostrado no exemplo. Por exemplo, pode-se definir que a variável de controle será incrementada de 2 em 2 (i += 2
) ou mesmo que ela será decrementada. Também é possível inicializar e realizar incremento/decremento em mais de uma variável dentro da mesma estrutura for
. Considere o exemplo a seguir, em que duas variáveis de controle (i
e k
) são inicializadas e incrementadas/decrementadas dentro do for
.
#include <stdio.h>
int main() {
int i;
int k;
for(i = 0, k = 99; i < 100; i++, k--) {
printf("Valor de i: %d\n", i);
printf("Valor de k: %d\n", k);
}
return 0;
}
Ao executar o programa gerado por esse código são mostradas 200 frases na saída, no formato mostrado a seguir.
Valor de i: 0
Valor de k: 99
Valor de i: 1
Valor de k: 98
Valor de i: 2
Valor de k: 97
Valor de i: 3
Valor de k: 96
...
Valor de i: 99
valor de k: 0
Resolver os seguintes problemas no beecrowd, usando a linguagem de programação C: