Datei heruntergeladen von: c-schell.de Autor: F. Waßewitz Letzte Aktualisierung am: 07.05.1998 --------------------------------------- Allgemeiner Hinweis: Ich möchte darauf Hinweisen, daß dies hier nur ein Einführungskurs in C/C++ ist. Es wird versucht sich an den Konventionen von ANSI zu halten. Sollte des dennoch Abweichungen geben, so werde ich darauf hinweisen. Man sollte weiterhin C und C++ nicht einen Topf werfen, da C++ eine starke Erweiterung von C ist. Dieser Kurs wird in verschiedenen Abständen aktuallisiert und erweitert. Sollte es Hinweise und Anregungen geben, so schreibt mir bitte eine E-Mail an der untengenannten E-Mail-Adresse. --------------------------------------- Inhaltsverzeichnis: 1. Einührung 1.1 Einführendes Beispielprogramm 1.1.1 Einführendes Beispielprogramm für C 1.1.2 Einführendes Beispielprogramm für C++ 1.1.3 Erklärung der Metasymbolik 1.2 Aufbau eines Programmes 1.2.1 Allgemeiner Programmaufbau 1.3 Die Anweisung 1.3.1 Der Anweisungsblock 1.4 Kommentare 1.4.1 Kommentare in C 1.4.2 Kommentare in C++ 1.5 Operatoren 1.5.1 Vergleichs-Operatoren 1.5.2 Arithmetische Operatoren 1.5.3 Logische Operatoren 1.5.4 Bit-Operatoren 1.6 Preprozessor-Anweisungen 1.6.1 Die #include-Anweisung 1.6.2 Die #define-Anweisung 1.6.3 Die #elif-Anweisung 1.6.4 Die #else-Anweisung 1.6.5 Die #endif-Anweisung 1.6.6 Die #if-Anweisung 1.6.7 Die #ifdef-Anweisung 1.6.8 Die #ifndef-Anweisung 1.6.9 Die #undef-Anweisung 1.7 Datentypen von C/C++ 1.7.1 Datentypen für Zeichen 1.7.2 Datentypen für ganze Zahlen 1.7.3 Datentypen für gebrochene Dezimalzahlen 1.7.4 Eigenen Datentyp festlegen 1.8 Variablen in C/C++ 1.8.1 Variablendeklaration in C/C++ 1.8.2 Wertzuweisung von Variablen einfachen Types 1.9 Die Datenverbunde in C/C++ 1.9.1 Der Datenverbund struct 1.9.2 Der Datenverbund union 1.10 True und False in C/C++ 1.11 Verzweigungen in C/C++ 1.11.1 Einfache Verzweigung durch die if-Anweisung in C/C++ 1.11.2 Mehrfachverzweigung durch die switch-Anweisung in C/C++ 1.12 Schleifen in C/C++ 1.12.1 Die for-Schleife 1.12.2 Die while-Schleife --------------------------------------- 1 Einführung: Die Programmiersprache C ist weitverbreitet. Der Vorteil der Sprache C liegt in der Portabilität, d.h. C ist auf vielen Plattformen vorhanden (DOS, Windows, UNIX, OS/2). Leider hat diese Portabilität auch ihren Preis, der C-Compiler sollte sich an den ANSI-Standard halten. Ist dies nicht der Fall, so sind Fehler vorprogrammiert. Eines sei hier auch noch zu erwähnen, viele Compilerhersteller haben zusaätzliche Funktionen in ihren Bibliotheken eingebaut. D.h. eine Funktion, welche in einer Headerdatei (.H) vorhanden ist, muß auch nicht in jener Headerdatei des anderen Compilieres vorhanden sein. Also: "Holzauge sei wachsam", es gab schon viele Verwirrungen und schlaflose Nächte bei Programmentwicklern. Programmierer, welche schon PASCAL können, werden ihre Schwierigkeiten haben, da die Unterschiede im Detail liegen. Als Beispiel wäre da der Zuweisungsoperator zu nennen. Der Funktionsumfang von C ist gering. Erst das Einbinden von einigen zusätzlichen Bibliotheken erweiter diesen Funktionsumfang. Dabei ist zu beachten, daß die Bibliotheken (Dateien mit der Endung .LIB) mit dem entsprechenden C-Compiler compilert wurden sind. Da jeder Compiler seinen eignen Code erzeugt. Man kann also nicht die Bibliotheken von Microsoft C in Borland C verwenden. Es würden nür sinnlose Fehlermeldungen beim Linker kommen. Besser ist es schon, wenn man die Bibliotheken als Source-Code hat. Diese kann man mit jeden Compiler neu compilieren und somit auch einwandfrei benutzen. Ein Programm wird in C/C++ in zwei Schritten erstellt: 1. Compilieren des Quelltextes zu einer Objektdatei (.OBJ) 2. Linken der entstandenen Objektdateien (.OBJ) zu einer ausführenbaren Datei oder ähnliches (.EXE bzw. .DLL) Wichtig sei noch zu erwähnen, daß man die Möglichkeit von vorcompilerten Headerdateien nutzen sollte, da diese einen enormen Geschwindigkeitszuwachs beim Compileren bringen. Dies ist aber eine Einstellungssache de Compilieres. Vorcompilierte Headerdateien haben aber auch einen Nachteil, sie sind sehr groß (teilweise bis zu 20 MByte oder größer) und die Erstellung dieser dauert auch seine Zeit. --------------------------------------- 1.1 Einführendes Beispielprogramm 1.1.1. Einführendes Beispielprogramm für C Beispielprogramm für die Sprache C Listing für HELLO.C: /*Binde Headerdatei ein */ #include int main() { /* Gebe "Hello world!" aus */ printf( "\nHello world!" ); /* Beende main-Funktion */ return 0; } --------------------------------------- 1.1.2 Einführendes Beispielprogramm für C++ Beispielprogramm für die Sprache C++ Listing für HELLO1.CPP: // Bind Headerdatei ein // #include // Hauptprogramm // int main() { // Gebe "Hello world!" aus // printf( "\nHello world!" ); // Beende main-Funktion // return 0; } Nun kann man aber auch die Möglichkeiten einer objektorientierten Sprache ausnutzen. Man benutzt zur Ausgabe nicht die Funktion printf, sondern die Klasse cout aus der Headerdatei iostream.h. Listing für HELLO2.CPP: // Bind Headerdatei ein // #include // Hauptprogramm // int main() { // Gebe "Hello world!" aus // cout << "\nHello world!"; // Beende main-Funktion // return 0; } --------------------------------------- 1.1.3 Erklärung der Metasymbolik Folgende Zeichen werden für die Beschreibung des Syntax verwendet: Fett Das fett geschriebene Wort ist das Schlüsselwort, für das der Syntax beschrieben wird [] Der Block kann weggelassen werden <> Der Block kann wiederholt werden --------------------------------------- 1.2 Aufbau eines Programmes 1.2.1. Allgemeiner Programmaufbau Bei einen C-Programm werden die Preprozessoren-Anweisungen am Anfang geschrieben. Eine Preprozessor-Anweisung ist z.B. das Einbinden einer Headerdatei. Danach folgen die Festlegung der globalen Variablen, der Funktionsprototypen, der Unions oder der Structs. Es besteht natürlich auch die Möglichkeit den Funktionsrumpf an den Funktionskopf anzuhängen, damit aber der Compiler einer Funktionsparameterlistenüberprüfung vornehmen kann, sollte die komplette Funktion unter der Main-Funktion stehen. Man kann aber man muß nicht, es ist halt jeden selbst überlassen. Danach folgt die Main-Funktion. Die Main-Funktion stellt das Hauptprogramm dar. --------------------------------------- 1.3 Die Anweisung Eine Anweisung ist eine Folge von Zeichen, welche mit einem Semikolon beendet wird. Beispiel: printf( "Hello world!" ); --------------------------------------- 1.3.1 Der Anweisungsblock Ein Anweisungsblock ist ein Block von Anweisungen, welcher mit einen { eingeleitet wird und mit einem } beendet wird. Beispiel: { /* Anfang des Blocks */ int a, b, c; a = 5; b = 6; c = a + b; printf( "\na + b = %d" , c ); } /* Ende des Blocks */ --------------------------------------- 1.4 Kommentare Kommentare sind wichtig, um den Quellcode zur erklären. Meist weiß man nach einigen Wochen gar nicht mehr, was der Code zu bedeuten hat. Dies gilt besonderst für optimierte Algorithmen, die man nicht auf Anhieb erkennt. Wer soll sich auch all diese Algorithmen merken. --------------------------------------- 1.4.1 Kommentare in C Kommentare werden in C mit der Zeichenfolge /* eingeleitet und mit der Zeichenfolge */ beendet. Beispiel: /* Das ist ein Kommentar-Beispiel */ Soll ein Kommentar über mehrere Zeilen gehen, so muß die Zeichenfolge */ nicht in der selben Zeile, wie die Zeichenfolge /*, stehen. Beispiel für ein Kommentar über mehrere Zeilen: /* Dieser Kommentar geht über mehrere Zeilen */ --------------------------------------- 1.4.2 Kommentare in C++ In C++ kann ein Kommentar wie in C erfolgen. Es besteht weiterhin die Möglichkeit einen Kommentar mit der Zeichenfolge // einzuleite. Der Kommentar endet somit aber automatisch am Zeilenende (Enter + Zeilenvorschub). Soll ein Kommentar über mehrere Zeilen gehen, so vor jeden Kommentar die Zeichenfolge // zur schreiben. Beispiel: // Die ist ein Kommentar der nur in C++ erlaubt ist --------------------------------------- 1.5. Die Operatoren 1.5.1 Vergleichs-Operatoren Folgende Vergleichs-Operatoren exitieren in C/C++: "ist gleich" = = "ungleich" ! = "kleiner" < "größer" > "kleiner gleich" <= "größer gleich" >= "ungleich" ! --------------------------------------- 1.5.2 Arithmetische-Operatoren Folgende arithmetische Operatoren extieren in C/C++: Zuweisungsoperator = Additionsoperator + Subtraktionsoperator - Multiplikationsoperator * Divisionsoperator / Modulooperator % Inkrementationsoperator ++, += Dekrementationsoperator --, -= Beispiele für eine Zuweisung: x = 5; y = 6; Beispiele für arithmetische Operatoren: x = 7 - 2; y = x / a; Beispiel für eine Inkrementation von x um 1: x++; oder x = x + 1; /* Aber man sollte schon die Möglichkeiten von C/C++ nutzen */ Beispiel für eine Dekrementation von y um 3: y -= 6; oder y = y - 6; /* Aber man sollte schon die Möglichkeiten von C/C++ nutzen */ --------------------------------------- 1.5.3 Logische-Operatoren Folgende Operatoren existieren in C/C++: logische UND (AND) && logische ODER (OR) | | logische Negation (NOT) ! --------------------------------------- 1.5.4 Bit-Operatoren Bit-Operatoren sind wichtig, wenn man zwei Bits mit AND, OR, oder XOR verknüpfen möchte. Folgende Bit-Operatoren existieren in C/C++: bitweise UND (AND) & bitweise inklusive ODER (OR) | bitweise exklusive ODER (XOR) ^ bitweise Negation (NOT) ! --------------------------------------- 1.6 Preprozessor-Anweisungen Preprozessor-Anweisungen sind Anweisungen für den Compiler. Preprozessor-Anweisung sind nur für die Compilierung entscheidend, für das Linken haben sie keine Bedeutung. Man sollte eine Preprozessor-Anweisung aber nicht mit der Programmiersprache im eigentlichen Sinn vergleichen, eine der am meisten benötigten Preprozessor-Anweisung ist das Einbinden einer Headerdatei mit der Preprozessor-Anweisung #include. --------------------------------------- 1.6.1 Die #include-Anweisung Die #include-Anweisung erlaubt eine Headerdatei einzubinden. Syntax für die -Anweisung:: #include oder #include "pfad-spezifikation" Dabei ist pfad-spezifikation die Angabe der Headerdatei inklusive Pfad. Der Pfad kann auch weggelassen werden, wenn dieser in einer Pfadliste für Headerdateien steht. Wird die Headerdatei nach der ersten Methode eingebunden, wird vorausgesetzt, daß die Headerdatei in einen Verzeichnis existiert, welches der Compilier mit Hilfe einer Pfadliste kennt. Diese Pfadliste für Headerdateien wird meist über einen Menüpunkt in Optionsmenü eingestellt oder durch die set-Anweisung im DOS. Wird die Headerdatei nach der zweiten Methode eingebunden, so befindet sich die Headerdatei im aktuellen Verzeichnis oder in einem anderen, welches hier angegeben werden muß (z.B. #include "include\datei.h" - hiere befindet sich die Headerdatei im include-Verzeichnis). Die #include-Anweisung sollte oben im Quelltext stehen. Nach einer #include-Anweisung folgt kein Semikolon. Durch das Einbinden von Headerdateien ist es möglich Funktionen, Klassen, Variablen u.ä. zu benutzen. Hinweis: Sollte der Compilier eine Funktion nicht finden, so kann dies meist daran liegen, daß eine Headerdatei noch nicht eingebunden wurden ist. Beispiel für das Einbinden der Headerdatei stdio.h #include stdio.h befindet sich in einen Verzeichnis welches der Compiler kennt. --------------------------------------- 1.6.2 Die #define-Anweisung Die #define-Anweisung ist leicht erklärt. Hier wird ein Symbol definiert welches einen konstanten Wert entspricht. Der Compiler ersetzt nun alle Vorkommen dieses Symbols im Quelltext durch den Wert, welches das Symbol repräsentiert. Man kann eine #define-Anweisung auch mit einer Konstantenvereinbarung vergleichen, was aber nicht ganz der Tatsache entsprechen würde. Nach einer #define-Anweisung folgt kein Semikolon. Syntax für die #define-Anweisung: #define toke-string Beispiel für eine #define-Anweisung: #define MAX_FILES 120 Hier würde nun der Compiler jedes Vorkommen von MAX_FILES im Quelltext durch die Konstante 120 ersetzen. Beispiel für eine #define-Anweisung: #define A_STRING "Hello world!" Hier würde nun der Compiler jedes Vorkommen von A_STRING im Quelltext durch die Konstante "Hello world!" ersetzen. --------------------------------------- 1.6.3 Die #elif-Anweisung Die #elif-Anweisung ist eine Verzweigung von einer #ifdef-, #ifndef- oder #if-Anweisung. Auf einer #elif-Anweisung kann einer #endif-, #else- oder einer #elif-Anweisung folgen. Der Block der nach einer #elif-Anweisung steht wird ausgeführt, wenn der Ausdruck in einer #ifdef-, #ifndef oder #if-Anweisung einen Wert ungleich Null ergibt. Nach einer #elif-Anweisung folgt kein Semikolon. --------------------------------------- 1.6.4 Die #else-Anweisung Die #else-Anweisung ist eine Verzeweisung von einer #ifdef-, #ifndef- oder #if-Anweisung. Nach #else-Anweisung muß immer eine #endif-Anweisung folgen. Nach einer #else-Anweisung folgt kein Semikolon. --------------------------------------- 1.6.5 Die #endif-Anweisung Die #endif-Anweisung markiert einen Block einer #ifdef-Anweisung. Die #endif-Anweisung wird nach einer #if-, #ifdef- oder #ifndef-Anweisung benötigt. Nach einer #endif-Anweisung folgt kein Semikolon. --------------------------------------- 1.6.6 Die #if-Anweisung Die #if-Anweisung markiert einen Block, welcher nur ausgeführt wird, wenn der Ausdrück in der -Anweisung gleich Null ist. Ansonsten wird der Block mit der #if-Anweisung übersprungen bis zum nächsten Block mit einem #endif, #else oder #elif. Nach der #if-Anweisung muß irgendwann eine #endif folgen! Nach einer #if-Anweisung folgt kein Semikolon. --------------------------------------- 1.6.7 Die #ifdef-Anweisung Eine #ifdef-Anweisung überprüft, ob ein Name mit der Anweisung #define festgelegt wurden ist. Ist dies der Fall so wird der nachfolgende Block ausgeführt, ansonsten wird der nachfolgende Block übersprungen. Nach einer #ifdef-Anweisung folgt kein Semikolon. --------------------------------------- 1.6.8 Die #ifndef-Anweisung Eine #ifndef-Anweisung überprüft, ob ein kein Name mit der Anweisung #define festgelegt wurden ist. Ist dies der Fall so wird der nachfolgende Block ausgeführt, ansonsten wird der nachfolgende Block übersprungen. Nach einer #ifndef-Anweisung folgt kein Semikolon. --------------------------------------- 1.6.9 Die #undef-Anweisung Die #undef-Anweisung ist das Gegenteil der #define-Anweisung. Alle Namen, welche mit #define festgelegt wurden sind werden gelöscht. --------------------------------------- 1.7 Datentypen von C/C++ C/C++ hat eine Menge an Datentypen. Es hat kein Sinn sich alle zu merken, aber die wichtigsten sollte man sich merken. Ich will hier darauf hinweisen, daß bei der Windows-Programmierung nach zusätliche Datentypen gibt. Da es sich aber um einen Einführungskurs handelt, möchte ich auf diese nicht weiter eingehen. Folgendes sei noch am Anfang gesagt: Es gibt keinen Datentyp, der einen String darstellt. Dies muß mit Hilfe eines Arrays erfolgen. Aber ihr werdet sehen, auch das ist nicht schwer. Sollte bei der Länge und beim Bereich systemabhängig stehen so bedeutet dies, daß es auf die Plattform ankommt für welches das Projekt compiliert wird. Weiterhin habe ich als Hinweis noch für diesen Fall die Länge und Größe im DOS (Real-Mode) angegeben. Name des Datentyps ## Länge ## Länge im DOS (Real-Mode) ## Äquivalente (Andere Namen) ## Bereich ## Bereich im DOS (Real-Mode) ############################################################################################################################################################## ## ## ## ## ## unsigned char ## 8 Bits /1 Bytes ## ## keine ## 0 bis 255 ## char 8 Bits / 1 Bytes keine -128 bis 127 enum systemabhängig 16 Bits / 2 Bytes keine systemabhängig -32.768 bis 32.767 int systemabhängig 16 Bits / 2 Bytes signed, signed int systemabhängig -32.768 bis 32.767 unsigned int systemabhängig 16 Bits / 2 Bytes unsigned systemabhängig 0 bis 65.535 short int 16 Bits / 2 Bytes short -32.768 bis 32.767 unsigned short int 16 Bits / 2 Bytes short in 0 bis 65.535 long 32 Bits /4 Bytes long int, signed long int -2.147.483.648 bis -2.147.483.647 unsigned long 32 Bits /4 Bytes unsigned long int 0 bis 4.294.967.295 float 32 Bits /4 Bytes keine 3.4 * 10^-38 bis 3.4 * 10^+38 double 64 Bits /8 Bytes keine 1.7 * 10^-308 bis 1.7 * 10^+308 long double 80 Bits /10 Bytes keine 3.4 * 10^-4.932 bis 1.1 * 10^+4.932 --------------------------------------- 1.7.1 Datentypen für Zeichen Folgende Datentypen für Zeichenen existieren: Name des Datentyps ## Länge ## Länge im DOS (Real-Mode) ## Äquivalente (Andere Namen) ## Bereich ## Bereich im DOS (Real-Mode) ############################################################################################################################################################## ## ## ## ## ## unsigned char 8 Bits /1 Bytes keine 0 bis 255 char 8 Bits /1 Bytes keine -128 bis 127 Hinweis: Der Datentyp char und unsigned char wird wie eine ganze Zahl interprediert. D.h. es kann mit den Datentyp char und unsigned char gerechnet werden. --------------------------------------- 1.7.2 Datentypen für ganze Zahlen Folgende Datentypen für ganze Zahlen existieren: Name des Datentyps ## Länge ## Länge im DOS (Real-Mode) ## Äquivalente (Andere Namen) ## Bereich ## Bereich im DOS (Real-Mode) ############################################################################################################################################################## ## ## ## ## ## enum systemabhängig 16 Bits / 2 Bytes keine systemabhängig -32.768 bis 32.767 int systemabhängig 16 Bits / 2 Bytes signed, signed int systemabhängig -32.768 bis 32.767 unsigned int systemabhängig 16 Bits / 2 Bytes unsigned systemabhängig 0 bis 65.535 short int 16 Bits /2 Bytes short -32.768 bis 32.767 unsigned short int 16 Bits /2 Bytes short in 0 bis 65.535 long 32 Bits /4 Bytes long int, signed long int -2.147.483.648 bis -2.147.483.647 unsigned long 32 Bits /4 Bytes unsigned long int 0 bis 4.294.967.295 --------------------------------------- 1.7.3 Datentypen für gebrochene Dezimalzahlen Folgende Datentypen für gebrochene Dezimalzahlen existieren: Name des Datentyps ## Länge ## Länge im DOS (Real-Mode) ## Äquivalente (Andere Namen) ## Bereich ## Bereich im DOS (Real-Mode) ############################################################################################################################################################## ## ## ## ## ## float 32 Bits /4 Bytes keine 3.4 * 10^-38 bis 3.4 * 10^+38 double 64 Bits /8 Bytes keine 1.7 * 10^-308 bis 1.7 * 10^+308 long double 80 Bits /10 Bytes keine 3.4 * 10^-4.932 bis 1.1 * 10^+4.932 --------------------------------------- 1.7.4 Eigenen Datentypen festlegen Einen eigenen Datentyp kann man mit der Anweisung typedef festlegen. Der Syntax lautet: typedef Typendefinition Bezeichner; Eine Typendefinition kann z.B. ein Struktur oder der Datentyp int sein. Der Bezeichner, wie der Name schon sagt, bezeichnet den neuen Datentyp. Beispiel: typedef unsigned char byte; Wir haben so ebend den Datentype byte in C/C++ definiert. --------------------------------------- 1.8 Variablen in C/C++ 1.8.1 Variablendeklaration in C/C++ Die Datentypen für C/C++ wurden nun beschrieben. Jetzt gilt es nur noch Variablen zu vereinbaren und diese zu benutzen. Dabei muß folgendes beachtet werden, in C werden die Variablen nach dem Beginn des Anweisungsblockes "{" festgelegt. In C++ kann die Variable an einer beliebigen Stelle im Anweisungsblock festgelegt werden. Der Syntax ist aber in C und C++ der selbe: Datentyp Variablenname [= Wert] [ <, Variablenname [= Wert]>]; Der Datentyp kann ein vorgegebener Datentyp oder ein selbst definierter Datentyp sein. Einen eigenen Datentyp kann man mit typedef festlegen.. Der Variablenname kann eine beliebige Folge von Zeichen sein, es dürfen nur keine Zeichen verwendet werden, die von C/C++ reserviert wurden sind (z.B ";"). Optional kann noch die Variable vorinitialisiert werden. Dies geschieht, indem man hinter den Variablenname ein = schreibt und einen Wert, der im Bereich des Datentypes ist angibt. Es besteht auch die Möglichkeit mehrere Variablen von ein und dem selben Typ auf einmal festzulegen. Die Variablennamen werden durch ein Komma getrennt. Soll jede Variable vorinitialisert werden, so wird nach dem Wert erst ein Komma geschrieben. Achtung: Semikolon nicht vergessen. Beispiele: Eine Variable wird festgelegt und vorinitialisiert. int i = 10; Zwei Variablen werden festgelegt und vorinitialisiert. int a = 20 , b = 30; Drei Variablen werden festgelegt und nicht vorinitialisiert. float x , y , z; --------------------------------------- 1.8.2 Wertzuweisung bei Variablen einfachen Types Die Zuweisung eines Wertes einer Variablen erfolgt durch den Zuweisungsoperator =. Es ist aber zu beachtet, daß der zugewiesene Wert genau dem Datentyp entspricht, da man sonst ein böses Erwachen haben kann. Dies kann z.B. sein, wenn man einer Variable von Typ gebrochene Dezimalzahl eine ganze Zahl zu weist. Beispiel: float x; x = 8.0; Das folgende Beispiel kann Fehler verursachen: float x; x = 8; Beispiel: int y; y = 2 Es steht nun in x eine ganze Zahl und keine gebrochene Zahl. Dies kann einige Fehler hervorrufen. Will man nun in eine Variable vom Typ float eine Variablen vom Typ int speichern, so muß die Variable vom Typ int mit 1.0 multiplizieren. Beispiel: float a; int b; b = 2; a = b * 1.0; --------------------------------------- 1.9 Datenverbunde in C/C++ In C/C++ existieren die Datenverbunde struct und union. Weiterhin gibt es in C++ den Datenverbund class, diesen werde ich aber erst bei der Objektoriertierung erklären. In den nachfolgenden Punkten werden wir unsere Aufmerksamkeit den Datenverbunden struct und union widmen. Die Gemeinsamkeit der beiden Datenverbunden besteht darin, Variablen von verschiedenen Datentypen zu einen neuen Datentyp (Datenverbund) zu vereinen. Der Unterschied zwischen beiden ist folgender: * im Datenverbund struct können mehrere Variablen zu einem Zeitpunkt exisieren, d.h. keine andere Variable im Datenverbund wird unterdrückt * im Datenverbund union kann aber nur ein Variable zu einem Zeitpunkt existieren, d.h. die anderern Variablen im Datenverbund werden unterdrückt bzw. existieren nicht --------------------------------------- 1.9.1 Der Datenverbund struct Im Datenverbund struct werden mehrere Variablen (Elemente) zu einen neuen Datentyp (Datenverbund) vereinigt. Im Datenverbund struct können mehrere Variablen zu einen Zeitpunkt existieren. Syntax: struct StructTypname { < Memberliste;> } [ Deklarator ]; StructTypname Name des Datenverbundes Member Feld von Elementen gleichen oder unterschiedlichen Datentypes. Deklarator Objektdefinition des Datenverbundes, d.h. es wird eine globale Variable des Datenverbundes definiert Wichtig: Das Semikolon hinter den Ende der Memberliste } nicht vergessen. Dies ist ein beliebter Fehler, den man schwer findet, wenn der Compiler ihn meldet Beispiele für die Deklaration ohne Deklarator: struct PERSON { char szName[ 50 ]; int iAge; float fWeight; }; Hier wurde der Datenverbund PERSON mit den Elementen szName (Name), iAge (Alter) und fWeight (Gewicht) deklariert. Beispiele für die Deklaration mit Deklarator: struct PERSON { char szName[ 50 ]; int iAge; float fWeight; } family_member; Hier wurde der Datenverbund PERSON mit den Elementen szName (Name), iAge (Alter) und fWeight (Gewicht) deklariert, und ein Objekt family_member definitiert. Wichtig: Das Semikolon hinter der Objektdefinition nicht vergessen. Dies ist ein beliebter Fehler, den man schwer findet, wenn der Compiler ihn meldet Will man nun eine Variable für diesen Datenverbund deklararieren, so ist der C-Stil und der C++-Stil zu beachten. Der C-Stil für eine Variablendeklaration (Syntax): struct StructTypname Variablenname Beispiel: struct PERSON sister; Der C++-Stil für eine Variablendeklaration (Syntax): StructTypname Variablenname Beispiel: PERSON brother; Der Unterschied zwischen C und C++ ist, daß man das Schlüsselwort struct weglassen kann. Man sollte diese beiden Unterschiede sich merken, da man sonst in einen C-Quellcode nur Fehlermeldungen bekommt. Der C-Stil hat natürlich auch einen Vorteil: man kann der Variable für den Datenverbund den selben Namen geben, wie schon der Datenverbund hat. Der Zugriff auf die Datenverbunde ist in C und C++ gleich. Syntax: StructVariablenName.MemberName StructVariablenName Variablenname für den Datenverbund MemberName Variablenname für das Element Beispiel: brother.iAge = 13; sister.iAge = 16; Beispielprogramm für den Datenverbund struct in C struct.c #include /* Headerdatei für die Ausgabe */ #include /* Headerdatei für die String-Operationen */ /* Lege Datenverbund PERSON fest */ struct PERSON { char szName[ 50 ]; int iAge; }; /* Hauptprogramm */ void main() { struct PERSON brother; /* Variable für den struct */ brother.iAge = 17; /* Weise Wert für das Alter zu */ strcpy( brother.szName , "Max" ); /* Weise Wert für den Namen zu */ printf( "%s ist %d alt." , brother.szName , brother.iAge ); } Beispielprogramm für den Datenverbund struct in C++ struct.cpp #include // Headerdatei für die Ausgabe #include // Headerdatei für die String-Operationen // Lege Datenverbund PERSON fest // struct PERSON { char szName[ 50 ]; int iAge; }; // Hauptprogramm // void main() { PERSON brother; // Variable für den struct brother.iAge = 17; // Weise Wert für das Alter zu strcpy( brother.szName , "Max" ); // Weise Wert für den Namen zu printf( "%s ist %d alt." , brother.szName , brother.iAge ); } --------------------------------------- 1.9.2 Der Datenverbund union Im Datenverbund union werden mehrere Variablen (Elemente) zu einen neuen Datentyp (Datenverbund) vereinigt. Im Datenverbund union kann nur eine Variable (Element) zu einen Zeitpunkt existieren. Es ist darauf zu achten, daß genügend Speicher für das größte Element zur Verfügung steht. Syntax: union UnionTypname { < Member; > } [ Deklarator ]; UnionTypname Name des Datenverbundes Member Feld von Elementen gleichen oder unterschiedlichen Datentypes. Deklarator Objektdefinition des Datenverbundes, d.h. es wird eine globale Variable des Datenverbundes definiert Wichtig: Das Semikolon hinter den Ende der Memberliste } nicht vergessen. Dies ist ein beliebter Fehler, den man schwer findet, wenn der Compiler ihn meldet Beispiele für die Deklaration ohne Deklarator: union INT_OR_LONG { int i; long l; }; Hier wurde der Datenverbund INT_OR_LONG mit den Elementen i für int und l für long deklariert. Beispiele für die Deklaration mit Deklarator: union INT_OR_LONG { int i; long l; } int_long; Hier wurde der Datenverbund INT_OR_LONG mit den Elementen i für int und l für long deklariert, und ein Objekt int_long definitiert. Wichtig: Das Semikolon hinter der Objektdefinition nicht vergessen. Dies ist ein beliebter Fehler, den man schwer findet, wenn der Compiler ihn meldet Will man nun eine Variable für diesen Datenverbund deklararieren, so ist der C-Stil und der C++-Stil zu beachten. Der C-Stil für eine Variablendeklaration (Syntax): union UnionTypname Variablenname Beispiel: union INT_OR_LONG int_long; Der C++-Stil für eine Variablendeklaration (Syntax): UnionTypname Variablenname Beispiel: INT_OR_LONG int_long; Der Unterschied zwischen C und C++ ist, daß man das Schlüsselwort union weglassen kann. Man sollte diese beiden Unterschiede sich merken, da man sonst in einen C-Quellcode nur Fehlermeldungen bekommt. Der C-Stil hat natürlich auch einen Vorteil: man kann der Variable für den Datenverbund den selben Namen geben, wie schon der Datenverbund hat. Der Zugriff auf die Datenverbunde ist in C und C++ gleich. Syntax: UnionVariablenName.MemberName UnionVriablenName Variablenname für den Datenverbund MemberName Variablenname für das Element Es kann aber nur ein Element existieren! D.h. man kann nicht auf alle Elemente zur gleichen Zeit zugreifen. Beispiel: int_long.i = 13; --------------------------------------- 1.10 True und False in C/C++ In C/C++ existieren keine Schlüsselwörter mit der Bezeichnung True und False. In C/C++ wird folgendes festgelegt * alles, was gleich Null ist, ist False * alles, was ungleich Null ist, ist True. Einige Compiler haben aber solche Typen vordefiniert. Meist durch eine #define-Anweisung. Man sollte sich aber nicht darauf verlassen, das True und False bei jeden C/C++ - Compiler existiert. Schaut deshalb in der Online-Hilfe nach. Möglichkeit für die Definition von True und False #define FALSE 0 #define TRUE !FALSE --------------------------------------- 1.11 Verzweigungen in C/C++ Verzweigungen in C/C++ gibt es zwei Möglichkeiten der Verzweigung im Quellcode. Die Einfache Verzweigung erfolgt durch eine if-Anweisung, und die mehrfach Verzweigung erfolgt durch eine switch-Anweisung. --------------------------------------- 1.11.1 Einfache Verzweigung durch die if-Anweisung in C/C++ Eine einfache Verzweigung in C/C++ erfolgt durch eine if-Anweisung. Es besteht auch die Möglichkeit if-Anweisungen zu verschachteln. Sollte mehr als drei if-Anweisungen benötigt werden, so sollte aus Preformenzgründen eine switch-Anweisung verwendet werden. Syntax: if ( Ausdruck ) < Anweisung1; > [ else < Anweisung2; > ] Wenn der Ausdruck ungleich Null ist, wird die Anweisung1 ausgeführt. Sollte eine Verzweigung mit else festgelegt wurden sein, so wird diese Ausgeführt, wenn der Ausdruck gleich Null ist. Wichtig: Das Semikolon vor dem else nicht vergessen. Sollte vor dem else ein Anweisungsblock stehen, so wird kein Semikolon vor dem else geschrieben. Beispiele: if ( count < 50 ) count ++; if ( x < y ) z = y; else z = x; // Überprüfe, ob Ready Null (False) ist // if ( !Ready ) { printf( "\nFehler! Weiter mit beliebiger Taste..." ); getch(); } else { printf( "\nKeine Fehler aufgetreten! Weiter mit beliebiger Taste..." ); getch(); } Hier wird überprüft, ob Ready nicht True ist. D.h. Ready muß Null sein, damit die Anweisung nach Ready ausgeführt wird. Beispiel für eine verschachtelte if-Anweisung: if ( x == 10 ) if ( y == 10 ) z = y; else // else für die 2. if-Anweisung z = x; else // else für die 1. if-Anweisung z = 0; --------------------------------------- 1.11.2 Mehrfachverzweigung durch die switch-Anweisung in C/C++ Eine Mehrfachverzweiung in C/C++ ist durch die switch-Anweisung möglich. Syntax: switch ( Ausdruck ) { [] ... [] ... [default: Anweisung;] } Die Auswertung des Ausdrucks muß einen Integertypen liefern. Die Verzweigungpunkte werden durch das Schlüsselwort case mit nachfolgenden konstanten Ausdruck, welcher von Typ Integer und eindeutig sein muß, festgelegt. Nach einen Verzweigungspunkt können mehrere Anweisungen (Anweisungsblock) stehen. Wird eine Übereinstimmung zwischen den Ausdruck und einem konstanten Ausdruck gefunden, so wird zu dem gefundenen konstanten Ausdruck gesprungen und alle Anweisungen nach dem konstanten Ausdruck ausgeführt, bis eine break-Anweisung folgt oder das Ende der Anweisung (Anweisungsblock) erreicht wird. Befindet sich das Pinfix default in der switch-Anweisung, so wird die Ausführung an diesem Punkt fortgesetzt, wenn keine Übereinstimmung gefunden wurden ist. Andernfalls wird die switch-Anweisung nicht ausgeführt. Beispiel: switch ( operand ) { case add: z = x + y; break; case sub: z = x - y; break; case mul: z = x * y; break; case div: z = x / y; break; case inc: z++; break; case dec: z--; break; default: printf( "\nOperand nicht definiert!" ); } add, sub, div, inc und dec sind konstante Integertypen, welche eindeutig sind. --------------------------------------- 1.12 Schleifen in C++ Es gibt drei verschiedene Arten von Schleifen in C/C++: * die kopfgesteuerte for-Schleife * die kopfgesteuerte while-Schleife * die fußgesteuerte do-while-Schleife Schleifen dienen dazu einen Anweisung bzw. einen Anweisungsblock mehrfach auszuführen. Dabei hängt die Anzahl der Schleifendurchläufe von der Abbruchsbedingung ab. --------------------------------------- 1.12.1 Die for-Schleife Die for-Schleife wird meist auch als Zählschleife bezeichnet. Syntax: for ( [Ausdruck1] ; [Ausdruck2] ; [Ausdruck3] ) Anweisung; Die Anweisung wird solange wiederholt, bis die Auswertung von Ausdruck2 False ergibt (d.h. den Wert 0). Ausdruck1 wird vor dem ersten Durchlauf ausgewertet und initialisiert normalerweise eine Laufvariable, die im Test mit Ausdruck2 verwendet wird. Ausdruck3 wird nach jedem Durchlauf ausgewertet und normalerweise zur Erhöhung der Laufvariablen verwendet. Alle drei Ausdrücke sind optional. Für ein nicht definiertes Ausdruck2 wird 1 angenommen. In C++ kann Ausdruck1 ein Ausdruck oder eine Deklaration sein. Der Bereich der deklarierten Bezeichner reicht nur bis zum Ende der Steueranweisung. Die Anweisung kann auch durch ein Anweisungsblock ersetzt werden. Es folgt vor den Anweisungungsblock ein { und nach dem Anweisungsblock ein }. Beispiel: for ( i = 1 ; i < 10 ; i ++ ) sum += i; i muß schon vorher festgelegt wurden sein. Beispiel für C++: for ( int i = 1 ; i < 10 ; i ++ ) sum += i; Hier ist zu beachten, daß eine Deklaration in Ausdruck1 vorgenommen werden darf. --------------------------------------- 1.12.2 Die while-Schleife Wiederholt die Ausführung von Anweisungen. Syntax: while ( Ausdruck ) Anweisung; Die Anweisung wird so oft wiederholt, bis die Auswertung von Ausdruck den Wert FALSE (0) ergibt. Die Prüfung von Ausdruck findet jeweils vor der Ausführung von Anweisung statt, d.h. zu Beginn jedes Schleifendurchlaufs. Beispiel: while ( i < 10 ) i++; Einfaches Beispielprogramm #include void main() { char szString[ 50 ] = { "Hello world" }; int i = 0; while ( szString[ i ] != '\0' ) { printf( "\nDas %d. Zeichen des String ist %c. " , i , szString[ i ] ); i++; } } --------------------------------------- --------------------------------------- Autor: Frank.Wassewitz@in.fh-merseburg.de Übesetzung in das txt-Format: webmaster@c-schell.de www.c-schell.de