Jump to content

Recommended Posts

Posted (edited)

Bom, estou fazendo um programa em C que cadastra veículos utilizando a inserção por recursão em uma árvore binária. Quando vou cadastrar, insere o primeiro elemento, se eu tentar inserir o mesmo elemento outra vez, ele imprime uma mensagem dizendo que o veículo já foi cadastrado. Mas quando vou inserir um veículo com ID diferente, o programa dá pau e fecha. Não sei onde estou errando, por favor me ajudem. Segue abaixo o código temporário do meu programa:

#include <stdio.h>
typedef struct arvore{
   int id;
   char marca[50];
   char modelo[50];
   char cor[20];
   char proprietario[50];
   struct arvore *dir;
   struct arvore *esq;
}arvore;
arvore *aloca(arvore *novo){
   novo = (arvore*)calloc(1,sizeof(arvore));
   printf("Entre com a Identificacao do veiculo: ");
   scanf("%d", &(novo->id));
   printf("Digite a marca do veiculo: ");
   scanf("%s", &(novo->marca));
   printf("Digite o modelo do veiculo: ");
   scanf("%s", &(novo->modelo));
   printf("Digite a cor do veiculo: ");
   scanf("%s", &(novo->cor));
   printf("Digite o nome do proprietario do veiculo: ");
   scanf("%s", &(novo->proprietario));
   return novo;
}
void cadastrar(arvore **T, arvore *novo){
   if((*T) == NULL){
           novo->dir = NULL;
           novo->esq = NULL;
           (*T) = novo;
   }
   else{
           if(novo->id == (*T)->id){
               printf("\nVeiculo ja cadastrado!\n");
   }
   else if(novo->id < (*T)->id){
           cadastrar((*T)->esq, novo);
   }
   else{
           cadastrar((*T)->dir, novo);
   }
   }
   }


int main()
{
   int op;
   arvore *T = NULL;
   int id;
           printf("\n1 -Cadastrar novo veiculo: \n2 -Modificar dados de um veiculo \n3 -Buscar veiculo \n4 -Remover veiculo \n5 -Imprimir lista de veiculos\n6 -Imprimir arvore\n7 -Sair\n\n");
       scanf("%d",&op);
       while(op != 7)
   {
       if(op == 1){
           arvore *novo = aloca(novo);
           cadastrar(&T, novo);
       }
       if (op == 2){
           printf("\nDigite a identificacao do veiculo que deseja modificar:\n");
           scanf("%d",& id);
       }
       if (op == 3){
           printf("\nDigite a identificacao do veiculo que deseja buscar:\n");
           scanf("%d",& id);
         //  busca(T,id);
       }
       if (op == 4){
           printf("\nDigite a identificacao do veiculo que deseja remover:\n\n");
           scanf("%d",& id);
          // remover(&T,id);
       }
       if (op == 5){
           printf("\nLista dos veiculos: \n");
           printf("------------------------------------------------------------\n");
          // imprime(T);
       }
       if (op == 6){
           printf("\nArvore impressa: \n");
           printf("------------------------------------------------------------\n");
          // imprime_arvore(T);
       }
       printf("\n1 -Cadastrar novo veiculo: \n2 -Modificar dados de um veiculo \n3 -Buscar veiculo \n4 -Remover veiculo \n5 -Imprimir lista de veiculos\n6 -Imprimir arvore\n7 -Sair\n\n");
       scanf("%d",&op);
       }
   }

Edited by pmg
Falta LP no GeSHi
  • Vote 1
Posted (edited)

Liga o máximo de warnings do teu compilador, e não aceitas compilações com warnings.

void cadastrar(arvore **T, arvore *novo){
   /* ... */
   else if(novo->id < (*T)->id){
           cadastrar((*T)->esq, novo);
   /* ... */

Tu chamas a funcao cadastrar() recursivamente -- não há nada de mal nisso.

Na primeira chamada (de dentro da main) chamas com os tipos correctos, nas chamadas seguintes (as chamadas recursivas) os tipos não batem certo: a funcao pretende um ponteiro para um ponteiro para arvore (arvore **T) mas tu passas um ponteiro para arvore ((*T)->esq).

Os warnings devem-te avisar disso!

Edited by pmg

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!

Posted (edited)

Então o correto seria o seguinte?

void cadastrar(arvore **T, arvore *novo){
   /* ... */
   else if(novo->id < (*T)->id){
           cadastrar(&(T)->esq, novo);
   /* ... */
Edited by pmg
Falta LP no GeSHi
Posted

Nem por isso, não. Falta-te "desreferenciar" T:

cadastrar(&((*T)->esq), novo);

Mais uma coisa: para que é que serve o parametro da tua função aloca()? E o valor devolvido pela mesma função?

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!

Posted (edited)

Deu certo, muito obrigada!

Bom, usei o parâmetro da função aloca() para passar a variável 'novo' que chamo na main na hora de cadastrar, depois retorno o valor para a variável que a chamou, e assim passo o nó já alocado para a função cadastrar():

int main(){
/*...*/
if(op == 1){
           arvore *novo = aloca(novo);
           cadastrar(&T, novo);
       }
/*... */
Edited by brunoais
geshi
Posted

Entao e se chamasses a função com outra variavel qualquer (do tipo correcto)? fazia diferença?

arvore *novo;
arvore *velho;
arvore *outra;
novo = aloca(novo);
novo = aloca(velho);
novo = aloca(outra);

Não achas mais cómodo definir a função sem parametros e chamá-la sem argumentos?

arvore *aloca(void) {
   arvore *novo;
   /* ... */
   return novo;
}

arvore *novo;
novo = aloca();

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!

Posted (edited)

Verdade. Então na função aloca ficaria:

arvore *aloca(void) {
  arvore *novo = (arvore*)malloc(sizeof(arvore));
   /* ... */
   return novo;
}

Certo?

sim

na realidade não necessitas de fazer o cast do retorno do malloc, basta:

arvore * aloca(void)
{
  return memset(malloc(sizeof(arvore)), 0, sizeof(arvore));
}

ps : nota que não estou a fazer as verificações do resultado das chamadas das funções malloc e/ou memset que deverias fazer ...

Edited by HappyHippyHippo
IRC : sim, é algo que ainda existe >> #p@p
Posted

Correcto!

novo = aloca(novo);

Quando eu vi o novo a ser usado nos dois lados do =, fiquei logo alerta!

Depois ao ver a implementacao da funcao vi que eram coisas a mais: ou usas o valor de retorno (como eu sugeri) ou usas o parametro (*).

// (*) usando o parametro
void aloca(arvore **novo);

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!

  • 3 years later...
Posted
Em 03/14/2013 às 11:32, pmg disse:

Correcto!

 


novo = aloca(novo);
 

 

Quando eu vi o novo a ser usado nos dois lados do =, fiquei logo alerta!

Depois ao ver a implementacao da funcao vi que eram coisas a mais: ou usas o valor de retorno (como eu sugeri) ou usas o parametro (*).

 


// (*) usando o parametro
void aloca(arvore **novo);
 

Boa noite , você tem esse código completo? Rodando e imprimindo?

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
×
×
  • 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.