Jump to content
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Sign in to follow this  
fo_11

Problema com apontadores

Recommended Posts

fo_11

O objectivo deste programa é inserir numeros inteiros e quando inserir zero deixo de poder inserir. Depois o programa procura a maior sequencia de inteiros positivos e diz quantos são e qual é a respectiva sequencia.

Problema é não conseguir mostrar a respectiva sequencia  o que reparei é que a informacao contida na funcao que ve qual é a sequencia maior não passa a informacao para a main, isto é seqmaior não passa a sua informacao para a main mesmo sendo um apontador.

edit:

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

int SeqMaior(int*,int,int*);

int main()
{
    int *num=NULL,contador=0,aux,*seqmaior=NULL,i,maior;
    
    do//Inserir numeros inteiros até inserir o zero
     {printf("Inserir numero:");
       scanf("%d",&aux);
       num=(int*)realloc(num,++contador*sizeof(int));
       num[contador-1]=aux;
     }while(aux!=0);
     
     printf("\nA sequencia maior tem %d elementos\n",(maior=SeqMaior(num,contador,seqmaior)));
     printf("Sequencia maior:");
     for(i=0;i<maior+1;i++)
      printf(" %d",seqmaior[i]);
     printf("\n");
     
     free(seqmaior);
     free(num);
     system("pause");
}


int SeqMaior(int *num,int dim,int *seqmaior)
{
     int contador=0,maior=0,i,j;
     seqmaior=(int*)realloc(seqmaior,sizeof(int));//em caso de ser introduzie logo o zero o programa não deixar de funcionar
     seqmaior[0]=0;
     
     for(i=0;i<dim;i++)
      {if(num[i]>0)
        ++contador;//conta o numero de elementos da sequencia
        
         
        
       else if(num[i]<=0 && maior<contador)//quando encontro um numero negativo tenh de reniciar a contagem mas antes de tudo tenho de guardar os elementos da sequencia
        {maior=contador; //se a sequencia anterior tiver menos elementos que a actual guardar o tamanho da nova sequencia
         seqmaior=(int*)realloc(seqmaior,maior*sizeof(int));
      
         for(j=0;j<maior;j++)//guardar os elementos da nova sequencia
          seqmaior[j]=num[j];
         contador=0;
        }
      
      }
      return maior;
}
      

Share this post


Link to post
Share on other sites
fo_11

não percebi o que queres dizer com isso...

no seqmaior, ele é que não fica com os valores adquiridos na função abaixo...

Share this post


Link to post
Share on other sites
fo_11

agora fiquei mesmo confuso... Eu sei que é possivel fazer isso mas só não sei como trabalhar com eles...

será isto?

int SeqMaior(int *num,int dim,int *seqmaior)
{
     int **pts=&seqmaior;
     int contador=0,maior=0,i,j;
     pts=(int**)realloc(pts,sizeof(int));//em caso de ser introduzie logo o zero o programa não deixar de funcionar
     *pts[0]=0;
     
     for(i=0;i<dim;i++)
      {if(num[i]>0)
        ++contador;//conta o numero de elementos da sequencia
        
         
        
       else if(num[i]<=0 && maior<contador)//quando encontro um numero negativo tenh de reniciar a contagem mas antes de tudo tenho de guardar os elementos da sequencia
        {maior=contador; //se a sequencia anterior tiver menos elementos que a actual guardar o tamanho da nova sequencia
         pts=(int**)realloc(pts,maior*sizeof(int));
      
         for(j=0;j<maior;j++)//guardar os elementos da nova sequencia
          *pts[j]=num[j];
         contador=0;
        }
      
      }
      return maior;
}
      

Share this post


Link to post
Share on other sites
Localhost

Sim. Acho que é isso.

Tu tens de usar ponteiros para ponteiros porque estás a passar um array (nome do array é um ponteiro) logo já tens um ponteiro. Depois ainda estás a trabalhar com memória dinâmica, ou seja, é mais um ponteiro.


here since 2009

Share this post


Link to post
Share on other sites
fo_11

não há uma maneira mais simples de elaborar este programa?

ps:agora já não corre o programa

Share this post


Link to post
Share on other sites
Localhost

Há. Nem sei para quê que estás a utilizar memória dinâmica.

Vou tentar resumir:

→ Cria uma função para o input.

