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
 
(170 revisões intermediárias por 3 usuários não estão sendo mostradas)
Linha 4: Linha 4:
 
=Objetivos=
 
=Objetivos=
  
*O aluno deverá ser capaz de colocar estruturas de repetição especificadas
+
Após esta aula o aluno deverá:
em fluxogramas ou pseudo-código na forma de estruturas em linguagem C.
+
*conhecer a sintaxe e a semântica dos comandos de repetição do C: while, do while, for e goto.
 +
*utilizar comando break para sair de loops e o continue para interromper um laço específico;
 +
*identificar quando usar variáveis inteiras com maior ou menor capacidade de armazenamento (char, unsigned, long).
 +
*mapear estruturas simples de repetição especificadas em fluxogramas ou pseudo-código em estruturas em linguagem C.
  
 
</center>
 
</center>
Linha 18: Linha 21:
 
*''goto label''
 
*''goto label''
  
  NOTA: Observe que repetir o código siginifica voltar a executá-lo, normalmente sobre o controle de uma expressão lógica.
+
  NOTA: Observe que repetir o código significa voltar a executá-lo (sem ter que escrevê-lo novamente) e normalmente sobre o controle de uma expressão lógica.
  
 
=O comando ''''while()'''': TESTE da REPETIÇÃO no começo =
 
=O comando ''''while()'''': TESTE da REPETIÇÃO no começo =
Linha 38: Linha 41:
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
main()  
+
int main()  
 
{
 
{
 
   int contador;
 
   int contador;
Linha 46: Linha 49:
 
     contador=contador+1;
 
     contador=contador+1;
 
   printf("valor do contador =  %d\n", contador);
 
   printf("valor do contador =  %d\n", contador);
 +
  return 0;
 
}  
 
}  
 
</syntaxhighlight>
 
</syntaxhighlight>
Linha 55: Linha 59:
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
main()  
+
int main()  
 
