Enviar um café pro programador

Pode me ajudar a transformar cafeína em código?

Exercícios resolvidos sobre testes condicionais e laços em C

No artigo passado de nossa apostila de C, propomos uma série de questões e desafios, como parte do treinamento final sobre testes condicionais e laços em C.

Não há uma única, nem uma melhor maneira de resolver as questões.
Você terá que raciocinar e usar o que achar necessário.

Use:
Teste condicional IF ELSE
Laço WHILE
Laço FOR
Teste condicional SWITCH, com ou sem CONTINUE e BREAK
Laço DO WHILE


Exercícios sobre testes condicionais e loopings em C

Questão 0:
Vamos usar quatro variáveis na solução desse exercício: o 'n' vai armazenar quantos números o usuário vai inserir, o 'count' será usado como contador do laço, o 'num' é a variável que vai armazenar o número que o usuário digitar a cada iteração e por fim temos a variável 'menor' que, como o nome diz, vai armazenar o valor do menor número inserido.

A lógica da questão é simples: a cada laço, pedimos um número ao usuário.
Se esse número for o primeiro a ser inserido, ele será o menor até então.

Depois disso, continuamos a pedir os números ao usuário, e comparamos se esse número inserido é menor que o valor do número armazenado em 'menor', se for menor, a variável 'menor' vai receber esse novo valor.

Fazendo isso em todas as iterações, terminamos o laço com o menor valor inserido dentro da variável 'menor'.
Código C:
#include<stdio.h>

int main()
{
    int n,
        count,
        num,
        menor;

    printf("Quantos numeros deseja comparar: ");
    scanf("%d", &n);

    for(count = 1 ; count <= n ; count++)
    {
        printf("Insira o numero %d: ", count);
        scanf("%d", &num);

        if(count == 1)
            menor=num;

        if(num < menor)
            menor=num;
    }

    printf("Menor numero: %d", menor);
}


Questão 1:
Como de praxe, a variável 'n' recebe quantos números serão exibidos (de 1 até n) e a variável 'count' será a responsável pelo controle de nosso laço.

Iniciamos as variáveis 'pares' e 'impares', que irão receber o produto, com valor 1 (consegue pensar o motivo disso?)

A seguir entramos no laço, e dentro deste fazemos um teste condicional do tipo IF ELSE.
Testamos se o número é par. Se for, ele deixará resto da divisão por 2 igual a 0, então multiplicamos esse número por 'pares'.
Caso o número seja ímpar, vamos multiplicar esse 'count' pela variável 'impares'.






Assim, ao final do laço, teremos o produto de todos os pares e de todos os números ímpares de 1 até n, nas variáveis 'pares' e 'impares', respectivamente.

Relembrando que os seguintes símbolos:
pares *= count;
impares *= count;

Representam o mesmo que:
pares = pares * count;
impares = impares * count;

Assim, o código de nossa questão será:
Código C:
#include<stdio.h>

int main()
{
    int n,
        count,
        pares=1,
        impares=1;

    printf("Produto dos pares e impares ate o numero: ");
    scanf("%d", &n);


    for(count = 1 ; count <= n ; count++)
    {
        if(count % 2 == 0)
            pares *= count;
        else
            impares *= count;
    }

    printf("\nProduto dos pares: %d\n", pares);
    printf("\nProduto dos impares: %d\n", impares);
}


Questão 2:
Essa questão é uma continuação da anterior. Se fez a questão 1, fará essa com facilidade.
Porém essa tem uma utilidade muito grande: calcular fatoriais é muito importante em Matemática.
Assim, criando esse programa você terá criado uma ferramenta muito útil.

Pois bem, a variável 'n' e a 'count' você já sabe o que faz.
Agora, para armazenar o produto de 1 até n, vamos usar só a variável 'res', que nos fornecerá a resposta final.

O laço não tem segredo, basta fazer rodar de 1 até n, e a cada iteração multiplicamos esse número da iteração por 'res', que ao final temos o número desejado, o fatorial de n: n!
Código C:
#include<stdio.h>

int main()
{
    int n,
        count,
        res=1;

    printf("Insira um inteiro positivo: ");
    scanf("%d", &n);


    for(count = 1 ; count <= n ; count++)
        res *= count;

    printf("\nFatorial de %d eh: %d\n", n, res);
}


Questão 3:
O funcionamento é o seguinte:
Você inicia sua conta com um valor 'inicial'.
Depois de 1 mês, rendeu 0,5%, ou seja, você teve um lucro de 0.005 * inicial
Agora seu total é: inicial + 0,005*inicial = 1,005 inicial