→ Cria uma função que procura pela maior sequência.

→ Cria uma função para o output.

Para a função que cria a maior sequência fazes um loop principal que vai percorrer o array.

Depois um loop secundário que começa na posição em que está o loop principal e percorres até o array acabar ou até ser encontrado um número que é menor do que 0. Neste loop aumentas uma variável auxiliar.

Depois verificas se a variável auxiliar é maior do que a anterior. Se for, guardas a posição inicial e a final da sequência se não for continuas.


here since 2009

Share this post


Link to post
Share on other sites
fo_11

Estou a perceber o que estás a dizer...

Mal recebo informacao comparar logo se a sequencia é maior ou não que a anterior se sim fico com eu vector senão substitu-o.

O problema é que neste programa à uma nota, imposta pelo professor, que não mencionei é que temos de trabalhar com memoria dimanica pra nos preparar para  um trabalho que vamos fazer...

Isto é, ele disse que temos de receber todos os valores num array e depois ver qual qual é o numero de elementos da sequencia maior e qual é essa sequencia. O problema está é que não posso returnar dois valores  :thumbsup:

Share this post


Link to post
Share on other sites
Localhost

Não estava a dizer isso. Tens de fazer as coisas por passos. Ou seja, primeiro recebes a informação, só depois é que trabalhas com ela.

Tens de usar memória dinâmica em algum lugar especifico do código ou é só mesmo onde quiseres?


here since 2009

Share this post


Link to post
Share on other sites
fo_11

Mas não estou a fazer isso?

Primeiro recebo todos os valores possiveis para o *num e depois envio para uma funcão que vais ver qual é a maior e envio tambem um vector que a vai conter. Visto que não sei o tamanho dele faço *v=NULL e na função uso o realloque para aumenta o seu tamanho até onde for necessessário.

ps:é onde quiser...

Share this post


Link to post
Share on other sites
Localhost

Então, declara um ponteiro global que vai contêr o endereço do primeiro elemento de um array criado dinamicamente.

Depois recebes os valores para esse array.

A partir daqui tens de trabalhar com ponteiros e com aritmética de ponteiros. Ou seja, na função que vai determinar a sequência tens de ter um ponteiro que vai percorrer todo o array (não é preciso declarar como ponteiro para ponteiro, só mesmo como um ponteiro simples). Depois no loop secundário tens de ter outro ponteiro que verifica o que já tinha dito. Tens de ter a variável auxiliar, como já tinha dito, uma variável simples, um int.

Depois verificas aquilo que te disse e se quiseres trabalhas com ponteiros para "dar" a outra função o inicio e o fim da sequência, se não declaras duas variáveis globais e tens o trabalho feito.


here since 2009

Share this post


Link to post
Share on other sites
fo_11

Não sei bem se era isto que querias dizer.

Ele funciona quase bem, isto é se fizer uma sequenca de numeros não há problema se for for muito grande já não funciona

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

int SeqMaior(int*,int);
int *seqmaior=NULL;

int main()
{
    int *num=NULL,contador=0,aux,i,maior;
    
    do//Inserir numeros inteiros até inserir o zero
     {printf("Inserir numero:");
       scanf("%d",&aux);
       num=(int*)realloc(num,++contador*sizeof(int));
       num[contador-1]=aux;
     }while(aux!=0);
     
     printf("\nA sequencia maior tem %d elementos\n",(maior=SeqMaior(num,contador)));
     printf("Sequencia maior:");
     for(i=0;i<maior;i++)
      printf(" %d",seqmaior[i]);
     printf("\n");
     
     free(seqmaior);
     free(num);
     system("pause");
}


int SeqMaior(int *num,int dim)
{
     int contador=0,maior=0,i,j,k;
     seqmaior=(int*)realloc(seqmaior,sizeof(int));//em caso de ser introduzie logo o zero o programa não deixar de funcionar
     seqmaior[0]=0;
     
     for(i=0;i<dim;i++)
      {if(num[i]>0)
        ++contador;//conta o numero de elementos da sequencia
        
         
        
       else if(num[i]<=0 && maior<contador)//quando encontro um numero negativo tenh de reniciar a contagem mas antes de tudo tenho de guardar os elementos da sequencia
        {maior=contador; //se a sequencia anterior tiver menos elementos que a actual guardar o tamanho da nova sequencia
         seqmaior=(int*)realloc(seqmaior,maior*sizeof(int));
      
         for(k=0,j=(i-maior);j<=i;j++,k++)//guardar os elementos da nova sequencia
          seqmaior[k]=num[j];
         contador=0;
        }
      
      }
      return maior;
}
    

