Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

 << zurück
C von A bis Z von Jürgen Wolf
Das umfassende Handbuch für Linux, Unix und Windows
– 2., aktualisierte und erweiterte Auflage 2006
Buch: C von A bis Z

C von A bis Z
1.116 S., mit CD, Referenzkarte, 39,90 Euro
Galileo Computing
ISBN 3-89842-643-2
gp Kapitel 17 Strukturen
  gp 17.1 Struktur deklarieren
  gp 17.2 Initialisierung und Zugriff auf Strukturen
  gp 17.3 Strukturen als Wertübergabe an eine Funktion
  gp 17.4 Strukturen als Rückgabewert einer Funktion
  gp 17.5 Strukturen vergleichen
  gp 17.6 Arrays von Strukturen
  gp 17.7 Strukturen in Strukturen (Nested Structures)
  gp 17.8 Kurze Zusammenfassung zu den Strukturen
  gp 17.9 Union
  gp 17.10 Aufzählungstyp enum
  gp 17.11 Typendefinition mit typedef
  gp 17.12 Attribute von Strukturen verändern (nicht ANSI C)
  gp 17.13 Bitfelder
  gp 17.14 Das offsetof-Makro


Galileo Computing - Zum Seitenanfang

17.11 Typendefinition mit typedef  toptop

Mit dem Schlüsselwort typedef kann ein neuer Bezeichner für einen einfachen Datentyp verwendet werden. Die Syntax einer einfachen Typendefinition sieht so aus:

typedef Typendefinition Bezeichner;

Damit lässt sich die Lesbarkeit eines Programms erheblich verbessern. Diese Typendefinition mit typedef soll anhand des Adressprogramms demonstriert werden. Hier das Listung dazu:

/* typedef1.c */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 30
static int x;
struct adres {
   char vname[MAX];
   char nname[MAX];
   long PLZ;
   char ort[MAX];
   int geburtsjahr;
} adressen[100];
typedef struct adres ADRESSE;
void Eingabe(int nr, ADRESSE *neu) {
   printf("Vorname : ");
   fgets(neu[nr].vname, MAX, stdin);
   printf("Nachname : ");
   fgets(neu[nr].nname, MAX, stdin);
   printf("Postleitzahl: ");
   do {
      scanf("%5ld",&neu[nr].PLZ);
   } while(getchar()!= '\n');
   printf("Wohnort : ");
   fgets(neu[nr].ort, MAX, stdin);
   printf("Geburtsjahr : ");
   do {
      scanf("%4d",&neu[nr].geburtsjahr);
   } while(getchar()!= '\n');
}
void Suche(ADRESSE *search, char buchstabe, int nr) {
   int i;
   for(i = 0; i <= nr; i++)  {
      if(search[i].nname[0] == buchstabe) {
         printf("\n\nGefunden unter Buchstabe :\"%c\"\n\n",
            buchstabe);
         printf("Vorname.......:%s",search[i].vname);
         printf("Nachname......:%s",search[i].nname);
         printf("Postleitzahl..:%ld\n",search[i].PLZ);
         printf("Ort...........:%s",search[i].ort);
         printf("Geburtsjahr...:%d\n",search[i].geburtsjahr);
         printf("\n\tWeiter mit <ENTER>\n");
         getchar();
      }
   }
}
void Ausgabe(ADRESSE *all, int nr) {
   int i;
   for(i = 0; i < nr; i++) {
      printf("Vorname.........:%s",all[i].vname);
      printf("Nachname........:%s",all[i].nname);
      printf("Postleitzahl....:%ld\n",all[i].PLZ);
      printf("Ort.............:%s",all[i].ort);
      printf("Geburtsjahr.....:%d\n\n",all[i].geburtsjahr);
      if( (!(i%2)) && i!=0)  {
         //fflush(stdin);
         printf("\n\tWeiter mit <Enter>\n\n");
         getchar();
      }
   }
}
void Sort(ADRESSE *sort,int nr) {
   ADRESSE *temp;
   int i,j;
   temp = (ADRESSE *)malloc(sizeof(ADRESSE *));
   if(NULL == temp) {
      printf("Konnte keinen Speicher reservieren ...\n");
      return;
   }
   for(i = 0; i < nr; i++) {
      for(j=i+1;j<nr;j++) {
         if(strcmp(sort[i].nname, sort[j].nname)>0) {
            *temp=sort[j];
            sort[j]=sort[i];
            sort[i]=*temp;
         }
      }
   }
   printf("... sortiert!!\n");
}
int main(void) {
   int auswahl;
   char c;
   do {
      printf("-1- Neue Adresse eingeben\n");
      printf("-2- Bestimmte Adresse ausgeben\n");
      printf("-3- Alle Adressen ausgeben\n");
      printf("-4- Adressen sortieren\n");
      printf("-5- Programm beenden\n");
      printf("\nIhre Auswahl : ");
      scanf("%d",&auswahl);
      /* fflush(stdin); */
      getchar();
      switch(auswahl) {
         case 1 : Eingabe(x++,adressen);        break;
         case 2 : printf("Anfangsbuchstabe Nachnamen :");
                  do {
                     scanf("%c",&c);
                  } while(getchar()!= '\n');
                  Suche(adressen,c,x);
                  break;
         case 3 : Ausgabe(adressen,x);          break;
         case 4 : Sort(adressen,x);             break;
         default: break;
      }
   } while(auswahl < 5);
   return EXIT_SUCCESS;
}