Essa fórmula será usada sempre: o dinheiro que você tem no início do mês, é 1,005 daquele que você tinha há um mês atrás.
Então, 'valor_final' = '1,005*valor_final'

Após esse lucro gerado pela poupança, você vai adicionar, todo mês, um 'investimento'.
Assim, após o lucro e investimento, seu dinheiro é: valor_final = 1,005*valor_final + investimento

Logo, nosso código C fica:
Código C:
#include<stdio.h>

int main()
{
    float inicial = 0.0,
          investimento = 0.0,
          valor_final;

    int meses=0,
        count;

    printf("Investimento inicial: ");
    scanf("%f", &inicial);
    valor_final = inicial;

    printf("Investimento mensal: ");
    scanf("%f", &investimento);

    printf("Tempo, em meses, que deixara rendendo: ");
    scanf("%d", &meses);


    for(count = 1 ; count <= meses ; count++)
    {
        valor_final = 1.005*valor_final;
        valor_final += investimento;
        printf("Apos %d mes(es) voce tera: %.2f\n", count, valor_final);
    }

    printf("\nVoce comecou com %.2f e investiu %.2f durante %d meses\n", inicial, investimento, meses);
    printf("Seu lucro foi de %.2f\n", valor_final - inicial - (meses*investimento));
}


Questão 4:
Note que o usuário vai fornecer o número de linha e que o número da linha, é o primeiro dígito da linha.
Por exemplo, a linha 3 começa com o número 3.

Note também que estamos calculando os múltiplos.
Por exemplo, a linha 'n' tem elementos que são o 'n' multiplicado de 1 até n: n*1, n*2, n*3, ...,n*n

Vamos usar dois laços for, encadeados.
O primeiro, é o que vai ficar responsável pela linha. Essas linha vão de 1 até n.

Dentro de cada linha dessa, vamos imprimir 'n' elementos. Ou seja, vamos imprimir as colunas.
Cada elemento da coluna é o valor do número da linha multiplicado pelo número da coluna (as colunas variam de 1 até n).

Então, nosso código fica assim:
Código C:
#include<stdio.h>

int main()
{
    int num,
        linha,
        coluna;

    printf("Entre com o numero: ");
    scanf("%d", &num);

    for(linha = 1 ; linha <= num ; linha++)
    {
        for(coluna = 1 ; coluna <= linha ; coluna++)
            printf("%3d ", linha*coluna);

        printf("\n");
    }
}


Questão 5:
Uma maneira simples de fazer essa questão é com o laço while, pois as operações que deverão ser feitas, devem acontecer ENQUANTO o número for diferente de 1.

Dentro desse laço, usamos o resto da divisão do número por 2, pra saber se o número é par ou ímpar e então a operação é
Código C:
#include <stdio.h>

int main()
{
        int num;

        printf("Digite um numero inteiro: ");
        scanf("%d", &num);

        while(num != 1)
        {
            if( num%2 == 0)
                num = num/2;
            else
                num = 3*num +1;

            printf("%d ", num);
        }
}


Desafio dos números de FIbonacci:
Vamos chamar o n-ésimo termo da série de 'numero', o (n-1)-ésimo termo de 'ultimo' e o (n-2)-ésimo de 'penultimo'.
Assim, temos a fórmula geral: numero = ultimo + penultimo;

Para calcularmos o próximo termo da série ('numero'), temos que mudar os valores de 'ultimo' e 'penultimo'.
Para tal, o valor de 'penultimo' agora será o valor de 'ultimo', e o valor de 'ultimo' será agora o valor de 'numero'. Após fazer isso, podemos calcular o novo valor de 'numero', que é 'ultimo + penultimo'.

Por exemplo, chegamos em um ponto que:
numero = 21
ultimo = 13
penultimo = 8


Para calcular o próximo termo, fazemos 'penultimo=ultimo', ou seja, agora:
penultimo = 13
Analogamente, fazemos 'ultimo=numero', e temos:
ultimo=21

De posse desses novos valores, temos o novo valor de 'numero', que é: 21 + 13 = 34, que é o próximo termo da série.
Código C:
#include<stdio.h>

