Mudanças entre as edições de "Programação 1 - Engenharia - Comandos de Repetição no C"

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar
Linha 516: Linha 516:
 
         continue;
 
         continue;
 
     }
 
     }
     printf("valor de j = %d\n", j);
+
     printf("valor de i = %d\n", i);
 
     for (j=0;j<4;j++) {
 
     for (j=0;j<4;j++) {
 
         if (j==1) {  
 
         if (j==1) {  
Linha 527: Linha 527:
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 
 
  
 
===Usando funções da biblioteca matemática===
 
===Usando funções da biblioteca matemática===

Edição das 14h14min de 21 de agosto de 2018

AULA 6

Objetivos

O aluno deverá ser capaz de colocar estruturas de repetição especificadas em fluxogramas ou pseudo-código na forma de estruturas em linguagem C.

Estruturas de Repetição

Existem 4 estruturas/comandos que permitem implementar loops ou repetições de blocos de código:

  • while()
  • do while()
  • for()
  • goto label
NOTA 1: Observe que repetir o código siginifica voltar a executá-lo, normalmente sobre o controle de uma expressão lógica.

O comando while():teste da repetição no começo

O comando while permite implementar loops com controle no início:

#include <stdio.h>
main() 
{
  int contador;
  
  contador=0;
  while (contador<5)     
     contador=contador+1;
  printf("valor do contador =  %d\n", contador);
}

Variação do exemplo anterior:

#include <stdio.h>
main() 
{
  int contador;
 
  contador=0;
  while (contador<5) {  
	 printf("valor da expressão =  contador < 5 é %d\n", contador<5);  
         printf("valor do contador =  %d\n", contador);
         contador=contador+1;
  }
  printf("NO FINAL a expressão  contador < 5 é %d\n", contador<5);
}
Notar que a expressão contador<5 assume valor 0 (falso) e 1 (verdadeiro).

A estrutura do comando, informalmente, é:

while (expressão)
  instrução_simples;

ou

while (expressão) {
  lista_de_instruções
} 

Vamos ver a correspondência do comando while com um fluxograma:

Fluxograma C Comentário
Fluxo5.jpg
while(contador<5) {
   printf("Entre com x\n");
   scanf("%f",&x);
   soma=soma+x;
   contador = contador + 1;
}
comando while() aplicado sobre um bloco de instruções. Note que se for uma instrução simples, as chaves podem ser omitidas.
NOTE que no exemplo anterior o contador inicialmente DEVE conter um valor válido.

Comando do while: controle do loop no final

O comando do while() permite a repetição de uma ou mais instruções, com controle do loop no final. Isto permite que o bloco seja executado pelo menos uma vez.

#include <stdio.h>
main() 
{
  int contador;
  
  contador=0;
  do {  
     printf("valor do contador =  %d\n", contador);
     contador=contador+1;
  } while (contador<5);
}

A estrutura do comando, informalmente, é:

do 
  instrução_simples;
while (expressão);

ou

do {
  lista_de_instruções
} while (expressão); 
 
Fluxograma C Comentário
FluxoDoWhile-Eraldo.jpg
contador = 0;
do {
   scanf("%d",&x);
   soma=soma+x;
   if (soma>150) 
       y=z+x;
   contador++;
} while(contador<5);
Note que instruções while e if são tratadas como instruções normais que podem ser aninhadas normalmente em outros comandos.

Comando for()

O comando for() permite uma forma mais elaborada de loop, com controle no início do bloco de repetição.


#include <stdio.h>

main()
{
  int i;
  
  for (i=0;i<10;i=i+1)
      printf("i =%d\n",i);
}

A estrutura do comando é:

for(expressão_inicial;expressão_de_controle; expressão_de_final_de _bloco)
    instrução_simples;

ou

for(expressão_inicial;expressão_de_controle; expressão_de_final_de _bloco) {
    lista_de_instruções
}
Fluxograma C Comentário
FluxogramaComandoFor-Eraldo.jpg
for(i=0; i<10; i++) {
  printf("Laço de número %d\n", i);
  if (i==5)
      printf("Este é o laço 5\n");
}
Observe que a expressão i=0 é executada SEMPRE e uma única VEZ, no início do comando.

A expressão i<10 é o controle do loop. Se FALSA o loop é encerrado. Ela é executada após a expressão de inicialização e, na sequência, no início de cada loop. A expressão i++ é executada no final de cada loop.

Aninhamento de loops

#include <stdio.h>
main()
{
  int i,j;
 
  for (i=0;i<3;i++) {
     for (j=0;j<4;j++) {
         printf("valor de j = %d\n", j);
     }
     printf("valor de i = %d\n", i);
  }
}

Comando goto

O comando goto é um dos mais antigos da programação. A ideia é comandar um salto para um determinado ponto específico do programa marcado por um rótulo (LABEL). Para utilizá-lo deve-se, portanto, marcar o ponto para onde será feito o salto usando um LABEL.

Exemplo:

#include <stdio.h>

main()
{
   int i;

   i=0;

PONTO1:
   printf("Laço de número %d\n", i);
   i++;
   if (i<10)
       goto PONTO1;
}
Devido a ser uma instrução "desestruturante", em geral NÂO se recomenda o uso deste comando.

Em alguns casos de tratamento de erro pode ser interessante o uso do goto.

Leia um pouco mais sobre o goto aqui.

Loop Infinito

É possível implementar loops infinitos com qualquer uma das instruções acima.

Exemplo com comando for:

main()
{
   for(;;) {
        /* Este bloco se executará infinitamente */
   }
}

ou com o comando while:

main()
{
   while(1) {
        /* Este bloco se executará infinitamente */
   }
}


Exercícios

1.Usando o comando for aninhado, construa um programa que implemente a figura abaixo. A margem esquerda (margem de espaços), o caracter do desenho, o número de linhas vazadas e o tamanho horizontal da figura devem ser lidos pelo teclado.

  aaaaaaaaaa
  a        a
  aaaaaaaaaa
 SUGESTÃO: dividir em subproblemas.
solução
#include <stdio.h>

main()
{
  int i, j, margem, largura, linhas_vazadas;
  char caracter;
  
  /** sub-problema 1 - ler margem , largura de desenho, caracter desenho e numero de linhas **/

  printf("\n=====================\n");
  printf("Entrar com margem => ");
  scanf("%d", &margem);
  printf("\n=====================\n");
  printf("Entrar com largura => ");
  scanf("%d", &largura);
  printf("\n=====================\n");
  printf("Entrar com caracter => ");
  scanf(" %c", &caracter);
  printf("\n=====================\n");
  printf("Entrar com linhas_vazadas => ");
  scanf(" %d", &linhas_vazadas);
  
  /* sub-problema 2 - desenhar linha de topo */

  /* desenhar margem */
  for (i=0;i<margem;i++) 
     printf(" ");
  /* desenhar restante da linha de topo */
  for (i=0;i<largura;i++)
     printf("%c", caracter);
  printf ("\n"); /* avançar para a próxima linha */

  /* sub-problema 3 - desenhar linhas vazadas */

  for (j=0;j<linhas_vazadas;j++) {
     /* desenhar margem */
     for (i=0;i<margem;i++) 
        printf(" ");
     if(largura>0)
        printf("%c", caracter);
     for (i=0;i<largura-2;i++)
          printf(" ");
     if(largura>1)
        printf("%c", caracter);
     printf("\n");
  }

  /* sub-problema 4 - desenhar linha de fundo */

  /* desenhar margem */
  for (i=0;i<margem;i++) 
     printf(" ");
  /* desenhar restante da linha de topo */
  for (i=0;i<largura;i++)
     printf("%c", caracter);
  printf ("\n"); /* avançar para a próxima linha */
}

2.Dado um ´numero inteiro positivo, calcular a soma de todos os números inteiros compreendidos entre 0 e o número dado. Fazer uma versão com while e outra com for.

3.Construa um programa para desenhar a seguinte figura de forma parametrizável (dado caracter, margem, e número de linhas):

  AAAAAAAAAAAAAAAA
  AAAAAAAAAAAAAA
  AAAAAAAAAAAA
  AAAAAAAAAA
  AAAAAAAA
  AAAAAA
  AAAA
  AA
  BB
  BBBBB
  BBBBBBBB
  BBBBBBBBBBB
  BBBBBBBBBBBBBB
  BBBBBBBBBBBBBBBBB
  BBBBBBBBBBBBBBBBBBBB
  BBBBBBBBBBBBBBBBBBBBBBB
solução
#include <stdio.h>

main()
{
  int i, j, margem, largura, linhas;
  char caracter1,caracter2;
  
  /** sub-problema 1 - ler margem , largura de desenho, caracter desenho e numero de linhas **/

  printf("\n=====================\n");
  printf("Entrar com margem => ");
  scanf("%d", &margem);
  printf("\n=====================\n");
  printf("Entrar com caracter 1 => ");
  scanf(" %c", &caracter1);
  printf("\n=====================\n");
  printf("Entrar com caracter 2 => ");
  scanf(" %c", &caracter2);
  printf("\n=====================\n");
  printf("Entrar com linhas (tem que ser maior ou igual a 1) => ");
  scanf(" %d", &linhas);
  
  /* sub-problema 2 - desenhar parte superior */

  for (i=linhas;i>0;i--) {
     /* desenhar margem */
     for (j=0;j<margem;j++) 
        printf(" ");
     for (j=0;j<i*2;j++) {
        printf("%c", caracter1);
     }
     printf("\n");
  }

  /* sub-problema 3 - desenhar parte inferior */
  for (i=1;i<=linhas;i++) {
     /* desenhar margem */
     for (j=0;j<margem;j++) 
        printf(" ");
     for (j=0;j<i*2;j++) {
        printf("%c", caracter2);
     }
     printf("\n");
  }

}

4.Estude o programa (referência) abaixo:

/* rand example: guess the number */
/* extract from www.stackoverflow.com */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main ()
{
      int iSecret, iGuess;

      /* initialize random seed: */
      srand ( time(NULL) );

      /* generate secret number: */
      iSecret = rand() % 10 + 1;

      do {
          printf ("Guess the number (1 to 10): ");
          scanf ("%d",&iGuess);
          if (iSecret<iGuess) 
              printf ("The secret number is lower\n");
          else {
              if (iSecret>iGuess) 
                 printf ("The secret number is higher\n");
          }
      } while (iSecret!=iGuess);

      printf ("Congratulations!\n");
      return 0;
}

Estude também o significado das instruções:

 srand ( time(NULL) );
 iSecret = rand() % 10 + 1;

5.Sobre o exercício 3, implemente uma versão usando o comando while().

solução

/* rand example: guess the number */

  1. include <stdio.h>
  2. include <stdlib.h>
  3. include <time.h>

int main () {

     int iSecret, iGuess;

     /* initialize random seed: */
     srand ( time(NULL) );

     /* generate secret number: */
     iSecret = rand() % 10 + 1;

     /* set a initial value for iGuess not in the range 1-10*/
     iGuess=0;

     while (iSecret!=iGuess) {
         printf ("Guess the number (1 to 10): ");
         scanf ("%d",&iGuess);
         if (iSecret<iGuess) 
             printf ("The secret number is lower\n");
         else {
             if (iSecret>iGuess) 
                printf ("The secret number is higher\n");
         }
     } while (iSecret!=iGuess);

     printf ("Congratulations!\n");
     return 0;

}

6.Elabore um programa que lê um número inteiro e imprime todos os números pares entre 1 e este número.

Uso de break para sair de loops

Em exercícios anteriores, a finalização de um loop normalmente se dá pela expressão de controle de loop associado a instrução usada. É possível sair de um loop na força bruta usando a instrução break:

#include <stdio.h>
main()
{
  int i,j;

  for (i=0;i<10;i++) {
     if (i==5)
       break;
  }
  printf("valor de i=%d\n", i);
}

Note que o break sempre sai do loop mais próximo a ele.

#include <stdio.h>
main()
{
  int i,j;

  for (i=0;i<3;i++) {
     for (j=0;j<4;j++) {
         if (j==1) { 
             break;
         }
         printf("valor de j = %d\n", j);
     }
     if (i==2)
         break;
     printf("valor de i = %d\n", i);
  }

}

Uso do continue para prosseguir no início do loop

#include <stdio.h>
main()
{
  int i,j;

  for (i=0;i<3;i++) {
     if (i==1) { 
         continue;
     }
     printf("valor de i = %d\n", i);
     for (j=0;j<4;j++) {
         if (j==1) { 
             continue;
         }
         printf("valor de j = %d\n", j);
     }
  }

}

Usando funções da biblioteca matemática

Para usar as funções matemáticas da biblioteca padrão, fazer os seguintes passos:

  • No arquivo-fonte incluir o header math.h da biblioteca matemática:
 
#include <stdio.h>
#include <math.h>

main()
{
 
  float x,y; /* declaração de duas variáveis reais */

  printf ("Entre com o valor de x ");
  scanf("%f",&x);

  y = sqrtf(x);
  printf ("Raiz de x = %lf", y);
}

NOTA: a maior parte de parâmetros e valores de retorno das funções matemáticas são reais de dupla precisão (double).

  • Compilar e linkar o arquivo da forma:
 gcc ex1.c -o ex1 -lm

EXERCÍCIOS

  1. Faça uma versão "politicamente incorreta" do programa de adivinhação da aula passada, Faça um loop infinito com o do while() e use uma instrução goto para sair do loop.
  2. Ainda sobre o exercício 1, implemente uma versão usando o comando while().
  3. Ainda sobre o exercício 1, implemente uma versão usando loop infinito e o comando break;
  4. Implemente um programa C para ler N resistências. O programa deve ler inicialmente N, depois o valor das resistências (fazendo os cálculos cumulativos) e então calcular o valor da resistência série e paralelo equivalente do circuito. Não usar vetores. Usar um comando while.
  5. Tente descobrir por tentativas qual carga em um circuito com uma fonte de tensão de 500 V e resistência interna de 10 ohms produz a máxima dissipação de potẽncia (ver https://en.wikipedia.org/wiki/Maximum_power_transfer_theorem). Sugestão: gere/imprima uma tabela com valor de resistores de carga de 1 a 20 ohms com acréscimos de 0.5 ohms indicando a potência dissipada em cada um.