{
 
{
 
   int contador;
 
   int contador;
Linha 61: Linha 65:
 
   contador=0;
 
   contador=0;
 
   while (contador<5) {   
 
   while (contador<5) {   
printf("valor da expressão =  contador < 5 é %d\n", contador<5);   
+
        printf("valor da expressão =  contador < 5 é %d\n", contador<5);   
 
         printf("valor do contador =  %d\n", contador);
 
         printf("valor do contador =  %d\n", contador);
 
         contador=contador+1;
 
         contador=contador+1;
 
   }
 
   }
 
   printf("NO FINAL a expressão  contador < 5 é %d\n", contador<5);
 
   printf("NO FINAL a expressão  contador < 5 é %d\n", contador<5);
 +
  return 0;
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
Linha 112: Linha 117:
 
===SOLUÇÃO:===
 
===SOLUÇÃO:===
  
 +
NOTE que existem outras soluções. Por exemplo, detectar se o número é par (ou ímpar) e depos fazer um loop decrementando de dois em dois (sugestão dos alunos). Esta última opção é mais eficiente em termos de tempo de execução.
 +
 
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
Linha 147: Linha 154:
  
 
===SOLUÇÃO:===
 
===SOLUÇÃO:===
 +
 +
NOTE que a solução abaixo é simplificada pois não testa se a entrada é menor que ZERO.
  
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
Linha 170: Linha 179:
 
==Exercício 1==
 
==Exercício 1==
  
Modificar o exercício do FATORIAL apresentado anteriormente para caso sejam lidos números negativos o programa pergunte novamente o número N. Usar um comando "while" adicional.
+
Modificar o exercício do FATORIAL apresentado anteriormente para, caso sejam lidos números negativos, o programa pergunte novamente o número N. Usar um comando "while" adicional.
  
 
<blockquote style="background: lime; border: 1px solid black; padding: 1em;">
 
<blockquote style="background: lime; border: 1px solid black; padding: 1em;">
Antes de entrar com o valor de N, atribua um valor NEGATIVO, por exemplo -1 a N. A expressão de teste no comando "while" deve ser verdadeira enquanto N for negativo.
+
OPÇÂO 1: Ler N com 'scanf()' e depois elaborar um 'loop' com 'while' com expressão de teste que resulte em verdadeiro caso N seja negativo. Dentro do loop é realizado uma nova leitura.<br>
 +
OPÇÂO 2: Antes de entrar com o valor de N, atribua um valor NEGATIVO, por exemplo -1 a N. A expressão de teste no comando "while" deve ser verdadeira enquanto N for negativo.
 
Coloque o scanf dentro deste "while".
 
Coloque o scanf dentro deste "while".
 
</blockquote>
 
</blockquote>
  
 
{{collapse top | Solução Ex. 1}}
 
{{collapse top | Solução Ex. 1}}
 +
<!--
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
Linha 203: Linha 214:
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
-->
 
{{collapse bottom}}
 
{{collapse bottom}}
  
 
==Exercício 2==
 
==Exercício 2==
  
Elaborar um programa C para computar a SOMA do fatorial de dois números inteiros fornecidos como entrada. O programa deve prever a entrada somente de números não negativos. Olhe as soluções acima e reproduza as estruturas propostas.
+
Elaborar um programa C para computar a SOMA do fatorial de dois números inteiros fornecidos como entrada. O programa deve prever a entrada somente de números não negativos. Olhe as soluções acima e reproduza as estruturas propostas. Será que poderia ser proposta uma solução mais otimizada? A pensar...
  
 
{{collapse top | Solução Ex. 2}}
 
{{collapse top | Solução Ex. 2}}
Linha 260: Linha 272:
 
{{collapse top | Solução Ex. 3}}
 
{{collapse top | Solução Ex. 3}}
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 +
int main()
 +
{
 +
  int maior, menor, n1, n2,i,fat1, fat2;
 +
 +
  printf("Entre com o valor do fatorial 1\n");
 +
  scanf ("%d", &n1);
 +
 +
  printf("Entre com o valor do fatorial 2\n");
 +
  scanf ("%d", &n2);
 +
 +
  while (n1 < 0){
 +
    printf("Entre com um novo valor de N1\n");
 +
    scanf ("%d", &n1);
 +
  }
 +
    while (n2 < 0){
 +
    printf("Entre com um novo valor de N1\n");
 +
    scanf ("%d", &n2);
 +
  } 
 +
 +
  if (n2>n1) {
 +
    maior = n2;
 +
    menor = n1;
 +
  } else {
 +
    maior = n1;
 +
    menor = n2;
 +
  }
 +
 
 +
  i=menor;
 +
  fat1=1;
 +
 +
  while(i>1) {
 +
      fat1=fat1*i;
 +
      i=i-1;
 +
  }
 +
 +
  i=maior;
 +
  fat2=1;
  
 +
  while(i>menor) {
 +
      fat2=fat2*i;
 +
      i=i-1;
 +
  }
 +
  fat2=fat2*fat1;
 +
 +
  printf("A soma dos fatoriais de N1 (%d)e N2(%d) é %d\n", fat1, fat2, (fat1+fat2));
 +
  return 0;
 +
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 
{{collapse bottom}}
 
{{collapse bottom}}
 +
 +
==Exercício 4==
 +
 +
Elaborar um programa C para computar a média de N números reais. Ver fluxograma da aula de lógica de programação para computaçlão de [https://wiki.sj.ifsc.edu.br/index.php/L%C3%B3gica_de_Programa%C3%A7%C3%A3o_1_-_Estruturas_de_Repeti%C3%A7%C3%A3o#Exemplo_de_Problema_com_Repeti.C3.A7.C3.A3o soma acumulada].
  
 
=Desenhando no terminal MODO texto=
 
=Desenhando no terminal MODO texto=
Linha 294: Linha 358:
  
 
[[imagem:ImpressaoSimplesTerminal.jpg|border|550px]]
 
[[imagem:ImpressaoSimplesTerminal.jpg|border|550px]]
 +
 +
{{collapse top | Solução Ex. 1}}
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 +
int main(){
 +
 +
int p1,p2,p3,i;
 +
char c1, c2, c3;
 +
 +
printf("Carcater a ser desenhado na primeira parte da linha\n");
 +
scanf("%c", &c1);
 +
printf("Quantidade de caracteres a ser desenhado na primeira parte da linha\n");
 +
scanf("%d", &p1);
 +
 +
printf("Carcater a ser desenhado na segunda parte da linha\n");
 +
scanf(" %c", &c2);
 +
printf("Quantidade de caracteres a ser desenhado na segunda parte da linha\n");
 +
scanf("%d", &p2);
 +
 +
printf("Carcater a ser desenhado na terceira parte da linha\n");
 +
scanf(" %c", &c3);
 +
printf("Quantidade de caracteres a ser desenhado na terceira parte da linha\n");
 +
scanf("%d", &p3);
 +
 +
i=0;
 +
while (i < p1) {
 +
  printf("%c", c1);
 +
  i=i+1;
 +
}
 +
 +
i=0;
 +
while (i < p2) {
 +
  printf("%c", c2);
 +
  i=i+1;
 +
}
 +
 +
i=0;
 +
while (i < p3) {
 +
  printf("%c", c3);
 +
  i=i+1;
 +
}
 +
 +
printf("\n");
 +
return 0;
 +
}
 +
</syntaxhighlight>
 +
{{collapse bottom}}
  
 
==Exercício 2==
 
==Exercício 2==
  
 
Modificar o exercício anterior para imprimir uma quantidade variável de LINHAS. As linhas são exatamente iguais.
 
Modificar o exercício anterior para imprimir uma quantidade variável de LINHAS. As linhas são exatamente iguais.
 +
 +
{{collapse top | Solução Ex. 2}}
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 +
int main(){
 +
 +
int p1,p2,p3,i,j,linhas;
 +
char c1, c2, c3;
 +
 +
printf("Carcater a ser desenhado na primeira parte da linha\n");
 +
scanf("%c", &c1);
 +
printf("Quantidade de caracteres a ser desenhado na primeira parte da linha\n");
 +
scanf("%d", &p1);
 +
 +
printf("Carcater a ser desenhado na segunda parte da linha\n");
 +
scanf(" %c", &c2);
 +
printf("Quantidade de caracteres a ser desenhado na segunda parte da linha\n");
 +
scanf("%d", &p2);
 +
 +
printf("Carcater a ser desenhado na terceira parte da linha\n");
 +
scanf(" %c", &c3);
 +
printf("Quantidade de caracteres a ser desenhado na terceira parte da linha\n");
 +
scanf("%d", &p3);
 +
 +
printf("Informe a quantidade de linhas\n");
 +
scanf("%d", &linhas);
 +
 +
j=0;
 +
while (j < linhas){
 +
    i=0;
 +
    while (i < p1) {
 +
        printf("%c", c1);
 +
        i=i+1;
 +
    }
 +
 +
    i=0;
 +
    while (i < p2) {
 +
        printf("%c", c2);
 +
        i=i+1;
 +
    }
 +
 +
    i=0;
 +
    while (i < p3) {
 +
        printf("%c", c3);
 +
        i=i+1;
 +
    }
 +
    printf("\n");   
 +
    j = j+1;   
 +
}
 +
printf("\n");
 +
return 0;
 +
}
 +
</syntaxhighlight>
 +
{{collapse bottom}}
  
 
=Comando ''do while'': controle do ''loop'' no final=
 
=Comando ''do while'': controle do ''loop'' no final=
Linha 305: Linha 472:
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
main()  
+
int main()  
 
{
 
{
 
   int contador;
 
   int contador;
Linha 314: Linha 481:
 
     contador=contador+1;
 
     contador=contador+1;
 
   } while (contador<5);
 
   } while (contador<5);
 +
  return 0;
 
}  
 
}  
 
</syntaxhighlight>
 
</syntaxhighlight>
Linha 382: Linha 550:
  
 
<blockquote style="background: lime; border: 1px solid black; padding: 1em;">
 
<blockquote style="background: lime; border: 1px solid black; padding: 1em;">
Um problema na computação do fatorial é que rapidamente pode existir ''overflow', ou seja, ultrapassar a capacidade da da variável do tipo 'int'.
+
Um problema na computação do fatorial é que rapidamente pode existir ''overflow', ou seja, ultrapassar a capacidade da da variável do tipo 'int'. VEJA  a tabela abaixo com alternativas de inteiros com seus respectivos tamanhos.
 +
</blockquote>
  
Um int de 64 bits tem um RANGE de -922.372.036.854.775.808 até +9.223.372.036.854.775.807
+
{| class="wikitable"
</blockquote>
+
! style="background-color:#f8a102; color:#000000;" | TIPO
 +
! style="background-color:#f8a102; color:#000000;" | bytes
 +
! style="background-color:#f8a102; color:#000000;" | RANGE
 +
! COMENTÁRIO
 +
|-
 +
| style="background-color:#fffc9e;" | char
 +
| style="background-color:#96fffb;" | 1
 +
| style="background-color:#96fffb;" | -128 até 127
 +
| um bit para o sinal
 +
|-
 +
| style="background-color:#fffc9e;" | short int
 +
| style="background-color:#96fffb;" | 2
 +
| style="background-color:#96fffb;" | 32,768 to 32,767
 +
| um bit para o sinal
 +
|-
 +
| style="background-color:#fffc9e;" | int
 +
| style="background-color:#96fffb;" | 4
 +
| style="background-color:#96fffb;" | -2147483648 até 2147483647
 +
| um bit para o sinal. Dependendo da máquina poderia ser 8 bytes
 +
|-
 +
| style="background-color:#fffc9e;" | long int
 +
| style="background-color:#96fffb;" | 8
 +
| style="background-color:#96fffb;" | -9223372036854775808 até 9223372036854775807
 +
| um bit para o sinal
 +
|-
 +
| style="background-color:#fffc9e;" | unsigned char
 +
| style="background-color:#96fffb;" | 1
 +
| style="background-color:#96fffb;" | 0 to 255
 +
|
 +
|-
 +
| style="background-color:#fffc9e;" | unsigned short
 +
| style="background-color:#96fffb;" | 2
 +
| style="background-color:#96fffb;" | 0 to 65,535
 +
|
 +
|-
 +
| style="background-color:#fffc9e;" | unsigned int
 +
| style="background-color:#96fffb;" | 4
 +
| style="background-color:#96fffb;" | 0 to 4294967295
 +
|
 +
|-
 +
| style="background-color:#fffc9e;" | unsigned long
 +
| style="background-color:#96fffb;" | 8
 +
| style="background-color:#96fffb;" | 0 até 18446744073709551615
 +
|
 +
|}
 +
 
 +
Execute o programa abaixo para conferir.  
 +
 
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 
 +
int main()
 +
{
 +
  char num0;
 +
  short num1;
 +
  int num2;
 +
  long int num3;
 +
 
 +
  /* Leitura do número e
 +
    verificação se o número é negativo */
 +
 
 +
  printf ("tamanho de num0 = %ld\n", sizeof (num0));
 +
  printf ("tamanho de num1 = %ld\n", sizeof (num1));
 +
  printf ("tamanho de num2 = %ld\n", sizeof (num2));
 +
  printf ("tamanho de num3 = %ld\n", sizeof (num3));
 +
 
 +
  return 0;
 +
}
 +
</syntaxhighlight>
 +
 
 +
==Exercício==
 +
 
 +
Reimplementar o exemplo anterior usando o long int para computar o fatorial.
 +
 
 +
==Exemplo 2==
 +
 
 +
O programa abaixo foi extraído de ([http://stackoverflow.com/questions/5743678/how-to-generate-random-number-between-0-and-10-in-c referência]). Ele permite realizar a adivinhação de um número entre 1 e 10. Observe que as instruções permitem a geração do número randômico.
 +
<syntaxhighlight lang=c>
 +
srand ( time(NULL) ); /* inicia o gerador com a semente baseada no relógio local */
 +
iSecret = rand() % 10 + 1 /* gera o número */
 +
</syntaxhighlight>
 +
<syntaxhighlight lang=c>
 +
// exemplo de geração randômica
 +
// extracted and adapted from www.stackoverflow.com
 +
#include <stdio.h>
 +
#include <stdlib.h>
 +
#include <time.h>
 +
 
 +
int main ()
 +
{
 +
      int segredo, sugestao;
 +
 
 +
      /* iniciar semente: */
 +
      srand ( time(NULL) );
  
=Comando ''for()'' =
+
      /* gerar o número secreto: */
 +
      segredo = rand() % 10 + 1;
  
 +
      do {
 +
          printf ("Adivinhe um número entre (1 a 10): ");
 +
          scanf ("%d",&sugestao);
 +
          if (segredo<sugestao)
 +
              printf ("O número secreto é menor\n");
 +
          else {
 +
              if (segredo>sugestao)
 +
                printf ("O número secreto é maior\n");
 +
          }
 +
      } while (segredo!=sugestao);
 +
 +
      printf ("Parabéns!\n");
 +
      return 0;
 +
}
 +
</syntaxhighlight>
 +
 +
=Comando ''for()''=
 
O comando ''for()'' permite uma forma mais elaborada de ''loop'', com controle no início do bloco de repetição.
 
O comando ''for()'' permite uma forma mais elaborada de ''loop'', com controle no início do bloco de repetição.
  
Linha 399: Linha 679:
 
   int i;
 
   int i;
 
    
 
    
   for (i=0;i<10;i=i+1)
+
   for ( i=0; i<10; i=i+1 )
 
       printf("i =%d\n",i);
 
       printf("i =%d\n",i);
 
}
 
}
Linha 414: Linha 694:
 
  }
 
  }
  