int main()
{
    int numero,
        ultimo=1,
        penultimo=0,
        count,
        termo;

    printf("Entre com o termo desejado: ");
    scanf("%d", &termo);

    for( count = 3 ; count <= termo ; count++)
    {
        numero = ultimo + penultimo;
        penultimo=ultimo;
        ultimo=numero;
    }

    printf("Elemento de termo %d: %d\n", termo, numero);
}


Desafio do diamante de asteriscos:
Há duas coisas na figura: espaços em branco e asteriscos.
Vamos resolver esse desafio analisando o padrão do número de asteriscos (variável asteriscos) e do número de espaços em branco (variável espacos).

Antes de desenhar o diamante, temos que checar se o número que o usuário forneceu é ímpar, através de um teste condicional:
if(numero%2 != 0)

Se não for, o programa cai no else e nossa aplicação C é finalizada.
Vamos desenhar o dito cujo.

Parte de cima do diamante
Qual o número inicial de espaços?
Note que é sempre: (numero-1)/2
...e essa é a lógica do problema, a parte mais difícil, que é notar esse padrão.

E o número de asteriscos inicial?
Fácil, é 1 e vai crescendo de 2 em 2 até que o número de asteriscos impressos seja igual a numero.

Pois bem, vamos desenhar linha por linha, imprimindo primeiro o número correto de espaços e depois o de asteriscos.
Esse controle de linhas é feito pela linha de código:
for(linha=1 ; espacos > 0 ; linha++)

Ou seja, vamos imprimir da linha 1 até a linha central (note que a linha central é a que tem espacos=0).

Agora, dentro desse looping vamos imprimir, em cada linha, primeiro o número de espaços e depois os asteriscos.
Sabemos que o número inicial de espaços é (numero-1)/2 e o número inicial de asteriscos é 1.

Para imprimir o número correto de espaços e asteriscos vamos usar a variável count:
for(count=1 ; count <= espacos ; count++)
for(count=1 ; count <= asteriscos ; count++)

Após o looping maior, o das linhas, temos que decrementar o número de espaços em 1, e incrementar o número de asteriscos em 2, além da quebra de linha.


Parte de cima do diamante
A lógica é a mesma da de cima, porém o número de espaços aumenta em 2, e o número de asteriscos é decrementado em 2.
Outra diferença é que vamos imprimir uma linha a menos, pois a linha central já foi impressa. Assim, essas linhas são impressas desde a primeira abaixo da linha central, até enquanto houver asteriscos (até ter 1, que é o último):
for(linha=1 ; asteriscos > 0 ; linha++) 
Código C:
#include<stdio.h>

int main()
{
        int numero,
            espacos,
            asteriscos,
            count,
            linha;

        printf("Insira um numero impar: ");
        scanf("%d", &numero);

        if(numero%2 != 0)
        {
            //Imprimindo a parte de cima do diamante
            asteriscos = 1;
            espacos = (numero-1)/2;
            for(linha = 1 ; espacos > 0 ; linha++)
            {
                //Espaços
                for(count = 1 ; count <= espacos ; count++)
                    printf(" ");

                //Asteriscos
                for(count = 1 ; count <= asteriscos ; count++)
                    printf("*");

                espacos--;
                asteriscos += 2;
                printf("\n");
            }

            //Imprimindo a parte de baixo do diamante
            for(linha=1 ; asteriscos > 0 ; linha++)
            {

                //Espaços
                for(count = 1 ; count <= espacos ; count++)
                    printf(" ");

                //Asteriscos
                for(count = 1 ; count <= asteriscos ; count++)
                    printf("*");

                espacos++;
                asteriscos -= 2;
                printf("\n");
            }

        }
        else
            printf("Não é ímpar!");

}


Super hiper mega desafio de Fibonacci
Essa questão é um pouco mais complicada, vai precisar de conhecimentos em Programação e um pouco de Matemática, mas não deixa de ser simples e engenhosa.

Na seção passada usamos três variáveis: 'numero', 'ultimo' e 'penultimo', para descrever o n-ésimo, (n-1)-ésimo e o (n-2)-ésimo termo, respectivamente.
Vamos excluir a variável 'numero', e trabalhar somente com o 'ultimo' e 'penultimo'.

Vamos supor que em um determinado ponto temos:
ultimo=5
penultimo=3

É fácil ver que o próximo termo é sempre (ultimo + penultimo), que nesse caso é 8.
Nosso objetivo então é fazer com que as variáveis tenham o valor ultimo=8 e penultimo=5, concorda?

