stackInit()

stackInit()

por José Coelho de Pina -
Número de respostas: 7

Salve,

O que vocês acham da função abaixo?

typedef struct stackNode* Link;
struct stackNode { 
    Item conteudo; 
    Link prox; 
};

/* cria uma pilha vazia.
   A pilha e implementada atraves de uma lista encadeada com cabeca.
*/
void
stackInit(Link *topo)
{
   topo = malloc(sizeof *topo); /* celula cabeca */
   topo->prox = NULL;
}
Em resposta à José Coelho de Pina

Re: stackInit()

por Thiago Pereira Bueno -

Na função stackInit o parâmetro 'topo' é do tipo Link *, ou seja, struct stackNode **

Para inicializar o campo 'prox' da cabeça com "topo->prox = NULL;" ( => (*topo).prox = NULL;) supõe-se que 'topo' seja do tipo Link...

Assim, para manter a coerência nos tipos, mantendo a assinatura da função, acho que uma possível solução seria algo como:

void stackInit(Link *topo)
{
*topo = malloc(sizeof (Link)); /* celula cabeca */
(*topo)->prox = NULL;
}

[]s
Em resposta à José Coelho de Pina

Re: stackInit()

por Marcelo Rabello Rossi -

Acredito que não vai funcionar da maneira esperada. Será criada uma variável local que aponta para o mesmo lugar do parâmetro. Essa variável local receberá o endereço da cabeça alocada e, ao final da função, será destruída. O ponteiro passado como parâmetro não será modificado e a memória alocada não poderá mais ser acessada.

Caso queira manter o tipo void para a função, o código abaixo parece mais correto:

void
stackInit(Link **topo)
{
   *topo = malloc(sizeof **topo); /* celula cabeca */
   (*topo)->prox = NULL;
}
Em resposta à Marcelo Rabello Rossi

Re: stackInit()

por Thiago Pereira Bueno -

Talvez esteja me confundindo, mas com a nova assinatura acho que " (*topo)->prox = NULL; " não funcionará pois sendo topo do tipo Link **, (*topo) é do tipo Link *, e para acessar o campo prox dessa maneira é necessário que (*topo) fosse do tipo Link apenas, já que Link já é um ponteiro para o struct... não?

Que tal?

void stackInit(Link *topo)
{
*topo = malloc(sizeof (struct stackNode)); /* celula cabeca */
(*topo)->prox = NULL;
}
Em resposta à Thiago Pereira Bueno

Re: stackInit()

por Marcelo Rabello Rossi -

Realmente, o tipo Link é um stackNode *, então vamos reescrever o código para facilitar:

void
stackInit(stackNode **topo)
{
*topo = malloc(sizeof **topo); 
(*topo)->prox = NULL;
}

O que me faz acreditar que o código inicial estava correto. Substituindo stackNode * por Link, temos:

void
stackInit(Link *topo)
{
topo = malloc(sizeof *topo); 
topo->prox = NULL;
}

Que é o código que tínhamos inicialmente. Repare que *topo é um stackNode, então sizeof *topo parece estar de acordo.

Por esse mesmo motivo, (*topo)->prox = NULL daria erro, porque *topo é um StackNode, tornando a notação -> inválida. O que acha?

Uma vez que você tem um tipo Link definido, acredito que topo->prox seja uma notação válida, porque topo é um ponteiro para Link (ainda que Link seja stackNode*).

Coelho, ainda resta a dúvida se a função, do jeito que foi escrita, irá modificar o ponteiro passado como parâmetro e fazê-lo apontar para a cabeça alocada.

Em resposta à Marcelo Rabello Rossi

Re: stackInit()

por Thiago Pereira Bueno -

Por esse mesmo motivo, (*topo)->prox = NULL daria erro, porque *topo é um StackNode, tornando a notação -> inválida. O que acha?

Ainda acho que não... rs... se topo é do tipo Link* (cf. assinatura void stackInit(Link *topo)) entao *topo é um Link, que por sua vez é um sinonimo de struct stackNode* e nao apenas struct stackNode, de maneira que a notacao -> deve funcionar sem problemas...bem, eu acho...rs...

Em resposta à Thiago Pereira Bueno

Re: stackInit()

por Marcelo Rabello Rossi -

Você tem razão! Esse typedef Link deu um nó na cabeça.

O topo->prox dá erro na compilação, porque *topo não é uma struct.

(*topo)->prox, por sua vez, compila sem problemas.