problema em C

frangadas

Membro
olá, sou um novato em c e aprendo tudo pela net - tutoriais, foruns, ...
estou a fazer um exercício que é o seguinte:
Fazer um programa em que entrem: a data de nascimento e a data actual. O programa deve calcular o número de dias vividos pela pessoa.
Uso o lcc 4.0

A fonte .c:
Código:
#include <stdio.h> /*Comandos printf e scanf*/

int meses[13]={31,28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; /*Meses do ano comum*/
int ano_bissexto=0; /*Variável booleana*/
int nasc_ano, nasc_mes, nasc_dia; /*Vartáveis com a data de nascimento*/
int hoje_ano, hoje_mes, hoje_dia; /*Variáveis com a data currente*/
unsigned int total_c; /*Variável final da função total_ano_currente*/
unsigned long int total_total; /*Variável final da função resto_anos*/
int total_primeiro; /*Variável final da função primeiro_ano*/


/*Função booleana que testa se o ano é comum ou bissexto*/
int comumoubissexto (x) /*Recebe argumento x*/
{
    ano_bissexto = (((x%4)==0) && ((x%100)!=0) || ((x%400)==0)); /*Bissexto se divisível por 4 ou por 400 e não por 100!*/
    return (ano_bissexto); /*Retorna 1 ou 0*/
}


/*Função que interage com o utilizador*/
void io (void)
{
    printf ("\nInsira a data de nascimaento no formato dd/mm/aaaa: ");
    scanf ("%d/%d/%d", &nasc_ano, &nasc_mes, &nasc_ano); /*Recebe variáveis nasc*/
    printf ("\nInsira a data em que se encontra no formato dd/mm/aaaa: ");
    scanf ("%d/%d/%d", &hoje_ano, &hoje_mes, &hoje_dia); /*Recebe variáveis hoje*/
}


/*Funçao que conta o número de dias desde o ano currente até à ao próprio dia, não contando com este*/
int total_ano_currente (void)
{
    switch (hoje_mes)    /*Switch que conta o número de dias passados desde o mês corrente*/
    { /*Falta o comando break para que todos os meses anteriores sejam somados*/
        case 12: total_c += meses[10];                         //30     novembro
        case 11: total_c += meses[9];                         //31     outubro
        case 10: total_c += meses[8];                        //30     setembro
        case  9: total_c += meses[7];                        //31     agosto
        case  8: total_c += meses[6];                        //31     julho
        case  7: total_c += meses[5];                        //30     junho
        case  6: total_c += meses[4];                        //31     maio
        case  5: total_c += meses[3];                        //30     abril
        case  4: total_c += meses[2];                        //31     marco
        case  3: total_c += comumoubissexto(hoje_ano)?29:28;//28_29     fevereiro
        case  2: total_c += meses[0];                        //31     janeiro
    }
    total_c += hoje_dia-1; /*Adiciona os dias do mês corrente, retirando o dia currente (ainda não passaram 24h)*/
    return (total_c);
}


/*Função que conta o número de dias desde o 2.º ano da pessoa até ao ano anterior ao currente*/
int resto_anos (void)
{
    int ontem_ano=hoje_ano-1; /*Variável da função com o ano anterior ao corrente*/
    int variavel_ano=ontem_ano; /*Variável da função com o ano anterior ao corrente para o loop*/
    for (variavel_ano; variavel_ano==nasc_ano; variavel_ano--) /*Conta todos os anos anteriores ao currente*/
        {
        if (comumoubissexto(variavel_ano)) /*Testa se o ano que está a ser contado é ou não bissexto*/
            {
            meses[1]=29; /*Se sim conta 29*/
            total_total+=meses[0]+meses[1]+meses[2]+meses[3]+meses[4]+meses[5]+meses[6]+meses[7]+meses[8]+meses[9]+meses[10]+meses[11];
            }
        else
            {
            meses[1]=28; /*Se não conta 28*/
            total_total+=meses[0]+meses[1]+meses[2]+meses[3]+meses[4]+meses[5]+meses[6]+meses[7]+meses[8]+meses[9]+meses[10]+meses[11];
            }
        }
    return (total_total);
}


/*Função que conta o número de dias do primeiro ano*/
int primeiro_ano (void)
{
    switch (nasc_mes) /*Switch que conta o número de dias passados desde o dia de nascimento até ao próximo ano*/
    { /*Falta o comando break para que todos os meses seguintes sejam somados*/
        case  1: total_primeiro += comumoubissexto()?29:28;    //fevereiro
        case  2: total_primeiro += meses[2];                //março
        case  3: total_primeiro += meses[3];                //abril
        case  4: total_primeiro += meses[4];                //maio
        case  5: total_primeiro += meses[5];                //junho
        case  6: total_primeiro += meses[6];                //julho
        case  7: total_primeiro += meses[7];                //agosto
        case  8: total_primeiro += meses[8];                //setembro
        case  9: total_primeiro += meses[9];                //outubro
        case 10: total_primeiro += meses[10];                //novembro
        case 11: total_primeiro += meses[11];                //dezembro
    }
    total_primeiro += meses[nasc_mes-1]-nasc_dia+1; /*Adiciona os dias do mês em que nasceu, subtrai os dias que não viveu e soma o primeiro dia*/
    return (total_primeiro);
}


/*Função principal*/
void main (void)
{
    void io (void);
    int total_ano_currente (void);
    int resto_anos (void);
    int primeiro_ano (void);
    io (); /*Entrada de datas*/
    total_ano_currente (); /*Dias desde início do ano currente incluíndo o próprio dia*/
    resto_anos (); /*Dias desde 2.º ano até ano anterior ao currente*/
    primeiro_ano (); /*Dias desde do 1.º ano*/
    printf ("Viveu %lu dias, contando com o currente!", total_c+total_total+total_primeiro); /*FINALMENTE!*/
}

ao compilar:
57 statement has no effect
alguns missing prototypes da função comumoubissexto

ajudem-me por favor e desculpem postar um código tão extenso
 
Código:
ano_bissexto = (((x%4)==0) && (((x%100)!=0) || ((x%400)==0))); /*Bissexto se divisível por 4 ou por 400 e não por 100!*/
Talvez por isto não ser nada.
Código:
if ( ( (x%4)==0 ) && ( ( (x%100)!=0 ) || ( (x%400)==0) ) )
 ano_bissexto = 1;
else
 ano_bissexto = 0;
 
boas, obrigadao pela resposta mas o problema persiste.
talvez n m tenha explicado convenientemente: no
Código:
for (variavel_ano; variavel_ano==nasc_ano; variavel_ano--) 
        {
        if (comumoubissexto(variavel_ano)) /*Testa se o ano que está a ser contado é ou não bissexto*/
            {
            meses[1]=29; /*Se sim conta 29*/
            total_total+=meses[0]+meses[1]+meses[2]+meses[3]+meses[4]+meses[5]+meses[6]+meses[7]+meses[8]+meses[9]+meses[10]+meses[11];
            }
        else
            {
            meses[1]=28; /*Se não conta 28*/
            total_total+=meses[0]+meses[1]+meses[2]+meses[3]+meses[4]+meses[5]+meses[6]+meses[7]+meses[8]+meses[9]+meses[10]+meses[11];
            }
        }
    return (total_total);
}
o problema não é o if mas sim o for (statement has not effect). a função comumoubissexto funciona mas concordo que fique muito melhor como sugerido. Não percebo o que se passa com o programa. Ele executa mas dá resultados que não estão correctos
 