Para que consigamos gerar mais números de Fibonacci, fazemos com que 'ultimo' receba seu antigo valor somado com o valor de 'penultimo', pois assim a variável 'ultimo' terá a soma dos dois números anteriores, como diz a regra de Fibonacci. Em C, fica assim:
ultimo = ultimo + penultimo

Agora ultimo = 8, e penultimo = 3.
Nosso objetivo agora é fazer com que penultimo receba o valor 5. Mas como, se nenhuma das variáveis possui valor 5? De onde obter esse valor?
De uma relação matemática da série de Fibonacci! Note que sempre: ultimo = numero - penultimo
Veja como obter 5:  5 = 8 -3 , ou seja, é o novo valor de 'ultimo' subtraído do atual valor de 'penultimo'.

Em C fica assim: penultimo = ultimo - penultimo

Note no desenho como variam os valores das variáveis no decorrer da execução:

Veja como fica o resultado:
Código C:
#include<stdio.h>

int main()
{
    int ultimo=1,
        penultimo=0,
        termo,
        count;

    printf("Entre com o termo desejado: ");
    scanf("%d", &termo);

    printf("%d\n%d\n", penultimo, ultimo);

    for( count = 3 ; count <= termo ; count++)
    {
        ultimo = ultimo + penultimo;
        penultimo = ultimo - penultimo;
    }

    printf("Elemento de termo %d: %d\n", termo, ultimo);
}

11 comentários:

Felipe Ergueta disse...

Olá, primeiro vou parabeniza-lo pelo blog, estou fazendo todos os exercícios e em poucas semanas já avançei muito na linguagem C. Eu me divirto fazendo os códigos de programação (quando acho logo a lógica), mas as vezes é algo mais complicado, esquento a cabeça, mas faz parte! Enfim, a minha dúvida é no diamante de astericos:

asteriscos = 1;
espacos = (numero-1)/2;
for(linha = 1 ; espacos > 0 ; linha++)
{
//Espaços
for(count = 1 ; count <= espacos ; count++)
printf(" ");

//Asteriscos
for(count = 1 ; count <= asteriscos ; count++)
printf("*");

espacos--;
asteriscos += 2;
printf("\n");

Minha dúvida está nessa passagem, o primeiro for, a lógica é enquanto espaços forem maiores que 0. Sendo 9 o número escolhido e sendo asterisco=1 e vazio=4 os valores inicias... no primeiro loop do código, espaço torna-se 3, asteriscos 3. No segundo loop, espaço torna-se 2, e asteriscos 5. No terceiro, espaço torna-se 1, e asteriscos 7. No final do código, espaço torna-se 0 e asteriscos 9. Agora chegou minha dúvida, a condição é espaço>0, como o código continua e imprime os 9 asteriscos, se 0 não é maior que 0... Obrigado pela ajuda desde já!

Jorge Hernandes disse...

Oi Felipe, cara eu consegui resolver esse problema... vc está com dificuldade para imprimir a linha central e a parte de baixo do diamante, sugiro que realize um teste IF logo após o FOR principal que escreve as linhas. Nesse teste vc determina uma condição capaz de identificar a linha do meio do diamante, sendo que se for a parte de baixo vc incrementa espaços (espaco++) e decrementa asteristicos (asteristicos-=2). Note a diferença na inicialização das variáveis tambem, isso se dá pelo posicionamento mas é facil de se corrigir.

int asteriscos = -1;
int espacos = ((numero-1)/2+1);

for(linha = 1 ; linha<=numero ; linha++)
{
if(linha<=(numero/2+1))
{
espacos--;
asteriscos += 2;
}
else
{
espacos++;
asteriscos -= 2;
}

//Espaços
for(count = 1 ; count <= espacos ; count++)
printf(" ");

//Asteriscos
for(count = 1 ; count <= asteriscos ; count++)
printf("*");

printf("\n");
}

Espero ter ajudado!

Unknown disse...

ola gostaria que você me respondesse esses dois exercício que está me dando dor de cabeça já tentei muito e ñ estou conseguindo, os exercício é esses:

pergunte ao usuário quantos números da sequencia ele quer ver

pergunte um numero e imprima seu fatorial em ambos casos pergunte se ele quer continuar o programa ou encerrar
desde já fico agradecido pela sua ajuda
ah muito bom esse seu blog está de parabéns bons conteúdo.

Apostila C Progressivo disse...

Olá Elenilson,

Quais são suas dúvidas nos exercícios? O que não conseguiu resolver?

Anônimo disse...

Prezados,

No exercicio 1 se eu colocar um inteiro, pex. 20, pelo menos no meu computador, o produto dos pares dá erro e aparece um numero negativo. Penso que houve o famoso "estouro".No meu computador a variavel int ocupa 4 bytes, bem como a short e a long tb.Já tentei usar o float e o double mas o problema persiste.Como eu poderia resolver este problema? Segue o codigo abaixo:(eu chamo a função produto_parimpar() do main)

int produto_parimpar()
{
int num,i;
unsigned int pp=1,pi=1;
system("cls");
printf("\n\t\tCALCULA O PRODUTO DOS PARES E IMPARES DO NUMERO DIGITADO");
printf("\n\nEntre com o numero desejado:");
scanf("%d",&num);
for(i=1;i<=num;i++)
{
if(i%2==0) pp*=i;
else pi*=i;
}
printf("\n\nO produto dos numeros pares ate %d eh: %d",num,pp);
printf("\n\nO produto dos numeros impares ate %d eh: %d",num,pi);
return;
}

joagostini disse...

Eis como resolvi o desafio de fibonacci. No exemplo dado, o código é mais direto, no meu, em troca, consegue imprimir, menos o zero, a cadeia toda.
/*#include
#include
#include */

void fibonacci(int x)
{
int i=1,n1=1,n2=0;
printf("\n\nA sequência de Fibonacci é 0 ");
for(;i<x;++i)
{
if(i%2==0)
{
n2=n1+n2;
printf("%d ",n2);
}
else
{
n1=n1+n2;
printf("%d ",n1);
}
}

int main() {
setlocale(LC_ALL,"");

int qtos;

printf("Informe o número de termos da sequência Fibonacci. ");
scanf("%i",&qtos);
fibonacci(qtos);

return (0);
}

}

ze disse...

Super hiper mega desafio de Fibonacci

Muita boa a solução.alias, genial.
eu fiz a questão anterior de Fibonacci.Quando eu tentei fazer essa, eu pensei:"impossível,pois no mínimo é necessário duas variavéis(count e termo)". :@)