{| border="1" cellpadding="2"
+
 
!Fluxograma
+
 
!C
+
{| style="width: 1690px;" border="1" cellpadding="2" data-mce-style="width: 1690px;"
!Comentário
+
!Fluxograma !C !Comentário |
|-
+
|-  
| |[[imagem:FluxogramaComandoFor-Eraldo.jpg|300px]]
+
|[[imagem:FluxogramaComandoFor-Eraldo.jpg|300px]]
||<syntaxhighlight lang=c>
+
| style="width: 678.602px;" data-mce-style="width: 678.602px;"|<syntaxhighlight lang=c>
for(i=0; i<10; i++) {
+
for( i=0; i<10; i++ ) {
 
   printf("Laço de número %d\n", i);
 
   printf("Laço de número %d\n", i);
 
   if (i==5)
 
   if (i==5)
 
       printf("Este é o laço 5\n");
 
       printf("Este é o laço 5\n");
 
}
 
}
</syntaxhighlight>|| Observe que a expressão ''i=0'' é executada SEMPRE e uma única VEZ, no início do comando.
+
</syntaxhighlight>
 +
| style="width: 991.398px;" data-mce-style="width: 991.398px;"|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
 
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''.
+
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====
+
==Exemplo==
 +
Elaborar um programa que lê um número inteiro e imprime todos os números pares entre 1 e este número INCLUSIVE.
  
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
main()
+
 
 +
int main()
 +
{
 +
  int i, N;
 +
 
 +
  printf("Entre com o número\n");
 +
  scanf ("%d", &N);
 +
 
 +
  for ( i=1; i<=N; i=i+1) {
 +
    if (i%2==0)
 +
      printf("número par ====> %d\n", i);
 +
  }
 +
  printf("FIM\n");
 +
 
 +
  return 0;
 +
}
 +
 
 +
</syntaxhighlight>
 +
 
 +
=Aninhamento de loops=
 +
 
 +
É muito comum que a solução de problemas exijam o aninhamento de loops. Neste caso, as instruções são aninhadas normalmente usando, se necessário, o recurso de bloco de instruções. Observe no código abaixo que para cada laço mais externo o comando for interno é executado integralmente.
 +
 
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
int main()
 
{
 
{
 
   int i,j;
 
   int i,j;
Linha 445: Linha 752:
 
     printf("valor de i = %d\n", i);
 
     printf("valor de i = %d\n", i);
 
   }
 
   }
 +
  return 0;
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
Linha 457: Linha 765:
 
#include <stdio.h>
 
#include <stdio.h>
  
main()
+
int main()
 
{
 
{
  int i;
+
    int i;
  
  i=0;
+
    i=0;
 
+
   
PONTO1:
+
    PONTO1:
  printf("Laço de número %d\n", i);
+
    printf("Laço de número %d\n", i);
  i++;
+
    i++;
  if (i<10)
+
    if (i<10)
      goto PONTO1;
+
        goto PONTO1;
 +
    return 0;
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
Linha 484: Linha 793:
  
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
main()
+
int main()
 
{
 
{
 
   for(;;) {
 
   for(;;) {
 
         /* Este bloco se executará infinitamente */
 
         /* Este bloco se executará infinitamente */
 
   }
 
   }
 +
  return 0;
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
Linha 494: Linha 804:
 
ou com o comando ''while'':
 
ou com o comando ''while'':
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
main()
+
int main()
 
{
 
{
 
   while(1) {
 
   while(1) {
 
         /* Este bloco se executará infinitamente */
 
         /* Este bloco se executará infinitamente */
 
   }
 
   }
 +
  return 0;
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
  
===Exercícios===
+
=Uso de break para sair de loops=
 
 
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.
 
{{collapse top|solução}}
 
<syntaxhighlight lang=c>
 
#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 */
 
}
 
</syntaxhighlight>
 
{{collapse bottom}}
 
2. Dado um número 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
 
{{collapse top|solução}}
 
<syntaxhighlight lang=c>
 
#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");
 
  }
 
 
 
}
 
</syntaxhighlight>
 
{{collapse bottom}}
 
 
 
4.Estude o programa ([http://stackoverflow.com/questions/5743678/how-to-generate-random-number-between-0-and-10-in-c referência]) abaixo:
 
<syntaxhighlight lang=c>
 
// 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 = 1 + (rand() % 10);
 
 
 
      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;
 
}
 
</syntaxhighlight>
 
Estude também o significado das instruções:
 
  srand ( time(NULL) );
 
  iSecret = rand() % 10 + 1;
 
 
 
 
 
5. 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:
 
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:
Linha 689: Linha 819:
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
main()
+
int main()
 
{
 
{
 
   int i,j;
 
   int i,j;
  
   for (i=0;i<10;i++) {
+
   for (i=0;i<10;i=i+1) {
 
     if (i==5)
 
     if (i==5)
 
       break;
 
       break;
 
   }
 
   }
 
   printf("valor de i=%d\n", i);
 
   printf("valor de i=%d\n", i);
 +
  return 0;
 
}
 
}
  
Linha 737: Linha 868:
 
     //break    -> simplesmente interrompe o nosso ciclo
 
     //break    -> simplesmente interrompe o nosso ciclo
 
     //continue  -> interrompe o laço (desvia o fluxo para o início do laço)
 
     //continue  -> interrompe o laço (desvia o fluxo para o início do laço)
 +
    int x;
  
     for(int x = 0; x<=10; ++x){
+
     for(x = 0; x<=10; x++){
  
 
         //qndo x == 2, interrompa somente o laço atual
 
         //qndo x == 2, interrompa somente o laço atual
 
         if(x == 2){
 
         if(x == 2){
             printf("-\n", x);
+
             printf("Valor de x é 2 - fazendo continue...\n");
 
             continue;
 
             continue;
 
         }
 
         }
Linha 748: Linha 880:
 
         //Quando chegamos a 8 o looping será finalizado
 
         //Quando chegamos a 8 o looping será finalizado
 
         if(x == 8){
 
         if(x == 8){
             printf("-\n", x);
+
             printf("Valor de x é 8 - fazendo continue...\n");
 
             break;
 
             break;
 
         }
 
         }
  
         printf("%i\n", x);
+
         printf("%d\n", x);
 
     }
 
     }
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 
==== Exercício ====
 
==== Exercício ====
 
Elabore um programa em C que leia no máximo 5 números inteiros positivos. Caso um número negativo seja digitado no meio da seqüência uma mensagem deve ser impressa uma mensagem de aviso no terminal e o laço é encerrado de imediato.
 
Elabore um programa em C que leia no máximo 5 números inteiros positivos. Caso um número negativo seja digitado no meio da seqüência uma mensagem deve ser impressa uma mensagem de aviso no terminal e o laço é encerrado de imediato.
Linha 775: Linha 908:
 
-->
 
-->
  
====Uso do continue para prosseguir no início do ''loop''====
+
=Uso do continue para prosseguir no início do ''loop''=
  
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
main()
+
int main()
 
{
 
{
  int i,j;
+
    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);
 
    }
 
  }
 
  
 +
    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);
 +
        }
 +
    }
 +
    return 0;
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
  
===Usando funções da biblioteca matemática===
+
=Usando funções da biblioteca matemática=
  
 
Para usar as funções [http://en.wikipedia.org/wiki/C_mathematical_functions matemáticas] da biblioteca padrão, fazer os seguintes passos:
 
Para usar as funções [http://en.wikipedia.org/wiki/C_mathematical_functions matemáticas] da biblioteca padrão, fazer os seguintes passos:
Linha 829: Linha 962:
 
   gcc ex1.c -o ex1 -lm
 
   gcc ex1.c -o ex1 -lm
  
====EXERCÍCIOS====
+
=EXERCÍCIOS - nível INICIANTE=
  
1. Desenvolver um algoritmo que efetue a soma de todos os números ímpares que são múltiplos de três e que se encontram no conjunto dos números de 1 até 500.
+
<ol>
 +
<li>
 +
Desenvolver em C um programa que efetue a soma de todos os números ímpares que são múltiplos de três e que se encontram no conjunto dos números de 1 até 500 inclusive. Usar comando for.
 +
 
 +
{{collapse top | Solução - Exercício 1}}
 +
<!--
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 +
int main(){
 +
 
 +
int i,soma=0;
 +
 
 +
for(i=1;i <= 500;i++){
 +
    if ((i%2 == 1) && (i%3 == 0)){
 +
        printf("%d\n",i);
 +
        soma = soma+i;     
 +
    }
 +
}
 +
printf("Valor de %d\n", soma);
 +
return 0;
 +
}
 +
</syntaxhighlight>
 +
-->
 +
{{collapse bottom}}
 +
</li>
 +
 
 +
<li>
 +
Faça uma versão "controversa" do programa de adivinhação mostrado na aula usando uma instrução ''goto'' para sair de um ''loop'' infinito.
  
2. 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''.
 
 
{{collapse top | Solução - Exercício 2}}
 
{{collapse top | Solução - Exercício 2}}
 
+
<!--
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
* rand example: guess the number */
 
* rand example: guess the number */
Linha 867: Linha 1 027:
 
  Final:printf ("Congratulations!\n");
 
  Final:printf ("Congratulations!\n");
 
       return 0;
 
       return 0;
 
 
</syntaxhighlight>
 
</syntaxhighlight>
 
+
-->
 
{{collapse bottom}}
 
{{collapse bottom}}
 
+
</li>
 
+
<li>
3. Ainda sobre o exercício 1, implemente uma versão usando o comando while().
+
Ainda sobre o exercício 2, implemente uma versão usando o comando while().
  
 
{{collapse top | Solução - Exercício 3}}
 
{{collapse top | Solução - Exercício 3}}
 
+
<!--
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
/* rand example: guess the number */
 
/* rand example: guess the number */
Linha 911: Linha 1 070:
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 
+
-->
 
{{collapse bottom}}
 
{{collapse bottom}}
 +
</li>
 +
<li>
 +
Ainda sobre o exercício 2, implemente uma versão usando ''loop'' infinito e o comando ''break'';
  
 
<syntaxhighlight lang=c>
 
/* rand example: guess the number */
 
#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;
 
 
      /* coloca um valor em iGuess que nunca será inserido pelo usuário */
 
      iGuess = -1;
 
 
      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");
 
          }
 
      }
 
 
      printf ("Congratulations!\n");
 
      return 0;
 
}
 
</syntaxhighlight>
 
 
4. Ainda sobre o exercício 1, implemente uma versão usando ''loop'' infinito e o comando ''break'';
 
 
{{collapse top|Solução - Exercício 4}}
 
{{collapse top|Solução - Exercício 4}}
 
+
<!--
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
/* rand example: guess the number */
 
/* rand example: guess the number */
Linha 986: Linha 1 111:
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 
+
-->
 
{{collapse bottom}}
 
{{collapse bottom}}
 
+
</li>
<syntaxhighlight lang=c>
+
<li>
/* rand example: guess the number */
+
Implemente uma variação do jogo de adivinhação para que ele conte o número de tentativas do jogador.
#include <stdio.h>
+
</li>
#include <stdlib.h>
+
<li>
#include <time.h>
+
Implemente uma variação do jogo de adivinhação para que dois dados (1 a 6) sejam jogados. O jogador deve adivinhar a soma dos dados.
+
</li>
int main ()
+
<li>
{
+
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.
      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");
 
          }
 
          if (iSecret==iGuess) /* se acertou sai do loop */
 
              break;
 
      } while(1);
 
 
      printf ("Congratulations!\n");
 
      return 0;
 
}
 
