Jump to content
Sign in to follow this  
DoutorDiamantino

Soma de elementos de um array

Recommended Posts

DoutorDiamantino

int diaMes1[ 12 ] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}

  if (mesAct1 > 2){

    contador = 0;

while (contador < mesAct1 - 1){

  dias2 = dias2 + diaMes1[ contador ];

  contador++;}

Tenho todas as variáveis declaradinhas e tudo o mais, não há erro de compilação (só tenho avisos de que não estou a verificar se o scanf teve sucesso ou algo do género (num compilador online), não sei bem o que é suposto isso significar).

Como raio é que aquela soma de elementos de array me vai dar coisas como 67000?

mesAct vai de 1 a 12, portanto não estou a procuarar o elemento de indíce 400 nem nada.

 

Share this post


Link to post
Share on other sites
pmg

Falta-te a inicialização de dias2?

int dias2 = 0;


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
KTachyon

Para além de faltar código, o que é que pretendes fazer ao certo?

Pelo que estou a ver, e assumindo que mesAct1 vai de 1 a 12, como dizes, estás a somar várias vezes o números de dias de cada mês.


“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.”

-- Tony Hoare

Share this post


Link to post
Share on other sites
DoutorDiamantino



#include <stdio.h>
#include <math.h>


int numdias( int diaNas1, int mesNas1, int anoNas1, int mesAct1, int anoAct1 );

int menu(void);








/*inicio da funcao menu*/
int main(void)

{
  int reposicao = 0; /* variavel que controla a reposicao de valores*/

  while ( reposicao == 1 || reposicao == 0 ) {
  int diaNas; 
  int mesNas;
  int anoNas; /*dados do utilizador*/
  int mesAct; 
  int anoAct; /*dados do mes*/

  reposicao = 0; /*para reiniciar o ciclo do menu*/



  /*Introducao da data de nascimento e do calendario*/
  printf("Bem vindo ao calculador de biorritmos\n Introduza a data de nascimento\n:"); 
  scanf("%d%d%d", &diaNas, &mesNas, &anoNas);
  printf("Introduza o mes e ano a analisar:\n");
  scanf("%d%d", &mesAct, &anoAct);
  
  int escolha = 1; /*variavel que sera a opcao do menu*/
  while (escolha > 0 && escolha < 9 && reposicao == 0){


    escolha = menu(); 


/*-----menu imprime agora-----*/




    /*execucao da opcao 0 - terminar*/
    if (escolha < 1 || escolha > 8){ /*Termina o ciclo do menu*/
      printf("Terminou a execucao!");
      reposicao = -1; }/*Para terminar o primeiro ciclo*/
    
    


    /*execucao da opcao 8 - novos dados*/
    if (escolha == 8)
      reposicao = 1; /*Termina o ciclo que imprime o menu mas nao o primeiro menu*/
    



    /*execucao da opcao1 - diferenca de dias*/

    if (escolha == 1) 
      printf("%d\n", numdias( diaNas, mesNas, anoNas, mesAct, anoAct ));
      
      }} return 0;}









    /*-------funcao para calcular a opcao 1--------*/
int numdias ( int diaNas1, int mesNas1, int anoNas1, int mesAct1, int anoAct1 ) {
  
  /* calculo para os dias nos anos entre mas nao incluindo o ano de nascimento e de
     execucao (como se fossem nao bissextos)*/
  int dias1 = (anoAct1 - anoNas1) * 365;
  
  
  /*calculo dos anos bissextos e dias extra*/
  int contador = anoNas1 + 1;
  int bissexto = 0; /*soma o numero de anos bissextos entre os anos (e dias extra)*/
  int dias2 = 0;
  int dias3 = 0; /* ferramentas*/
  
  while (contador < anoAct1)
    if ((contador%100 != 0 && contador%4 == 0) || contador%400 == 0) {
      bissexto++;
      contador++;}/*incremento do contador*/
  
  
  
  /*calculo dos dias no ano actual*/
  int diaMes1[ 12 ] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; /*array com os dias de 
								  cada mes para ano normal*/
  if (anoAct1 != anoNas1){ /* anos desiguais*/

/*calculo dos dias no ano actual*/
  dias2 = 0; /*dias vividos no ano actual*/
  contador = 0;
      
  
  if (mesAct1 == 2) /*uma situacao onde nao ha poss. de dias extra*/
    dias2 = 31;
  
  if (mesAct1 > 2){ /*depois de fevereiro*/
    contador = 0;
while (contador < mesAct1 - 1){
  dias2 = dias2 + diaMes1[ contador ];
  contador++;}
  
if ((anoAct1 % 100 != 0 && anoAct1 % 4 == 0) || anoAct1 % 400 == 0) /* calculo para ver se apanha dias extra*/
  dias2++;} /*incremento do dia extra se bissexto*/
  
  
  
  
/*calculo dos dias vividos no ano de nascimento*/
  dias3 = 0; 
  contador = mesNas1 - 1;
  
  if (mesNas1 > 2){ /*sem dias extra*/
    while( contador < 12){
      dias3 = dias3 + diaMes1[ contador ]; /*dias vividos no primeiro ano, (com o mes de nasc.inteiro)*/
      contador++;}
    dias3 = dias3 - diaNas1;} /* dias vividos */

  else {
    while( contador < 12){
      dias3 = dias3 + diaMes1[ contador ];
    contador++;} /*dias vividos no primeiro ano com o mes de nasc.*/
    dias3 = dias3 + diaMes1[ mesNas1 - 1 ] - diaNas1; /* dias vividos no ano de nasc.*/


  if((anoNas1 % 100 != 0 && anoAct1 % 4 == 0) || anoNas1 % 400 == 0)
    dias3++;}/*incremento do bissexto*/

  }

  else { /* anos iguais*/
    dias2 = 0;
    dias3 = 0;
    contador = mesNas1 - 1;

    while (contador < (mesAct1 - 1)){
        dias2 = dias2 + diaMes1[contador];
contador++;}
      dias2 = dias2 - diaNas1;}



  
  
  int dias = dias1 + dias2 + dias3 + bissexto;
  
  return dias;}







      

/*----funcao de impressao do menu----*/

int menu(void){
  
  int opcao;
  
  printf ("1 _ Numero de dias decorridos desde a data de nascimento \n");
  printf ("2 _ Tabela de biorritmos para o mes \n");
  printf ("3 _ Dias positivos no mes \n");
  printf ("4 _ Dias maximos no mes \n");
  printf ("5 _ Dias nulos no mes \n");
  printf ("6 _ Dias negativos no mes \n");
  printf ("7 _ Grafico das classificacoes dos dias no mes \n");
  printf ("8 _ Introduzir novos dados \n");
  printf ("0 _ Terminar \n");
  
  
  /*escolha de opcao*/
  printf("Opcao:");
  scanf("%d", &opcao);

  return opcao;}

Este é o código da minah funçõa /vocês têm algumas tags para código, para isto não ficar assim tão mal amanhado?

De qualquer maneira, é suposto calcular o nº de dias entre uma data de nascimento e o primeiro dia de um mês de um an o arbitrário.

O dias1 seria o nº de dias entre (não incluindo) os dois anos com osendo bissextos. O bissextos é o número de bissextos nesse mesmo intervalo.

O dias2 é o número de dias vividos já no ano da execução, uma soma de elementos de array do i1 mes ao mes anterior a do de execução

O dias3 é o nº de dias vividos no an ode nascimento. Soma de array de início do mes de nascimento até ao fi mde ano - dia de nascimento.

Se os anos forem os mesmos, é só uma soma de arrays do mes de nascimento ao mes antes do da execução - o dia de nascimento.

SOma-se tudo e devia dar o nº de dias, mas está-me a dar resultados estranhíssimos.

Share this post


Link to post
Share on other sites
KTachyon

[ code=c] e [/ code] sem os espaços.


“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.”

-- Tony Hoare

Share this post


Link to post
Share on other sites
DoutorDiamantino

Obrigado, acabei por meter aqui o programa todo, não vá ser um problema fora da tal função.

Share this post


Link to post
Share on other sites
pmg

    /*-------funcao para calcular a opcao 1--------*/
int numdias ( int diaNas1, int mesNas1, int anoNas1, int mesAct1, int anoAct1 ) {
  
  /* calculo para os dias nos anos entre mas nao incluindo o ano de nascimento e de
     execucao (como se fossem nao bissextos)*/
  int dias1 = (anoAct1 - anoNas1) * 365;
  
  
  /*calculo dos anos bissextos e dias extra*/
  int contador = anoNas1 + 1;
  int bissexto = 0; /*soma o numero de anos bissextos entre os anos (e dias extra)*/
  int dias2 = 0;
  int dias3 = 0; /* ferramentas*/
  
  while (contador < anoAct1)
    if ((contador%100 != 0 && contador%4 == 0) || contador%400 == 0) {
      bissexto++;
      contador++;}/*incremento do contador*/
  
  
  
  /*calculo dos dias no ano actual*/
...

Não estive a olhar com atenção para o código, mas este ciclo while não me parece correcto (nem sei se tem influência no resultado que estás a ver ...)


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
KTachyon

Só para ter a certeza, o que queres é calcular o número de dias entre duas datas? Se a resposta é sim, acho que estás a complicar demasiado o processo.

O código podia estar um pouco mais organizado. Não dá grande vontade de ler, quanto mais de entender. De qualquer forma, a primeira coisa que encontrei que está mal:

while (contador < anoAct1)
    if ((contador%100 != 0 && contador%4 == 0) || contador%400 == 0) {
        bissexto++;
        contador++; /*incremento do contador*/
    }

Aqui ficas preso num loop infinito...

Corrigindo isso e executando, o resultado parece-me bem.

EDIT: Está a adicionar um ano a mais.


“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.”

-- Tony Hoare

Share this post


Link to post
Share on other sites
DoutorDiamantino

Tenda em conta isso, agredeço-vos especialmente, então.

Tem razão, o contador++ estava fora do while.

Mas mesmo assim, quando teste 1/1/2000 e 1/2001 para nascimento e data actual, dá-me 700 dias. E quando experimento 1//1/2000 e  6/2004 não me dá resposta sequer, nem me permite escrever mais na janela.

E onde é que estou a adicionar um ano a mais?

Share this post


Link to post
Share on other sites
KTachyon

O contador tem que estar dentro do while, fora do if.

De 1/1/2000 até 1/2001 nunca deveria dar 700 dias, daí que eu tenha dito que está a adicionar um ano a mais. Mas, aquilo que eu acho é que estás a complicar demasiado o código para um problema que não é assim tão complexo.


“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.”

-- Tony Hoare

Share this post


Link to post
Share on other sites
DoutorDiamantino

Sinceramente, não vejo maneira de simplificar mais.

E de qualquer maneira, confesso que isto já me é difícil de deitar fora, já ando há uns dias a tentar perceber porque é que não funciona.

Share this post


Link to post
Share on other sites
KTachyon

Estás a adicionar os dias do ano de nascimento completo.

int numdias ( int diaNas1, int mesNas1, int anoNas1, int mesAct1, int anoAct1 ) {
int diaMes1[ 12 ] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

int i, dias = 0;

// dias nos anos intermédios:
for (i = anoNas1 + 1; i < anoAct1; i++) {
	dias += 365 + is_bissexto(i);
}

if (anoAct1 > anoNas1) {
	// dias após o início do ano actual:
	for (i = 0; i < mesAct1-1; i++) {
		dias += diaMes1[i];
		if (i == 1) // fevereiro
			dias += is_bissexto(anoAct1);
	}

	// dias do ano de nascimento:
	dias += diaMes1[mesNas1-1] - diaNas1; 

	for (i = mesNas1; i < 12; i++) {
		dias += diaMes1[i];
		if (i == 1) // fevereiro
			dias += is_bissexto(anoAct1);
	}
}

return dias;
}

int is_bissexto(int ano) {
int b = 0;

if ((ano % 100 != 0 && ano % 4 == 0) || ano % 400 == 0) b = 1;

return b;
}


“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.”

-- Tony Hoare

Share this post


Link to post
Share on other sites
DoutorDiamantino

Estou? Em que parte do código?

Eu agrodeço o seu tempo e esforço mas o programa é parte de uma avaliação. Eu não posso simplesmente usar o seu código.

Share this post


Link to post
Share on other sites
KTachyon

int dias1 = (anoAct1 - anoNas1) * 365;

Aqui.

O código que coloquei foi só uma forma de reformular o teu código de modo a que ficasse mais simples/legível. Separar código em funções ajuda a resolver problemas. Tal como colocar prints no meio do código e/ou utilizar um debugger.


“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.”

-- Tony Hoare

Share this post


Link to post
Share on other sites
DoutorDiamantino

Mas a - b não me dá todos os saltos entre inteiros de a até b? Um ano menos o outro não me daria todos os anos completos entre eles? todos os períodos de 365 dias?

Share this post


Link to post
Share on other sites
KTachyon

Dá-te um ano a mais. Repara:

Nascido 2000

2001

2002

2003

Actual 2004

Os anos intermédios são só 3, mas 2004-2000 = 4.


“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.”

-- Tony Hoare

Share this post


Link to post
Share on other sites
DoutorDiamantino

Tens razão. Mas isso não resolve tudo. Se eu usar 1/1/2004 e 2/2004, dá-me -365, era porque se os anos fossem iguais, a soam ficava negativa, já resolvi.

Mas se usar 1/1/2000 e 6/2005, o programa encrava.

Share this post


Link to post
Share on other sites
KTachyon

Não obrigatóriamente. Podes fazer uma simples verificação.

Mas se os anos forem iguais, só tens que  fazer qualquer coisa parecida com o que fazes para os outros casos.

Aconselho-te a separares esse teu método em várias funções mais simples. Vais ver que se torna mais fácil de resolver os teus problemas.


“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.”

-- Tony Hoare

Share this post


Link to post
Share on other sites
HappyHippyHippo

Podes (e deves) continuar a ver qual o erro no teu código para assim aprenderes mais rapidamente a programar.

No entanto este código deverá resolver-te o problema :

#include <time.h>

int numdias ( int diaNas1, int mesNas1, int anoNas1, int mesAct1, int anoAct1 ) {
  struct tm tm_aux;
  time_t nas, act;

  // calcular o numero de segundos passados desde 1900 ate ao dia de nascimento
  memset(&tm_aux, 0, sizeof struct tm);
  tm_aux.tm_mday = diaNas1;
  tm_aux.tm_mon = mesNas1;
  tm_aux.tm_year = anoNas1;
  nas = mktime(&tm_aux);

  // calcular o numero de segundos passados desde 1900 ate ao mes/ano a calcular
  memset(&tm_aux, 0, sizeof struct tm);
  tm_aux.tm_mday = 1;
  tm_aux.tm_mon = mesAct1;
  tm_aux.tm_year = anoAct1;
  act = mktime(&tm_aux);

  // retornar o numero de dias passados
  // : diferenca entre segundos a dividir pela quantidade de segundos por dia
  return ((act - nas) / (60*60*24));
}


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
KTachyon

O problema desse código é que não funciona para datas anteriores a 1970.


“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.”

-- Tony Hoare

Share this post


Link to post
Share on other sites
Flinger

Por acaso até funciona :cheesygrin:

Percebi a tua lógica e fiz um teste rápido, atribui a uma tm a data de 1960, converti num time_t e mandei imprimir a data (ctime). Thu Dec 31 00:00:00 1959 (provavelmente porque estava no dia 0, e não 1).

O time_t tem o valor 0xed2eb700, usando a calculadora do windows para conversão, -315 705 600. Ou seja, o time_t pode ser negativo, sendo estes valores usados para datas anteriores à base (1/1/1970)

Share this post


Link to post
Share on other sites
DoutorDiamantino

meti printfs em tudo o que era dias e vi que oe ero estava no contador de bissextos, o contador++ estava dentro do if e eu pensava que estava fora.

Muito obrigado.

Share this post


Link to post
Share on other sites
KTachyon

Pensava que já tinhas tratado disso. Se vires alguns posts atrás, vais reparar que já tinhamos indicado esse erro.


“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.”

-- Tony Hoare

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.