Programmieren in C 1 2 3 4 5 6 Wirtschaftsgymnasium Eisenberg GK Einführung ................................................................................................................................... 2 Grundlegende Sprachelemente .................................................................................................... 4 2.1 Kommentare .......................................................................................................................... 4 2.2 Datentypen und Variablen ..................................................................................................... 4 2.2.1 Variablennamen ............................................................................................................. 4 2.3 Datentypen............................................................................................................................. 5 2.3.1 Ganzzahlige Variablen ................................................................................................... 5 2.3.2 Fließkommazahlen ......................................................................................................... 5 2.3.3 Zeichen ........................................................................................................................... 5 2.4 Konstanten ............................................................................................................................. 5 2.5 Anweisungen und Blöcke ...................................................................................................... 7 Kontrollstrukturen ........................................................................................................................ 8 3.1 Selektion ................................................................................................................................ 8 3.1.1 Einfache Abfragen (if – else) ......................................................................................... 8 3.1.2 Verschachtelte if- Anweisung ........................................................................................ 9 3.1.3 Die switch - case – Anweisung ................................................................................... 15 3.2 Iteration ............................................................................................................................... 17 3.2.1 Abweisende Schleife mit while (kopfgesteuerte Schleife) .......................................... 17 3.2.2 For-Schleife .................................................................................................................. 19 3.2.3 Do-while Schleife ........................................................................................................ 21 Unterprogramme ........................................................................................................................ 24 4.1 Hinführung .......................................................................................................................... 24 4.2 Funktionen ........................................................................................................................... 24 4.3 Vordefinierte Funktionen (Standard-Funktionen) ............................................................... 25 4.4 Benutzerdefinierte Funktionen ............................................................................................ 25 4.4.1 Ort der Definition von Funktionen............................................................................... 25 Blöcke und Funktionen .............................................................................................................. 30 5.1 Stuktur eines Blockes .......................................................................................................... 30 5.1.1 Schachtelung von Blöcken ........................................................................................... 30 5.2 Gültigkeit, Sichtbarkeit und Lebensdauer ........................................................................... 31 Felder (Arrays) und Zeichenketten ............................................................................................ 35 6.1 Arrays verwenden................................................................................................................ 35 6.2 Das eindimensionale Feld ................................................................................................... 35 6.3 Arrays initialisieren und darauf zugreifen ........................................................................... 35 6.4 Initialisierung mit einer Initialisierungsliste........................................................................ 37 6.5 Strings (Zeichenketten) ....................................................................................................... 39 6.5.1 Strings initialisieren ..................................................................................................... 39 6.5.2 Einlesen von Strings..................................................................................................... 39 6.6 Die Standard- Bibliothek <string.h> ................................................................................... 40 6.6.1 strcat() – Strings aneinanderhängen ............................................................................. 40 6.6.2 strchr() – ein Zeichen im String suchen ....................................................................... 41 6.6.3 strcmp() – Strings vergleichen ..................................................................................... 42 6.6.4 strcpy() – einen String kopieren ................................................................................... 43 6.6.5 strlen() - Länge eines Strings ermitteln ....................................................................... 44 Seite 1 von 45 Einführung Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg 1 Einführung http://www.c-howto.de/tutorial-einfuehrung-compiler-windows.html http://www.tutorials.at/c/c-oder-cplusplus.html 1. Erstes Programm Programm Devc++ öffnen Dort folgendes Programm eingeben: Programmbestandteile: Programmteil #include <stdio.h> main() Seite 2 von 45 Beschreibung Befehl zur Einbindung von Bibliothen Standard Input/Output Ermöglicht die Verwendung von Ein- Ausgabebefehlen z.B. printf() und scanf() Funktion, die jedes C-Programm aufweisen muss. Wird auch als Hauptprogramm bezeichnet. int gibt den Rückgabewert der Funktion an. Weißt das Programm im Ablauf keinen Fehler auf ist der Rückgabewert 0. (void) steht dafür, dass keine Werte übergeben werden. Einführung Nicole Rottmann GK Programmieren in C {} printf() system(„Pause“) return 0 ; Wirtschaftsgymnasium Eisenberg GK In den Klammern stehen die Anweisungen, welche zum Hauptprogramm gehören. Ausgabe auf den Bildschirm Wird benötigt zur Ansicht des Bildschirms Beendet das Hauptprogramm Semikolon schließt jede! Anweisung ab. Programm abspeichern unter ErstesProgramm.c Um das Programm compilieren (übersetzen) zu können in Devc++ auf Ausführen Kompilieren Gestartet wird das Programm mit Ausführen Ausführen Als Ausgabe erscheint Hello World 1. Übung Ergänze die Zeichenkette um einen Zeilenumbruch \n „Hello Word \n“. Compiliere das Programm und führe es aus. Seite 3 von 45 Einführung Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK 2 Grundlegende Sprachelemente 2.1 Kommentare Kommentare sind für die Lesbarkeit und Verständlichkeit von Programmen von großer Bedeutung. Einzeilige Kommentare können mit // erstellt werden. Ein größerer Kommentarblock beginnt mit /* und endet mit */ 2.2 Datentypen und Variablen Jedes Programm verarbeitet während seiner Ausführung Daten, die in geeigneter Form im Programm abgelegt sein müssen. Zur eindeutigen Identifizierung wird jedem einzelnen Datum ein Name zugeordnet. Dieser ermöglicht es dem Programmierer auf den Inhalt dieses Datums zuzugreifen, bzw. Veränderungen daran vorzunehmen. Durch die Zuordnung eines Namens zu einem bestimmten Datum wird eine Variable erzeugt. Variablen sind reservierte mit Namen versehene Platzhalter für gewisse Informationen während des Programmablaufs. Variablen müssen vor ihrem ersten Gebrauch deklariert werden. Dazu gibt der Programmierer einer Speicherzelle einen Namen und ordnet diesem Namen, und damit auch der Speicherzelle einen Datentyp zu. Jede Variable besitzt in C einen Datentyp. Durch die reine Deklaration ist der Variablen aber noch kein Startwert zugewiesen. Dies muss vor dem ersten Gebrauch durch den Programmierer gewährleistet werden. 2.2.1 Variablennamen Bei der Vergabe von Variablennamen ist auf die Aussagefähigkeit des Namens zu achten. Z.B. ist zaehler statt z deutlicher. Folgende Regeln sind zu beachten: Zulässig sind die Zeichen A-Z, a-z, 0-9 und der Unterstrich_ Groß- und Kleinschreibung sind zu beachten. Zahl, zahl und ZAHL sind drei unterschiedliche Variablen. Dieses Verhalten wird als case-sensitiv bezeichnet. Die Schlüsselwörter von C wie z.B. switch, float, printf,... sind als Variablennamen nicht erlaubt. Variablennamen dürfen nicht mit einer Ziffer beginnen. Variablennamen sollten mit einem Kleinbuchstaben beginnen, also besser zahl1 als Zahl1. Das ist für die Unterscheidung von später einzuführenden sog. Klassen von großer Bedeutung und erhöht die Lesbarkeit von Programmen. Für die Deklaration von Variablen stehen unterschiedliche Datentypen für die verschiedensten Aufgabenbereiche der Variablen zur Verfügung. Seite 4 von 45 Grundlegende Sprachelemente Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK 2.3 Datentypen 2.3.1 Ganzzahlige Variablen In c gibt es drei Datentypen zur Aufnahme und Darstellung von Ganzzahlen (also Zahlen ohne Nachkommastellen): char int short int bzw. long int Der Datentyp char ist der kleinste verfügbare Ganzzahldatentyp. Er kann maximal 8 Bit breite Werte aufnehmen und ist dazu geeignet jeden beliebigen ASCII-Wert einer Variablen darzustellen, Der darstellbare Zahlenbereich liebt also zwischen -128 und +127, d.h., dass es sich hier um eine vorzeichenbehaftete Darstellung handelt. Der Ganzzahldatentyp int erfasst 32 Bit kann somit Zahlen im Bereich von -2147483648 bis 2147483647 darstellen. Long int besitzt die Möglichkeit 64 Bit große Zahlen darzustellen. An welcher Stelle die Deklaration der Variablen vorzunehmen ist lässt sich nicht für alle Fälle eindeutig beantworten. Grundsätzlich muss die Deklaration einer Variablen vor ihrem ersten Gebrauch passieren. Allerdings hat die exakte Position der Deklaration Einfluss auf den Gültigkeitsbereich der Variablen. 2.3.2 Fließkommazahlen Fließkommazahlen dienen zur Aufnahme von Zahlen mit einem möglichen Nachkommanteil, also klassische Dezimalzahlen. In c gibt es zwei Möglichkeiten, Fließkommazahlen zu deklarieren. float double Als Dezimalkomma in der Eingabe dient bei Fließkommazahlen der Punkt. bei der Eingabe von Zahlenwerten in Programme. 2.3.3 Zeichen Um einzelne Zeichen darstellen und verarbeiten zu können, wird der Datentyp char verwendet. Zugewiesen werden die Werte zu solchen char Variablen durch Verwendung der einfachen Anführungszeichen: char zeichen = ' ? ' char buchstabe = ' a ' Dabei gilt immer ' a ' < ' b ' < ' c ' <.........< ' z ' 2.4 Konstanten Für Werte, die im Programm nicht veränderbar sein sollen, werden in einem Programm Konstanten verwendet. Ihnen wird bereits bei der Deklaration ein fester Wert zugewiesen, der sich während des Programmlaufs nicht mehr ändern kann. Eingeleitet werden solche Deklarationen durch das Schlüsselwort const. Konstanten können für jeden Datentyp deklariert werden. const float PI = 3.14159265; const int WELTWUNDER = 7; Seite 5 von 45 Grundlegende Sprachelemente Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK Für die Benennung von Konstanten gelten im Wesentlichen die gleichen Regeln, wie für Variablennamen. Um die Lesbarkeit des Quelltextes zu erhöhen, sollte man die Namen von Konstanten konsequent komplett mir Großbuchstaben darstellen. 2. Übung Schreibe ein Programm, das die Kreisfläche eines Kreises mit dem Radius 4 cm berechnet. Die Ausgabe soll lauten: Die Kreisfläche beträgt: 50.24 cm ² Als Datentyp für die Variable kreisflaeche muss float gewählt werden, da das Ergebnis eine Kommazahl ergibt. Formatierte Ausgabe mit printf(): Die Funktion printf() dient zur Ausgabe. Es können Texte und Platzhalter für Variablenwerte angegeben werden. Platzhalter für Variablenwerte beginnen mit %, die darauf folgenden Zeichen geben an, von welchem Datentyp der auszugebende Variablenwert ist und wie die Ausgabe formatiert werden soll, d.h. Die Anzahl der gewünschten Stellen, ob die Ausgabe rechts- oder linksbündig erfolgen soll, ob führende Nullen angegeben werden sollen etc. %c für Daten vom Typ char. Die Funktion gibt das Zeichen aus, das dem ASCII Code des Variablenwertes entspricht. %d für Daten vom Typ int. %f für Daten vom Typ float und double Die Angabe %m.nf sorgt dafür, dass die auszugebende Zahl insgesamt mit m Stellen ausgegeben wird. Davon sind dann n Nachkommastellen. Für die Anzahl der Vorkommastellen ist der Dezimalpunkt und das Vorzeichen abzuziehen. Bsp. Es sollen beliebige Zahlen aufsummiert werden und die gebildete Summe mit dem Variablenname summe ausgegeben werden. Die Ausgabe soll folgendermaßen aussehen: Die Summe ergibt: 200.66 Dazu ist folgende Programmzeile notwendig (nur für die Ausgabe, dies ist keine Berechnung!) printf(„Die Summe ergibt: %5..2f „ , summe) Dabei sollen die Anführungszeichen oben sein. Es wird also der Text und die Formatierungsvorschrift in hochgestellte Anführungszeichen gesetzt und mit einem Komma getrennt der Variablenname der auszugebenden Variable. Soll nach der ausgegebenen Variablen noch ein Text stehen so muss dieser in einer erneuten printf() Anweisung stehen. Ergänze noch die Konstante PI und verwende sie zur Berechnung der Kreisfläche. 3. Übung Schreibe ein Programm, welches 60 Grad Fahrenheit in Grad Celsius umrechnet. Verwende dazu folgende Formel: Grad Celsius = 0,5556*(Grad Fahrenheit – 32). Die Ausgabe soll folgendermaßen erfolgen: Fahrenheit 60 Seite 6 von 45 Celsius 15 Grundlegende Sprachelemente Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK 2.5 Anweisungen und Blöcke In C wird jede Programmzeile mit einem Semikolon abgeschlossen. Folglich stellt jede Programmzeile eine Anweisung dar. Einzelne Anweisungen werden durch die Verwendung von geschweiften Klammern {} zu Blöcken zusammen gefasst. Diese Blöcke spielen eine wesentliche Rolle bei den Abfragen (Alternationen) und Wiederholungen (Iterationen). Darüber hinaus haben solche Blöcke die Wirkung, dass in ihnen deklarierte Variablen nur innerhalb des Blockes definiert sind. Seite 7 von 45 Grundlegende Sprachelemente Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK 3 Kontrollstrukturen 3.1 Selektion 3.1.1 Einfache Abfragen (if – else) Mit Hilfe von if und else werden Entscheidungen formuliert. Diese Anweisung besitzt folgende Syntax. if (Ausdruck) { Anweisung1; } else { Anweisung2; } Zunächst wird Ausdruck auf seinen Wahrheitsgehalt überprüft. Ist Ausdruck wahr, so wird Anweisung1 (oder ein entsprechender Anweisungsblock in geschweiften Klammern) ausgeführt. Ist Ausdruck jedoch falsch, so wird Anweisung2 (oder entsprechender Block in geschweiften Klammern) ausgeführt. Der else - Teil ist optional. Soll keine spezielle Anweisung abgearbeitet werden, kann dieser Block komplett entfallen. Beispiel: Programm: if ( b == 0) { ergebnis = 4; } else { ergebnis = 4 – b; } Struktogramm: b=0 ja ergebnis = 4 nein ergebnis = 4-b Achtung !! Der Bedingungsoperator ist gleich (=) wird im Ausdruck der if Abfrage mit zwei Gleichheitszeichen dargestellt (==). Seite 8 von 45 Kontrollstrukturen Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK 3.1.2 Verschachtelte if- Anweisung Folgt innerhalb einer Alternation eine weitere Bedingung in einem der Anweisungsblöcke so erhält man eine Verschachtelung. Die Verschachtelung kann sowohl im ja- Zweig als auch im nein-Zweig oder in beiden Zweigen erfolgen. Ebenso auch in allen tiefer liegenden Fällen. Auf diese Art und Weise kann schnell eine komplexe Struktur entstehen. Programm: if (b == 0) { ergebnis = 4; } else if (b == 4) { ergebnis = 8; } else { ergebnis = 4 – b; } b=0 ja nein ergebnis = 4 b=4 ja ergebnis =8 nein ergebnis =4-b 4. Übung Programme\Zahlenvergleich.c Schreibe ein Programm, das nachdem zwei Zahlen eingegeben wurden folgendes ausgibt: „beide gleich“, „erste Zahl größer als zweite Zahl“, erste Zahl kleiner als zweite Zahl“. Beispiel wenn zahl1 =7 und zahl2 = 4 dann Ausgabe: „erste Zahl größer zweite Zahl“. Hinweis: Es gibt folgende Vergleichsoperatoren: < > == != <= >= kleiner größer gleich ungleich kleiner gleich größer gleich Logische Operatoren Mit logischen Operatoren kann man mehrere Bedingungen miteinander verknüpfen. Logisches UND Syntax if (Bedingung1) && (Bedingung2) { } Beim logischen UND müssen beide Bedingungen wahr sein, damit der Gesamtausdruck erfüllt ist. Seite 9 von 45 Kontrollstrukturen Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK 5. Übung Programme\logischUnd.c Schreibe ein Programm das nach Eingabe eines Alters für Jugendliche über 6 und unter 16 Jahren folgendes ausgibt: „Du bekommst ein Jugendticket“. Logisches ODER Syntax if (Bedingung1) || (Bedingung2) { } Beim logischen ODER muss eine Bedingung wahr sein, damit der Gesamtausdruck wahr wird. 6. Übung Programme\Logisch Oder.c Man erhält einen ermäßigten Preis, wenn man jünger als 14 und älter als 60 Jahre ist. Ausgabe: „Du erhältst eine Ermäßigung.“ Logisches NICHT Syntax if (! Bedingung) { } 7. Übung Programme\Logisch Nicht.c Wenn jemand nicht älter als 18 Jahre ist. Ausgabe „Zu jung.“ 8. Übung Programme\kartenpreis.c Eingabe : Alter und Kartenpreis unter 5 frei; 5-12 Jahre halber Preis; 13 – 55 Jahre voller Preis; über 55 frei. Zeichne das Struktogramm dazu. Einschub: char- Variable In einer char – Variable kann nur ein Buchstabe gespeichert werden. Beispiel: In einer Disco zahlen Jungs den vollen Preis, Mädchen sind frei. Seite 10 von 45 Kontrollstrukturen Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK Achtung!! Zur Abfrage eines Buchstabens ist dieser in Hochkomma zu setzten. 9. Übung Programme\Konzertkarte.c Schreibe ein Programm, das den Preis von Konzertkarten ausgibt. Eingabe: Grundpreis in € Altersgruppe: (J)ugendlicher: -30 %; (E)rwachsener, (P)ensionist: -20% Kategorie 1 (Stehplatz) oder 2 (Sitzplatz) +50% Ausgabe: Grundpreis, Altersrabatt, Kategoriezuschlag, Endpreis. 3.1.2.1 Postfix- und Präfixoperatoren Postfix- Operatoren sind einstellige (unäre) Operatoren, die hinter (post) ihrem Operanden stehen. Präfix- Operatoren sind einstellige Operatoren, die vor (prä) ihrem Operanden stehen. Der Inkrement Ausdruck ++ erhöht den Wert einer Variablen um 1. i++ stellt die Anwendung des Postfix-Operators ++ auf seinen Operanden i dar. Beispiel int i = 3: printf (″%d″, i++); //Es wird 3 ausgegeben und anschließend wird i auf 4 erhöht. printf(″%d″, i); // Es wird 4 ausgegeben. ++ i stellt die Anwendung des Präfix-Operators ++ auf seinen Operanden i dar. Seite 11 von 45 Kontrollstrukturen Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK Beispiel int i =3: printf(″%d″, ++i); printf(″%d″, i); // Es wird 4 ausgegeben, da i zuerst um 1 erhöht wird. // Wiederum wird 4 ausgegeben. Der Dekrement Ausdruck -- vermindert den Wert einer Variablen um 1. i-- : i wird erst nach Ausführung einer Anweisung vermindert. -- i : erst wird i vermindert und dann die Anweisung ausgeführt. 3.1.2.2 Auswertungsreihenfolge Wie in der Mathematik spielt es bei C eine wichtige Rolle, in welcher Reihenfolge ein Ausdruck berechnet wird. Genau wie in der Mathematik gilt auch in C die Regel ″Punkt vor Strich″, weshalb 5+2*3 gleich 11 und nicht 21 ist. Allerdings gibt es in C sehr viele Operatoren. Daher muss für alle Operatoren festgelegt werden, welcher im Zweifelsfall Priorität hat. Seite 12 von 45 Kontrollstrukturen Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg 10. Übung Verändere das Programm so, dass nur noch eine if- else Anweisung verwendet wird. Die Funktionalität des Programms soll dabei erhalten bleiben. Seite 13 von 45 Kontrollstrukturen Nicole Rottmann GK Programmieren in C Wirtschaftsgymnasium Eisenberg GK 11. Übung Lösung Gebrauch verschiedener Operatoren Gegeben sei: int a = 2, b = 1; Finde ohne C-Compiler heraus, welcher Wert der Variablen a in den einzelnen Anweisungen zugewiesen wird. Beachte dabei genau die Priorität der entsprechenden Operatoren. a) b) c) d) e) f) g) h) i) j) a = b = 2; a = 5 * 3 + 2; a = 5 * (3+2); a = !(--b == 0); (Bedenke an dieser Stelle, dass für einen falschen Ausdruck der Zahlenwert 0 zurückgegeben wird, für einen wahren Ausdruck der Zahlenwert 1.) a = 0 && 0 + 2; a = - 5 – 5; a = - (+ b++); a = 5 == 5 && 0 || 1; (Auch hier wird wieder für jeden wahren Ausdruck der Zahlenwert 1 gesetzt, für jeden falschen Audruck der Zahlenwert 0) a = ((((((b + b) *2) + b) && b || b)) == b); (Jeder Zahlenwert ungleich 0 wird als wahr gewertet) a = b + (++b); Seite 14 von 45 Kontrollstrukturen Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK 12. Übung c-Programme\Staubsauger.c Schreibe ein Programm, das Verkäuferprovisionen berechnet. Verkäufer erhalten pro Monat ein Grundgehalt von 500€. Er verkauft Staubsauger zu je 750€. Für jeden Staubsauger erhält er 3% Provision; ab 20 Stk. 5%, ab 100 Stk. 7%. Eingabe: Staubsauger Ausgabe: Grundgehalt, Provision, Endgehalt 3.1.3 Die switch - case – Anweisung Eine weitere Möglichkeit mehrere Alternativen zu einem Ausdruck zu bearbeiten, stellt die caseAnweisung dar. Ihre Syntax lautet: switch (Ausdruck) { case (Ausdruck1) : case (Ausdruck2): case (Ausdruck3): ….. default: Anweisung1; break; Anweisung2; break; Anweisung3; break; Anweisung4; } Beispiel: Programm Seite 15 von 45 Kontrollstrukturen Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK 13. Übung Welche der folgenden Zuweisungen sind falsch? a) summe = summe + 10; b) x*x = x*5; c) 5a = anfang + ende; d) wert = eingabe + alter_wert * 2 e) g_betrag = betrag * 1.14; f) gesamt-wert = wert1 + wert2 + wert3 ; 14. Übung Programme\rechentrainer.c Rechentrainer Welche Rechenoperationen möchtest du üben ? (+ , - , * , /) Beispiel für + Operation Wieviel ist 3 + 5 ? Bei Eingabe 8 soll „richtig“ ansonsten „falsch“ ausgegeben werden Lösungweg: Ausgabe: „Welche Rechenoperation…..“ Eingabe rechenop Computer erzeugt zwei zufällige Zahlen: zahl1, zahl2 Auswahl erfolgt über case Anweisung: Für +: Ausgabe: Zahl1 + Zahl2 = Eingabe: ergebnisBenutzer ergebnisCompulter berechnen Wenn ergebnisBenutzer = ergebnisComputer übereinstimmen, dann Ausgabe „richtig“, sonst Ausgabe „falsch“: Für -: …. Welche Variablen brauchen wir? rechenop, zahl1, zahl2, ergebnisComputer, ergebnisBenutzer Zufallszahlen erzeugen 3 und 5 sind zufällige Werte zwischen 1 und 10, die vom Computer erzeugt werden. Folgende Befehle sind dazu notwendig srand( time(0)); //wird benötigt, damit jedes mal eine neue Zufallszahl erzeugt wird. zahl1 = rand() % 10 +1; // rand() lautet die Funktion, die eine Zufallszahl zwischen 0 und 32767 erzeugt. Damit eine Zahl zwischen 1 und 10 entsteht wird die gewonnene Zahl durch 10 geteilt und der Rest davon genommen % 10. 512 / 10 = 51 Rest 2; 390/10 = 39 Rest 0 da wir eine Zahl zwischen 1 und 10 bekommen wollen müssen wir noch 1 addieren. Seite 16 von 45 Kontrollstrukturen Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK Einschub Modulo- Operation Für den Datentyp int sind, außer den Grundrechenarten Addition (+), Subtraktion (-), Multiplikation (*) und Division (/), der Divisionsrest (%) definiert. Bei der Division von Zahlen des Datentyps int ist zu beachten, dass das Ergebnis der Division immer vom Datentyp int ist. Beispiel: 9 / 4 = 2 ,die Kommastellen werden abgeschnitten. 9 % 4 = 1 , 2 * 4 ergibt 8, somit ist 1 der ganzzahlige Rest der Division. Übung zu den Operationen / und %: 7/ 2= -11 / 4 = -11 / -4 = 11 / -4 = 7% 2= -11 % 4 = -11 % -4 = 11 % -4 = 3.2 Iteration 3.2.1 Abweisende Schleife mit while (kopfgesteuerte Schleife) Stell dir vor, wir wollen die Zahlen von 1 bis 5 untereinander auf dem Bildschirm ausgeben. Das kann man einfach folgendermaßen umsetzen. printf( ″ 1 \n 2\n 3\n 4\n 5\n ″); Sollen jedoch deutlich mehr Zahlen ausgegeben werden, bzw. größere Anweisungsblöcke mehrmals ausgeführt werden, verwenden wir die while-Schleife. Die Syntax der while- Schleife lautet: while (Ausdruck) Anweisung Solange Ausdruck Anweisung In einer while-Schleife kann eine Anweisung in Abhängigkeit von der Auswertung des Ausdrucks wiederholt ausgeführt werden. Da der Ausdruck vor der Ausführung der Anweisung bewertet wird, spricht man von einer abweisenden Schleife. Der Ausdruck wird berechnet und die Anweisung nur dann ausgeführt, wenn der Ausdruck wahr ist. Um keine Endlos-Schleife zu erzeugen, muss daher der Wert des Ausdrucks im Schleifenrumpf, d.h. im Anweisungsteil verändert werden. Seite 17 von 45 Kontrollstrukturen Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK Beispiel: i=0 Solange (i < 10) Gib den Wert von i aus. Erhöhe i um 1. i++ ist ausführlich geschrieben i = i +1 Die Ausgabe auf dem Bildschirm ist: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 15. Übung Schreibe ein Programm, das 10 aufeinander folgende Zahlen untereinander auf dem Bildschirm ausgibt, wobei die erste Zahl bei jedem Programmdurchlauf frei wählbar ist. 16. Übung Schreibe ein Programm, das alle 5er Zahlen zwischen 10 und 50 addiert und sowohl den jeweiligen Zwischenwert als auch die Endsumme auf dem Bildschirm ausgibt. 17. Übung Schreibe ein Programm, das von 1 * 1 beginnend die Quadratzahlen bis zu einer eingebbaren Zahl k, also k * k berechnet und untereinander auf dem Bildschirm ausgibt. 18. Übung Programme\Funktion.c Erstelle mit einer while- Schleife eine formatierte Wertetabelle der Funktionsgleichung y=0,1x³+2x²+5 . Dabei sollen die Anfangs- und Endwerte von x sowie eine beliebige Schrittweite vom Benutzer eingegeben werden. z.B. -10 <= x >= 10, Schrittweite 1 Die Ausgabe soll folgendermaßen erscheinen: Seite 18 von 45 Kontrollstrukturen Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK 19. Übung Programme\Kapital.c Schreibe ein Programm zur Kapitalberechnung. Einzugebende Werte sind das Anfangskapital, die Laufzeit und der Zinssatz. Die Ausgabe soll folgendermaßen aussehen: 20. Übung Versuche folgendes Programm auf dem Papier nachzuvollziehen und schreibe auf die vorgegebenen Linien die jeweilichen Ausgaben. 3.2.2 For-Schleife Die for-Schleife verwenden wir, wenn die Anzahl der Schleifendurchläufe bekannt ist. Wir benötigen also immer eine Variable, die zum Zählen der Schleifendurchläufe verwendet wird. Üblicherweise bezeichnet man diese Zählvariablen mit i, j, k, usw. Seite 19 von 45 Kontrollstrukturen Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK Beispiel Wir wollen wieder die Zahlen von 1 bis 5 untereinander auf dem Bildschirm ausgegeben. Die Schleife leiten wir mit dem Schlüsselwort for ein. Dann folgen in der Klammer drei Bereiche, welche durch einen Strichpunkt ; voneinander getrennt werden: Bereich 1: Startwert der Zählvariablen setzten z.B. i = 1 Bereich 2: Durchlaufbedingung z.B. i <= 5 Bereich 3: Operation auf Zählvariable durchführen z.B. i++ Beispiel: Der Wert der Laufvariable wird bei jedem Schleifendurchlauf um 1 verringert: Es werden die Zahlen von 5 bis 0 ausgegeben. 21. Übung Programme\Teiler.c Lasse alle Teiler einer einzulesenden ganzen Zahl z ausgeben. Prüfe dazu bei jeder Zahl i zwischen 1 und z, ob der Divisionsrest von z/i gleich 0 ist. Die Ausgabe soll folgendermaßen aussehen: 22. Übung Schreibe alle Übungen zur while-Schleife mit der for-Schleife. 23. Übung Schreibe ein Programm, das folgende Ausgabe erzeugt: 12, 10, 8, 6, 4, 2, 0, 24. Übung Schreibe ein Programm, das alle durch fünf teilbaren Zahlen zwischen 104 und 31 untereinander auf dem Bildschirm ausgibt. Seite 20 von 45 Kontrollstrukturen Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK Verschachtelte Schleifen 25. Übung Schreibe ein Programm, das 10 Zeilen mit Sternchen ausgibt, wobei mit 1 Sternchen in der 1.Zeile begonnen wird und in jeder Zeile ein Sternchen hinzukommt. In der letzten Zeile müssen dann 10 Sternchen zu sehen sein. 26. Übung Was gibt folgendes Programm aus? Überlege dir die Ausgabe zuerst und überprüfe anschließend dein Ergebnis durch einen Programmlauf. 3.2.3 Do-while Schleife Die do-while Schleife ist der while Schleife sehr ähnlich. Der einzige Unterschied besteht darin, dass die Anweisung einmal ausgeführt wird und erst dann die Bedingung zum ersten Mal geprüft wird. Die Schleife wird also mindestens einmal ausgeführt. Da die Bedingung am Ende geprüft wird, bezeichnet man die do-while Schleife als Fußgesteuerte Schleife. Die Syntax der do-while Schleife lautet: do { Anweisung } while (Ausdruck); Achtung! Hier wird ein Semikolon nach der Schleifenbedingung verlangt, weil hier das Ende der Anweisung erreicht ist. Anweisung Solange Ausdruck Seite 21 von 45 Kontrollstrukturen Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK Beispiel: Bis eine 0 eingegeben wird sollen ganze Zahlen eingelesen und aufaddiert werden. Da eine ganze Zahl erst eingelesen werden muss, bevor sie geprüft werden kann, bietet sich hier die Fußgesteuerte Schleife an. summe = summe + zahl Solange zahl nicht 0 27. Übung Schreibe ein Programm, das eine Zahlenreihe von 0 bis 9 ausgibt. 28. Übung Teste folgendes Programm. Ersetze die while Schleife durch eine do while-Schleife. 29. Übung (für Fortgeschrittene!) Programme\Reihenentwicklung.c Die Exponentialfunktion ez soll mit Hilfe einer Reihenentwicklung berechnet werden. Schreibe ein Programm in C, welches die ersten n Glieder der Reihenentwicklung aufsummiert. z und n sollen ganzzahlig sein und eingelesen werden. Die Terme der Reihe sind in einer Schleife aufzusummieren. Dabei soll die Fakultät in der Schleife selbst berechnet werden. ez = 1 + Seite 22 von 45 z/1! + z2/2! + …… + z n-1/(n-1)! Kontrollstrukturen Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK Fragen zu Schleifen: 1. Welche Schleifen stehen zur Verfügung? 2. Welche Schleife solltest du verwenden, wenn mehrere Anweisungen mindestens einmal ausgeführt werden sollen? 3. Was gibt diese Schleife aus, und welcher Fehler wurde hier gemacht? 4. Warum läuft folgende Schleife in einer Endlosschleife? Was kann man dagegen tun? Lösungen Seite 23 von 45 Kontrollstrukturen Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK 4 Unterprogramme In der Praxis werden komplette Programmausführungen nicht in einem einzigen Anweisungsblock zusammen gefasst, sondern eine Problemlösung in viele kleine Teilprobleme zerlegt und mithilfe von Unterprogrammen, auch Funktionen genannt, gelöst. Anweisungen eines Programms werden grundsätzlich in Funktionen zusammengefasst. Die Funktion, die immer als erstes angesprochen wird, ist die main- Funktion. Die main- Funktion bildet die Hauptfunktion, von dort aus werden alle Unterprogramme aufgerufen und gestartet. Ein Programm ohne main- Funktion kann nicht funktionieren. 4.1 Hinführung Schreibe ein Programm, das nach Eingabe von zweimal zwei ganzen Zahlen die jeweils größte der beiden Zahlen auf den Bildschirm ausgibt. Wie du leicht feststellen kannst taucht in deinem Programm zweimal ein beinahe gleicher Programmteil, die if..else.. Anweisung, auf. Es besteht durch eine geringe Änderung des Programms die Möglichkeit die gleiche if…else Anweisung zweimal aufzurufen und damit das Programm übersichtlicher zu gestalten durch die mehrfache Verwendung von Programmteilen(Unterprogrammen) die Schreibarbeit und damit die Fehlerquote zu verringern. auch in mehreren Programmen verwendbar sind und in einer Bibliothek(library) zur Verfügung gestellt werden können Unterprogramme sind ein Mittel zur Strukturierung eines Programms. Ziel darf es nicht sein, ein einziges riesengroßes Programm zu schreiben, da dies schwer zu überblicken wäre. Gefordert ist hingegen eine Modularität. Das Hauptprogramm soll so weit wie möglich nur Unterprogramme aufrufen, damit es leicht verständlich bleibt. Mit dem Hauptprogramm beginnt ein Programm seine Ausführung. Ein Hauptprogramm kann Unterprogramme aufrufen. Ein Unterprogramm kann ebenfalls Unterprogramme aufrufen. Ein Unterprogramm ist eine Programmeinheit, die einen Namen trägt und über ihren Namen aufgerufen werden kann. Ein Unterprogramm ist eine Folge von Anweisungen, die in einem Programm über den Unterprogramm-Namen aufgerufen werden kann. Unterprogramme werden auch als Funktionen bezeichnet. 4.2 Funktionen Funktionen haben folgende Vorteile: Verschiedene Programmteile sind relativ unabhängig voneinander und können deshalb einzeln geschrieben und getestet werden. Ein Programmteil braucht nur einmal geschrieben, kann jedoch mehrfach ausgeführt werden. Umfangreiche Programme lassen sich aus bereits vorhandenen Programmen als Bausteine zusammensetzten (Library). Seite 24 von 45 Unterprogramme Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK 4.3 Vordefinierte Funktionen (Standard-Funktionen) Zum Lieferumfang des Compilers gehören fertige Funktionen für alle möglichen Anwendungsfälle wie z.B printf(…) und scanf(…) Diese werden durch unterschiedliche Bibliotheken wie z.B. stdio.h eingebunden. Es entfällt die Vereinbarung der Funktionen, da sie vordefiniert sind, jedoch benötigen die meisten Funktionen Parameter, welche in Klammern anzugeben sind. Beim Aufruf der printf Funktion muss beispielsweise angegeben werden, was auf dem Bildschirm ausgegeben werden soll. 4.4 Benutzerdefinierte Funktionen Im Gegensatz zu den Standard Funktionen können die Namen und die jeweiligen Anweisungsfolgen vom Benutzer frei gewählt werden. 4.4.1 Ort der Definition von Funktionen Eine Funktion stellt eine Anweisungsfolge dar, die unter einem Namen aufgerufen werden kann. Eine Funktion, die unter ihrem Namen aufgerufen werden soll, muss definiert sein. Die Definition einer Funktion besteht in C aus dem Funktionskopf und dem Funktionsrumpf. Der Funktionskopf legt die Aufruf-Schnittstelle der Funktion fest. Der Funktionsrumpf enthält lokale Vereinbarungen und die Anweisungen der Funktion. Die Aufgabe einer Funktion ist es, aus Eingabedaten Ausgabedaten zu erzeugen. Syntax der Definition einer Funktion rueckgabetyp funktionsname (typ_1 formaler_parameter_1, typ_2 formaler_parameter_2,…..) { ….. } Funktions rumpf In C gibt es parameterlose Funktionen und Funktionen mit Parametern 4.4.1.1 Parameterlose Funktionen Beispiel void printGestrichelteLinie (void) { printf (″-------------------------------------------------------------″); } Seite 25 von 45 Unterprogramme Nicole Rottmann Funktions kopf Programmieren in C Wirtschaftsgymnasium Eisenberg GK Parameterlose Funktionen werden definiert mit einem Paar von runden Klammern hinter dem Funktionsnamen, die anstelle von Übergabeparametern und ihren Datentypen den Datentyp void enthalten. Der Aufruf der Funktion erfolgt durch Anschreiben des Funktionsnamens, gefolgt von einem Paar runder Klammern, printGestrichelteLinie(); 4.4.1.2 Funktionen mit Parametern (call by value) Hat eine Funktion formale Parameter- das sind die Parameter in den runden Klammern der Definition der Funktion- so muss der Aufruf mit aktuellen Parametern erfolgen. Als Beispiel für eine Funktion mit Parametern wird die Funktion ausgebenPLZ() betrachtet, die die ihr übergebene Postleitzahl auf dem Bildschirm ausgeben soll: void ausgebenPLZ( int plz) { printf (″Die Postleitzahl ist: ″); printf(″%d\n″, plz); } Der Aufruf für dieses Beispiel erfolgt mit: ausgebenPLZ (aktPLZ); Hier ist aktPLZ der aktuelle Parameter. Er ist die Postleitzahl, die auf dem Bildschirm ausgegeben werden soll. Beispiel Maximum Programm ohne Funktionen: Seite 26 von 45 Unterprogramme Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK Programm mit der Funktion max() Die Parameter x und y werden innerhalb der Funktion als Platzhalter verarbeitet, sie sind formale Parameter. Beim Funktionsaufruf werden an Stelle der formalen Parameter x und y die aktuellen Parameter a und b bzw. c und d eingesetzt. Die Funktion arbeitet nur mit den lokalen Parametern x und y. Beim Aufruf der Funktion max(a,b) wird eine lokale Kopie von a und b in den formalen Parametern x und y angelegt. Der aktuelle Parameter kann von der aufgerufenen Funktion aus nicht verändert werden. Soll der aktuelle Parameter verändert werden, so muss stattdessen mit Pointern als Übergabeparameter gearbeitet werden. (späteres Kapitel) Implizite Datentypumwandlung Wird nicht der Datentyp als Argument an die Funktion übergeben, welcher als formaler Parameter definiert wurde, findet eine implizite Typumwandlung statt. Beispiel: Seite 27 von 45 Unterprogramme Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK In diesem Beispiel wird zwar ein Gleitpunkttyp an die Funktion circle als Argument übergeben, aber der formale Parameter von circle() ist ein Integer- Wert. Daher wird eine Umwandlung von float nach int durchgeführt und die Nachkommastellen abgeschnitten. 4.4.1.3 Funktionen mit Rückgabetyp - die return Anweisung In der Funktion max() ist eine Bildschirmausgabe enthalten. Programmteile sollen aber möglichst universell sein. Daher ist es günstiger eine Funktion max() zu schreiben, die den Maximalwert an das aufrufende Programm zurückgibt, anstatt ihn sofort auf den Bildschirm auszugeben. Das aufrufende Programm kann dann mit dem in der Funktion ermittelten Wert beliebig weiter verfahren. Z.B in arithmetischen Ausdrücken weiter verrechnen oder mit einem speziellen Format selbst auf dem Bildschirm auszugeben. Sehr oft hat eine Funktion den Zweck, genau einen einzigen, ganz bestimmten Wert zu berechnen. In diesem Fall gibt man der Funktion einen Rückgabetyp der es erlaubt, den berechneten Wert im Funktionsnamen an das aufrufende Programm zurückzugeben. Die return- Anweisung beendet den Funktionsaufruf. Das Programm kehrt zu der Anweisung, in der die Funktion aufgerufen wurde, zurück und beendet diese Anweisung. Anschließend wird die nächste Anweisung nach dem Funktionsaufruf abgearbeitet. Eine Funktion muss keinen Resultatwert liefert. Sich hat dann den Rückgabetyp void. Soll ein Resultatwert geliefert werden, so erfolgt dies mit Hilfe der return- Anweisung. Hat eine Funktion einen von void verschiedenen Rückgabetyp, so muss sie mit return einen Wert zurückgeben. Nach return kann ein beliebiger Ausdruck stehen. Mit Hilfe der return – Anweisung ist es möglich, den Wert eines Ausdrucks, der in der Funktion berechnet wird, an den Aufrufer der Funktion zurückzugeben (Funktionsergebnis): Beispiel Maximum: Seite 28 von 45 Unterprogramme Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK Fragen zu Funktionen 1. Beschreibe den Begriff call-by-value. 2. Was muss bei der Verwendung eines Rückgabewertes beachtet werden und mit welcher Anweisung kann ein Wert aus einer Funktion zurückgegeben werden? 3. Warum lässt sich das folgende Programm nicht übersetzen? 4. Was wurde bei folgendem Beispiel falsch gemacht? Lösungen Seite 29 von 45 Unterprogramme Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK 5 Blöcke und Funktionen 5.1 Stuktur eines Blockes Anweisungen eines Blockes werden durch Blockbegrenzer (geschweifte Klammern {}) dargestellt. Einen Block benötigt man aus folgenden Gründen: der Rumpf einer Funktion ist ein Block ein Block gilt syntaktisch als nur eine Anweisung, z.b im if- oder else Zweig. Anweisungsfolgen werden logisch gegliedert. Variablen können an verschiedenen Stellen deklariert und definiert werden: außerhalb von Funktionen (globale Variablen) innerhalb von Funktionen und Blöcken vor der ersten Anweisung (lokale Variablen) 5.1.1 Schachtelung von Blöcken Da eine Anweisung eines Blocks selbst wieder ein Block sein kann, können Blöcke geschachtelt werden. Vereinbarungen, die innerhalb eines Blockes festgelegt werden, gelten nur lokal für diesen Block. Lokal definierte Variablen und deklarierte Namen sind nur innerhalb diese Blockes sichtbar, in einem umfassenden Block sind sie unsichtbar. In C können in jedem Block Vereinbarungen durchgeführt werden. Beispiel Seite 30 von 45 Blöcke und Funktionen Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK 5.2 Gültigkeit, Sichtbarkeit und Lebensdauer In der üblichen Programmierung werden viele Variable in Funktionen oder in Anweisungsblöcken deklariert und definiert. (Deklarieren: Der Variable wird ein Name gegeben und ein Typ zugewiesen. Definieren: Während dem Compilieren wird der Variablen ein Speicherplatz zugewiesen.) Grundlegend unterscheidet man zwischen lokalen und globalen Variablen. Die lokalste Variable ist immer die Variable im Anweisungsblock. Globale Variablen können in allen Funktionen verwendet werden. Existiert eine lokale Variable mit gleichem Namen wie die globale Variable bekommt immer die lokale Variable den Zuschlag. Vorsicht ! Dies kann zu unerwarteten Ergebnissen führen. Eine lokale Variable muss immer initialisiert, d.h. mit einem Wert versehen werden. Globale Variablen werden vom Compiler automatisch initialisiert. Besser, da übersichtlicher ist es aber die Variable selbst zu initialisieren. Wenn möglich globale Variablen vermeiden. Beispiel: Ausgabe: Seite 31 von 45 Blöcke und Funktionen Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK Die Lebensdauer ist die Zeitspanne, in der das Laufzeitsystem des Compilers der Variablen einen Platz im Speicher zur Verfügung stellt. Mit anderen Worten, während ihrer Lebensdauer besitzt eine Variable einen Speicherplatz. Die Gültigkeit einer Variablen bedeutet, dass an einer Programmstelle der Namen einer Variablen dem Compiler durch eine Vereinbarung bekannt ist. Die Sichtbarkeit einer Variablen bedeutet, dass man von einer Programmstelle aus die Variable sieht, das heißt, dass man auf sie über ihren Namen zugreifen kann. Eine Variable kann gültig sein und von einer Variablen desselben Namens verdeckt werden und deshalb nicht sichtbar sein. Auf eine verdeckte Variable kann nur über ihre Adresse zugegriffen werden, nicht über ihren Namen. Generell gilt für die Sichtbarkeit von Variablen: Variablen in inneren Blöcken sind nach außen nicht sichtbar. Globale Variablen und Variablen in äußeren Blöcken sind in inneren Blöcken sichtbar. Wird in einem Block eine lokale Variable definiert mit demselben Namen wie eine globale Variable oder wie eine Variable in einem umfassenden Block, so ist innerhalb des Blocks nur die lokale Variable sichtbar. Die globale Variable bzw. die Variable in dem umfassenden Block wird durch die Namensgleichheit verdeckt. Schlüsselwörter für Variablen static: Variable behält ihren Wert bei, auch außerhalb ihres Bezugsrahmens. Beispiel: Programme\static_1.c Der Wert i wird innerhalb der Funktion inkrement() zwar um eins erhöht, bei jedem erneuten Aufrufen der Funktion jedoch wieder auf 1 gesetzt. Dem kann mit dem Schlüsselwort static entgegengewirkt werden. Programme\static_2.c Seite 32 von 45 Blöcke und Funktionen Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK volatile: Modifiziert eine Variable so, dass der Wert dieser Variable vor jedem Zugriff neu aus dem Hauptspeicher eingelesen werden muss. Andernfalls besteht oft die Gefahr in c, dass der Compiler Programmteile wegoptimiert. Mit volatile versehene Variablen müssen genauso verarbeitet werden, wie der Programmier dies vorgibt. Fragen: 1. Das folgende Programm soll 10 Mal die Textfolge Hallo 0, Hallo 1, Hallo 2, ….Hallo 9 ausgeben. Die Ausgabe ist allerdings folgende: Wo liegt der Fehler? Was muss verändert werden? Seite 33 von 45 Blöcke und Funktionen Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg 2. Folgendes Programm lässt sich nicht übersetzen. Wo liegt der Fehler? Lebensdauer Seite 34 von 45 Blöcke und Funktionen Nicole Rottmann GK Programmieren in C Wirtschaftsgymnasium Eisenberg GK 6 Felder (Arrays) und Zeichenketten Bisher haben wir uns auf einfache Datentypen beschränkt. (char, short, int, float, double) In diesem Kapitel werden zusammengesetzte Datenstrukturen besprochen, sogenannte Arrays. 6.1 Arrays verwenden Mit Arrays werden einzelne Elemente als Folge von Werten eines bestimmten Typs abgespeichert und bearbeitet. 6.2 Das eindimensionale Feld Ein eindimensionales Feld bezeichnet man auch als Liste. Die Syntax zur Definition eines Arrays sieht wie folgt aus: Datentyp Arrayname [Anzahl_der_Elemente]; Beispiel: Ein Feld zur Speicherung von Temperaturwerten vom Datentyp float mit 100 Einträgen wird folgendermaßen definiert: float temperatur[100]; //Feld aus 100 float-Zahlen. Für den Feldname gelten die gleichen Regeln wie für die Vergabe der Variablenbezeichnungen. In den eckigen Klammern steht die Anzahl der Elemente als ganzzahlige Konstante, die größer als 0 sein muss. Ein Array, das aus Elementen verschiedener Datentypen besteht gibt es in C nicht. Zugreifen kann man auf das gesamte Array mit allen Komponenten über den Array Namen. Einzelne Elemente eines Arrays werden über den Namen und einen Indexwert in eckigen Klammern [n] angesprochen. Der Indexwert selbst wird über eine Ganzzahl angegeben und fängt bei 0 zu zählen an. 6.3 Arrays initialisieren und darauf zugreifen Um einzelnen Array-Elementen einen Wert zu übergeben oder Werte daraus zu lesen, wird der Indizierungsoperator [] verwendet. Beispiel: Ausgabe: Seite 35 von 45 Arrays und Strings Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK Vorsicht ! Das Array wird mit der Ganzzahl [3] initialisiert. Der erste Arraywert wird aber mit der Indexnummer 0 angesprochen. Der letzte Arraywert hat den Indexwert [n-1]. (n ist die Arraygröße). Fügen wir im Programm noch folgende Zeile hinzu: iArray[3] = 6666; würden wir auf einen nicht geschützen und reservierten Speicherbereich zugreifen. Bestenfalls stürzt das Programm mit einer Schutzverletzung (Segmentation fault) oder Zugriffsverletzung (Access violation) ab. Schlimmer ist es, wenn das Programm weiterläuft und irgendwann eine andere Variable den nicht geschützten Speicherbereich verwendet. Wir erhalten dann unerwünschte Ergebnisse. Häufig werden Werte von Arrays in Schleifen übergeben: Hierbei kann es leicht zu einem Überlauf kommen. Beispiel: Vorsicht!! In der for Schleife muss es i < MAX heißen, da es bei i<=MAX zu einer Indizierung des Elements [10] kommt. Somit ein Feld zu viel initialisiert wird. Seite 36 von 45 Arrays und Strings Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK Frage: In folgendem Programm wurden zwei Fehler gemacht: Anwort 6.4 Initialisierung mit einer Initialisierungsliste Arrays können bereits bei der Definition mit einer Initialisierungsliste explizit initialisiert werden. Hierbei wird eine Liste von Werten, getrennt durch Kommata, in geschweiften Klammern bei der Definition an das Array zugewiesen. Beispiel: float fArray[3] = {0.75, 1.0, 0.5} In der Definition eines Arrays mit Initialisierungsliste kann die Längenangabe fehlen. Folgende Definition ist gleichwertig zur obigen: float fArray[] = {0.75, 1.0, 0.5} Wird hingegen bei der Längenangabe ein größerer Wert gewählt, werden die restlichen Elemente in der Liste automatisch mit dem Wert 0 initialisiert. Beispiel float fArray[5] = {12.3, 15.8} Nur die ersten beiden Werte enthalten Zahlen, die verbleibenden drei Werte haben den Wert 0. Bestimmte Elemente direkt initialisieren int iArray[5] = { 123, 456, [4] = 789} Die ersten beiden Elemente wurden direkt initialisiert und der letzte Element Wert wurde über den Index angesprochen. Seite 37 von 45 Arrays und Strings Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK Arrays mit Schreibschutz Wenn ein Array benötigt wird, bei dem die Werte schreibgeschützt sind und nicht veränderbar sein sollen, so muss das Schlüsselwort const vor der Arraydefinition stehen. Beispiel const float fArray[3] = {0.75, 1.0, 0.5} fArray[0] = 0.8 erzeugt eine Fehlermeldung. 1. Frage Wo ist der Unterschied bei folgenden Initialisierungslisten? const int MAX = 5; int val[MAX] = {1, 2}; int val[MAX] = { 1, 2, 0, 0 }; int val[] = { 1, 2, 0, 0, 0}; int val[MAX] = {1, 2, 0, 0, 0, 1, 2}; 2. Frage Mit welchen Werten sind folgende Array-Definitionen anschließend initialisiert? const int MAX = 10; int a[MAX] = { 1, [MAX/2] = 123, 678, [MAX-1] = -1}; long val[]= {[19] = 123}; float fval[100] ={0.0}; Lösung 30. Übung Schreibe ein Programm, das die Inhalte zweier Arrays miteinander vergleicht. Deklariere dazu zwei Arrays mit 10 Feldern. Initialisiere beide Felder mit einer for- Schleife, so dass sie identisch sind. Verändere von einem Feld die Pos 5 und vergleiche nun beide Felder mit einer weiteren forSchleife. Die veränderte Position soll angegeben werden. Programme\arrayvergleich.c 31. Übung Schreibe ein Programm, das die Anzahl der Elemente eines Arrays ermittelt. Deklariere und initialisiere dazu ein Array mit 17 beliebigen Zahlen. Die Größe eines Datentyps in Byte lässt sich mit dem sizeof- Operator ermitteln. Beispiel sizeof(int) liefert als Ergebnis entweder 16 oder 32, je nachdem um welches System es sich handelt. Da der sizeof Operator also für jedes Feldelement die Bit-Anzahl ausgibt, muss das Ergebnis noch durch sizeof(int) geteilt werden. Sofern das Feld vom Typ Integer ist. Für jeden anderen Typ entsprechend. Ergänze das Programm so, dass die Anzahl der Zahlenwerte und die Zahlenwerte vom Benutzer eingegeben werden können. Programme\anzahlelementearray.c Seite 38 von 45 Arrays und Strings Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK 6.5 Strings (Zeichenketten) Was passiert, wenn ein Array vom Typ char verwendet wird? Mit einer Folge von char-Zeichen kann ein kompletter Text gespeichert, verarbeitet und ausgegeben werden. Für Arrays vom Typ char gelten nicht nur die Einschränkungen herkömmlicher Arrays, sondern es muss darauf geachtet werden, dass die zusammenhängende Folge von Zeichen mit dem NullZeichen ´\0´ abgeschlossen wird. Genaugenommen heißt das, dass die Länge eines char- Arrays immer um ein Zeichen größer sein muss als die Anzahl der relevanten Zeichen. Für Arbeiten mit Stings bietet die Standard Bibliothek außerdem viele Funktionen in der Headerdatei string.h an. 6.5.1 Strings initialisieren Zur Initialisierung von char- Arrays können Sting-Literale in Anführungszeichen gesetzt werden, anstatt ein Array Zeichen für Zeichen zu initialisieren. Somit sind die beiden folgenden char-Array Definitionen gleichwertig: char string1[20] = “String“; char string2[20] = {‘S’ , ‘t’ , ‘r’ , ‘i’ , ‘g’ , ‘\0’}; Beide Initialisierungen sind äquivalent. Es wird jeweils ein char-Array definiert, das 19 Zeichen enthalten kann. Die restlichen Zeichen werden auch hier, mit 0 vorbelegt. Ausgegeben wird der String mit printf(“%s \n“, sting1); Achtung! Das Stringende – Zeichen ’0’ Ein char-Array, das einen String speichert, muss immer um mindestens ein Element länger sein als die Anzahl der relevanten (lesbaren) Zeichen. Nur dann kann es noch das Stringende- Zeichen (oder auch NULL- Zeichen) ’\0’ aufnehmen. Soll also ein Text mit exakt 10 Zeichen abgespeichert werden, braucht man dafür ein char-Array mit 11 Zeichen. Fehlt das Stringende Zeichen und wird eine Funktion so lange ausgeführt bis das Stringende Zeichen erreicht ist, kann das Programm hinter dem eigentlichen Ende der Zeichenkette fortgeführt werden, bis sich irgendwo im Speicher ein Null- Wert befindet. Bei einem schreibenden Zugriff können hierbei natürlich Daten zerstört werden. 6.5.2 Einlesen von Strings Es ist möglich ein char-Array formatiert mit scanf einzulesen. Die scanf- Funktion liest allerdings nur bis zum ersten Leerzeichen ein. Alle restlichen Zeichen dahinter werden ignoriert. Aus diesem Grund wird die Standardfunktion fgets() verwendet. Die Syntax von fgets(): char *fgets(char *str, int n_chars, FILE *stream); Der String wird mit dem ersten Parameter str angegeben. Im zweiten Parameter wird angegeben, wie viele Zeichen eingelesen werden. Von wo etwas eingelesen wird, legt der dritte Parameter stream fest. In unserem Fall soll es die Standarteingabe sein, die mit dem Stream stdin angegeben wird. Seite 39 von 45 Arrays und Strings Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK Beispiel: Programme\String_einlesen.c Mit vorliegendem Programm können maximal 19 Zeichen eingelesen werden. Das 20 Zeichen wird automatisch mit ’\0’ belegt. Ist noch ein weiteres Zeichen frei, wird ein Zeilenumbruch \n eingefügt. 6.6 Die Standard- Bibliothek <string.h> Funktionen, mit denen Strings kopiert, zusammengefügt oder verglichen werden können sind in der Standard- Headerdatei <string.h> definiert. Alle String- Verarbeitungsfunktionen verwenden char-Zeiger, die auf den Anfang des Strings, also auf das erste Zeichen verweisen. Deshalb sind alle Syntax Beschreibungen mit dem Zeigeroperator* versehen. Im Programm selber erscheint vorerst aber die schon bekannte Array Schreibweise. 6.6.1 strcat() – Strings aneinanderhängen Syntax: char *strcat(char *s1, char *s2); Damit wird s2 an s1 angehängt, wobei das Stingendezeichen /0 am Ende von String 1 überschrieben wird. Voraussetzung ist, dass s2 Platz in s1 hat. Beispiel: Seite 40 von 45 Arrays und Strings Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK 32. Übung Ergänze das Programm, so dass zusätzlich „Strasse: Meine_Strasse“ ausgegeben wird. Programme\stringcat.c 6.6.2 strchr() – ein Zeichen im String suchen Syntax: char *strchr (const char *s, int ch); Diese Funktion gibt die Position im String s beim ersten Auftreten von ch zurück. Tritt das Zeichen ch nicht auf, wird NULL zurückgegeben. Beispiel: Programme\stringchr.c Dabei wird ab dem Buchstabe W der komplette String ausgegeben. Seite 41 von 45 Arrays und Strings Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK 6.6.3 strcmp() – Strings vergleichen Für das Vergleichen zweier Strings kann die Funktion strcmp() mir folgender Syntax verwendet werden. int strcmp(const char *s1, const char *s2); Sind beide Strings identisch, gibt diese Funktion 0 zurück. Ist der String s1 kleiner als s2 ist der Rückgabewert kleiner als 0 ist s1 größer als s2, dann ist der Rückgabewert größer als 0. Beispiel : Programme\string_vergleichen.c Seite 42 von 45 Arrays und Strings Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK 6.6.4 strcpy() – einen String kopieren Soll ein String in einen adressierten char- Vektor kopiert werden, kann die Funktion strcpy() benutzt werden. Syntax: char *strcpy (char *s1, const char *s2); Beispiel Programme\string_kopieren.c In diesem Beispiel kann man sehen, dass es auch möglich ist, mit strcpy() Strings aneinander zu hängen. Seite 43 von 45 Arrays und Strings Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg GK 6.6.5 strlen() - Länge eines Strings ermitteln Um die Länge eines Strings zu ermitteln, kann die Funktion strlen() eingesetzt werden. Syntax: size_t strlen(const char *s1); Damit wird die Länge des adressierten Strings s1 ohne das abschließende Stringende- Zeichen zurückgegeben. Beispiel: Programme\stringlaenge.c 33. Übung Schreibe ein Programm, das die Größe in Bytes und die Anzahl der Elemente eines Arrays bzw. Strings ermittelt und ausgibt. Verwende dazu den sizeof – Operator. Bei den Strings kann die strlen() verwendet werden. Folgende Arrays und Strings sind „auszumessen“. int iarr[] = {2,4,6,4,2,4,5,6,7}; double darr[] = {3.3,4.4,2.3,5.8,7.7}; char str[] = {„Hallo Welt“}; Programme\Aufgabe1_Stringlaenge.c 34. Übung Schreibe eine Funktion, die zwei int-Arrays auf Gleichheit überprüft. Die Funktion soll -1 zurückgeben, wenn beide Arrays gleich sind, oder die Position, an der ein Unterschied gefunden wurde. -2 soll zurückgegeben werden, wenn beide Arrays unterschiedlich lang sind. Programme\Aufgabe2_Stringvergleich.c 35. Übung Schreibe eine Funktion, die in einem String ein bestimmtes Zeichen durch ein anderes Zeichen ersetzt. Programme\Aufgabe3_zeichenersetzen.c Seite 44 von 45 Arrays und Strings Nicole Rottmann Programmieren in C Wirtschaftsgymnasium Eisenberg Verwendete Literatur: 1 2 3 4 Jürgen Wolf, Grundkurs in C Galileo Computing, Bonn 2010 Jürgen Wolf, C von A bis Z Galileo Computing, Bonn 2009 Norbert Heiderich, Wolfgang Meyer, Technische Probleme lösen mit C/ C++ Hanser Verlag, München 2010 Manfred Dausmann, Ulrich Bröckl, C als erste Programmiersprache Vieweg+Teubner, Wiesbaden 2011 Seite 45 von 45 Sortierverfahren Nicole Rottmann GK