ERRO DE COMPILAÇÃO

1. ERRO DE COMPILAÇÃO

Wendel Rios
wendelrios

(usa Ubuntu)

Enviado em 09/10/2016 - 12:21h

to estudando p EStrutura de Dados , ai peguei um código e joguei no compilador , mas tá dando erro e eu to tentando entender o código na verdade

#include<iostream>
#include<cstdlib>

using namespace std;


typedef struct lista{
int elemento ;
struct lista *prox;
}celula;

void insereh(celula **topo , int ele){
celula *novo;
novo = malloc(sizeof(celula));
novo -> elemento = ele;
if(*topo==NULL){
novo -> prox=NULL;
*topo = novo;
}else{
novo-> prox=*topo;
*topo = novo;
}
}

void printar(celula *topo){
celula *aux;
aux = topo;
if(aux==NULL){

}else {
do{
cout<<aux->elemento;
aux = aux->prox;
}while(aux!=NULL);
}
}

int main() {

celula *topo=NULL;

insereh(&topo,3);
insereh(&topo,6);
insereh(&topo,9);
printar(topo);

return(0);
}

O erro q dá no compilador é o seguinte :

altyouth@mac:~/MATERIAL FACULDADE/ESTRUTURA DE DADOS/LISTA$ g++ insere_inicio.cpp -oinsere_inicio.exe
insere_inicio.cpp: In function ‘void insereh(celula**, int)’:
insere_inicio.cpp:14:16: error: invalid conversion from ‘void*’ to ‘celula* {aka lista*}’ [-fpermissive]
novo = malloc(sizeof(celula));



  


2. Re: ERRO DE COMPILAÇÃO

Paulo
paulo1205

(usa Ubuntu)

Enviado em 09/10/2016 - 20:56h

wendelrios escreveu:

to estudando p EStrutura de Dados , ai peguei um código e joguei no compilador , mas tá dando erro e eu to tentando entender o código na verdade

#include<iostream>
#include<cstdlib>

using namespace std;


typedef struct lista{
int elemento ;
struct lista *prox;
}celula;


Um primeiro problema é que você está misturando estilos de C++ com C.

Em C++ é redundante atribuir um nome de tipo a algo que já foi declarado como estrutura. O jeito C++ de reescrever a declaração acima seria o seguinte.

struct celula {
int elemento;
celula *prox;
};


void insereh(celula **topo , int ele){
celula *novo;
novo = malloc(sizeof(celula));


Aqui o erro principal, que também é consequência da mistura de estilos entre C e C++.

Em C++, a maneira usual de alocar e desalocar memória é através dos operadores new e delete. Esses operadores são melhores do que as funções malloc() e free() do C porque são seguros quanto a tipos de dados envolvidos.

A maneira correta de reescrever a linha acima em C++ é a seguinte.

novo=new celula; 


Se você tiver de usar malloc(), tem de se adaptar ao fato que que ele devolve um ponteiro para um tipo diferente daquele que recebe o endereço da alocação, de modo que você é forçado a fazer explicitamente uma conversão de tipos (essa conversão de tipos é automática e feita implicitamente em C, mas não o é em C++ porque poderia levar conversões de tipo inseguras).

Uma forma correta, MAS NÃO RECOMENDADA, de fazer isso seria a seguinte.

novo=static_cast<decltype(novo)>(malloc(sizeof *novo)); 


Há razões para preferir usar “decltype(novo)” e “sizeof *novo” a, respectivamente, “cliente *” e “sizeof(cliente)”. O mais eloquente, para mim, é que você só precisa fazer a correspondência entre a variável e o seu tipo apenas umas vez, na hora da declaração, e não ficar reexpressando tal associação em outras partes do código. Isso facilita inclusive a manutenção do código: se amanhã você decidir trocar o tipo do ponteiro, não vai precisar mudar também a linha que faz a alocação.

Outro jeito de fazer é AINDA PIOR: usar malloc() e conversão de tipos ao estilo de C. Não vou nem mostrar, para você não achar que eu a chancelei. Essa conversão é ruim até em C, já que é redundante, e pior ainda em C++, por passar por cima do sistema de tipos sem nenhuma chance de deixar o compilador detectar se a conversão é segura ou não.

  novo -> elemento = ele;
if(*topo==NULL){


Em C++ geralmente não se usa “NULL”. Se você usar uma versão antiga do C++ (antes do padrão de 2011), o usual era comparar com o valor 0 mesmo (ou não comparar com nada, pois um ponteiro nulo é automaticamente entendido como falso num contexto de valor booleano, e qualquer outro valor de ponteiro é entendido como verdadeiro). A partir do padrão de 2011, existe o valor específico nullptr, que é mais seguro quanto a tipo de dados do que a antiga macro NULL do C.

    novo -> prox=NULL;
*topo = novo;
}else{
novo-> prox=*topo;
*topo = novo;
}
}

void printar(celula *topo){
celula *aux;
aux = topo;
if(aux==NULL){

}else {


Por que essa construção assim, com um bloco de condição verdadeira vazio, e tudo o que existe para fazer ser executado apenas quando a condição é falsa? Seria melhor você inverter o teste, e omitir completamente o bloco else.

    do{
cout<<aux->elemento;
aux = aux->prox;
}while(aux!=NULL);
}


Bom, agora ainda piorou. Na verdade, todo o bloco “if(!aux){ /*nada!*/ } else { do { /*imprime e avança aux*/ } while(aux); }” pode ser escrito de modo mais sucinto do seguinte modo.

for(aux=topo; aux; aux=aux->prox)
cout << aux->elemento << '\n';


}

int main() {

celula *topo=NULL;

insereh(&topo,3);
insereh(&topo,6);
insereh(&topo,9);
printar(topo);

return(0);
}







Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts