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);
}