</syntaxhighlight>
 
 
 
5. 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.
 
  
 
{{collapse top | Solução - Exercício 5}}
 
{{collapse top | Solução - Exercício 5}}
 
+
<!--
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include < stdio.h >
 
#include < stdio.h >
Linha 1 062: Linha 1 160:
 
     }
 
     }
 
   }
 
   }
 +
</syntaxhighlight>
 +
-->
 +
{{collapse bottom}}
 +
 +
</li>
 +
<li>
 +
Dado um número inteiro positivo, calcular a soma de todos os números inteiros compreendidos entre 1 e o número dado. Fazer uma versão com ''while'' e outra com ''for''. Caso o número apresentado for negativo ou zero, solicitar a entrada novamente. Use o comando ''do while'' para esta finalidade.
 +
</li>
 +
<li> Dado dois números inteiros positivos "M" e "N", computar o valor "V" conforme a equação:
 +
 +
<math>
 +
V=\frac{M!*2.5}{N! + 7}
 +
</math>
 +
</li>
 +
</ol>
 +
 +
=EXERCÍCIOS - nível MÉDIO=
 +
 +
<ol>
 +
<li>
 +
Tente descobrir por tentativas qual carga em um circuito com uma fonte de tensão contínua 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). Sabe-se que esta carga está entre 1 e 20 ohms. Sugestão: faça um "loop" com para testar cargas que vão de 1 a 20 ohms com acréscimos de 0.5 ohms. Crie uma variável
 +
para anotar a maior potência e a carga que produziu esta potência.
 +
 +
{{collapse top|Solução}}
 +
<!--
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 +
int  main() {
 +
 +
  float V=500,  /* tensão da fonte */
 +
        rf =10, /* resistência da fonte */
 +
        Pl;    /* potência dissipada na carga */
 +
  float il,    /* corrente na carga */
 +
        rl=1;  /* carga tentativa */
 +
       
 +
  float maior_pot=0, /* maior potência */
 +
        maior_rl;    /* maior carga */
 +
 +
  for (rl=1;rl<=20;rl=rl+0.5) {
 +
      il=V/(rl+rf);
 +
      Pl=rl*il*il;
 +
      if (Pl>maior_pot) {
 +
        maior_pot = Pl;
 +
        maior_rl=rl;
 +
      }
 +
  }
 +
  printf("Maior potência dissipada = %.2f W para carga de %.2f ohms\n", maior_pot,maior_rl);
 +
}
 +
-->
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 
{{collapse bottom}}
 
{{collapse bottom}}
  
 +
</li>
 +
 +
<li>
 +
Usando o comando for aninhado, construa um programa que implemente a figura abaixo. A margem esquerda (margem de espaços representada por ponto), o caracter do desenho, o número de linhas vazadas e o tamanho horizontal da figura devem ser lidos pelo teclado.
 +
 +
<syntaxhighlight> 
 +
...aaaaaaaaaa
 +
...a        a
 +
...aaaaaaaaaa
 +
</syntaxhighlight>
 +
  SUGESTÃO: dividir em subproblemas da forma:
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 +
int main()
 +
{
 +
  int i, j, margem, largura, linhas_vazadas;
 +
  char caracter;
 +
 
 +
  /** sub-problema 1 - ler margem , largura de desenho, caracter do desenho e numero de linhas **/
 +
 
 +
  /* sub-problema 2 - desenhar linha de topo */
  
6. 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.
+
  /* sub-problema 3 - desenhar linhas vazadas */
 +
 
 +
  for (j=0;j<linhas_vazadas;j++) {
 +
      /* desenhar linha vazada*/
 +
  }
  
{{collapse top|Solução - Exercício 6}}
+
  /* sub-problema 4 - desenhar linha de fundo  (igual ao sub-problema 1*/
  
 +
  return 0;
 +
}
 +
</syntaxhighlight>
 +
{{collapse top|solução}}
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
  
   main() {
+
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 */
 +
}
 +
</syntaxhighlight>
 +
{{collapse bottom}}
 +
</li>
 +
<li>
 +
Construa um programa para desenhar a seguinte figura de forma parametrizável (dado caracter, margem, e número de linhas):
 +
<syntaxhighlight lang=c>
 +
...AAAAAAAAAAAAAAAA
 +
...AAAAAAAAAAAAAA
 +
...AAAAAAAAAAAA
 +
...AAAAAAAAAA
 +
...AAAAAAAA
 +
...AAAAAA
 +
...AAAA
 +
...AA
 +
...BB
 +
...BBBBB
 +
...BBBBBBBB
 +
...BBBBBBBBBBB
 +
...BBBBBBBBBBBBBB
 +
...BBBBBBBBBBBBBBBBB
 +
...BBBBBBBBBBBBBBBBBBBB
 +
...BBBBBBBBBBBBBBBBBBBBBBB
 +
</syntaxhighlight>
 +
{{collapse top|solução}}
 +
<syntaxhighlight lang=c>
 +
#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");
 +
  }
 +
 
 +
}
 +
</syntaxhighlight>
 +
{{collapse bottom}}
 +
 
 +
</li>
 +
 
 +
<li>
 +
<!-- Plotar no terminal em modo texto os valores de "y" para a função <math>y=x+2</math> com <x=1 a 10><> variando de 1 em 1. Sugestão: para facilitar cada linha corresponde a um valor inteiro de x e cada coluna um valor inteiro de y.
 +
</li>-->
 +
</ol>
  
    float V=500, rs =10, Is, Pl;
+
= Exercícios Extras (resolver em sala) =
    float rl=1, n;
 
    int i=1;
 
 
while(i<40){//40 pois é esse o numero de loops somando 0.5 por loop para chegar ao valor 20 para rl
 
n = rl/(rl+rs);
 
printf("Com rl=%f a eficiencia fica em %f\n",rl,n);
 
                Is=(V/rs);
 
                Pl=(Is*Is)*rl;
 
                printf("E a maxima potencia dissipada fica %f\n",Pl);
 
                printf("--------------------------\n");//uma quebra de linha para a melhor visualizacao dos valores
 
                rl = rl+0.5;
 
i++;
 
}
 
  
 +
<ol>
 +
<li>
 +
Escreva um  programa em C que mostre a tabuada de um número fornecido pelo teclado. Esse número deve estar entre 1 e 10.
 +
</li>
 +
<li>
 +
Faça um programa em C  que calcule a média de N números a serem lidos pelo teclado.
 +
</li>
 +
<li>
 +
Escreva um programa em C que para ler continuamente  ''' números inteiros''' pelo teclado, e informe ao final qual o maior e o menor deles. A condição de parada do programa ocorre quando o usuário informar um '''valor negativo ou zero'''.
 +
{{collapse top | Solução 1}}
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 +
int main()
 +
{
 +
  int maior = -1, numero;
 +
 +
  printf("Entre com um número\n");
 +
  scanf("%d", &numero);
 +
  while (numero > 0) {
 +
      if(numero > maior) {
 +
          maior = numero;
 +
      }
 +
      printf("Entre com um número\n");
 +
      scanf("%d", &numero);
 
   }
 
   }
 +
  if (maior>0)
 +
      printf("Maior é %d\n", maior);
 +
  else
 +
      printf("Não foi fornecido nenhum número\n");
 +
  return 0;
 +
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 
{{collapse bottom}}
 
{{collapse bottom}}
 +
{{collapse top | Solução 2}}
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
  