Share this post


Link to post
Share on other sites
fo_11

Consegui arranjar um outro programa embora seja um pouco difernte o objectivo é o mesmo.

Mas não percebo como ou porque razao ele retorna o vector.

Pessoa* recebeInformacao(int *tot){
Pessoa *v=NULL, x;
*tot=0;
while(1){
printf(“BI?\n”); scanf(“%d”,&x.bi);
if (x.bi<=0)
break;
printf(“Idade?\n”); scanf(“%d”,&x.idade);
printf(“Nome?\n”); gets(x.nome);
printf(“Salário?\n”); scanf(“%f”,&x.salario);
printf(“Sexo?\n”); scanf(“%c”,&x.sexo);
v=(Pessoa*)realloc(v,++(*tot)*sizeof(Pessoa));
v[*tot-1].bi=x.bi;
v[*tot-1].salario=x.salario;
v[*tot-1].idade=x.idade;
v[*tot-1].sexo=x.sexo;
strcpy(v[*tot-1].bi,x.bi);
}
return(v);
}

Share this post


Link to post
Share on other sites
Localhost

Não era isso que eu estava a dizer.

Acho que vais ter de recomeçar tudo de novo.

Tu não precisas de nenhum array para guardar a sequência. Só precisas dos valores inicial e final e depois percorrer o array desde aí.

Imagina que tens duas variáveis: ini e fin. Estas vão conter a pos. inicial e final da sequência com mais elementos, respectivamente.

Tu lês toda a informação e guardas num array alocado dinamicamente. Aqui é melhor colocares o array como variável global para te facilitar a tarefa.

Depois tens outra função que vai percorrendo o array e que vai aumentando uma variável até que encontre um elemento menor do que 0 ou o fim do array. Quando encontra um destes dois verifica se é maior que a variável "oficial" que vai contêr o número de elementos no final. Se for maior então actualizas a variável ini para o inicio da sequência e a fin para o fim da mesma. Repetes isto até percorreres o array todo no loop principal.

Não precisas de andar a fazer alocações extra na função SeqMaior. Só tens de fazer alocações quando estás a receber os dados. Depois disto é só implementar o que eu disse.


here since 2009

Share this post


Link to post
Share on other sites
Localhost

Se precisares de códigos exemplo avisa.

Depois no final eu vou-te dar uma dica que acho que resulta neste caso para tornares o teu programa mais rápido. É um extra xD


here since 2009

Share this post


Link to post
Share on other sites
fo_11

Já consegui elaborar o programa...  :) Está muito mais simples do que estava a pensar inicialmente.

Obrigadão pela ajuda

Aqui está o programa:

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

int SeqMaior(int*,int,int*);

int main()
{
    int *num=NULL,contador=0,aux,maior,*ptr=&maior,pos_maior,i;
    
    do//Inserir numeros inteiros até inserir o zero
     {printf("Inserir numero:");
       scanf("%d",&aux);
       num=(int*)realloc(num,++contador*sizeof(int));
       num[contador-1]=aux;
     }while(aux!=0);
     
     pos_maior=SeqMaior(num,contador,ptr);
     
     printf("\nA sequencia maior tem %d elementos\n",maior);
     printf("Sequencia maior:");
     
     for(i=(pos_maior-maior);i<pos_maior;i++)
      printf(" %d",num[i]);
     
     printf("\n");
     free(num);
     system("pause");
}


int SeqMaior(int *num,int dim,int *ptr)
{
      int i,aux=0,pos=0,contador=0;
      *ptr=0;
      
      for(i=0;i<dim;i++)
       {if(num[i]>0)
          contador++;
          
        else if(contador>*ptr)
         {*ptr=contador;
          pos=(i);
          contador=0;
         }
       }
       
       return pos;
}

Ps:Já agora qual é a dica para tornar o programa mais rápido :)

Share this post


Link to post
Share on other sites
Localhost

Acho que um Knuth Morris Pratt aqui é bom. Pesquisa sobre isso, não tenho muito tempo para explicar.


here since 2009

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  

×

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.