ze disse...

Desafio do diamante de asteriscos

Solução genial e bem comentada como foi a do hiper desafio fibonacci.

Eu fiz de outro jeito.
1- Eu fiz um algoritmo que exibia um triângulo.
2- Eu fiz outro algoritmo que exibia um triângulo invertido.
3- juntei os dois algoritmos.fiz uma adaptação no algoritmo triângulo invertido para não imprimir a linha inicial.

O meu jeito de fazer eu usei a tecnica dividir para conquistar kkkkkk... claro, depois de usar muito a tecnica tentativa e erro kkkk mas enfim o importante é que deu certo

Anônimo disse...

No Exercício 4 eu não entendi direito a ideia do for entrelaçado, mas fiz uma resolução diferente. Entrelaçando while eu me sinto mais no controle da situação...
Meu codigo ficou assim:

#include

int main(void)
{
int num;
int linha = 1;
int count = 1; //Esse count representará a quantidade de termos por linha, sendo também o 'n' da progressão aritimética de razão = linha e primeiro termo = linha.


printf("Insira um numero inteiro: ");
scanf("%d",&num);

while(linha <= num) //Esse while resetará o count e pulará as linhas
{

printf("\n");

while(count <= linha) //Esse while escreve os termos em cada linha
{
printf("%d ",linha+(count - 1)*linha); //Formula do An da progressao aritimética
count++;
}

count = 1;
printf("\n");
linha++;

}
}

Unknown disse...

Primeiramente, gostaria de parabenizar pela iniciativa, conteúdo relevante com uma didática incrível! Estou acompanhando o site como um estudo paralelo de programação e gostaria de deixar uma contribuição.

No Desafio do diamante, o for que controla a linha está sendo usado como while, apenas o teste "asterisco>0" ou "espaco>0" é relevante, a variável linha não realiza nenhum função.
Daí seria mais eficiente usar "while(espaco>0)" e while(asterisco>0).
Ou então, os argumentos de "for" não são obrigatórios, poderia fazer da seguinte forma "for( ;espaco>0; )" ou "for( ;asterisco>0; )"

Obrigado por manter sites do tipo no ar!!!!
PARABÉNS!!!!

Anônimo disse...

João Carlos Agostini, você precisa de um "fechar chaves(})" antes do int main() e eliminar um "fechar chaves(})" do final pois a linguagem C não aceita função dentro de função (o que não a inclue no grupo de Linguagem Estruturada em Blocos).