Oi pessoal, o código abaixo é pra calcular o ano bissexto, aparentemente o resultado está sendo o correto, mas na apostila a implementação parece ser muito melhor do que a minha, pensando apenas na eficiência do código, o meu está correto, quer dizer o resultado é o esperado?
[code]#include <stdio.h> #include <stdlib.h>
int main()
{
int m,d,a;
do{
printf ("Entre com o dia [1,31]: ");
scanf ("%d", &d);
}while(d<1||d>31);
do{
printf ("Entre com o mes [1,12]: ");
scanf ("%d", &m);
}while(m<1||m>12);
do{
printf ("Entre com o ano [1900,2100]: ");
scanf ("%d", &a);
}while(a<1900||a>2100);
if(a%4==0 || a%100!=0 || a%400==0)
printf ("\nO ano %d e bissexto.\n", a);
printf ("\nData: %d/%d/%d \n\n", d,m,a);
system("PAUSE");
return (0);
[quote=armando]Paloma:
Seu código está errado, …deveria ser:
if(a%4==0 && (a%100!=0 || a%400==0))
[/quote]
Armando, acho que o seu também está.
Meu algorítmo é diferente do seu (este eu escrevi há uns 16 anos atrás). A parte diferente é que o OU tem que ser EXCLUSIVO para os módulos de 100 e 400, e em C não existe OU EXCLUSIVO, aliás só vi OU exclusivo até hoje em BASIC e ASSEMBLER.
Por isto há a condição p/ verificação do terceiro módulo, pois não podemos ter ano bissexto cujo (a%100!=0 && a%400==0), e o “ou” “||” permite isto, por não ser exclusivo.
Aliás, este maldito “ou exclusivo” é motivo de discussões em qualquer questão de estatística.
#define UTIL_ANO_BISSEXTO(ano) (!((ano)%4) ?(!((ano)%100) ?(!((ano)%400) ?1 :0) :1) :0) Por favor, não critiquem a macro. Foi escrita em C ANSI, que não tem funções inline, por isto a macro para não replicar código, já que uma função nos traria uma entrada a mais na pilha seguida de mais um “call” - problema sério para o desempenho na época.
Paloma e Armando. Desculpe-me. Muito bonito o assunto do XOR, mas creio estar enganado. Não li a expressão, e me baseie num comentário no código, que parece não ter o menor sentido, pois se algo for divisivel por 400 certamento o será por 100 também.
Esqueça o XOR, não sei de onde surgiu este comentário sem sentido, no código.
[quote=lucianomx]Paloma e Armando. Desculpe-me. Muito bonito o assunto do XOR, mas creio estar enganado. Não li a expressão, e me baseie num comentário no código, que parece não ter o menor sentido, pois se algo for divisivel por 400 certamento o será por 100 também.
Esqueça o XOR, não sei de onde surgiu este comentário sem sentido, no código.[/quote]
Uma forma ‘suja’ seria deixar o C tentar converter a data
[code]#include <time.h> #include <stdio.h>
int main(void)
{
int d,m,a;
struct tm t;
time_t t_of_day;
for(;;) {
printf ("Digite a data no formato dd/mm/yyyy \n");
scanf("%d/%d/%d",&d,&m,&a);
t.tm_year = a - 1900;
t.tm_mon = m - 1;
t.tm_mday = d;
t.tm_hour = 0;
t.tm_min = 0;
t.tm_sec = 0;
t.tm_isdst = 0;
t_of_day = mktime(&t);
if(t_of_day <= 0)
printf("!!!data invalida!!!\n");
else
break;
}
return 0;
}[/code]
Em C mais basico
[code]#include <time.h> #include <stdio.h>
int main(void)
{
int dia,mes,ano;
int ultimo_dia[] = {-1,31,28,31,30,31,30,31,31,30,31,30,31};
for(;;) {
printf ("Digite a data no formato dd/mm/yyyy \n");
scanf("%d/%d/%d",&dia,&mes,&ano);
// testa coisas obvias: dia/ano negativo,mes invalido
if(dia<=0||mes<1||mes>12||ano<=0){
printf("Data invalida\n");
continue;
}
// atualiza o ultimo dia do mes se bissexto
if(ano%4==0 && (ano%400==0 || ano%100!=0))
ultimo_dia[2]=29;
else
ultimo_dia[2]=28;
// verifica se o dia eh maior que o ultimo dia do ano
if(dia>ultimo_dia[mes])
printf("Data invalida\n");
else
break;
}
return 0;