Dynamic stack - C

Asked

Viewed 1,146 times

5

I’m studying dynamic stack from the code below:

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

#define tam 50

// ---- Estruturas para os tipos -------------------------------------------------------------------------------
typedef struct                          // Definicao da estrutura do registro
{                                       // Com definição do tipo (typedef)
       int   Chave;
       // Outros campos
}REGISTRO;

// ---- Funções ligadas aos REGISTROs --------------------------------------------------------------------------
REGISTRO LerRegistro()                  // Ler os dados de um registro
{
    REGISTRO r;

    printf("\n\n Digite a chave da pessoa : ");
    scanf("%d", &r.Chave);

    // Outros campos
    return r;          
}

void ImprimeRegistro(REGISTRO r)        // Imprimir um registro
{
     printf(" Chave : %d \n",   r.Chave);
    // Outros campos
}


// --- Tipo PILHA ---------------------------------------------
struct TNo{
       REGISTRO         reg;
       struct TNo       *prox;
};

typedef struct TNo *TPILHA; //não entendi o motivo da criação dessa //struct

void InicializarPilha(TPILHA *pPilha)
{
    (*pPilha) = NULL;
}


int PilhaCheia(TPILHA pPilha)
{
    return 0;
}

int PilhaVazia(TPILHA pPilha)
{
    return (pPilha == NULL);
}


void Empilhar(TPILHA *pPilha, REGISTRO pReg )
{
    struct TNo *novo;// pq essa struct foi criada?

    novo = (struct TNo *) malloc(sizeof (struct TNo));
    novo->reg     = pReg;
    novo->prox    = NULL;// pq o valor do próximo é nulo?

    if (*pPilha == NULL)
    {
        (*pPilha) = novo;//o que essa linha quer dizer?
    }
    else
    {
        novo->prox = (*pPilha); //o que essa linha quer dizer?
        (*pPilha) = novo; //o que essa linha quer dizer?
    }
}

REGISTRO Desempilhar(TPILHA *pPilha)
{
    REGISTRO aux;

    if (*pPilha == NULL)
    {
        aux.Chave = -1;
    }
    else
    {
        aux = (*pPilha)->reg;
        (*pPilha) = (*pPilha)->prox;
    }
    return aux;
}

void Visualizar(TPILHA pPilha)
{
    TPILHA aux1 = pPilha;

    printf("\n\n");
    while (aux1 != NULL)
    {
          printf(" %d \n", aux1->reg.Chave);
          aux1 = aux1->prox;
    }                                             
    printf(" ------- ");
    printf("\n\n");
}


// ---- Funções Uteis --------------------------------------------------------------------------
char Menu2()                            // Menu com retorno da 
                                        // opcao selecionada
{
    char o;

    printf(" -- Menu -- \n");
    printf("  ( A ) Adicionar ao Estoque \n");
    printf("  ( R ) Retirar do estoque \n");
    printf("  ( > ) Transferir da Pilha 1 para a Pilha 2 \n");
    printf("  ( < ) Transferir da Pilha 2 para a Pilha 1 \n");
    printf("  ( V ) Visualizar Estoque \n");
    printf("  ( S ) Sair \n");
    printf("\n  Opcao :  ");
    fflush(stdin);
    scanf("%c", &o);

    return o;    
}

