Ano Bissexto - Linguagem C

13 respostas
P

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?

#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);
}

13 Respostas

A

Paloma:

Seu código está errado, porque:

  • Aceita datas inválidas, como 30/02, por exemplo.
  • A verificação de ano bissexto está incorreta, deveria ser:
    if(a%4==0 && (a%100!=0 || a%400==0))

Abraço,

Armando

L

armando:
Paloma:
Seu código está errado, …deveria ser:
if(a%4==0 && (a%100!=0 || a%400==0))

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.

P

Então quer dizer que desta forma está incorreto?

if(a%4==0 && (a%100!=0 || a%400==0)) printf ("\nO ano %d e bissexto.\n", a);

L

Sendo preciosista, sim. Está errado.

Já que este ou “||” não invalida a condição quando ambas as partes da condição no OU forem verdadeiras, ou seja, quando um && se aplicar.

Este OU tem nome: é o “XOR”, mas não o temos em C e nem em Java como um operador condicional. Não confundir com o XOR para operações binárias “^”.

Em BASIC, existia o tal do XOR, escrito mais ou menos assim:

if (exp1 XOR exp2) then goto 100

Pensando… talvez fosse legal se existisse um correspondente usando o “^^”, mas fica horrível:

if (expr1 ^^ expr2) { ...}
L

Incrível ! Acabei de testar, e a Microsoft absorveu bem o BASIC no VB. O também VB tem o XOR, e funciona.

L

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.

R

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.

P

if (ANO%4==0 && (ANO%400==0 ||ANO%100!=0)) cout<<”Ano Bissexto”; else cout<<”Ano não é Bissexto”;

P

Oi pessoal, o programa agora tá rodando certinho, mas meu código tá muito feio, alguém tem uma idéia pra que fique mais legível?

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int d,m,a;
    
    printf ("\t\t\tCALENDARIO ANO BISSEXTO\n\n");

    do{
     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);
        
        if((d==30 || d==31) && (m==2))
          printf ("\nData Invalida, digite novamente.\n\n");
          
        }while((d==30 || d==31) && (m==2));
        
    if((d==30 || d==31) && (m==2))
    {
      printf ("Data Invalida.\n\n");
      return(0);
      }
           
    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);
}
R

Não use C :smiley:

P

Vc tá falando pra não usar a linguagem C? :roll:

P

Uma forma 'suja' seria deixar o C tentar converter a data

#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; 
}

Em C mais basico

#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; 
}
E

eu completei o codigo
[size=18][/size]
#include <stdio.h>
#include <stdlib.h>

int main()
{
  
  int dia , mes ,ano;
  int ultimo_dia[]= {-1,31,28,31,30,31,30,31,31,30,31,30,31};
  for (;;){
      printf("digite o dia---&gt;");
      scanf ("%d",&dia);
      system ("cls");
      printf("digite o mes---&gt;");
      scanf("%d",&mes);
      system ("cls");
      printf ("digite o ano---&gt;");
      scanf("%d",&ano);
      system("cls");
      if(dia&lt;=0 ||mes&lt;0||mes&gt;12||ano&lt;=0)
      {
         printf("data invalida\n");
         continue;
         system("pause");
      }
      if (ano%4==0&& (ano%400==0 ||ano%100!=0))
      ultimo_dia[2]= 29;
      else
      ultimo_dia[2]= 28;
      if(dia &gt;ultimo_dia[mes])
      {
      printf("data invalida\n");
                   continue;
      }
      if (ano%4==0 && (ano%400==0||ano%100!=0))
      {
      printf("ano bissexto\n\n");
      }
    printf("%d/%d/%d\n",dia,mes,ano);
  	
 break;     
} 
system("PAUSE");
 return 0;
}
Criado 12 de junho de 2006
Ultima resposta 16 de mai. de 2009
Respostas 13
Participantes 7