Código:
for (inicialização;condição;iteração/whatever)

no teu for

Código:
for (variavel_ano; variavel_ano==nasc_ano; variavel_ano--)

a inicialização não está correcta. variável_ano é iniciada a que valor?

correctamente, deveria ser

for (variavel_ano=ontem_ano; variavel_ano==nasc_ano; variavel_ano--) (e podes remover na declaração o "=ontem_ano")

ou

for (; variavel_ano==nasc_ano; variavel_ano--)


Vê se o erro desaparece assim.
 
Se ainda não conseguis te experimenta em vez de colocares a igualdade '==' no segundo argumento do for, coloca uma desigualdade, ie, <= ou >=, conforme a solução do teu codigo.
 
p/warrior: sim, o erro fica resolvido! nunca me iria lembrar disso! obrigado
p/andronikus: nao percebi como é que faço isso, gostava que exemplificasses, bgd
 
frangadas disse:
p/warrior: sim, o erro fica resolvido! nunca me iria lembrar disso! obrigado
p/andronikus: nao percebi como é que faço isso, gostava que exemplificasses, bgd
desculpem mas afinal o erro fica resolvido mas o resultado é errado. Eu hoj n vou tr tempo p/ confirmar td max amanha digo s encontrei algma razao para isso
 
Desculpem lá..., mas até a mim o for está a fazer confusão...

for(INICIALIZAÇÃO; VALIDAÇÃO ; INCREMENTAÇÃO)

certo?

Neste caso a Validação é que o for é executado SEMPRE que variavel_ano==nasc_ano