=== Exercícios Extras (resolver em sala) ===
+
int main()
 +
{
 +
  int maior = -1, numero;
  
# Escreva um  algoritmo que mostre a tabuada de um número fornecido pelo teclado. Esse número deve estar entre 1 e 10.
+
  do {
# Faça um algoritmo que calcule a média para uma quantidade de números a serem lidos seja previamente, informada pelo teclado.
+
      printf("Entre com um número\n");
# Escreva um algoritmo que leia até 10 números do teclado, e informe ao final qual o maior e o menor deles.
+
      scanf("%d", &numero);
# Escreva um algoritmo que teste se um número informado pelo teclado é primo.
+
      if(numero > maior) {
 +
          maior = numero;
 +
      }
 +
  } while(numero>0);
 +
  if (maior>0)
 +
      printf("Maior é %d\n", maior);
 +
  else
 +
      printf("Não foi fornecido nenhum número\n");
 +
  return 0;
 +
}
 +
</syntaxhighlight>
 +
{{collapse bottom}}
  
 +
</li>
 +
<li>
 +
Escreva um programa C  que teste se um número informado pelo teclado é primo.
 
{{collapse top | Solução}}
 
{{collapse top | Solução}}
 +
A solução abaixo usa um contador para contar o número de divisores do número dado.
 +
Poderia ser usado um break para encerrar o loop assim que o número fosse divisível...
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 +
int main(){
 +
  int n, num, k, primo;
 +
 +
  printf("Informe o número a ser testado: ");
 +
  scanf("%d",&num);
 +
 +
  primo=0;
 +
 +
  for(k=2; k<num; k++)
 +
    if((num%k/2) == 0) {
 +
          primo=1;
 +
          break;
 +
  }
 +
  if(primo == 1)
 +
    printf("%d não é primo\n", num);
 +
  else
 +
    printf("%d é primo\n", num);
 +
   
 +
  return 0;
 +
}
 +
</syntaxhighlight>
 +
{{collapse bottom}}
 +
 +
<li>
 +
Escreva um programa C  que calcule N termos da série de Fibonacci, onde é N informado pelo usuário (Ex. 0 1 1 2 3 5 8 13 21 ...). Não usar vetores.
 +
{{collapse top | Solução 1 - com while}}
 +
Nesta solução, os dois últimos termos da série sempre ficam armazenados em duas variáveis (ant2 e ant1). Inicialmente ant2 já possui 0 e ant1 possui 1. A partir do termo 3 o loop atua, computando o próximo termo e atualizando os valores de ant1 e ant2. 
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 +
int main (void){
 +
    int ant1, ant2, prox, i, n;
 +
 +
    printf("Informe o número de termos\n");
 +
    scanf("%d",&n);
 +
 +
    ant2=0;
 +
    ant1=1;
 +
    if (n==1)
 +
        printf("%d", ant2);
 +
    else
 +
        printf("%d %d ", ant2 ,ant1);
 +
 +
    i = 3;
 +
    while (i <= n){
 +
        prox = ant1 + ant2;
 +
        printf("%d ", prox);
 +
        ant2 = ant1;
 +
        ant1 = prox;
 +
        i++;
 +
    }
 +
    printf("\n");
 +
    return 0;
 +
}
 +
</syntaxhighlight>
 +
{{collapse bottom}}
 +
{{collapse top | Solução 2 - uso de for com desempenho prejudicado por if no laço}}
 +
A solução abaixo é similar a anterior mas usa o comando for e podemos dizer que tem uma ineficiência pois sempre terá, no laço do loop, a execução de uma instrução de teste (if else) para ajustar a impressão dos 2 primeiros termos.
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
#include <stdlib.h>
 
  
 
int main()
 
int main()
 
{
 
{
    int n, num, k, primo;
+
  int seq, n1=0,n2=1,i,n;
 +
 
 +
  printf("Entre com n\n");
 +
  scanf ("%d", &n);
 +
 
 +
  for(i=0;i<n;i=i+1) {
 +
    if (i<=1) {
 +
      seq = i;
 +
    } else {
 +
      seq = n1+n2;
 +
      n1=n2;
 +
      n2=seq;
 +
    }
 +
    printf("%d ", seq);
 +
  }
  
printf("Informe o valor a ser validado: ");
+
  printf("\n");
 +
  return 0;
 +
}
 +
</syntaxhighlight>
 +
{{collapse bottom}}
  
        scanf("%d",&num);
+
{{collapse top | Solução 3 - com  comando for e eficiente, porém não tão 'intuitiva'}}
        primo=0;
+
<syntaxhighlight lang=c>
 +
#include <stdio.h>
  
        for(k=1; k<=num; k++)
+
int main()
            if((num%k)==0)
+
{
                primo++;
+
  int seq, n1=-1,n2=1,i,n;
        if(primo>2)
 
            printf("%d nao e primo\n", num);
 
  
        else
+
  printf("Entre com n\n");
            printf("%d e primo\n", num);
+
  scanf ("%d", &n);
 +
  printf("A série é\n");
 +
  for(i=0;i<n;i=i+1) {
 +
      seq = n1+n2;
 +
      n1=n2;
 +
      n2=seq;
 +
      printf("%d ", seq);
 +
  }
 +
  printf("\n");
 +
  return 0;
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 
{{collapse bottom}}
 
{{collapse bottom}}
 +
</li>
 +
 +
<li>
 +
Escreva um programa C  que calcule a média entre todos os números ÍMPARES da série de Fibonacci até o termo N sendo o primeiro termo 0.  Exemplo: para N = 5 a série é 0 1 1 2 3 e a soma dos termos ímpares é 5. Assumir que N é sempre maior que 2.
 +
 +
{{collapse top | Solução 1}}
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 +
/* atenção: ajustar esta solução ao enunciado */
 +
int main()
 +
{
 +
    int seq, n1=0,n2=1,i,n, cont_impar=0, soma=0;
 +
    float media;
 +
 +
    printf("Entre com n\n");
 +
    scanf ("%d", &n);
 +
 +
    for(i=0;i<n;i=i+1) {
 +
        if (i<=1) {
 +
            seq = i;
 +
        } else {
 +
            seq = n1+n2;
 +
            n1=n2;
 +
            n2=seq;
 +
        }
 +
        if ((seq%2)==1) {
 +
            soma = soma + seq;
 +
            cont_impar = cont_impar + 1;
 +
        }
 +
        printf("%d ", seq);
 +
    }
 +
    if (cont_impar!=0)
 +
        media = (float)soma/cont_impar;
 +
    printf("\nA média dos números ímpares é %.2f\n", media);
 +
    return 0;
 +
}
 +
</syntaxhighlight>
 +
{{collapse bottom}}
 +
</li>
 +
 +
<li>
 +
Considere a função:<br>
 +
<math>f(x) = 2x^2 + 3x + 1 </math><br>
 +
Supondo x definido no domínio dos inteiros, faça um programa para calcular a média dos valores da função para x entre 1 e 1000.
 +
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 +
int main()
 +
{
 +
    int x, y, soma_ac, limite;
 +
    float media;
 +
 +
    /* calcular a soma acumulada aqui */
 +
    soma_ac = 0;
 +
    limite = 1000;
 +
    for ( x = 1; x <= limite; x++ ) {
 +
        y = 2 * x * x + 3 * x + 1;
 +
        printf("Valor de y é %d\n", y);
 +
        soma_ac = soma_ac + y;
 +
    }
 +
 +
    printf("Soma acumulada de f(x) para x entre 1 e %d: %d\n", limite, soma_ac);
 +
 +
    /* calcular a média aqui */
 +
    media = (float) soma_ac / limite;
 +
 +
    printf("media calculada é %f\n", media);
 +
 +
    return 0;
 +
}
 +
</syntaxhighlight>
 +
</li>
 +
 +
<li>
 +
Refazer o exercício anterior, criando uma função C que faz a computação da média. A função deve receber 5 parâmetros:
 +
*os coeficientes da equação;
 +
*os limites inferior e superior.
 +
Testar no programa principal (função main())
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 +
float media_func_quadratica(int a, int b, int c, int limite_inf, int limite_sup)
 +
{
 +
    int x, y, soma_ac;
 +
    float media;
 +
   
 +
    /* testar consistencia de limites e inverter se necessário */
 +
    if (limite_inf > limite_sup) {
 +
        int aux;
 +
        aux = limite_sup;
 +
        limite_sup = limite_inf;
 +
        limite_inf = aux;
 +
    }
 +
 +
    /* calcular a soma acumulada aqui */
 +
 +
    for ( soma_ac = 0, x = limite_inf; x <= limite_sup; x++ ) {
 +
        y = a * x * x + b * x + c;
 +
        printf("Valor de y é %d\n", y); // tirar futuramente
 +
        soma_ac = soma_ac + y;
 +
    }
 +
 +
    /* calcular a média aqui */
 +
    media = (float) soma_ac / (limite_sup - limite_inf + 1);
 +
 +
    return media;
 +
}
 +
 +
int main()
 +
{
 +
    float media;
 +
    int a,b,c,inf,sup;
 +
 +
    a = 2; b = 3; c = 1; inf = 1; sup = 3;
 +
    media = media_func_quadratica(a, b, c, inf, sup);
 +
 +
    printf("media calculada para a = %d b = %d c = %d limite inferior = %d e limite superior %d : %f\n", a, b, c, inf, sup, media);
 +
 +
    a = 2; b = 3; c = 1; inf = 1; sup = 10;
 +
    media = media_func_quadratica(a, b, c, inf, sup);
 +
 +
    printf("media calculada para a = %d b = %d c = %d limite inferior = %d e limite superior %d : %f\n", a, b, c, inf, sup, media);
 +
 +
    a = 2; b = 3; c = 1; inf = 1; sup = 3;
 +
    media = media_func_quadratica(a, b, c, sup, inf);
 +
 +
    printf("media calculada para a = %d b = %d c = %d limite inferior = %d e limite superior %d : %f\n", a, b, c, inf, sup, media);
 +
 +
    return 0;
 +
}
 +
</syntaxhighlight>
 +
</li>
 +
<li>
 +
Fazer uma variação da função anterior mas agora a função deve retornar o MAIOR f(x) para uma determinada faixa colocada.
 +
</li>
 +
</ol>

Edição atual tal como às 09h49min de 3 de outubro de 2023

Objetivos

Após esta aula o aluno deverá:

  • conhecer a sintaxe e a semântica dos comandos de repetição do C: while, do while, for e goto.
  • utilizar comando break para sair de loops e o continue para interromper um laço específico;
  • identificar quando usar variáveis inteiras com maior ou menor capacidade de armazenamento (char, unsigned, long).
  • mapear estruturas simples de repetição especificadas em fluxogramas ou pseudo-código em 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: Observe que repetir o código significa voltar a executá-lo (sem ter que escrevê-lo novamente) e 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.

A semântica do while é a seguinte: ao entrar no comando a EXPRESSÃO entre parênteses é AVALIADA. Caso resulte em uma valor VERDADEIRO o LAÇO do loop é executado uma vez. O programa testa então novamente a expressão. LEMBRAR que:

  • VERDADEIRO é qualquer valor diferente de ZERO;
  • DENTRO do laço NORMALMENTE existe uma modificação de alguma parte da expressão de teste de forma que em algum momento o LOOP se encerra.
  • Ao se encerrar o programa continua na próxima instrução APÓS o comando "while()";
  • ANTES DE entrar no comando while SEMPRE tenha certeza que as variáveis estão com valores adequados de forma que a expressão SEJA AVALIADA sempre corretamente.

No exemplo que se segue existe UMA única instrução simples (terminada em ";").

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

OBSERVE a seguir uma variação do exemplo anterior usando um bloco de instruções delimitado por "{" e "}"

#include <stdio.h>
int 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);
  return 0;
}
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.

