Programmieren in C


von Prof. Dr. Rainer Thomas

9. Weitere zusammengesetzte Datentypen

9.1 Aufbau und Vereinbarungen von Strukturen ("structures")
9.2 Operationen mit Structuren
9.3 Dynamische Datenstrukturen
9.4 Typdefinition mit "typedef"
9.5 Variante Strukturen ("unions")
9.6 Bitfelder
9.7 Vorwärtsdeklaration von Struktur-Typen


9.1 Aufbau und Vereinbarungen von Strukturen ("structures")


Strukturen (structures) in C


Vereinbarung von Strukturen in C


Beispiele zur Vereinbarung von Strukturen in C

/* -------------------------------------------------------------------- */

/* Definition eines Structure-Typ-Namens */

   struct datum
   { int tag;
     char monat[4];
     int jahr;
   };

/* -------------------------------------------------------------------- */

/* Variablenvereinbarung unter Verwendung eines vorher definierten
   Structure-Typ-Namens */

   struct datum geb_datum;

/* -------------------------------------------------------------------- */

/* Vereinbarung einer Variablen eines "namenlosen" Structure-Typs */

   struct
   { int tag;
     char monat[4];
     int jahr;
   } geb_datum;

/* -------------------------------------------------------------------- */

/* Definition eines Structure-Typ-Namens und Vereinbarung einer
   Variablen dieses Typs */

   struct datum
   { int tag;
     char monat[4];
     int jahr;
   } geb_datum;

/* -------------------------------------------------------------------- */

/* Struktur mit einer Struktur als Komponente */

   struct person
   { char name[20],
          vorname[20];
     struct
     { int tag;
       char monat[4];
       int jahr;
     } geb_datum;
     char verheiratet;
   } student, diplomand;

/* -------------------------------------------------------------------- */

/* Struktur mit einer Struktur als Komponente
   Verwendung eines vorher definierten Typ-Namens fuer diese Struktur */

   struct datum
   { int tag;
     char monat[4];
     int jahr;
   };


   struct person
   { char name[20],
          vorname[20];
     struct datum geb_datum;
     char verheiratet;
   } student, diplomand;


/* -------------------------------------------------------------------- */


Initialisierung von Strukturen in C

/* ------------------------------------------------------------------- */
/*                                                                     */
/*   KuR-C  : Nur für Speicherklassen "extern" und "static" zulässig   */
/*                         (wie bei arrays)                            */
/*   ANSI-C : Auch für Speicherklasse "auto" zulässig                  */
/*            (Initialisierung durch konst. Ausdrücke)                 */
/*                                                                     */
/* ------------------------------------------------------------------- */
/*                                                                     */
/*   Achtung : Eine Initialisierung ist nicht zulässig in einer reinen */
/*             Strukturtypdefinition                                   */
/*                                                                     */
/* ------------------------------------------------------------------- */



/* Beispiel 1  */

   struct
   { int tag;
     char monat[4];
     int jahr;
   } aktuell_datum = {1, "jan", 1987};



/* -------------------------------------------------------------------- */



/* Beispiel 2  */

   struct datum
   { int tag;
     char monat[4];
     int jahr;
   };


   struct datum aktuell_datum = {1, "jan", 1987};



/* -------------------------------------------------------------------- */


9.2 Operationen mit Strukturen


Programmbeispiele zu Strukturen in C

/* Programm CPLMUL1 */

/* Multiplikation zweier komplexer Zahlen */
/* Pointer auf Strukturen als Parameter   */

#include <stdio.h>

struct complex
{ double re;
  double im;
};

void liescomplex(struct complex *px)
                 /* px ist Pointer auf Variable vom Typ complex */
{ struct complex xh;
  scanf("%lf%lf",&xh.re,&xh.im);
  *px=xh;
}

void multcomplex(struct complex *px1, struct complex *px2,
                 struct complex *pz)
               /* px1, px2, pz sind Pointer auf Variable vom Typ complex */
{ (*pz).re = (*px1).re * (*px2).re - (*px1).im * (*px2).im;
  (*pz).im = (*px1).re * (*px2).im + (*px1).im * (*px2).re;
}

void auscomplex(struct complex *px)
                /* px ist Pointer auf Variable vom Typ complex */
{ printf("( %.4f , %.4f )",px->re,px->im);
}