certo?

Então se a incrementação (neste caso decrementação) altera o valor de variavel_ano, este for fica sem qualquer sentido..., pois essa condição só será verdadeira uma vez (se for) e só essa vez será executada...., se aquela comparação for falsa à partida o for nunca é executado...

Vi o código assim por algo, mas de facto isso pareceu-me bastante estranho...

abraços, HecKel
 
Ainda não sei se voltas te a rever o codigo.... eu dei uma olhadela muito por alto e logo no inicio da função main()

printf ("\nInsira a data de nascimaento no formato dd/mm/aaaa: ");
scanf ("%d/%d/%d", &nasc_ano, &nasc_mes, &nasc_ano); /*Recebe variáveis nasc*/
printf ("\nInsira a data em que se encontra no formato dd/mm/aaaa: ");
scanf ("%d/%d/%d", &hoje_ano, &hoje_mes, &hoje_dia); /*Recebe variáveis hoje*/

no primeiro scanf() tas a colocar o resultado na mesma variavel (o dia e o ano)
no segundo scanf() não tens as variaveis assinaladas trocadas(isto claro se estivers a fazer a leitura dd/mm/aaaa como tens no printf())

cumps:)
 
obrigado. sim, a função io nos scanfs tava trocada.
em relação ao for o que eu queria fazer com ele seria:
enquanto a variavel_ano não for igual ao ano de nascimento executa o if-else (que estão dentro do for para contar todos os anos entre o 2.º e o penúltimo). penso que não devo ter percebido o comando for porque estou a aprender c há pouco tempo (4dias).

P.S.-não sei nenhuma linguagem bem mas tenciono apostar no c. Comecei a aprender com qbasic. Depois exprimentei pascal mas nao m dei bem. Depois python e agora c. Estou a "simpatizar com ele" :)
 
Boas!

Sobre o for tens 3 partes, o iniciador, o terminador e o incrementador (nomes inventados à pressão mas que servem perfeitamente para perceber para que serve), o iniciador serve para indicar qual o ponto de "arranque" do for, por exemplo i=3, o terminador indica até quando o for é executado, por exemplo se queres que seja executado até i ser igual a 6 fazes i <= 6, o incrementador diz qual o "passo" do for, por exemplo i +=2

Código:
for (i=3; i<=6; i +=2)

printf("%d\n",i);

Este código iria imprimir o seguinte texto:

Não chegaria a imprimir o 7 pois este já é maior que 6 :) Espero que dê para perceber o exemplo e que não te tenha baralhado ainda mais... :(

abraços, HecKel
 
Código:
    int ontem_ano=hoje_ano-1;
    int variavel_ano=ontem_ano; 
    for (; variavel_ano==nasc_ano; variavel_ano--)
...

isto é: enquanto a variavel_ano não for igual ao ano de nascimento executa as chavetas (...)???
se não é como é que faço isto?
 
Podes fazer com um while, ou em vez de == mete != :)

Código:
for(; variavel_ano != nasc_ano ; variavel_ano--)

Assim este for é executado até que variavel_ano seja igual a nasc_ano. Atenção que variavel_ano TEM DE SER maior que nasc_ano, senão este for nunca termina..., aliás..., termina por overflow :)

Podes também usar uma forma menos confusa, >=

Código:
for(; variavel_ano >= nasc_ano ; variavel_ano--)

abraços, HecKel
 
Ele está a aprender :) Pode ainda não ter chegado a esse ponto, daí apenas eu ter referido o while e nem o ter explicado :)

abraços, HecKel
 
HecKel disse:
Ele está a aprender :) Pode ainda não ter chegado a esse ponto,
mas se ele está a aprender e se nos pediu ajuda, cabe a nós indicar-lhe o melhor caminho que ele tem de tomar.

HecKel disse:
daí apenas eu ter referido o while e nem o ter explicado :)

abraços, HecKel

Tb eu, mas não lhe podemos dar a papinha toda, temos de lhe aguçar o engenho.
 
queria saber 1a csa:
quando eu aprendi 1 bocado d cada linguagem eu nunca encontrei nada gráfico. aprendia os codigos como este (+simples) mas faltou-me o incentivo das janelas, gráficos,... podiam recomendar-m qualquer coisa que abordasse isto? por ex: 1 tutorial +facil e outro para quando tiver + experiencia.
eu sou 1 newbie nisto e por isso gostava de saber se com c posso fazer o que se faz com c++ e se vale a pena aprender c++. quais as vantagens em relação ao c??
 
Back
Topo