Dank der neuen Typendefinition

typedef struct adres ADRESSE;

kann auf die Struktur jetzt mit

ADRESSE neueadressen[100];

zugegriffen werden. Dies lässt sich bei längeren Programmen wesentlich einfacher lesen. Vor allem ist dies sinnvoll, wenn mehrere Strukturen vorhanden sind, die einander vom Aufbau sehr ähnlich sind. Die Typendefinition im Programm ließe sich auch noch anders definieren:

typedef struct adres {
   char vname[20];
   char nname[20];
   long PLZ;
   char ort[20];
   int geburtsjahr;
} ADRESSE;
...
ADRESSE adressen[100];

Die Typendefinitione kann ebenso auf andere Variablen angewendet werden. Recht häufig sind folgende Definitionen zu sehen:

typedef unsigned char BYTE;    // 1 Byte = 8 BIT
typedef unsigned int WORD;     // 1 WORD = 16 BIT
typedef unsigned long DWORD;   // 1 DOUBLE WORD = 32 BIT
typedef unsigned double QWORD; // 1 QUAD WORD = 64 BIT
typedef unsigned int uint;
typedef unsigned char uchar;

Zum Beispiel ist danach die folgende Schreibweise

uint wert1, wert2;

äquivalent zu

unsigned int wert1,wert2;

Das Schlüsselwort typedef wird ebenfalls dazu benutzt, so genannte primitive Datentypen zu erzeugen. Wozu soll das gut sein? Nehmen wir als Beispiel den primitiven Datentyp uclock_t (primitive Datentypen enden normalerweise immer mit _t). Dieser ist in der Headerdatei <time.h> definiert mit:

typedef long uclock_t;

Auf einem anderen System sieht diese Definition vielleicht so aus:

typedef unsigned int uclock_t;

Die primitiven Datentypen machen ein Programm portabler. Dadurch müssen Sie sich nicht mit den Datentypen bei Portierung auf anderen Systemen auseinander setzen. Wenn Sie ein Programm beispielsweise auf einem 32-Bit-System programmiert haben und dies anschließend auf einem 16-Bit-System getestet wird, kann die Suche nach dem Fehler einer falschen Werteausgabe frustrierend sein.

Wie schon mit enum oder define wird mit typedef das Programm nicht etwa besser oder schneller, sondern es dient auch hier lediglich dem besseren Lesen, Schreiben und Portieren des Programms auf andere Systeme.

 << zurück
  
  Zum Katalog
Zum Katalog: C von A bis Z
C von A bis Z
bestellen
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: Shell-Programmierung






 Shell-Programmierung


Zum Katalog: Linux-UNIX-Programmierung






 Linux-UNIX-Programmierung


Zum Katalog: C/C++






 C/C++


Zum Katalog: UML 2.0






 UML 2.0


Zum Katalog: Reguläre Ausdrücke






 Reguläre Ausdrücke


Zum Katalog: Linux






 Linux


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo





Copyright © Galileo Press 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de