void main(void)
{ struct complex czahl1,czahl2,czahl3;
  int zeich;
  printf("\n? ");
  while ((zeich=getchar())!=EOF)
  { ungetc(zeich,stdin);
    liescomplex(&czahl1);
    liescomplex(&czahl2);
    multcomplex(&czahl1,&czahl2,&czahl3);
    auscomplex(&czahl1);
    printf(" * ");
    auscomplex(&czahl2);
    printf(" = ");
    auscomplex(&czahl3);
    printf("\n\n? ");
    getchar();
  }
}

Bildschirmausgabe :

/* Programm CPLMUL2 */

/* Multiplikation zweier komplexer Zahlen      */
/* Strukturen als Parameter und Funktionswert  */

#include <stdio.h>

struct complex
{ double re;
  double im;
};

struct complex liescomplex(void)
{ struct complex x;
  scanf("%lf%lf",&x.re,&x.im);
  return(x);
}

struct complex multcomplex(struct complex x1, struct complex x2)
                   /* Parameter x1 und x2 sind Variable vom Typ complex */
{ struct complex z;
  z.re = x1.re * x2.re - x1.im * x2.im;
  z.im = x1.re * x2.im + x1.im * x2.re;
  return(z);
}

void auscomplex(struct complex x)
                           /* Parameter x ist Variable vom Typ complex */
{ printf("( %.4f , %.4f )",x.re,x.im);
}

void main(void)
{ struct complex czahl1,czahl2,czahl3;
  int zeich;
  printf("\n? ");
  while ((zeich=getchar())!=EOF)
  { ungetc(zeich,stdin);
    czahl1=liescomplex();
    czahl2=liescomplex();
    czahl3=multcomplex(czahl1,czahl2);
    auscomplex(czahl1);
    printf(" * ");
    auscomplex(czahl2);
    printf(" = ");
    auscomplex(czahl3);
    printf("\n\n? ");
    getchar();
  }
}

Bildschirmausgabe :

Der sizeof-Operator in C


Arrays von Strukturen in C


Dynamische Datenstrukturen in C


Aufbau verketteter Datenstrukturen mittels rekursiver Strukturen


Beispiel zu rekursiven Strukturen :
Sortierte Speicherung von double-Werten in einem Binär-Baum


Programm zum Beispiel zu rekursiven Strukturen

/* Programm SORTD */

/* Sortierte Ausgabe (aufsteigende Wertefolge) einer beliebigen
   Anzahl in beliebiger Reihenfolge ueber stdin eingegebenen Folge
   von double-Werten nach stdout.
   Speicherung der Werte in einem Binär-Baum */

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

struct dknoten                     /* Typ-Definition des Knotens */
{ double wert;
  int anzahl;
  struct dknoten *rechts;
  struct dknoten *links;
};

void main(void)
{ struct dknoten *wurzel;
  double d;
  struct dknoten *einf_baum(struct dknoten *, double);
  void baumaus(struct dknoten *);
  wurzel=NULL;
  printf("\nBitte Zahlen eingeben !\n");
  while (scanf("%lf",&d)!=EOF)
    wurzel=einf_baum(wurzel,d);
  printf("\nSortierte Folge der eingegeben Zahlen :\n\n");
  baumaus(wurzel);
}

struct dknoten *einf_baum(struct dknoten *pk, double a)
  /* Einfügen Wert in Baum */   /* pk  Zeiger auf akt. Knoten des Baums */
{                               /* a   neuer einzufuegender Wert        */
  if (pk==NULL)                    /* neuer Wert ist einzufuegen        */
  { pk=malloc(sizeof(struct dknoten));
    pk->wert = a;
    pk->anzahl = 1;
    pk->links = pk->rechts = NULL;
  }
  else if (a==pk->wert)            /* Wert bereits vorhanden */
    pk->anzahl++;
  else if (a<pk->wert)             /* Wert ist kleiner als Knotenwert */
    pk->links = einf_baum(pk->links,a);
  else                             /* Wert ist groesser als Knotenwert */
    pk->rechts = einf_baum(pk->rechts,a);
  return pk;
}

void baumaus(struct dknoten *pk)   /* Rekursive Ausgabe der Baumwerte */
{                             /* pk  Zeiger auf akt. Knoten des Baums */
  if (pk!=NULL)
  { baumaus(pk->links);
    printf("%13.6lf",pk->wert);
    if (pk->anzahl > 1)
      printf("  (%2d)",pk->anzahl);
    putchar('\n');
    baumaus(pk->rechts);
  }
}                                     /*  Ergebnis Probelauf s. umseitig */

