Programar em C/Condicionais

Origem: Wikilivros, livros abertos por um mundo aberto.

Recycle001.svg 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;
}



Criação de menu.

#include <iostream>
using namespace std; 
int main ()
{
  int  i;
  do
   {
      	cout << "\n\nEscolha a fruta pelo numero:\n\n";
      	cout << "\t(1)...Mamao\n";
      	cout << "\t(2)...Abacaxi\n";
      	cout << "\t(3)...Laranja\n\n";
      	cin >> i; 
   } while ((i<1)||(i>3));
  switch (i)
      {
      	case 1:
              	cout << ("\t\tVoce escolheu Mamao.\n");
      	      break;
      	case 2:
              	cout <<"\t\tVoce escolheu Abacaxi.\n";
      		break;
      	case 3:
              	cout << ("\t\tVoce escolheu Laranja.\n");
      		break;
       }
  system (“pause”);
  return(0);
}