Programar em C/Condicionais
Origem: Wikilivros, livros abertos por um mundo aberto.
| Esta página precisa ser reciclada (discuta). Ao melhorá-la, você estará ajudando o Wikilivros. |
Tabela de conteúdo |
[editar] Control Structures
Aqui vamos criar funções que nos permitam alterar a leitura de execução do código. Ou seja, já dissemos que a leitura de execução do código é de cima para baixo (lê a primeira linha de código – executa, lê a 2ª linha --- executa,..e por aí adiante) O que agora vamos fazer e criar mecanismos para alterar esse leitura sequencial e permitir:
- Execução de código sujeito a condição
- Repetição de execução de código sujeito a condição
- Saltar linhas de código
…enfim isto é o que nos vai permitir realmente começar a ser imaginativos, vejamos…
[editar] Branching - Função IF
A função if só é executada se a expressão relacional for true=1.
A sintax é:
if (Boolean value) statement;
Reparar que só temos o ponto e virgula no final do statement.
Exemplificando:
#include <iostream>
using namespace std;
int main(void)
{
int num;
cout << "entre com um número inteiro: ";
cin >> num;
if ( num % 2 == 0 )
cout << "o número é par" << endl;
/* O comando system utilizar um argumento difetente conforme o compilador.
Retire o comentário daquela que parecer funcionar no compilador corrente */
// system (“pause”);
// system ("PAUSE");
// cin.get() // Outra opção é utiliza cin.get() ao invés de system ("PAUSE")
return 0;
}
|
No exemplo se colocarmos um valor impar o programa acaba, se colocarmos um valor par ele apresenta a frase “o número é par”. Repare no operador de igualdade “==”. Como o operador aritmético tem uma precedência superior em relação aos operadores relacionais primeiro é feita a conta num%2.
Erro: Um erro bastante comum é colocar o ponto e virgula antes do statement como já avisei. Mas isto não vai dar um erro de compilação mas sim um erro lógico. Isto é aceite porque é permitido ter nenhum statement.
Erro: Outro erro também bastante comum é trocar o = por ==, ou seja querem fazer a comparação em vez de atribuição!
Depois ainda temos o ponto se tivermos 2 statements depois do if, só o primeiro é que é afectado pela avaliação do valor boolean. Ou seja o 2º statement é como estivesse fora do if. Para colocarmos vários (+de 2) afectados pela avaliação do if temos de os colocar em grupo com {}.
Pergunta: não tem realmente sentido a sintax do c++ permitir a questão do ponto e vírgula, para funções de controlo de execução de código. Deveria dar logo erro de compilação. Mas penso que isto se deve por termos mais operadores para além do if.
IF-ELSE No exemplo anterior não acontecia nada se inseríssemos um valor impar. Podemos remendar isso se utilizarmos o if-else
if (relational expression) conditional statement; else conditional statement;
Remendando o exemplo anterior ficamos com
#include <iostream>
using namespace std;
int main(void)
{
int num;
cout << "Enter a whole number: ";
cin >> num;
if ( num % 2 == 0 )
cout << "The number is even" << endl;
else
cout << "The number is odd" << endl;
system (“pause”);
return 0;
}
|
Não utilizar o “;” a seguir ao else Aqui também costuma acontecer um erro bem comum que é
if ( num % 2 == 0 )
cout << "The number is even" << endl;
else ( num % 2 == 1 )
cout << "The number is odd" << endl;
|
O problema está no else que não deve ter a expressão relacional
If - ELSE IF - Else
#include <iostream>
using namespace std;
int main(void)
{
int testScore;
cout << "Entre com um valor (0 a 100): ";
cin >> testScore;
if (testScore >= 90 )
cout << "o valor é A" << endl;
else if (testScore >= 80 )
cout << " o valor é B" << endl;
else if (testScore >= 70 )
cout << " o valor é C" << endl;
else if (testScore >= 60 )
cout << " o valor é D" << endl;
else
cout << " o valor é F" << endl;
system (“pause”);
return 0;
}
|
Notar que o ultimo é apenas else e não else if
Mas há ainda aqui 1 pormenor importante. Se inserirmos 87, deveria dar B e ainda C e D, pois para ambos é cumprida a relação de comparação. o que se passa é que quando uma das hipóteses é realizada, os outros elses são ignorados. Portanto se alterássemos o else-if do C para antes do B teríamos o resultado C. portanto aqui temos a questão da ordenação do código
o programa começa a testar as condições começando pela primeira até achar uma condição que seja verdadeira, se não encontrar nenhuma temos o else final (que é o defaut) mas ela é opcional!
IF-ELSE dentro de IF-ELSE
if (age >= 18)
if(citizen == true)
cout << "You are eligible to vote";
else
cout << "You are not eligible to vote";
else
cout << "You are not eligible to vote";
|
Chama-se a IF dentro de IF ou NESTED IF ou ainda em português IF ANINHADO
[editar] Branching - Switch
O switch é muito parecido com o if-else. Apenas a sintaxe e construção é diferente
#include <iostream>
using namespace std;
int main(void)
{
char grade;
cout << "Enter your grade (A to F): ";
cin >> grade;
switch (grade)
{
case 'A':
cout << "Your average must be between 90 - 100"<< endl;
break;
case 'B':
cout << "Your average must be between 80 - 89"<< endl;
break;
case 'C':
cout << "Your average must be between 70 - 79"<< endl;
break;
case 'D':
cout << "Your average must be between 60 - 69"<< endl;
break;
default:
cout << "Your average must be below 60" << endl;
}
system (“pause”);
return 0;
}
|
- Cada um dos casos tem de ser uma constante (não pode alterar durante a vida do programa), neste exemplo A, B, …
- O defaut serve para a condição de todas as avaliações dos casos anteriores der falsa. (é tipo o else)
- O break serve para terminar o switch, caso contrário se num dado case fosse verdadeiro, iria executar todos os statementes mesmo de outros cases até terminar o switch.
- Aqui para cada caso não necessitamos de {} se tivermos mais do que 2 statements.
- o if-else é mais forte do que o switch por que permite fazer coisas como:
if (apples == oranges) do this; else if (sales >= 5000) do that;
- Para além do ponto já dito de os casos serem obrigatoriamente constants, no switch
- Também posso utilizar operadores lógicos no switch
switch (age >= 18 && citizen == true)
{
case true:
cout << "You are eligible to vote";
break;
case false:
cout << "You are not eligible to vote";
}
|
[editar] LOOP - WHILE
#include <iostream>
using namespace std;
int main(void)
{
int num = 1;
while (num <= 10)
{
cout << num << " ";
num++;
}
system (“pause”);
return 0;
}
|
Notar que colocamos o incremento dentro do bloco caso contrário tínhamos um loop infinito. Notar que se quisermos podemos ter o incremento e a condição ao mesmo tempo while (num++ < 10) Mas neste caso quem é que tem maior precedência o ++ postfix ou o <.? (Vem primeiro a comparação.)
a condição do loop pode ser da forma”(a0)” não esquecer a aula dos operadores
[editar] LOOP – DO –WHILE
Aqui a diferença é que o teste da condição é feita depois dos statements, o que significa que os statements são executados pelo menos uma vez
do
{
statement(s);
} while (condition);
A função do while é exactamente igual à while só que põe a condição depois do bloco, o que significa que o bloco é executado pelo menos uma vez. ou seja o seu uso garante que os statements ou declaração é executada pelo menos uma vez! por isso é que ela é tão usada nos menus.
[editar] LOOP - FOR
Esta é para mim a arma mais poderosa
#include <iostream>
using namespace std;
int main(void)
{
for (int num = 1; num <= 10; num++)
cout << num << " ";
system (“pause”);
return 0;
}
|
A sintaxe é
for ([iniciação]; [condição]; [incremento]) statement;
- A condição tem de ser true (=1) para ser executado o statement.
- Depois dos statements serem executados vem a instrução de incremento e
- Novamente é avaliada a condição. Se esta ainda for true volta-se a repetir o ciclo.
Notar mais uma vez onde está o ponto e vírgula. Notar que a condição pode ser “a<10 || b>20”, a iniciação e o incremento também podem ser desta forma.
Pergunta: se não tivermos um dos parâmetros o que é que acontece? Com esta possibilidade podemos alcançar loops infinitos, tipo
Caso 1: ausência do 2º parâmetro
for (int num =1; ;num++)
{
cout << num << " ";
}
Isto vai colocar um valor a mais no num indefinidamente.
Caso 2: ausência do 3º parâmetro
for (int num=1; num <= 10; )
{
cout << num << " ";
}
Isto vai repetir sempre o num=1, apesar de termos condição, mas a condição num chega a ser alcançada.
Felizmente o sistema operativo consegue detectar muitas vezes o loop infinito, mas caso isso não aconteça utilizar o CRTL-BREAK.
Podemos ter também loops dentro de loops
Podemos também quebrar o loop através do break
[editar] Comando - Break
O que o break faz é quebrar a execução para fora do bloco de código onde ela está presente
#include <iostream>
using namespace std;
int main(void)
{
int num;
char choice;
bool quit = false;
while (true)
{
cout << "Enter a positive number: ";
cin >> num;
if (num > 0)
break;
else
{
cout << "Number must be positive; try again (Y/N): ";
cin >> choice;
if (choice != 'Y')
{
quit = true;
break;
}
}
}
if (quit == false)
cout << "The number you entered is " << num << " ";
else
cout << "You did not enter a positive number";
system (“pause”);
return 0;
}
|
O break faz com que a execução do programa continue na primeira linha seguinte ao loop ou bloco
[editar] Comando – Continue
Esta instrução é bem parecida com o break, mas algo diferente. Pois em vez de mandar a execução para fora do bloco manda-a para a avaliação do loop. Ou seja faz saltar uma determinada iteração do loop, enquanto o break faz acabar o loop
#include <iostream>
using namespace std;
int main(void)
{
int num, counter = 0, total = 0;
cout << "How many items do you want to buy: ";
cin >> num;
while (counter++ < num)
{
if (counter % 13 == 0)
continue;
total += 3;
}
cout << "Total for " << num << " items is $" << total;
return 0;
}
|
Neste exemplo quando o conter for múltiplo de 13, a instrução seguinte é saltada total+=3
[editar] Comando goto
O goto realiza um salto para um local especificado. Este local é determinado por um rótulo. Portanto pode ser em qualquer parte do programa.
nome_do_rótulo: .... goto nome_do_rótulo; ....
// goto loop example
#include <iostream>
using namespace std;
int main ()
{
int n=10;
loop:
cout << n << ", ";
n--;
if (n>0)
goto loop;
cout << "FIRE!";
system (“pause”);
return 0;
}
|
repare no rotulo
[editar] JUMP – O Comando exit
Esta função é definida com a biblioteca cstdlib (c+std+lib) O propósito da função é terminar com o programa com um específico código de saída O protótipo é:
- int exit (int exitcode);
Esta função é usada por alguns sistemas operativos e podem ser usadas para chamar programas. Por convenção o código 0 se saída significa que o programa terminou normalmente, como previsto, se vier com outro número significa que houve um erro e algo de inesperado sucedeu.
Pergunta: qual é a diferença entre o exit e o return?
[editar] COMMA OPERATOR ( , )
O operador vírgula (,) é usado para separar 2 ou mais expressões onde se espera apenas uma expressão. Quando tivermos várias expressões estiverem a ser avaliadas para um valor, a expressão mais á direita é a que é considerada.
- a = (b=3, b+2);
Neste exemplo iria colocar o valor 3 em b e depois adicionaria 2 ao valor de b ficando a com 5 e b com 3
[editar] Operador condicional ?
A sintaxe é
- [Relational expression] ? [statement if true] : [statement if false]
Ou seja, este operador faz um teste á expressão relacional e se o resultado for verdadeiro executa logo a 1ª afirmação caso contrário executa a segunda.
ou seja isto não é mais do que um if-else.
Há quem goste de usar este operador porque poupa escrita, mas acho que não vale a pena!
#include <iostream>
using namespace std;
int main(void)
{
int num;
cout << "Enter a whole number: ";
cin >> num;
cout << "The number is " << (num % 2 == 0 ? "even" : "odd") << endl;
system (“pause”);
return 0;
}
|
Notar que o operador condicional exige 3 operandos.
vamos fazer uns exercícios:
- 7==5 ? 4 : 3 // returns 3, since 7 is not equal to 5.
- 7==5+2 ? 4 : 3 // returns 4, since 7 is equal to 5+2.
- 5>3 ? a : b // returns the value of a, since 5 is greater than 3.
- a>b ? a : b // returns whichever is greater, a or b.
[editar] Increment/decremente Operator
Aqui vamos voltar a um tópico anterior que foi abordado nos operadores Temos
- a=a+1 é equivalente a ter a+=1 e ainda a ter a++ (este é novo)
Mas isto tudo é só no caso do incremento ser 1.
Podemos ter ++a ou ainda a++. Eles são parecidos mas diferentes, é a questão do prefixo e pós-fixo. A diferença é que
- O prefixo, faz o incremento ainda durante a instrução
- O pós-fixo faz o incremento quando se passa para a instrução seguinte.
#include <iostream>
using namespace std;
int main(void)
{
int num = 2;
cout << num << ”\n”;
cout << ++num << ”\n”;
cout << num++ <<”\n”;
cout << num << ”\n”;
system (“pause”);
return 0;
}
|
Portanto
- int num = 5;
- cout << (++num == 5);
[editar] Exercícios
Crie um programa que dê o factorial de um número
#include <iostream>
using namespace std;
int main(void)
{
int num, counter, total = 1;
cout << "Enter a number: ";
cin >> num;
cout << "The factorial of " << num << " is ";
for (int counter = 1; counter <= num; counter++)
total *= counter;
cout << total;
system (“pause”);
return 0;
}
|
Crie um programa para o utilizador adivinhar um número de 0 a 3. Dê 3 hipóteses para adivinhar. No caso de acertar antes de chegar ao fim das 3 hipóteses termine.
#include <iostream>
using namespace std;
int main(void)
{
int num, counter, secret = 3;
cout << "Guess a number between 1 and 10\n";
cout << "You have 3 tries\n";
for (int counter = 1; counter <= 3; counter++)
{
cout << "Enter the number now: ";
cin >> num;
if (num == secret)
{
cout << "You guessed the secret number!";
break;
}
}
cout << "Program over";
system (“pause”);
return 0;
}
|