Bildschirmausgabe :


9.4 Typedefinition mit "typedef"



Beispiele zur Typdefinition mittels "typedef" in C

/* --------------------------------------------------------------------* /

/* statt :   */

           struct datum                   /* Typdefinition */
           { int tag;
             char monat[4];
             int jahr;
           };

           struct datum geb_datum;        /* Variablenvereinbarung */

/* kann man auch formulieren :   */

           typedef struct                 /* Typdefinition */
           { int tag;
             char monat[4];
             int jahr;
           } datum;               /* Typname ! */

           datum geb_datum;               /* Variablenvereinbarung */

/* -------------------------------------------------------------------- */

/* Die Anwendung von "typedef" ist nicht auf struct-/union-Typen
   beschraenkt,
   sondern ist fuer alle Datentypen zulaessig */

/* zum Beispiel :   */

           typedef char wort[80];         /* Typdefinition */

           typedef float real;            /* Typdefinition */

           wort name;                     /* Variablenvereinbarung */

           real a;                        /* Variablenvereinbarung */

/* -------------------------------------------------------------------- */

/* Auch die Definition von Pointertypen (auch Pointer auf Funktionen)
   ist mit "typedef" moeglich */

/* zum Beispiel :    */              /* oder :                          */

   typedef struct                    /*  typedef struct                 */
           { double re;              /*          { double re;           */
             double im;              /*            double im;           */
           } complex;                /*          } complex, *complptr;  */

   typedef complex *complptr;        /* Definition des Typs "complptr"  */
                                     /* als Pointer auf complex         */

   typedef double (*pfd)(char *,     /* Definition des Typs "pfd" als   */
                         char *);    /* Pointer auf eine Funktion, die  */
                                     /* einen double-Wert liefert und   */
                                     /* zwei char-Pointer-Parameter hat */
/*--------------------------------------------------------------------- */


9.5 Variante Strukturen ("unions")


Unions (Variante Strukturen) in C


Vereinbarung von Unions in C


Programmbeispiel zu Unions in C

/*---------------------------------------------------------------------*/
/* Programm FLOATBYTE */
/*---------------------------------------------------------------------*/
/* Ausgabe der internen Darstellung von float-Werten als sedezimale    */
/* Bytefolge (MS-Byte zuerst)                                          */
/*---------------------------------------------------------------------*/

#include <stdio.h>

union floathex
{ float f;
  char b[sizeof(float)];      /* unabhaengig von interner Darstellung */
};

void main(void)

{ union floathex flvar;
  float r;
  int i;

  printf("\nInterne Darstellung von FLOAT-Werten als Bytefolge");
  printf(" (MS-Byte zuerst).\n");
  printf("Bitte geben Sie Zahlenwerte ein :\n\n");
  while (scanf("%f",&r)!=EOF)
  { flvar.f=r;
    for (i=sizeof(float)-1; i>=0; i--)
      printf("%02x  ",flvar.b[i]&0xff);
    printf("\n\n");
  }
}

/*---------------------------------------------------------------------*/

Bildschirmausgabe :

9.6 Bitfelder


9.7 Vorwärtsdeklaration von Struktur-Typen





Zum Inhaltsverzeichnis Zum nächsten Abschnitt


Copyright © FH München, FB 04, Prof. Dr. Rainer Thomas
V - PC - 911 - 00 - TH - 02
V - PC - 912 - 00 - TH - 02
V - PC - 913 - 01 - TH - 02
V - PC - 913 - 02 - TH - 02
V - PC - 914 - 00 - TH - 04
V - PC - 921 - 00 - TH - 02
V - PC - 922 - 00 - TH - 06
V - PC - 923 - 00 - TH - 06
V - PC - 924 - 00 - TH - 05
V - PC - 925 - 00 - TH - 03
V - PC - 931 - 00 - TH - 02
V - PC - 932 - 00 - TH - 02
V - PC - 934 - 00 - TH - 03
V - PC - 935 - 01 - TH - 03
V - PC - 935 - 02 - TH - 03
V - PC - 941 - 00 - TH - 05
V - PC - 943 - 00 - TH - 04
V - PC - 951 - 00 - TH - 04
V - PC - 952 - 00 - TH - 03
V - PC - 953 - 00 - TH - 03
V - PC - 961 - 00 - TH - 02
V - PC - 962 - 00 - TH - 02
V - PC - 971 - 00 - TH - 02