View Full Version : problema em C


frangadas
04-07-2006, 18:19
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:
#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

TuxBoss
04-07-2006, 21:16
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.

if ( ( (x%4)==0 ) && ( ( (x%100)!=0 ) || ( (x%400)==0) ) )
ano_bissexto = 1;
else
ano_bissexto = 0;

frangadas
04-07-2006, 21:57
boas, obrigadao pela resposta mas o problema persiste.
talvez n m tenha explicado convenientemente: no
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

Warrior
05-07-2006, 14:54
for (inicialização;condição;iteração/whatever)

no teu for

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.

andronikus
05-07-2006, 15:16
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.

frangadas
05-07-2006, 18:16
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
05-07-2006, 18:19
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

HecKel
05-07-2006, 19:18
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

andronikus
05-07-2006, 23:48
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:)

frangadas
06-07-2006, 01:51
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" :)

HecKel
06-07-2006, 02:06
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

for (i=3; i<=6; i +=2)

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

Este código iria imprimir o seguinte texto:
3
5

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

frangadas
06-07-2006, 02:43
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?

HecKel
06-07-2006, 12:52
Podes fazer com um while, ou em vez de == mete != :)

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, >=

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

abraços, HecKel

Tuaregue
06-07-2006, 18:42
E que tal um while em vez do for? Ai essa algoritmia!!

HecKel
06-07-2006, 19:03
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

Tuaregue
06-07-2006, 22:20
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.


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.

frangadas
11-07-2006, 20:59
Desculpem não ter dito nada mas tou a mudar de casa e fiquei sem net! Bem, obrigado pelas dicas!

frangadas
11-07-2006, 21:06
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??