C für PICs: Strukturierte Typen
zurück
zu
C für PICs
, C-Compiler , PIC-Prozessoren
,
Elektronik , Homepage
C
für PICs
Grundlagen
von C
Variablen
Funktionen
Operationen
Programmablaufsteuerung
Arrays
und Strings
Pointer
Strukturierte
Typen
PIC-spezifisches
zurück
zu C für PICs
Strukturierte
Typen
Wir kennen bisher einfache Typen (z.B. char, int, float) die jeweils
genau
einen Wert speichern können, und Arrays, die viele Werte des
gleichen Typs speichern können. Oft ist es aber sinnvoll, eine
Datenstruktur zu haben, die unterschiedliche Grundtypen kombiniert
anstelle identischer Typen.
Structure
Eine Structur-Typ beschreibt eine Gruppe zusammengehörender
Daten
(Variablen), die unter einem Namen gemeinsam angesprochen werden
können. Jedes Element einer solchen Structur kann einen
beliebiegen Typ haben, und bekommt einen eigenen "Unter"-Namen,
damit
es innerhalb der Structur identifiziert werden kann. (Das entspricht
in
Pascal dem Record.)
Ein Structure-Typ wird wie folgt definiert:
struct
dername
{
typ
element1;
typ
element2;
typ
element3;
};
Dieses Beispiel definiert den Structur-Typ mit dem Namen
"dername".
Die Structur besteht aus mehreren Elementen mit den Namen element1,
element2 und element3, die jeweils von einem z.Z. bekannten Typ sein
müssen. Dabei darf jedes Element von einem anderen Typ sein.
Man
kann die Liste der Elemente beliebig verlängern.
Mit dieser Definition wurde allerdings noch keine Variable
definiert,
sondern nur ein neuer Typ. Von nun an kennt der Compiler den neuen
Typ
"dername" und es können Variablen dieses struct-Types definiert
werden. Hier definiere ich nun eine Variable mit dem Namen "varname"
und dem oben definierten Typ "dername".
struct dername
varname;
Man kann das etwas abkürzen, indem man an die Typdefinition
gleich
noch eine Variablenliste oder wenigstens einen Variablennamen
anhängt.
struct
dername
{
typ
element1;
typ
element2;
typ
element3;
}
varname;
Dieses Zusammenfassen von Daten unterschiedlicher Typen ist in der
Praxis sehr praktisch, da die im Computer verwalteten Objekte aus
der
realen Welt oft mehrere unterschiedliche Eigenschaften haben. So
lässt sich z.B. ein Auto nicht mit nur einer einfachen
Variable beschreiben. Aber ein Satz von Daten unterschiedlicher
Typen
eignet sich sehr wohl:
struct
Auto
{
char
Hersteller[30];
char
Bezeichnung[30];
char
Tueren;
float
Verbrauch;
}
einauto;
Damit haben wir nun eine strukturierte Variable vom Typ "Auto" mit
dem
Namen "einauto". Wie kann man nun die einzelnen Elemente dieser
Variable beschreiben oder auslesen? Man addressiert sie durch den
Variablennamen, der um den mit einem Punkt abgetrennten Elementnamen
ergänzt wird.
einauto.Hersteller
= "Skoda";
einauto.Bezeichnung = "Oktavia
II";
einauto.Tueren
=
4;
einauto.Verbrauch
=
5.1;
Besitzt man zwei Variablen von gleichen strukturierten Typ, dann kan
man alle Were auf einmal übergeben:
struct
Auto nocheinauto;
nocheinauto
=
einauto;
Union
Eine Union sieht nur auf den ersten Blick wie eine Stucture aus.
Auch
eine
Union besteht aus mehreren Elementen, die unterschiedliche Typen
haben
können. Allerdings werden die Werte aller Elemente auf dem
selben
Speicherplatz gespeichert. Die Deklaration eines neuen union-Typs beginnt mit dem
Schlüsselwort union gefolgt
von
neuen Namen dieses neuen Typs. Danach werden innerhalb geschweifter
Klammern die Elemente der union aufgelistet.
Jedes
Element der Liste besteht aus dem Typ des Elements gefolgt vom
Bezeicher für dieses Element. Will man gleich eine oder mehrere
Variablen dieses neuen union-Typs
Deklarieren,
so schreibt man die Variablennamen hinter die geschweiften
Klammern.
union
dername
{
typ
element1;
typ
element2;
typ
element3;
}
varname;
Die Größe des von einer Union belegten Speichers ist
deshalb
so groß wie der Speicherbedarf des größten Elements
dieser Union. Beschreibt man nun ein Element einer Union mit einem
Wert, dann überschreibt man automatisch die Werte aller anderen
Elemente mit diesem Wert. Welchen Sinn sollte eine Union also haben?
Stellen wir uns einmal vor, es wäre in einem Programm
nötig,
ein 16-Bit-Word in seine zwei 8-Bit Bytes zu zerlegen. Es gibt
dafür mehrere programmtechnische Möglichkeiten, die
eleganteste ist der Einsatz einer Union. Da natives C die Typen byte und word nicht kennt, definiere ich
sie
erst einmal (typedef wurde noch nicht besprochen!), dann definiere
ich eine Union mit dem Namen _WORD, die aus
zwei Elementen
besteht. Das erste Element ist ein 16 Bit langes Word, das andere
Element ist eine Folge von zwei Bytes (als Structure). Eine Variable
dieser Union nenne ich Superword.
typedef
unsigned char
byte;
//
8-bit
typedef
unsigned
int
word;
//
16-bit
union
_WORD
{
word
_word;
struct
{
byte
LowByte;
byte
HighByte;
};
}
SuperWord;
Speichert man nun einen 16-Bit-Wert im Word-Element der Union
(Superword._word) ab, dann speichert man sie gleichzeitig
natürlich in den beiden Bytes des zweiten Elements der Union
ab.
Dort lässt sich nun auf das untere Byte (SuperWord.LowByte)
und auf das obere Byte (SuperWord.HighByte) des 16-Bit-Wertes
einfach
zugreifen.
word a;
byte b,c;
a =
12345;
SuperWord._word
=
a;
b =
SuperWord.LowByte;
c =
SuperWord.HighByte;
Die Dezimalzahl 12345 ist als Hexadezimalzahl 0x3039. Der
Programmabschnitt zerlegt die Zahl in seine zwei Bytes. Letztendlich
steht in b der Wert 0x39
und
in c der Wert 0x30.
--> zurück zu C
für
PIC-spezifischem
zurück
zu
C für PICs
, C-Compiler , PIC-Prozessoren
,
Elektronik , Homepage
Autor: sprut
erstellt: 01.10.2007
letzte Änderung: 01.10.2007