Exemplo 1

PROBLEMA: Elaborar um programa C para imprimir os números pares em ordem decrescente (até atingir 0 inclusive) a partir de um número N fornecido como entrada. Seguir o fluxograma mostrada abaixo.

DADOS DE ENTRADA: N (variável inteira)

DADOS DE SAÌDA: números pares impressos

FluxogramaRepeticaoImprimePar.jpg

SOLUÇÃO:

NOTE que existem outras soluções. Por exemplo, detectar se o número é par (ou ímpar) e depos fazer um loop decrementando de dois em dois (sugestão dos alunos). Esta última opção é mais eficiente em termos de tempo de execução.

#include <stdio.h>

int main()
{
  int N,i;

  printf("Entre com o valode N\n");
  scanf ("%d", &N);
  i=N;
  while(i>=0) {
      if (i%2==0) { /* parênteses em (i%2) é opcional porque o operador de resto tem precedência */
          printf("%d\n", i);
      }
      i=i-1;
  } 
  return 0;
}

Exemplo 2

PROBLEMA: Elaborar um programa C para computação do fatorial de um número conforme definição abaixo:

DADOS DE ENTRADA:número N (numero inteiro)

DADOS DE SAÌDA: FATORIAL computado

O fatorial é definido por:

FluxogramaFatorialNum.jpg

SOLUÇÃO:

NOTE que a solução abaixo é simplificada pois não testa se a entrada é menor que ZERO.

#include <stdio.h>

int main()
{
  int N,i,FAT;

  printf("Entre com o valor de N\n");
  scanf ("%d", &N);
  i=N;
  FAT=1;
  while(i>1) {
      FAT=FAT*i;
      i=i-1;
  } 
  printf("Valor de FAT  de %d é %d\n", N, FAT);
  return 0;
}

Exercício 1

Modificar o exercício do FATORIAL apresentado anteriormente para, caso sejam lidos números negativos, o programa pergunte novamente o número N. Usar um comando "while" adicional.

OPÇÂO 1: Ler N com 'scanf()' e depois elaborar um 'loop' com 'while' com expressão de teste que resulte em verdadeiro caso N seja negativo. Dentro do loop é realizado uma nova leitura.
OPÇÂO 2: Antes de entrar com o valor de N, atribua um valor NEGATIVO, por exemplo -1 a N. A expressão de teste no comando "while" deve ser verdadeira enquanto N for negativo. Coloque o scanf dentro deste "while".

Solução Ex. 1

Exercício 2

Elaborar um programa C para computar a SOMA do fatorial de dois números inteiros fornecidos como entrada. O programa deve prever a entrada somente de números não negativos. Olhe as soluções acima e reproduza as estruturas propostas. Será que poderia ser proposta uma solução mais otimizada? A pensar...

Solução Ex. 2
#include <stdio.h>
 
int main()
{
  int n1, n2,i,fat1, fat2;
 
  printf("Entre com o valor do fatorial 1\n");
  scanf ("%d", &n1);

   
  printf("Entre com o valor do fatorial 2\n");
  scanf ("%d", &n2);

  while (n1 < 0){
    printf("Entre com um novo valor de N1\n");
    scanf ("%d", &n1);
  } 
    while (n2 < 0){
    printf("Entre com um novo valor de N1\n");
    scanf ("%d", &n2);
  }   

  i=n1;
  fat1=1;

  while(i>1) {
      fat1=fat1*i;
      i=i-1;
  } 

  i=n2;
  fat2=1;
  while(i>1) {
      fat2=fat2*i;
      i=i-1;
  } 

  printf("A soma dos fatoriais de N1 e N2 é %d\n", (fat1+fat2));
  return 0;
}

Exercício 3

Elabore uma versão otimizada do programa que computa a soma do fatorial de dois números. Observe que poderíamos "economizar" laços de repetição se calcularmos o fatorial do menor número e depois computar o fatorial do maior usando o menor número como ponto de parada na repetição.

Solução Ex. 3
#include <stdio.h>
 
int main()
{
  int maior, menor, n1, n2,i,fat1, fat2;
 
  printf("Entre com o valor do fatorial 1\n");
  scanf ("%d", &n1);

  printf("Entre com o valor do fatorial 2\n");
  scanf ("%d", &n2);
 
  while (n1 < 0){
    printf("Entre com um novo valor de N1\n");
    scanf ("%d", &n1);
  } 
    while (n2 < 0){
    printf("Entre com um novo valor de N1\n");
    scanf ("%d", &n2);
  }   
 
  if (n2>n1) {
     maior = n2;
     menor = n1;
  } else {
     maior = n1;
     menor = n2;
  }
  
  i=menor;
  fat1=1;

  while(i>1) {
      fat1=fat1*i;
      i=i-1;
  } 
 
  i=maior;
  fat2=1;

  while(i>menor) {
      fat2=fat2*i;
      i=i-1;
  } 
  fat2=fat2*fat1;
 
  printf("A soma dos fatoriais de N1 (%d)e N2(%d) é %d\n", fat1, fat2, (fat1+fat2));
  return 0;
}

Exercício 4

Elaborar um programa C para computar a média de N números reais. Ver fluxograma da aula de lógica de programação para computaçlão de soma acumulada.

Desenhando no terminal MODO texto

A saída de um programa em um terminal modo TEXTO possui algumas limitações. Além da questão da definição, o programa escreve sempre na posição de um CURSOR que avança automaticamente. Em condições normais não é possível retornar o cursor para linhas acima. Deve-se portanto planejar cuidadosamente o desenho de figuras levando em consideração estas restrições. As instruções de repetição ajudarão bastante neste processo.

Exemplo: imprimir uma linha com 10 caracteres 'A'

AAAAAAAAA
#include <stdio.h>

int main()
{
 int i;
 
 i=0;
 while (i<10) {
    printf("A");
    i=i+1;
 }
 printf("\n");
}

Exercício 1

Elaborar um programa para imprimir uma linha CUSTOMIZADA em 3 partes. Cada parte imprime um número variável de caracteres. O número de caracteres e o caracter a ser impresso em cada parte deve ser informado.

ImpressaoSimplesTerminal.jpg

Solução Ex. 1
#include <stdio.h>
 
