Gabarito de Lista de Exercícios
Solução:
Neste exercício, segundo a sugestão apresentada, bastava
se adicionar a linha de código que está comentada, no exercício
abaixo. A variável índex, que aponta qual letra da string
será impressa, e que era incrementada circularmente a cada iteração,
agora só é incrementada de 5 em 5 iterações,
ou seja, quando o resto da divisão de contador por 5 for 0.
#include <stdio.h>
main()
{
int índex = 0, contador;
char letras[5] = "Joao";
for (contador=0; contador<1000; contador++)
{
printf("\n%c",letras[índex]);
if (( contador % 5 ) == 0)
/* Se o resto da divisão == 0, entao incrementa */
índex = (índex
== 4)? index=0: ++índex;
}
}
Solução:
#include <stdio.h>
main()
{
int índex;
char frase[30];
printf("\n\nEntre com a frase (max 30 caracteres): ");
gets(frase);
for (índex =0 ; frase[índex] != '\0'; index++)
{
switch(frase[índex])
{
case '\t': frase[índex] = '\n';
break;
case ' ': frase[índex] = '\n';
break;
}
}
printf("\n\nNova frase: \n%s", frase);
}
Solução:
Neste exercício existem alguns detalhes interessantes. Muitas
pessoas não conseguiram chegar ao resultado por causa de um pequeno
detalhe na 'linha em destaque'. Lembre-se sempre que se você
tem um string de 10 posições, o seu índice pode variar
de 0 a 9, e o '\0' vai estar na posição 9. Logo, você
deve inverter a posição 8 com a 0, 7 com a 1, e assim por
diante. É por isto que a expressão fica:
copia[i] = str[strlen(str)-i-1]
Não podemos também deixar de colocar o '\0' no final da nova string.
#include <stdio.h>
#include <string.h>
#define MAX 15
main()
{
char str[MAX], copia[MAX];
int i;
printf("\n\nEntre com uma palavra: ");
gets(str);
for(i=0; str[i] != '\0'; i++)
{
copia[i] = str[strlen(str)-i-1]; /* Linha
em destaque */
}
copia[i] = '\0';
printf("\n\nString Invertida: %s\n", copia);
}
Solução:
Como o comando while não tem o incremento próprio,
precisamos fazê-lo dentro do seu loop. Outra observação
importante é a necessidade de se inicializar a variável com
i = 0.
Entao temos:
#include <stdio.h>
#include <string.h>
#define MAX 15
main()
{
char str[MAX], copia[MAX];
int i = 0;
printf("\n\nEntre com uma palavra: ");
gets(str);
while (str[i] != '\0')
{
copia[i] = str[strlen(str)-i-1]; /* Linha
em destaque */
i++;
}
copia[i] = '\0';
printf("\n\nString Invertida: %s\n", copia);
}
Solução:
É preciso inicializar a variável contador, para garantir
o resultado desejado. O incremento também tem que ser feito 'na
mão'.
#include <stdio.h>
main()
{
int índex = 0, contador =0;
char letras[5] = "Joao";
do
{
printf("\n%c",letras[índex]);
if (( contador % 5 ) == 0) /* Se o resto
da divisão == 0, entao incrementa */
índex = (índex ==
4)? index=0: ++índex;
contador ++;
} while (contador < 1000);
}
Solução:
Este programa já é um programa mais trabalhado e exige
um pouco mais de paciência e atenção. Apresento a seguir
para vocês a minha solução para este problema. Vale
lembrar que esta solução é apenas mais uma entre milhares
possíveis. Os códigos estão bem comentados.
A primeira versão e uma versão básica.
A segunda já e mais avançada, realiza a leitura e testa
a consistência da data em um mesmo loop. Mas a filosofia das duas
versões é a mesma: O programa testa a validade dos dados
assim que os lê, para só entao processar.
A segunda versão também faz o uso do comando goto, o
que muitas vezes pode ser evitado. O mesmo efeito teria sido alcançado
usando-se um loop qualquer. Eu optei pelo seu uso pela elegância
que ele conferiu ao código.
Versão 1:
/* -------------------------------------------------------- */
/* CONTADORE DE DIAS: Versão 1 ----------------------------
*/
#include <stdio.h>
main()
{
int dia, mes, ano, i; /* Variaveis.. */
int ndias;
int meses[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
printf("\n\n ----Contador de dias----- \n");
/* Leitura da data */
do
{
printf("\nDia: ");
scanf("%d", &dia);
} while ((dia > 31) || (dia < 1));
do
{
printf("\nMes: ");
scanf("%d", &mes);
} while ((mes > 12) || (mes < 1));
do
{
printf("\nAno: ");
scanf("%d", &ano);
} while ((ano < 1900) || (ano > 2100));
/* E isto garante que a data seja valida */
/* Agora, ao processamento ------------------------------------
*/
/* Primeiro inicializamos ndias. Em seguida, somamos os dias
*/
/* do mes corrente e por fim somamos os dias dos meses passados
*/
ndias = 0;
/* Descobrindo se o ano e bissexto */
/* Caso seja, iremos somar um dia na soma final, mas somente se
*/
/* o mes corrente for posterior ao mes de fevereiro.. */
if ( ((ano%4) == 0) && ((ano%100) != 0) || (ano%400 == 0))
/* Se e bissexto */
if (mes > 2) ndias += 1; /* Se já passou o
mes de fevereiro */
/* Computa os dias do mes corrente */
ndias += dia;
/* O mes corrente já foi contado. Portanto o contador vai
ate mes-1 */
for (i=0; i< (mes-1); i++)
ndias += meses[i];
printf("\nDia Numero: %ld", ndias);
}
Versão 2:
/* -------------------------------------------------------- */
/* CONTADORE DE DIAS: Versão 2 ----------------------------
*/
#include <stdio.h>
main()
{
int dia, mes, ano, i;
long int ndias;
int meses[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
printf("\n\n ----Contador de dias----- \n");
/* Leitura da data
Lê ate que a data seja valida */
le_data:
/* Rotulo usado para o comando goto */
do
{
printf("\nEntre com a data no formato DD/MM/AA: ");
scanf("%d/%d/%d", &dia, &mes, &ano);
} while (((dia > 31) || (dia < 1)) &&
((mes > 12) || (mes < 1)) &&
((ano < 1900) || (ano > 2100)) );
/* Verificando se o ano e bissexto */
/* Caso seja, o mes de fevereiro ganha mais um dia.. */
if ( ((ano%4) == 0) && ((ano%100) != 0) || (ano%400 == 0))
meses[1] += 1;
/* Verifica a consistencia da data. Caso inconsistente volta a le_data
*/
if (dia > meses[mes-1]) /* DATA INCONSISTENTE!!
*/
{
printf("\n DATA INCONSISTENTE! \n ");
meses[1] = 28;
/* Desfaz a soma de um dia no mes de fevereiro */
goto le_data;
}
/* E isto garante que a data seja valida */
/* Agora, ao processamento -----------------------*/
ndias = 0;
/* Computa os dias do mes corrente */
ndias += dia;
for (i=0; i< (mes-1); i++) /* O mes corrente já
foi contado (mes-1)*/
ndias += meses[i];
printf("\nDia Numero: %ld", ndias);
}
< Conversao de base >
1: decimal para hexadecimal
2: hexadecimal para decimal
3: decimal para octal
4: octal para decimal
5: Encerra
Informe sua opcao:
A partir da opção escolhida, o programa deverá pedir o numero na base escolhida, lê-lo e apresentá-lo na base desejada. Em seguida, o programa deve perguntar ao usuário se ele deseja retornar ao menu principal ou finalizar o programa. O problema pode ser estendido a outras bases, de acordo com o interesse do aluno.
Solução:
A seguir é apresentada uma solução. O código
está bem comentado, com a intenção de torná-lo
de fácil entendimento. Mais uma vez, esta é apenas uma forma
de implementar, havendo muitos outros caminhos para se chegar à
solução.
/*------------------------------------------------------------------*/
/* Programa de conversao de bases ----------------------------------*/
/* Versão 1 --------------------------------------------------------*/
#include <stdio.h>
main()
{
int entrada, opcao = 0;
char opcao_c;
/* Loop principal do programa --------------------------------------*/
while (opcao != 5)
{
printf("\n\n");
/* Imprime a tela */
printf("\n\n\t< Conversao
de base >");
printf("\n 1: decimal
para hexadecimal");
printf("\n 2: hexadecimal
para decimal");
printf("\n 3: decimal
para octal");
printf("\n 4: octal
para decimal");
printf("\n 5: Encerra");
printf("\n\n\t\tOpcao: ");
scanf("%d", &opcao);
if ((opcao > 4)||(opcao <1))
continue;
/* Opcao invalida ou saida */
/* Volta ao inicio do loop */
printf("\nEntre com o numero:
");
switch (opcao)
{
case 1:
scanf("%d", &entrada);
printf("Numero convertido: %x", entrada);
break;
case 2:
scanf("%x", &entrada);
printf("Numero convertido: %d", entrada);
break;
case 3:
scanf("%d", &entrada);
printf("Numero convertido: %o", entrada);
break;
case 4:
scanf("%o", &entrada);
printf("Numero convertido: %d", entrada);
break;
}
do
{
printf("\n\n(F) Finaliza e (M) Retorna ao Menu. Opcao: ");
fflush(NULL);
scanf("%c", &opcao_c);
} while ((opcao_c != 'F')&&(opcao_c != 'M'));
if (opcao_c
== 'F') opcao = 5;
}
}