main()
{
    TPILHA p1, p2;
    char     opcao;

    InicializarPilha(&p1);
    InicializarPilha(&p2);

    do
    {   opcao = Menu2();   
        switch(opcao)
        {
           case 'A': case 'a':
                     {
                      // Solicitar qual pilha
                      printf(" Digite qual pilha : ");
                      int p;
                      scanf("%d", &p);

                      // Qual registro
                      REGISTRO aux;
                      printf(" Digite qual codigo : ");
                      scanf("%d", &aux.Chave);

                      // Empilhar
                      if (p==1)
                            Empilhar(&p1, aux); 
                      else
                            Empilhar(&p2, aux); 
                     } break;
           case 'R': case 'r': {
                      // Solicitar qual pilha
                      printf(" Digite qual pilha : ");
                      int p;
                      scanf("%d", &p);

                      // Desempilhar
                      if (p==1)
                            Desempilhar(&p1); 
                      else
                            Desempilhar(&p2); 
                     }break;
            case '<': {
                       REGISTRO raux;
                       raux = Desempilhar(&p2);
                       Empilhar(&p1, raux);
                    }break;
            case '>': {// Mover de Pilha 1 para Pilha 2
                       REGISTRO raux;
                       raux = Desempilhar(&p1);//Desemp de P1
                       Empilhar(&p2, raux);    //Emp em P2
                    }break;
            case 'V': case 'v': {
                      printf("pilha 1 :\n ");
                      Visualizar(p1);
                      printf("\n ----- \n ");
                      printf("pilha 2 :\n ");
                      Visualizar(p2);
                      printf("\n\n\n ");
                    }break; 
           case 's':
           case 'S': printf(" Opcao SAIR    escolhida \n"); break;
           default : printf(" Opcao invalida. \n");
        }
        system("pause");
        system("cls");
    }    
    while( (opcao != 'S') && (opcao != 's') );
}

I know how to assemble the structure, but I am in doubt in some parts that are commented on in the code, in case what the specific lines do

1 answer

1

typedef struct TNo *TPILHA; //não entendi o motivo da criação dessa //struct

It doesn’t create a struct. Is just one typedef that says a pointer to the structure TNo is now called TPILHA. Actually this type of typedefs are uncommitted because they make it difficult to read because they hide the pointer. Something similar yet simpler to realize would be:

typedef int inteiro;

Which means that inteiro becomes a type equivalent to int and then allows you to do something like inteiro x = 10;

Comments on the function Empilhar:

void Empilhar(TPILHA *pPilha, REGISTRO pReg )
{
    struct TNo *novo;// pq essa struct foi criada? (1)

    novo = (struct TNo *) malloc(sizeof (struct TNo));
    novo->reg     = pReg;
    novo->prox    = NULL;// pq o valor do próximo é nulo? (2)

    if (*pPilha == NULL)
    {
        (*pPilha) = novo;//o que essa linha quer dizer? (3)
    }
    else
    {
        novo->prox = (*pPilha); //o que essa linha quer dizer? (4)
        (*pPilha) = novo; //o que essa linha quer dizer? (5)
    }
}

1) Again this line also does not create a struct, only declares a pointer to a structure TNo. Creation only comes in the next line with the malloc.

2) The value of the next is null because it is useful to start the new element with something, and when it is empty the necessary is NULL which symbolizes that there are no more elements ahead. In cases where the prox will again be changed, on the line I marked as (4). I could do otherwise clear but this tends to be simpler, for the rest of the code that the function has.

3) Here you are changing the battery you received as pointer. If the battery is empty it is NULL then it will become the new node that was created. As received the stack as pointer you have to change with the * using the syntax *ptr = valor;.

4) If the stack is not empty then the new element created has to point to the last one on the stack, given by *pPilha, that is, the value pointed by pPilha.

5) This instruction is the same as for 3).

Now personally I think it got very complicated at the level of syntax and logic. Much simpler would be:

void Empilhar(TPILHA *pPilha, REGISTRO pReg )
{
    struct TNo *novo = malloc(sizeof (struct TNo));
    novo->reg     = pReg;
    novo->prox    = *pPilha;
    *pPilha       = novo;
}

So few lines to do the same! Ideas behind this transformation:

  • Do *pPilha = or (*pPilha) = is the same as parentheses are redundant in this case.

  • (*pPilha) = novo; was in the if and in the else so it does not depend on the if and must come after

  • novo->prox = *pPilha; - If puts the prox to NULL when *pilha is NULL and puts prox to *pilha when it is not then corresponds to always put *pilha which is much simpler.

  • = malloc(sizeof (struct TNo)); the cast in the malloc is not necessary and ends up simplifying reading among other things without it.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.