int main(){

int p1,p2,p3,i;
char c1, c2, c3;

printf("Carcater a ser desenhado na primeira parte da linha\n");
scanf("%c", &c1);
printf("Quantidade de caracteres a ser desenhado na primeira parte da linha\n");
scanf("%d", &p1);

printf("Carcater a ser desenhado na segunda parte da linha\n");
scanf(" %c", &c2);
printf("Quantidade de caracteres a ser desenhado na segunda parte da linha\n");
scanf("%d", &p2);

printf("Carcater a ser desenhado na terceira parte da linha\n");
scanf(" %c", &c3);
printf("Quantidade de caracteres a ser desenhado na terceira parte da linha\n");
scanf("%d", &p3);
 
i=0;
while (i < p1) {
   printf("%c", c1);
   i=i+1;
}

i=0;
while (i < p2) {
   printf("%c", c2);
   i=i+1;
}

i=0;
while (i < p3) {
   printf("%c", c3);
   i=i+1;
}

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

Exercício 2

Modificar o exercício anterior para imprimir uma quantidade variável de LINHAS. As linhas são exatamente iguais.

Solução Ex. 2
#include <stdio.h>
 
int main(){

int p1,p2,p3,i,j,linhas;
char c1, c2, c3;

printf("Carcater a ser desenhado na primeira parte da linha\n");
scanf("%c", &c1);
printf("Quantidade de caracteres a ser desenhado na primeira parte da linha\n");
scanf("%d", &p1);

printf("Carcater a ser desenhado na segunda parte da linha\n");
scanf(" %c", &c2);
printf("Quantidade de caracteres a ser desenhado na segunda parte da linha\n");
scanf("%d", &p2);

printf("Carcater a ser desenhado na terceira parte da linha\n");
scanf(" %c", &c3);
printf("Quantidade de caracteres a ser desenhado na terceira parte da linha\n");
scanf("%d", &p3);

printf("Informe a quantidade de linhas\n");
scanf("%d", &linhas);
 
j=0;
while (j < linhas){
    i=0;
    while (i < p1) {
        printf("%c", c1);
        i=i+1;
    }

    i=0;
    while (i < p2) {
        printf("%c", c2);
        i=i+1;
    }

    i=0;
    while (i < p3) {
        printf("%c", c3);
        i=i+1;
    }
    printf("\n");    
    j = j+1;    
}
printf("\n");
return 0;
}

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>
int main() 
{
  int contador;
  
  contador=0;
  do {  
     printf("valor do contador =  %d\n", contador);
     contador=contador+1;
  } while (contador<5);
  return 0;
}

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.

Exemplo 1

Modificar o exemplo do cálculo do FATORIAL apresentado anteriormente para caso sejam lidos números negativos o programa pergunte novamente o número N. Usar um comando "do while" para construir o loop onde será realizado o scanf().


#include <stdio.h>

int main()
{
  int N,i,FAT;

  /* Leitura do número e 
     verificação se o número é negativo */

  do {
    printf("Entre com o valor de N\n");
    scanf ("%d", &N);
    if (N<0)
       printf("Número negativo...");
  } while (N<0);

  /* computação do fatorial */
  i=N;
  FAT=1;
  while(i>1) {
      FAT=FAT*i;
      i=i-1;
  } 
  printf("Valor de FAT  de %d é %d\n", N, FAT);
  return 0;
}

Um problema na computação do fatorial é que rapidamente pode existir overflow', ou seja, ultrapassar a capacidade da da variável do tipo 'int'. VEJA a tabela abaixo com alternativas de inteiros com seus respectivos tamanhos.

TIPO bytes RANGE COMENTÁRIO
char 1 -128 até 127 um bit para o sinal
short int 2 32,768 to 32,767 um bit para o sinal
int 4 -2147483648 até 2147483647 um bit para o sinal. Dependendo da máquina poderia ser 8 bytes
long int 8 -9223372036854775808 até 9223372036854775807 um bit para o sinal
unsigned char 1 0 to 255
unsigned short 2 0 to 65,535
unsigned int 4 0 to 4294967295
unsigned long 8 0 até 18446744073709551615

Execute o programa abaixo para conferir.

#include <stdio.h>

int main()
{
  char num0;
  short num1;
  int num2;
  long int num3; 

  /* Leitura do número e 
     verificação se o número é negativo */

  printf ("tamanho de num0 = %ld\n", sizeof (num0));
  printf ("tamanho de num1 = %ld\n", sizeof (num1));
  printf ("tamanho de num2 = %ld\n", sizeof (num2));
  printf ("tamanho de num3 = %ld\n", sizeof (num3));
  
  return 0;
}

Exercício

Reimplementar o exemplo anterior usando o long int para computar o fatorial.

Exemplo 2

O programa abaixo foi extraído de (referência). Ele permite realizar a adivinhação de um número entre 1 e 10. Observe que as instruções permitem a geração do número randômico.

srand ( time(NULL) ); /* inicia o gerador com a semente baseada no relógio local */
iSecret = rand() % 10 + 1 /* gera o número */
// exemplo de geração randômica
// extracted and adapted from www.stackoverflow.com 
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main ()
{
      int segredo, sugestao;

      /* iniciar semente: */
      srand ( time(NULL) );

      /* gerar o número secreto: */
      segredo = rand() % 10 + 1;

      do {
          printf ("Adivinhe um número entre (1 a 10): ");
          scanf ("%d",&sugestao);
          if (segredo<sugestao) 
              printf ("O número secreto é menor\n");
          else {
              if (segredo>sugestao) 
                 printf ("O número secreto é maior\n");
          }
      } while (segredo!=sugestao);

      printf ("Parabéns!\n");
      return 0;
}

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
}


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.

Exemplo

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

#include <stdio.h>

int main()
{
  int i, N;

  printf("Entre com o número\n");
  scanf ("%d", &N);

  for ( i=1; i<=N; i=i+1) {
     if (i%2==0)
       printf("número par ====> %d\n", i);
  }
  printf("FIM\n");

  return 0;
}

Aninhamento de loops

É muito comum que a solução de problemas exijam o aninhamento de loops. Neste caso, as instruções são aninhadas normalmente usando, se necessário, o recurso de bloco de instruções. Observe no código abaixo que para cada laço mais externo o comando for interno é executado integralmente.

#include <stdio.h>
int 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);
  }
  return 0;
}

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>

int main()
{
    int i;

    i=0;
    
    PONTO1:
    printf("Laço de número %d\n", i);
    i++;
    if (i<10)
        goto PONTO1;
    return 0;
}
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:

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

ou com o comando while:

int main()
{
   while(1) {
        /* Este bloco se executará infinitamente */
   }
   return 0;
}

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>
int main()
{
  int i,j;

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

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


  • O comando break encerra o laço no ponto em que for executado.
  • O comando continue desvia o fluxo para o início do laço.
#include <stdio.h>

int main()
{
    //break     -> simplesmente interrompe o nosso ciclo
    //continue  -> interrompe o laço (desvia o fluxo para o início do laço)
    int x;

    for(x = 0; x<=10; x++){

        //qndo x == 2, interrompa somente o laço atual
        if(x == 2){
            printf("Valor de x é 2 - fazendo continue...\n");
            continue;
        }

        //Quando chegamos a 8 o looping será finalizado
        if(x == 8){
            printf("Valor de x é 8 - fazendo continue...\n");
            break;
        }

        printf("%d\n", x);
    }
}

Exercício

Elabore um programa em C que leia no máximo 5 números inteiros positivos. Caso um número negativo seja digitado no meio da seqüência uma mensagem deve ser impressa uma mensagem de aviso no terminal e o laço é encerrado de imediato.

Uso do continue para prosseguir no início do loop

#include <stdio.h>
int 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);
        }
    }
    return 0;
}

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 = %.2lf", 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 - nível INICIANTE

  1. Desenvolver em C um programa que efetue a soma de todos os números ímpares que são múltiplos de três e que se encontram no conjunto dos números de 1 até 500 inclusive. Usar comando for.
    Solução - Exercício 1
  2. Faça uma versão "controversa" do programa de adivinhação mostrado na aula usando uma instrução goto para sair de um loop infinito.
    Solução - Exercício 2
  3. Ainda sobre o exercício 2, implemente uma versão usando o comando while().
    Solução - Exercício 3
  4. Ainda sobre o exercício 2, implemente uma versão usando loop infinito e o comando break;
    Solução - Exercício 4
  5. Implemente uma variação do jogo de adivinhação para que ele conte o número de tentativas do jogador.
  6. Implemente uma variação do jogo de adivinhação para que dois dados (1 a 6) sejam jogados. O jogador deve adivinhar a soma dos dados.
  7. 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.
    Solução - Exercício 5
  8. Dado um número inteiro positivo, calcular a soma de todos os números inteiros compreendidos entre 1 e o número dado. Fazer uma versão com while e outra com for. Caso o número apresentado for negativo ou zero, solicitar a entrada novamente. Use o comando do while para esta finalidade.
  9. Dado dois números inteiros positivos "M" e "N", computar o valor "V" conforme a equação:

EXERCÍCIOS - nível MÉDIO

  1. Tente descobrir por tentativas qual carga em um circuito com uma fonte de tensão contínua 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). Sabe-se que esta carga está entre 1 e 20 ohms. Sugestão: faça um "loop" com para testar cargas que vão de 1 a 20 ohms com acréscimos de 0.5 ohms. Crie uma variável para anotar a maior potência e a carga que produziu esta potência.
    Solução

    </syntaxhighlight>

  2. Usando o comando for aninhado, construa um programa que implemente a figura abaixo. A margem esquerda (margem de espaços representada por ponto), 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 da forma:
    
    #include <stdio.h>
    
    int main()
    {
      int i, j, margem, largura, linhas_vazadas;
      char caracter;
      
      /** sub-problema 1 - ler margem , largura de desenho, caracter do desenho e numero de linhas **/
      
      /* sub-problema 2 - desenhar linha de topo */
    
      /* sub-problema 3 - desenhar linhas vazadas */
    
      for (j=0;j<linhas_vazadas;j++) {
          /* desenhar linha vazada*/
      }
    
      /* sub-problema 4 - desenhar linha de fundo  (igual ao sub-problema 1*/
    
      return 0;
    }
    
    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 */
    }
    
  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");
      }
    
    }
    

Exercícios Extras (resolver em sala)

  1. Escreva um programa em C que mostre a tabuada de um número fornecido pelo teclado. Esse número deve estar entre 1 e 10.
  2. Faça um programa em C que calcule a média de N números a serem lidos pelo teclado.
  3. Escreva um programa em C que para ler continuamente números inteiros pelo teclado, e informe ao final qual o maior e o menor deles. A condição de parada do programa ocorre quando o usuário informar um valor negativo ou zero.
    Solução 1
    #include <stdio.h>
    
    int main()
    {
      int maior = -1, numero;
    
      printf("Entre com um número\n");
      scanf("%d", &numero);
      while (numero > 0) {
          if(numero > maior) {
              maior = numero;
          }
          printf("Entre com um número\n");
          scanf("%d", &numero);
      }
      if (maior>0)
          printf("Maior é %d\n", maior);
      else
          printf("Não foi fornecido nenhum número\n");
      return 0;
    }
    
    Solução 2
    #include <stdio.h>
    
    int main()
    {
      int maior = -1, numero;
    
      do {
          printf("Entre com um número\n");
          scanf("%d", &numero);
          if(numero > maior) {
              maior = numero;
          }
      } while(numero>0);
      if (maior>0)
          printf("Maior é %d\n", maior);
      else
          printf("Não foi fornecido nenhum número\n");
      return 0;
    }
    
  4. Escreva um programa C que teste se um número informado pelo teclado é primo.
    Solução

    A solução abaixo usa um contador para contar o número de divisores do número dado. Poderia ser usado um break para encerrar o loop assim que o número fosse divisível...

    #include <stdio.h>
    
    int main(){
      int n, num, k, primo;
    
      printf("Informe o número a ser testado: ");
      scanf("%d",&num);
    
      primo=0;
    
      for(k=2; k<num; k++)
         if((num%k/2) == 0) {
              primo=1;
              break;
      }
      if(primo == 1)
         printf("%d não é primo\n", num);
      else
         printf("%d é primo\n", num);
         
      return 0;
    }
    
  5. Escreva um programa C que calcule N termos da série de Fibonacci, onde é N informado pelo usuário (Ex. 0 1 1 2 3 5 8 13 21 ...). Não usar vetores.
    Solução 1 - com while

    Nesta solução, os dois últimos termos da série sempre ficam armazenados em duas variáveis (ant2 e ant1). Inicialmente ant2 já possui 0 e ant1 possui 1. A partir do termo 3 o loop atua, computando o próximo termo e atualizando os valores de ant1 e ant2.

    #include <stdio.h>
    
    int main (void){
        int ant1, ant2, prox, i, n;
    
        printf("Informe o número de termos\n");
        scanf("%d",&n);
    
        ant2=0;
        ant1=1;
        if (n==1)
            printf("%d", ant2);
        else
            printf("%d %d ", ant2 ,ant1);
    
        i = 3;
        while (i <= n){
            prox = ant1 + ant2;
            printf("%d ", prox);
            ant2 = ant1;
            ant1 = prox;
            i++;
        }
        printf("\n");
        return 0;
    }
    
    Solução 2 - uso de for com desempenho prejudicado por if no laço

    A solução abaixo é similar a anterior mas usa o comando for e podemos dizer que tem uma ineficiência pois sempre terá, no laço do loop, a execução de uma instrução de teste (if else) para ajustar a impressão dos 2 primeiros termos.

    #include <stdio.h>
    
    int main()
    {
      int seq, n1=0,n2=1,i,n;
    
      printf("Entre com n\n");
      scanf ("%d", &n);
    
      for(i=0;i<n;i=i+1) {
        if (i<=1) {
           seq = i;
        } else {
           seq = n1+n2;
           n1=n2;
           n2=seq;
        }
        printf("%d ", seq);
      }
    
      printf("\n");
      return 0;
    }
    
    Solução 3 - com comando for e eficiente, porém não tão 'intuitiva'
    #include <stdio.h>
    
    int main()
    {
      int seq, n1=-1,n2=1,i,n;
    
      printf("Entre com n\n");
      scanf ("%d", &n);
      printf("A série é\n");
      for(i=0;i<n;i=i+1) {
           seq = n1+n2;
           n1=n2;
           n2=seq;
           printf("%d ", seq);
      }
      printf("\n");
      return 0;
    }
    
  6. Escreva um programa C que calcule a média entre todos os números ÍMPARES da série de Fibonacci até o termo N sendo o primeiro termo 0. Exemplo: para N = 5 a série é 0 1 1 2 3 e a soma dos termos ímpares é 5. Assumir que N é sempre maior que 2.
    Solução 1
    #include <stdio.h>
    
    /* atenção: ajustar esta solução ao enunciado */
    int main()
    {
        int seq, n1=0,n2=1,i,n, cont_impar=0, soma=0;
        float media;
    
        printf("Entre com n\n");
        scanf ("%d", &n);
    
        for(i=0;i<n;i=i+1) {
            if (i<=1) {
                seq = i;
            } else {
                seq = n1+n2;
                n1=n2;
                n2=seq;
            }
            if ((seq%2)==1) {
                soma = soma + seq;
                cont_impar = cont_impar + 1;
            }
            printf("%d ", seq);
        }
        if (cont_impar!=0)
            media = (float)soma/cont_impar;
        printf("\nA média dos números ímpares é %.2f\n", media);
        return 0;
    }
    
  7. Considere a função:

    Supondo x definido no domínio dos inteiros, faça um programa para calcular a média dos valores da função para x entre 1 e 1000.
    #include <stdio.h>
    
    int main()
    {
        int x, y, soma_ac, limite;
        float media;
    
        /* calcular a soma acumulada aqui */
        soma_ac = 0;
        limite = 1000;
        for ( x = 1; x <= limite; x++ ) {
            y = 2 * x * x + 3 * x + 1;
            printf("Valor de y é %d\n", y);
            soma_ac = soma_ac + y;
        }
    
        printf("Soma acumulada de f(x) para x entre 1 e %d: %d\n", limite, soma_ac);
    
        /* calcular a média aqui */
        media = (float) soma_ac / limite;
    
        printf("media calculada é %f\n", media);
    
        return 0;
    }
    
  8. Refazer o exercício anterior, criando uma função C que faz a computação da média. A função deve receber 5 parâmetros:
    • os coeficientes da equação;
    • os limites inferior e superior.
    Testar no programa principal (função main())
    #include <stdio.h>
    
    float media_func_quadratica(int a, int b, int c, int limite_inf, int limite_sup)
    {
        int x, y, soma_ac;
        float media;
        
        /* testar consistencia de limites e inverter se necessário */
        if (limite_inf > limite_sup) {
            int aux;
            aux = limite_sup;
            limite_sup = limite_inf;
            limite_inf = aux;
        }
    
        /* calcular a soma acumulada aqui */
    
        for ( soma_ac = 0, x = limite_inf; x <= limite_sup; x++ ) {
            y = a * x * x + b * x + c;
            printf("Valor de y é %d\n", y); // tirar futuramente
            soma_ac = soma_ac + y;
        }
    
        /* calcular a média aqui */
        media = (float) soma_ac / (limite_sup - limite_inf + 1);
    
        return media;
    }
    
    int main()
    {
        float media;
        int a,b,c,inf,sup;
    
        a = 2; b = 3; c = 1; inf = 1; sup = 3;
        media = media_func_quadratica(a, b, c, inf, sup);
    
        printf("media calculada para a = %d b = %d c = %d limite inferior = %d e limite superior %d : %f\n", a, b, c, inf, sup, media);
    
        a = 2; b = 3; c = 1; inf = 1; sup = 10;
        media = media_func_quadratica(a, b, c, inf, sup);
    
        printf("media calculada para a = %d b = %d c = %d limite inferior = %d e limite superior %d : %f\n", a, b, c, inf, sup, media);
    
        a = 2; b = 3; c = 1; inf = 1; sup = 3;
        media = media_func_quadratica(a, b, c, sup, inf);
    
        printf("media calculada para a = %d b = %d c = %d limite inferior = %d e limite superior %d : %f\n", a, b, c, inf, sup, media);
    
        return 0;
    }
    
  9. Fazer uma variação da função anterior mas agora a função deve retornar o MAIOR f(x) para uma determinada faixa colocada.