/*****************************************************************************/
/* File:     vb-linked-list.c
 * Status:   22-mar-2006, pfk.
 *           03-nov-2010, wlm
 * Functie:  Programma met dynamische allocatie en gebruik van structures
 *           als voorbeeld van een linked list.
 *****************************************************************************/

#include <stdio.h>
#include <stdlib.h>

#define AANTAL 10

/* globale declaratie van structure van type 'struct point' */
struct point
{ int          x;        /* x-ordinaat */
  int          y;        /* y-ordinaat */
  struct point *volgend; /* pointer naar volgende element in lijst */
};

int main ()
{
  /* NB:
   * Hieronder worden een aantal variabelen als pointer naar een structure
   * gedeclareerd.  
   * De structures (die de elementen van de lijst gaan vormen) worden eerst
   * door dynamische allocatie (met "malloc") gemaakt. 
   * Het gevolg is dat een veld van een element gerefereerd wordt als
   *  (*naam_van_pointer_naar_element).naam_van_veld
   * waarbij de "*" zorgt dat de inhoud van de pointer gebruikt wordt en
   * waarbij de "(" en ")" gebruikt moeten worden om dit eenduidig voor de
   * compiler aan te geven.
   * Alternatief: naam_van_pointer_naar_element->naam_van_veld
   *   In dit voorbeeld worden beide wijzen van adresseren gebruikt. Echter
   *   kies een methode concequent voor je programma's.
   *   De voorkeur heeft de laatste: naam_van_pointer_naar_element->naam_van_veld
   */

  /* ptr nodig voor allocatie en toevoegen van nieuw element aan lijst */
  struct point *tmpPtrPunt;
  /* ptr wijst naar laatst toegevoegde element in lijst */
  struct point *tussenPtrPuntenLijst;
  /* ptr wijst naar eerste element van lijst 
   * door de waarde NULL wordt aangegeven dat de lijst leeg is */
  struct point *beginPtrPuntenLijst = NULL;

  int teller;  /* loopvariabele en teller */

/* maak lijst aan, dit gebeurt in een loop m.b.v. dynamische allocatie:
 * - allocatie van nieuw element
 * - toevoegen van dit nieuwe element aan de bestaande lijst
 */

  for (teller=1; teller<=AANTAL; teller++)
  {
    /* allocatie van nieuw element */
    tmpPtrPunt = (struct point *) malloc (sizeof(struct point));

    /* vul velden van het nieuwe element */
    tmpPtrPunt->x = teller;
    (*tmpPtrPunt).y = 2 * teller;
    /* geef aan dat dit het einde van de lijst is */
    tmpPtrPunt->volgend = NULL;

    /* voeg het nieuwe element toe aan de lijst */
    if (beginPtrPuntenLijst == NULL)
    { /* de lijst is nog leeg, voeg element als eerste element toe */
      beginPtrPuntenLijst  = tmpPtrPunt;
    }
    else  /* lijst bevat al elementen */
    {
      /* maak verbinding tussen laatste element en het nieuwe element */
      tussenPtrPuntenLijst->volgend = tmpPtrPunt;
    }
    /* zet pointer naar het laatst toegevoegde element,
     * ofwel: onthoudt het adres van het laatst toegevoegde element */
    tussenPtrPuntenLijst = tmpPtrPunt;
  }

/* loop de lijst af,
 * druk x en y van het laatste elementen af,
 * druk aantal element af
 */

  /* begin bij het eerste element */
  tussenPtrPuntenLijst = beginPtrPuntenLijst;
  teller = 1;  /* teller voor aantal elementen in lijst */
  while (tussenPtrPuntenLijst->volgend != NULL)
  {
    printf ("Element %2d: x=%2d, y=%2d\n", teller, tussenPtrPuntenLijst->x,
                                                   tussenPtrPuntenLijst->y);
    teller++;  /* tel het volgende element */
    /* wijs naar het volgende element */
    tussenPtrPuntenLijst = tussenPtrPuntenLijst->volgend;
  }

  printf ("Element %2d: x=%2d, y=%2d\n", teller, (*tussenPtrPuntenLijst).x,
                                                 (*tussenPtrPuntenLijst).y);
  printf ("Aantal elementen: %d\n", teller);
  
#ifdef _WIN32
    printf("\n\n");
    system("PAUSE");
#endif
  
  return (0);
}
