Dynamic stack - C

I am 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 in the code, in case what the specific lines do

Author: Isac, 2018-09-17

1 answers

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

This does not create a struct. It's just a typedef that says a pointer to the structure TNo is called TPILHA. In fact this type of typedefs are disconcerted 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;

As for comments in 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 doesn't create a struct, it just declares a pointer to a TNo structure. The creation just comes in the next line with 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 it has no more elements ahead. In cases where it is not empty the prox will again be changed, in the line I marked as (4). I could make it otherwise clear but this tends to be simpler, for the rest of the code the function has.

3) here is changing the stack you received as a pointer. If the stack is empty because it is NULL then it will become the new node that was created. How you received the stack as a 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 that was in the stack, given by *pPilha, i.e. the value pointed by pPilha.

5) this statement is the same as 3).

Now I personally think it got pretty complicated in terms 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:

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

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

  • novo->prox = *pPilha; - if you put prox to NULL when *pilha is NULL and you put prox to *pilha when it is not then you 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.

 1
Author: Isac, 2018-09-17 22:22:19