Dynamic Stack - C

4

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 mount the structure, but I am in doubt on some parts that are commented out in the code, in case what the specific lines do

    
asked by anonymous 17.09.2018 / 23:19

1 answer

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

This does not create a struct . It is only a typedef that says that a pointer to the TNo structure is called TPILHA . In fact, these types of typedefs are discouraged because they make it difficult to read because they hide the pointer. Something similar though simpler to realize would be:

typedef int inteiro;

Meaning that inteiro becomes a type equivalent to int and then lets you do something like inteiro x = 10;

Regarding the comments in the Empilhar function:

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 , it only declares a pointer to a TNo structure. Creation only comes on the next line with malloc .

2) The value of the next one is null because it is possible to start the new element with something, and when it is empty, what is needed 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 that I marked as (4). You could make it otherwise clear but this tends to be simpler, for the rest of the code that the function has.

3) Here you are 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. Because you received the stack as a pointer, you must change it with * using the *ptr = valor; syntax.

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

5) This statement is the same as 3).

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

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

  • (*pPilha) = novo; was in if and in else soon does not depend on if and should come later

  • novo->prox = *pPilha; - If you set prox to NULL when *pilha is NULL and places prox to *pilha when it is not then corresponds to always put *pilha that is much simpler.

18.09.2018 / 00:22