• Keine Ergebnisse gefunden

C / C++ - Einfu hrung WS 2002/2003

N/A
N/A
Protected

Academic year: 2021

Aktie "C / C++ - Einfu hrung WS 2002/2003"

Copied!
87
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

C / C++ - Einfu hrung

WS 2002/2003

Michael Baum Dipl.-Math.

E-Mail: micbaum@de.ibm.com

(2)

1. ) Einfu hrung in die C ä Programmierung

1.1 Einige grundsatzliche Begriffsbestimmungen (ref. Beispiel 1 ) Seite 3

1.2 Definition von Variablen und Konstanten 7

2. ) Programmverzweigungen 2.1 Die if - Anweisung ( ref. Beispiel 2 ) 11

2.2 Vergleichsausdru cke 12

2.3 Die switch - Anweisung ( ref. Beispiel 3 ) 14

2.4 Die goto ä Anweisung 16

3.) Programmschleifen 3.1 Die while - Schleife ( ref. Beispiel 4 ) 16

3.2 Die for - Schleife ( ref. Beispiel 4 ) 18

3.3 Die do-while - Schleife ( ref. Beispiel 5 ) 19

3.4 Einfache Schleifenprogramme fu r Ein - / Ausgabe, getchar( ) und putchar(c) 20

4.) Die Entwicklungsumgebung (Einfu hrung ) 4.1 Einige grundsatzliche Moglichkeiten in der Entwicklungsumgebung 22 4.2 Spezielle Editierbefehle : Edit - und Search ä Menue 23

4.3 Austesten von Programmen : Debug ä Menue 23

5.) Ausdrucke und Anweisungen 5.1 Einfache und mehrfache Wertzuweisungen, Kommaoperator 23

(ref. Beispiel 6) 5.2 Arithmetische Operationen 26

5.3 Bitoperationen 29

5.4 Typkonvertierung in Ausdru cken 29

5.5 Aufzahlungskonstanten mit enum 31

6.) Eingabe von Konsole und Ausgabe am Bildschirm 6.1 Eingabe und Ausgabe mit cin, cout (ref. Beispiel 7) 32

6.2 Formatierte Eingabe und Ausgabe mit printf, scanf(ref. Beispiel 8 ) 34

7.) Felder 7.1 Eindimensionale Felder ( ref. Beispiele 9, 10 ) 37

7.2 Mehrdimensionale Felder ( ref. Beispiel 11 ) 40

7.3 Zeichenvektoren, die Funktionen gets(), puts() ( ref. Beispiel 12 ) 41

(3)

8.) Strukturen

8.1 Einfache Strukturen ( ref. Beispiele 13 , 14 ) Seite 43

8.2 Vektoren von Strukturen 46

8.3 Unions 47

8.4 Bitfelder 48

8.5 typedef structure ( ref. Beispiel 16 ) 49

9.) Zeiger 9.1 Adressierung von Daten uber Zeiger 51

9.2 Zeiger und Vektoren, Adressarithmetik 53

9.3 Char-Zeiger, Zeichenvektoren 55

9.4 Mehrdimensionale Vektoren, Vektoren von Zeigern, Zeiger auf 57

Zeiger ( ref. Beispiele 17, 18, 19, 1A ) 9.5 Dynamische Speicherverwaltung ( ref. Beispiele 20, 21, 22, 23 ) 59

9.6 Zeiger auf Strukturen, verkettete Listen (ref. Beispiele 24, 25, 26 ) 61

10.) Funktionen 10.1 Funktionsdefinition, Werteparameter und Variablenparameter 63

( ref. Beispiele 27, 28 ) 10.2 Funktionsprototyp, Deklaration versus Definition von Funktionen 67

10.3 Speicherklassen auto, static, register, Gu ltigkeitsbereiche fu r Namen 69 10.4 Zeiger auf Funktionen, Funktionsnamen als Parameter 73

( ref. Beispiele 29, 30 ) 10.5 Felder, Zeiger und Strukturen als Parameter ( ref. Beispiele 31, 32 ) 74 10.6 Rekursive Funktionen 76

10.7 Inline Funktionen, Makros 77

10.8 Grafische Anwendungen 78

11.) Unterprogrammtechnik, Programmstrukturen 11.1 Include Dateien, eigene Headerdateien 81

11.2 Projekte aus mehreren Quelldateien in Borland C++ 82

11.3 Strukturierte Programmierung 82

12.) Eingabe und Ausgabe von Daten 12.1 Datei-Funktionen mit stdio.h ( ref. Beispiel 33 ) 84

12.2 Dateifunktionen mit fstream.h 87

12.3 Zusammenfassung der Ein- und Ausgabefunktionen fu r C++ 90

(4)

1. ) Einfuhrung in die C - Programmierung

Das Ziel von Kapitel 1, 2 und 3 ist, moglichst schnell den Punkt zu erreichen, wo nutzliche Programme geschrieben werden konnen; Vollstandigkeit und Genauigkeit folgen in den spateren Kapiteln.

1.1 Einige grundsatzliche Begriffsbestimmungen (ref. Beispiel 1 )

Die Programmiersprache C wurde in den 70-er Jahren in USA von den Autoren Brian W. Kernighan und Dennis M. Ritchie entwickelt.

C ist eine Programmiersprache fur allgemeine Anwendungen. Dabei ist C eine relativ

'maschinennahe' Sprache : C geht mit den gleichen Objekten um wie der Computer : Zeichen, Zahlen und Adressen. Trotzdem ist C unabhangig von einer speziellen Maschinen-Architektur.

Der sogenannte ANSI-Standard (American National Standards Institute) wurde 1988

festgelegt. Ein wesentlicher Beitrag des Standards ist die Definition einer Bibliothek, welche zu C gehort.

C++ wurde in den 80-er Jahren von Bjarne Stroustrup entwickelt, teilweise als verbessertes C, zum wesentlichen Teil aber auch als Sprache fur Datenabstraktion und objektorientiertes

Programmieren. Die nachfolgenden Kapitel berucksichtigen die C-Erweiterungen bezw.

die C - Verbesserungen in C++ , soweit sie nicht direkt mit objektorientiertem Programmieren zu tun haben.

In einem C - Quellenprogramm kann ein Kommentar uberall dort stehen, wo auch ein Leerzeichen stehen kannn. Ein Kommentar beginnt mit /* und endet mit */ , er kann sich dabei auch uber mehrere Zeilen erstrecken:

/* Dieser Kommentar gilt fur eine Zeile */

/* Dieser Kommentar

gilt fur zwei Zeilen */

/*

* Auch dieser Kommentar * ist recht gut lesbar.

*/

In C++ sind auch Kommentare hinter dem Zeichen // bis zum Zeilenende moglich : // Dies ist ein C++ Kommentar

Der Kommentartext wird vom Compiler ignoriert. Jeder Programmbeginn und jeder neue

Programmabschnitt sollte mit erklarendem Kommentar versehen sein. Nicht jede Anwendungszeile benotigt einen Kommentar.

Variablen reprasentieren Speicherstellen, deren Inhalt durch Wertzuweisungen oder Einlesen von Daten bestimmt wird. Fur jede Variable wird vor ihrer ersten Anwendung ein Datentyp vereinbart, wobei bei dieser Definition auch ein Anfangswert festgelegt werden kann :

int anfangswert, endwert; // zwei ganzzahlige Variablen.

int _ziel = 100; // ganzzahlige Variable mit Anfangswert float inhalt, laenge = 20; // zwei reelle Variablen (Gleitkomma Variablen ) char zeichen, grbuchstabe = 'H' ,

klbuchstabe = 'e'; // char - Variablen

(5)

Das erste Zeichen eines Namens muÜ ein Buchstabe oder ein Unterstrich sein, die weiteren Zeichen konnen Buchstaben oder Ziffern sein, oder Unterstrich. Bis zu 32 Zeichen (ohne Leerzeichen ) sind fur die Namensgebung von Variablen relevant.

GroÜe Buchstaben werden dabei von kleinen Buchstaben unterschieden : Ziel, ziel, ZIEL sind drei verschiedene Namen in C. U blicherweise werden im C - Programm normale Variablennnamen klein geschrieben.

Eine Variable kann nur Werte vom vorgegebenen Datentyp annehmen. Aufgrund solcher Vereinbarungen kann der Compiler fur jede Variable Speicherplatz reservieren und der

Datendarstellung entsprechend Maschinenbefehle erzeugen. Variablen sollten vom Namen her ihre Bedeutung leicht erkennen lassen, z. B. zins, inhalt, flaeche; einfache Buchstaben wie i,j,r

empfehlen sich bei mathem. Aufzahlungen bezw. als besondere Gro Üen in mathem. Formeln.

Im allgemeinen ist fur jede neue Namensdefinition im Programm ein kurzer und erklarender Kommentar sinnvoll und nutzlich.

Vereinbarungen fur Namen stehen normalerweise am Anfang einer Funktion ( wie main().. ) oder zu Beginn eines Programm-Blocks, d. h. einer durch { } eingeklammerten Anweisungsfolge.

In C gibt es reservierte Namen, wie cin , cout, main, und auch vordefinierte Namen, wie sin, sqrt : alle solche Namen sind stets klein zu schreiben .

Konstanten sind Werte, welche im Programm unmittelbar angegeben werden. Man unterscheidet : Integer-Konstanten : 5, 78

Gleitkomma-Konstanten : 5.0 , 78.123 Zeichen - Konstanten ( Character - Konstante ) : 'a' , 'A' Textkonstanten ( Stringkonstanten ) : "Programm"

In einem Programm konnen solche Konstanten als Literale (direkte konstante Gro Üe wie 78) oder auch als symbolische Konstante auftreten : dann ist ein konstanter Wert mit einem symbolischen Namen verbunden ; der Symbolwert kann im Programmablauf nicht verandert werden.

Einzelne Zeichenkonstanten bestehen aus einem (oder mehreren ) Zeichen zwischen den Begrenzungszeichen Apostroph : 'm'

'M' '\xHexadezimalzahl'

'\n' // Escape - Sequenz fur neue Zeile

Die Zeichenkonstante 'm' ist ein ganzzahliger Wert und stellt den numerischen Wert des Zeichens m im Zeichensatz der Maschine dar.

Die Hexadezimalzahlen liegen im Bereich x00 bis x1F, z.B. '\x41' (Buchstabe A )

Fur nicht darstellbare Zeichen bietet C eine besonder Symbolik an : die Escape - Sequenzen.

Fur mogliche spezielle Steuerzeichen (Escape - Sequenzen) gilt die folgende Tabelle : '\a' BEL Tonerzeugung 0x07

'\b' BS Backspace=Rucktaste 0x08 '\f' FF Form Feed=Vorschub 0x0C '\n' LF Linefeed=Zeilenvorschub 0x0A '\r' CR Carriage Return 0x0D '\t' HT Tab horizontal=Tab Taste)0x09 '\v' VT Tab vertical 0x0B '\\' \ Backslash = Ruckstrich 0x5C '\'' ' Apostroph = Hochkomma 0x27 '\"' " Anfuhrungszeichen 0x22 '\?' ? Fragezeichen 0x3F

Dazu kommt noch das Zeichen '\0' (0x00) als Ende von intern gespeicherten Zeichenfolgen (Strings).

(6)

Textkonstanten ( auch strings genannt )sind Zeichenfolgen zwischen den Begrenzungszeichen Anfuhrunszeichen :

" Dies ist eine Textkonstante "

"\nDiese Textkonstante beginnt bei der Bildschirmausgabe in einer neuen Zeile "

Beim Abspeichern im Rechner wird an das Ende einer solchen Zeichenkette ein Nullzeichen '\0' noch vom System automatisch angehangt. Die Textkonstante "x" besteht also abgespeichert aus zwei Zeichen .

Der Dateiname fur ein C - Quellenprogramm richtet sich nach dem Betriebssystem ! Fur DOS kann ein Dateiname maximal 8 Zeichen (Buchstaben oder Zahlen oder auch spezielle

Sonderzeichen ) enthalten, mit zusatzlicher Namenserweiterung . Zwischen GroÜ - und Kleinschreibung wird bei DOS - Dateinamen nicht unterschieden :

Fur C++ : Aufg1.CPP

aufg1.cpp gleiche Datei wie Aufg1.CPP 1Aufg.CPP

Fur C : Aufg1.C

Einige der in DOS - Dateinamen erlaubten Sonderzeichen sind : _ , $ , # , & . Unter Windows gelten die fu r lange Namen gu ltigen Regeln !

Ein einfaches C - Programm besteht aus einem globalen Vereinbarungsteil und der

nachfolgenden Hauptfunktion main(). Das runde Klammernpaar ( ) kennzeichnet hier eine leere Parameter- liste der Funktion main(). Im gleichen C - Programm darf der Funktionsname main() nicht mehrmals auftreten.

Im globalen Vereinbarungsteil stehen u. a. die Preprozessor - Anweisungen, wie z.B.

#include <iostream.h>

Solche Preprozessoranweisungen fugen sog. Headerdateien mit Informationen uber Unterprogrammbibliotheken ein und besorgen dadurch die Zuordnung von solchen

Unterprogrammbiliotheken zum Programm; sie werden zeilenweise angeordnet und nicht durch ein Semikolon abgeschlossen. Preprozessoranweisungen konnen uberall im Programm stehen und irgendwo in einer Zeile beginnen (Borland C, C++) . Im globalen Vereinbarungsteil konnen auch globale Vereinbarungen stehen; daruber spater mehr .

Die Hauptfunktion main() enthalt die lokalen Vereinbarungen und Anweisungen, die festlegen, welche Aktionen nacheinander ausgefuhrt werden sollen. Jede lokale Vereinbarung und jede Anweisung wird in C mit ; abgeschlossen. Lokale Vereinbarungen und Anweisungen sind zwischen den Klammersymbolen { und }. Die geschweiften Klammern { und } dienen in C allgemein dazu, Vereinbarungen und Anweisungen in einem Block zusammenzufassen. Solchen Blocken mit geschweiften Klammern ( 'compound statements ') werden wir noch an verschiedenen Programmstellen begegnen.

Ein allgemeines C - Programm enthalt zusatzlich zu main() noch weitere Funktionen , welche innerhalb von main als Unterprogramme aufgerufen werden ; ein Beispiel dafur ware die formatierte Ausgabe von verschiedenen Ergebnissen..

Jeder Programmstart beginnt in einem C - Programm mit der Funktion main() .

In viele Programmen werden Formeln berechnet. Dazu gibt es die Wertzuweisungen als besondere Anweisung :

z = x + y ;

(7)

z = z + 5;

Der Wertzuweisungoperator = kennzeichnet keine mathem. Gleichung, sondern eine

Zuweisungstatigkeit. In der Wertzuweisung z = z + 5; wird zunachst der Wert von z um 5 erhoht und das Ergebnis anschlieÜ end in der Speicherstelle z abgespeichert.

Fur eine ubersichtliche Programmstruktur sollten bei solchen Ausdrucken die Operatoren immer mit Leerstellen umgeben werden, also nicht z=x+y; , sondern besser z = x + y ; .

Der Ausdruck

cout << "\nBitte, zwei ganze Zahlen ";

ist eine Anweisung fur die Ausgabe am Bildschirm. Das << Zeichen kennzeichnet hier die Ausgabeoperation 'ubertrage nach ' , cout kennzeichnet den Bildschirm.

Durch Wiederholung von << konnen auch mehrere Daten ausgegeben werden : cout << x << "+" << y << "ergibt " << z;

Fur die Werte x= 5 und y = 3 ergibt sich hier am Bildschirm : 5 + 3 ergibt 8

Der Ausdruck

cin >> x ;

ist entsprechenderweise eine Anweisung fur Dateneingabe von der Konsole. Das >> Zeichen kennzeichnet hier die Eingabeoperation 'lese von ', cin kennzeichnet die Konsole.

Durch Wiederholung von >> sind mehrere Eingaben in einer Anweisung moglich : cin >> x >> y;

An der Konsole muÜ die Dateneingabe mit cr abgeschlossen werden. Gegebenenfalls konnen mehrere Dateneingaben nacheinander an der Konsole, durch Leerstellen getrennt , erfolgen.

Im C - Programm werden Leerstellen, leere Zeilen und Tabulatorstopps vom Compiler ignoriert, sie zahlen als sog. whitespace - characters.

Die Anweisung return 0 ; innerhalb der Hauptfunktion main()bewirkt einen Rucksprung in die Entwicklungsumgebung oder in das Betriebssystem.

Wahrend das Format des Quellcodes fur den Compiler unwichtig ist, sollte fur den menschlichen Leser jeder Quellcode gut verstandlich strukturiert bezw. formatiert getaltet sein. Wesentliche Aspekte der Programmstrukturierung sind Einrucken bei neuen Zeilen, Leerstellen, Positionieren von Anweisungen (gleiche / neue Zeile ), Kommentare, Verwenden von groÜen / kleinen

Buchstaben bei Namen.

Der Wert des Quellcodes ergibt sich ganz wesentlich aus seiner Lesbarkeit. Auch sollte jedes C- Programm bezuglich Code und Kommentar in einem einheitlichen Stil erstellt werden. Nur so lassen sich Programmfehler eher vermeiden und auch leichter finden (Debugging ).

Ein sinnvolles Beispiel von Programmstruktur ist :

* geschweifte Klammern fur main() .. zu Beginn einer neuen Zeile, * interne Definitionen und Anweisungen um eine Tabulatorstelle oder z.B. um 4 Stellen eingeruckt.

* Alle Programmzeilen sollten vor dem rechten Bildschirmrand abschlieÜ en.

Beispiel :

#include <iostream.h>

main() {

float summe;

summe = 1.6 + 3.48;

cout << "Die berechnete Summe ist : " << summe ;

(8)

return 0 ; }

Mit Hilfe des Editors wird ein C - Programm in den Rechner eingegeben, und kann anschlieÜend als Datei mit der Namenserweiterung .C (bei C ) bezw .CPP (bei C++) auf Diskette oder Festplatte abgespeichert werden.

Von der Editor - Entwicklungsumgebung aus kann auch der Compiler gestartet werden. Der Compiler ubersetzt das C- Programm im Hauptspeicher in ein sog. Objektprogramm fur den Rechner (Namenserweiterung .OBJ).

Der Linker schlieÜlich fugt mehrere getrennt ubersetzte Objektprogramme zu einem endgultigen ausfuhrbaren Ladeprogramm zusammen ( Namenserweiterung .EXE). Beispiele fur solche getrennt ubersetzten Programme sind die Bibliotheksroutinen.

Das gelinkte Programm kann dann ausgefuhrt werden. Auch hierfur ist in der Entwicklungs- umgebung ein spezieller Menuebefehl vorgesehen : 'Run' .

1.2 Definition von Variablen und Konstanten

In C mussen alle Namen vereinbart sein, bevor sie im Programm benutzt werden.

Bei Variablendefinitionen muÜ immer der Datentyp vor dem Variablennamen stehen.

int summe; // Anfangswert nicht festgelegt int i = 15, j = 48; // Anfangswert explizit festgelegt

int k = i; // Die Initialisierung kann sich auch auf bereits definierte Variablen // beziehen.

In C mussen innerhalb eines Programmblocks alle Vereinbarungen zu Beginn dieses Blocks stehen.

In C++ ist eine solche Anordnung nicht zwingend, trotzdem fasst man normalerweise die Vereinbarungen auch in C++ am Anfang eines Blocks zusammen.

Eine solche Variablendefinition kann in C / C++ innerhalb einer Funktion (z.B. main() ), also lokal vorkommen, oder auch auÜerhalb jeder Funktion : dann gilt die Vereinbarung als global.

Global vereinbarte Variablen werden automatisch vor Programmbeginn auf Null initialisiert , sie liegen im statischen Speicherbereich ; lokal vereinbarte Variablen mussen in der Definition explizit initialisiert werden, sonst ist ihr Anfangswert bei Beginn der Funktion undefiniert, sie liegen im automatischen Speicherbereich.

Mit Hilfe des Speicherklassenspezifizierers static ist es jedoch moglich, auch lokal vereinbarte Variablen statisch zu machen :

static int yy; // lokal statisch, mit 0 vorbesetzt.

Alle Variablen vom Typ static werden, falls nicht explizit im Programm mit Werten initialisiert, automatisch mit Null zu Programmbeginn vorbesetzt; sie liegen dann im

statischen Bereich.

Allgemein gilt noch : innerhalb eines Programmblocks deklarierte Variablen konnen nur innerhalb dieses Blocks referiert werden, sie sind auÜerhalb des Blocks nicht bekannt. Der Block begrenzt ihren Gultigkeitsbereich.

Die ganzzahligen Datentypen werden haufig auch fur einfache Zahlaufgaben verwendet.

Rechnerintern werden ganze Zahlen als Binarzahlen dargestellt. Bei negativen ganzen Zahlen ist dabei das hochstwertigste Bit immer eine 1. N-stellige Binarzahlen haben einen Wertebereich : n n

(9)

von -2 bis 2 - 1

In der C - Sprache sind die folgenden ganzzahligen Datentypen vordefiniert :

Datentyp interne Lange dezimaler Zahlenbereich Anwendung

====== ======== =================== ==========

int , short int 16 bit -32768 .. +32767 ganze Zahl

unsigned int 16 bit 0 .. 65535 ganze positive Zahl

long , long int 32 bit -2 147 483 648 .. +2 147 483 647 ganze Zahl unsigned long 32 bit 0 .. 4 294 967 295 ganze positive Zahl

char, signed char 8 bit -128 .. +127 Zeichen, ganze Zahl char, unsigned char 8 bit 0 .. +255 Zeichen, ganze Zahl

Der Datentyp char wird je nach Einstellung eines Compilerschalters (im Menu Options / Compiler) als signed char oder als unsigned char (Voreinstellung ! ) angesehen.

Der Datentyp einer Konstanten ergibt sich aus ihrem Wert, der Datentyp einer Variablen aus ihrer Deklaration. Konstanten werden auch als Literale bezeichnet.

Ganzahlige Konstanten werden normalerweise in der int - Dartsellung intern abgespeichert, gro Üere ganzzahlige Konstanten in der long - Darstellung. Durch Anhangen eines

Kennbuchstabens u oder U fur unsigned, oder l bezw. L fur long an die ganzahlige Ziffernfolge laÜt sich eine vorzeichenlose bezw. lange Abspeicherung (32 Bit ) erzwingen :

40000 abgespeichert als long : 32 bit

40000u abgespeichert als unsigned int : 16 bit

40 abgespeichert als int : 16 bit 40L abgespeichert als long : 32 bit

AuÜ er fur die Null, durfen ganze Dezimalzahlen nicht mit einer fuhrenden Null beginnen.

0 1244 -27

Auch Zeichenkonstanten wie 'A' sind ganze Zahlen ( ASCII Zeichensatz : American Standard Code for Information Interchange); sie konnen in numerischen Operationen genau so wie andere Integerwerte verwendet werden ; sie werden jedoch am haufigsten zum Vergleich mit anderen Zeichen verwendet.

char Zeichen;

cout << "Bitte, einen groÜen Buchstaben eingeben "; cin >> Zeichen;

cout << " Das eingegebene Zeichen hat in ASCII die Position : "

<< Zeichen - 'A' ;

Ganze Hexadezimalzahlen beginnen mit dem Zeichen 0x oder 0X :

(10)

0X2B 0xff

Die in C vordefinierten reellen Datentypen ( reelle Zahlen bezw. Gleitkommazahlen) sind :

Datentyp interne Lange Dezimaler Zahlenbereich Genauigkeit in bit

===== ======= =================== ============

float 32 bit -3.4E38 .. +3.4E38 7 Dezimalstellen double 64 bit -1.7E308 .. +1.7E308 15 Dezimalstellen long double 80 bit -1.1E4932 .. +1.1E4932 19 Dezimalstellen

Die interne Darstellung ist eine normalisierte Gleitkommazahl im Dualsystem : 123.4567 wird als 1.234567E+2 abgespeichert.

Dabei wird eine bestimmte Anzahl Bits fur die normalisierte Mantisse verwendet (einschl.

Vorzeichen) und eine kleinere Anzahl Bits fur den Exponenten (einschl. Vorzeichen). Die fur die Mantisse verwendeten Bits bestimmen im wesentlichen die Genauigkeit eines reellen

Zahlenwertes.

Im Rechner sind also die ganzen Zahlen keine Teilmenge der reellen Zahlen, da die interne Darstellung ganz verschieden ist.

Beim Rechnen mit reellen Datentypen konnen sich Rundungs - und Umwandlungsfehler zu beachtlichen Gesamtfehlern summieren.

In einer konstanten Zahl legt ein Dezimalpunkt fest, daÜ es sich um eine Gleitkommakonstante ( reelle Konstante ) handelt.

Reelle Konstanten werden normalerweise in der double - Darstellung oder bei gro Üeren Werten in long double abgespeichert. Durch Anhangen von f oder F fur float oder von l bezw. L fur long double laÜt sich entsprechend eine andere interne Darstellungsform erzwingen.

Mit dem Datentyp - Modifizierer const (auch Datentyp - Attribut genannt ) konnen wir jedem konstanten Wert vom Typ char, int, float einen Namen geben :

const laenge = 5; // Typ int , implizit const int breite = 10; // Datentyp int explizit const double flaeche = 0; // Datentyp double explizit

Der Inhalt solcher Speicherstellen wird bei Programmstart vorbesetzt und kann im Programmablauf nicht verandert werden : dies wird vom Compiler kontrolliert.

main()

{ double radius, umfang, flaeche;

const double pi = 3.1415;

cout <<"\nRadius : "; cin >> radius ; umfang = 2 * pi * radius;

flaeche = pi * radius * radius ;

cout << "\nUmfang = " << umfang << ", Flaeche = " << flaeche ; return 0;

}

Der Gultigkeitsbereich solcher symbolischer Konstanten ist ebenfalls der umschlieÜ ende Block, bezw. bei globalen Definitionen das ganze Programm.

(11)

Die sog. Eingangsdaten eines Programms sind also entweder im Quellenprogramm als Literale bezw. als symbolische Konstanten vordefiniert, oder sie werden wahrend der Programmausfuhrung eingelesen.

Mit Hilfe der Preprozessoranweisung

#define SYMBOL Ersatztext

ist es moglich, vor der U bersetzung das SYMBOL im Programm durch den dahinter stehenden Ersatztext ersetzen zu lassen, und zwar an allen Programmstellen auÜerhalb von durch " "

gekennzeichneten Zeichenfolgen. Es ist ublich, den Bezeichner einer solchen Symbolkonstanten mit GroÜbuchstaben zu schreiben :

#define PI 3.1415927 main()

{

double umfang, radius=1.5 ; / / radius vorbesetzt.

umfang = 2 * PI * radius;

...

}

In diesem Beispiel wird vom Preprozessor die Zeile mit umfang = 2 * PI * radius umgewandelt in umfang = 2 * 3.1415927 * radius ;

In #define SYMBOL Ersatztext darf der Ersatztext nicht mit einem Semikolon abgeschlossen werden.

Jede Preprozessoranweisung kann in weiteren Zeilen fortgesetzt werden, indem eine Zeile durch \ abgeschlossen und dann in der Folgezeile fortgesetzt wird. Der Ersatztext in #define kann auch ein beliebiger Text sein :

#define FEHLER1 "Die Eingabe von der Konsole war fehlerhaft"

Ein nachfolgendes

cout << FEHLER1;

wird vom Preprozessor ubersetzt in

cout << "Die Eingabe von der Konsole war fehlerhaft" ;

Allgemein bezeichnet man solche durch #define festgelegten Namen auch als Makros : Jeder Makroname im C Programm wird vom Preprozessor durch den entsprechenden Makrotext ersetzt.

Daruber spater mehr!

Der Gultigkeitsbereich eines mit #define vereinbarten Namens erstreckt sich von der Definition bis zum Ende der Quelldatei.

Die bisher erwahnten Vereinbarungen fur Namen sind Namens - Definitionen und erzeugen Objekte im Speicher. Solche Definitionen sind spater zu unterscheiden von Deklarationen, welche nur die Eigenschaften von solchen Objekten festlegen. Jede Definition ist auch eine Deklaration, jedoch nicht umgekehrt. Daruber spater mehr !

Ein konstanter Ausdruck ist ein Ausdruck, in dem nur Konstanten beteiligt sind. Solche Ausdrucke werden schon vom U bersetzer bewertet, und nicht erst zur Laufzeit. In C durfen bei dieser Compile-Time-Auswertung von Ausdrucken auch Symbole vorkommen, welche gemaÜ

(12)

#define mit einem Ersatztext zu ersetzen sind; dagegen gelten in C Ausdrucke mit symbolischen Konstanten ( wie const int breite = 5; ) in diesem Sinn nicht als konstante Ausdrucke. Insbesondere darf in C in switch-Anweisungen die Konstante nach case keine symbolische Konstante der Art const breite = 5; sein. In C++ ist diese Einschrankung aufgehoben : dort durfen auch nach case solche symbolischen Konstanten stehen.

In diesem Sinn ist C++ vom Preprozessor weniger abhangig als C .

2. ) Programmverzweigungen

Jede hohere Programmiersprache enhalt zwei Arten von Anweisungen :

- was ist zu tun (z.B. Wertzuweisung, Eingabe , Ausgabe, Funktionsaufruf ) - wie ist etwas zu tun (z.B. if - Anweisung )

2.1 if - Anweisung (ref. Beispiel 2 )

Programmverzweigungen bieten die Moglichkeit, in Abhangigkeit von eingelesenen oder berechneten Daten bestimmte Programmzweige zu durchlaufen. Die entsprechenden

Auswahlanweisungen in C werden vom Compiler in bedingte Sprungbefehle der Maschinensprache ubersetzt.

Die einfache if - Anweisung :

if (Bedingungsausdruck ) Ja_Anweisung;

Der auf if nachfolgende Bedingungsausdruck steht meistens in runden Klammern : er wird

bewertet, und sofern das Resultat dieser Berwertung nicht null ist (also positiv, oder auch negativ ), so wird die Ja_Anweisung ausgefuhrt. Ist das Resultat gleich Null, so wird die Ja_Anweisung ubergangen.

Als Bedingunsausdruck gilt jeder in C definierte mogliche Ausdruck. Vorwiegend werden dafur Vergleiche verwendet :

int wert;

if ( wert == 0 ) cout << "\nwert ist 0 ";

if ( wert >= 0 )

{ cout << "\nwert ist gro Üer als 0 ";

wert = 0;

cout << "\nwert zuruckgesetzt auf 0 ";

}

Das Ergebnis eines solchen Vergleichs ist entweder 1 (bei wahr) oder 0 (bei falsch) . Wenn bei erfullter Bedingung mehrere Anweisungen ausgefuhrt werden sollen, so wird die sog.

Blockanweisung verwendet : eine durch { } eingeklammerte Folge von Anweisungen ('compound statement '). Am Ende einer solchen Blockanweisung, also nach }, erfolgt kein Semikolon ! Auch eine einfache Anweisung bei erfullter Bedingung kann als Blockanweisung formuliert werden. Dies hat den Vorteil, daÜ spatere Erweiterungen leichter ohne Fehler zu machen sind.

(13)

Ist die Ja-Anweisung eine einzige (einfache) Anweisung, so kann sie in der gleichen Zeile nachfolgend zur if - Bedingung stehen. Eine komplizierte Ja-Anweisung bezw. eine

Blockanweisung schreiben wir in der nachfolgenden Zeile, eingeruckt um eine Tabulatorposition bezw. um 4 Leerstellen; damit laÜt sich die logische Programmstruktur betonen.

Da bei if der numerische Wert eines Ausdrucks berechnet wird, sind bestimmte Abkurzungen moglich :

if (Ausdruck) ist gleichbedeutend wie if (Ausdruck == 1 )

Die zweiseitige if - Anweisung :

if (Bedingungsausdruck ) Ja_Anweissung ; else Nein _Anweisung ;

Wenn der Bedingungsausdruck den Wert 0 (also falsch) liefert, wird die hinter else stehende Nein_Anweisung ausgefuhrt. Dies kann eine einfache Anweisung oder auch eine Blockanweisung sein.

float radikand, wurzel;

....

if (radikand >=0 )

{ wurzel = sqrt(radikand) ;

cout << "nReeller Wurzelwert = " << wurzel ; }

else { wurzel = sqrt( -radikand) ;

cout << "\nImaginarer Wurzelwert = " << wurzel ; }

Unmittelbar nach else darf kein Semikolon stehen, sonst beendet es die if - Anweisung.

if-Anweisungen konnen auch verschachtelt werden :

if (ausdruck1) if ( ausdruck2) Anweisung1;

else

Anweisung2;

Hier gilt die allgemeine Sprachregel : ein else - Teil gehort immer zum nachsten hoheren if, fur das noch kein else - Teil existiert. Die folgende Anweisungsgruppe wird dank der Blockanweisung anders ausgefuhrt als die obige :

if (ausdruck1) { if (ausdruck2) Anweisung1;

}

else Anweisung1; // Hier gehort else zum ersten if.

Programmstruktur : else steht immer beginnend in der gleichen Spalte wie das entsprechende if .

(14)

2.2 Vergleichsausdrucke

In C sind die folgenden Vergleichsoperatoren definiert : < <= > >=

== (fur gleich) != ( fur ungleich )

Dabei haben die beiden letzten ( == und != ) eine geringere Prioritat als die ubrigen : if (a > b == c > d) ....; ist gleichbedeutend mit if ( (a>b) == ( c>d) ....;

Ein Vergleichsausdruck kann auch mehrere Vergleiche beinhalten. Das Resultat jedes einzelnen Vergleichs ist vom Typ int, entweder 1 (wahr) oder 0 (falsch). Umgekehrt gilt der Wert 0 als falsch, und jeder Wert ungleich 0 als wahr (positiv oder negativ ).

Zu achten ist auf den Unterschied zwischen = (Wertzuweisung) und == (Vergleich).

Werden Werte von verschiedenem Datentyp verglichen, so wird z.B. der int - Wert in einen reellen Wert umgewandelt.

Bei Vergleich von reellen Gro Üen auf Gleichheit (==) oder Ungleichheit (!=) kann das Resultat durch Umwandlungsfehler oder Rundungsfehler verfalscht werden. Dies betrifft besonders Nachpunktstellen und Ergebnisse, welche durch fortlaufende Addition und Subtraktion (etwa in Programmschleifen ) entstanden sind. Eine Abfrage von eingelesenen oder mit Konstanten besetzten reellen Variablen ist dagegen unkritisch.

Als Vergleichsausdrucke sind auch arithmetische Ausdrucke moglich : if (x+y > 0)... ist gleichbedeutend mit if ( (x+y) > 0 ) ...

Die arithmetischen Operatoren haben eine hohere Prioritat als die Vergleichsoperatoren.

Vergleichsergebnisse lassen sich mit logischen Operatoren verknupfen :

! (Negation) && (logisches Und ) || (logisches Oder) if ( x==y && ( a-b) > 0 )...

ist gleichbedeutend mit

if ( (x==y) && ( (a-b) > 0 ) )...

Die logischen Verknupfungen haben dabei die niedrigste Prioritat, && ist hierarchisch noch eine Stufe hoher als || . Diesen logischen Operatoren liegen die Regeln der Aussagelogik zugrunde.

Zu beachten ist noch, daÜ die einfachen Zeichen & und | fur Bitoperationen bei ganzen Zahlen verwendet werden; das Operatorzeichen ~ kennzeichnet die bitweise Negation. Die logischen Verknupfungen werden in einem Ausdruck von links nach rechts bewertet, nur bis das logische Resultat feststeht :

A && B && C && D

Wenn hier B den Wert 0 hat, wird der >Ausdruck nicht mehr weiter untersucht.

Bei der Reihenfolge von Operationen werden also arithmetische Operationen vor den Vergleichen und diese vor den logischen Operationen durchgefuhrt, wenn nicht durch runde Klammerung anders festgelegt.

(15)

Besondere Beachtung verdient : if( 1< y && y < 20)..

Fehlerhaft ware hier zu schreiben : if ( 1<y <20)..

Das folgende Beispiel liest einen Buchstaben von der Konsole ein und wandelt GroÜ buchstaben in Kleinbuchstaben um :

char c ;

cout << "Bitte, einen Buchstaben eingeben "; cin >> c ;

if ( ( c >= 'A' ) && ( c <= 'Z' ) ) // Vergleich von einfachen ASCII - Zeichen c = 'a' + c - 'A'; // ASCII Zeichensatz angenommen

cout << c;

2.3 Die switch _ Anweisung (ref. Beispiel 3 )

Man kann mehrere if -Anweisungen miteinander verketten, um Alternativen zu unterscheiden. Eine standardmaÜige Anweisungsfolge ist :

if (ausdruck1) anweisung1;

else if (ausdruck2) anweisung2;

else if (ausdruck3) anweisung3;

else

anweisung4;

Fur die Anweisungen durfen wieder ganze Blockanweisungen stehen, in welchen wiederum if- Anweisungen stehen konnen.

Ein Beispiel :

#include <iostream.h>

#include <math.h>

main() {

char zeichen ; double grad , bogen;

cout << "\nWinkel in [–] eingeben :"; cin >> grad ;

cout <<" s = Sinus , c = Cosinus , t = Tangens -> "; cin >> zeichen ; bogen = grad * M_PI / 180 ; // BogenmaÜ berechnen if ( zeichen == 's' )

cout << "\nSin " << grad << " = " << sin(bogen);

else if ( zeichen == 'c' )

cout << "\nCos " << grad << " = " << cos(bogen);

else if ( zeichen == 't')

cout << "\nTan " << grad << " = " << tan(bogen);

else cout <<"\n\afehler : kein Kennbuchstabe s c t ";

.. ... ..

}

Wenn dabei speziell auf konstante Werte gepruft wird, gibt es die switch-Anweisung anstelle von verketteten if's. Die switch - Anweisung ist eine Auswahl unter mehreren Alternativen.

(16)

switch ( Auswahlausdruck ) {

case Konstante1 : Anweisungsfolge_1; break;

case Konstante2 : Anweisungsfolge_2; break;

. . . . . . .

case Konstante_n : Anweisungsfolge_n; break;

default : Anweisungsfolge_s ; break;

}

Der hinter switch stehende Ausdruck wird ausgewertet. Das Ergebnis ist (evtl. nach Umwandlung ) ein Wert vom Typ int oder char. Dieser wird von oben nach unten mit den Konstanten hinter case verglichen. Diese Konstanten sind ublicherweise ganze Zahlen oder Zeichenkonstanten (z.B. 'J' ).

Reelle Datentypen werden nach den Regeln fur gemischte Ausdrucke ganzzahlig gemacht : Stellen hinter dem Komma werden dabei abgeschnitten.

Bei angetroffener Gleichheit werden entsprechend die hinter dem : stehenden Anweisungen ausgefuhrt, einschlieÜ lich aller nachfolgenden Anweisungen hinter den anderen case-Teilen.

Wird keine Gleichheit gefunden, werden die Anweisungen hinter default ausgefuhrt. Der default Ä Teil muÜ aber nicht vorhanden sein. Stimmt der Wert des Auswahlausdrucks mit keiner Konstanten uberein, und ist auch kein default - Teil vorhanden, so wird kein Zweig ausgefuhrt.

Jede Anweisungsgruppe kann man mit break abschlieÜ en : in diesem Fall wird nach break die switch-Anweisung verlassen. Fehlt ein break am Ende, so werden alle nachfolgenden Zweige durchlaufen, bis zum nachsten break oder switch - Ende.

Jede case - Konstante darf nur ein einziges Mal nach einem case vorkommen. Vor einer Anweisungsgruppe konnen auch mehrere case - Konstanten stehen :

case 0 : case 1 : Anweisungsfolge_0_1; break;

case 2 : Anweisungsfolge_2; break;

. . . .

Haufig wird im default - Teil ein Fehlerfall (z.B. falsche Eingabe von Konsole ) programmiert.

Die recht ubersichtliche Auswahlanweisung switch hat die Einschrankung, daÜ nur Konstanten vom Typ int oder char als Vergleichsoperanden zugelassen sind.

Ein Beispiel :

#include <iostream.h>

main()

{ int zensur ; ... .... ....

switch (zensur) {

case 1 : ; // Semikolon ist hier eine Leeranweisung case 2 : { cout << "\nEinstellen "; break ; }

case 3 : { cout << "\nGesprach "; break; } case 4 : { cout << "\nZusatzprufung "; break ; }

case 5 : // Programm wird nach nachstem Label fortgesetzt.

case 6 : { cout << "\nNicht einstellen "; break; } default : cout << "\nFalsche Note ";

} }

(17)

In C gibt es Einschrankungen bezuglich der Verwendung von symbolischen Konstanten nach case, wie das folgende Beispiel zeigt :

#define WERT 5 main()

{ const wert = 6 ; // WERT und wert sind nun verschiedene symbolische Konstanten ...

switch ( ... )

{ case WERT : .... // in C und in C++ erlaubt case wert : ... // nicht in C, nur in C++ erlaubt }

... ... ...

}

Programmstruktur : die geschweiften Klammern { } sind gegen switch eingeruckt.

2.4 Die goto - Anweisung

Die goto -Anweisung ist eine unbedingte Sprunganweisung :

goto ziel; // ziel ist hier eine Programmarke, zu der gesprungen wird . . . . .

ziel : cout "\nZiel ist erreicht ";

Eine Marke ( wie hier ziel ) hat die gleiche Form wir ein Variablenname. goto - Anweisungen finden auch Verwendung in bedingten Anweisungen :

if (bedingung) goto ziel;

. . . ziel : cout .. .. .. ..

Die Anweisung goto setzt das Programm immer an der hinter dem Sprungziel stehenden Anweisung fort.

Die Sprungmarke muÜ in der gleichen Funktion liegen, in der das goto benutzt wird. Die

Sprungziele erhalten einen eindeutigen frei wahlbaren Namen (Bezeichner), welcher unmittelbar vor der nachfolgend auszufuhrenden Anweisung steht, durch einen Doppelpunkt getrennt.

Eine strukturierte C-Programmierung erlaubt es, ohne das goto auszukommen. In Ausnahmefallen ist es jedoch sinnvoll, mit dem goto zu arbeiten. Beispiele dafur sind fehlerhafte Eingabe von der Konsole. Auch konnen verschachtelte Programmschleifen mit goto auf einmal verlassen werden.

Die Anwendung von break wurde hier nur die innerste Schleife beenden. Das Gleiche gilt fur verschachtelte switch Ä Anweisungen.

Code mit goto-Anweisungen ist im allgemeinen schwieriger zu verstehen. Daher sollten goto - Anweisungen nur selten verwendet werden. Insbesondere sollte ein goto nicht in enen

inneren Block hinein fuhren : solche Programmteile sind spater sehr schwierig zu andern.

3.) Programmschleifen

3.1 Die while - Schleife ( ref. Beispiel 4)

In vielen Anwendungen mussen Anweisungen mehrmals mit unterschiedlichen Daten

(18)

ausgefuhrt werden.

Die while - Schleife dient zu bedingten Schleifen, bei denen die Laufbedingung vor dem (ersten ) Schleifendurchlauf auf true oder false gepruft wird .

while (Bedingungsausdruck ) Schleifenanweisung;

Der Bedingungsausdruck wird vor jedem Schleifendurchlauf neu bewertet. Im Falle von wahr (1 bzw !=0 ) wird die Schleifenanweisung ausgefuhrt. Im Falle von falsch ( 0 ) wird die

Schleifenanweisung nicht mehr ausgefuhrt, und die while - Schleife ist damit beendet ; es folgt dann der an die while - Schleife sich anschlieÜende Teil des Programms. Die Schleifenanweisung kann eine einzige Anweisung oder auch eine Blockanweisung sein.

Innerhalb der Schleifenanweisung bzw. Blockanweisung muÜ der Bedingungsausdruck so verandert werden, daÜ die while - Schleife ein Ende findet. Wenn die Bedingung der while - Schleife bereits vor dem Eintritt in die Schleife nicht erfullt ist, wird der Schleifenkorper gar nicht ausgefuhrt.

int j = 0;

while ( j <= 200 ) {

cout << "\n" << j ; // Laufende Werte ausgeben j = j+10 ;

}

Hinter der runden Klammer des Bedingungsausdrucks darf kein Semikolon stehen.

Programmstruktur : Schleifenanweisung einrucken !

Gleich noch ein Beispiel : char zeichen = ' ';

while (zeichen != '\r' ) {

zeichen = getch();

}

Der Block hinter der while - Anweisung wird hier so oft durchlaufen, wie das eingelesene Zeichen nicht gleich dem ASCII Code der Return-Taste ist.

Bei reellen Variablen im Bedingungsausdruck konnen sich bei forlaufender Addition oder Subtraktion Umwandlungs - und Rundungsfehler so summieren, daÜ der beabsichtigte Endwert nicht genau getroffen wird.

Die Ungenauigkeiten der reellen Zahlendarstellung und Rechnung konnen besonders dann zu numerischen Problemen fuhren, wenn Stellen hinter dem Komma zu verarbeiten sind. Ein Beispiel ist der endliche Dezimalbruch 0.1 , der bei der Dualumwandlung einen unendlichen Dualbruch ergibt und daher nur gerundet dargestellt werden kann.

Fur reelle Zahlschleifen empfehlen sich folgende MaÜ nahmen : - nie den Endwert auf gleich oder ungleich prufen,

- nur auf gro Üer, gro Üer/gleich, kleiner oder kleiner/gleich testen, - den Endwert gegebenenfalls mit halber Schrittweite korrigieren, - oder reelle Gro Üen aus ganzahligen Laufvariablen ableiten.

Ein Beispiel :

#include <iostream.h>

main()

(19)

{ double xa, xe, xs, x;

cout << "\n Anfangswert -> "; cin >> xa;

cout << " Endwert -> "; cin >> xe;

cout << " Schrittweite -> "; cin >> xs;

x = xa ;

while ( x <= xe + 0.5 * xs ) // Korrektur wegen reeller Ungenauigkeit {

cout << endl << x ; x = x + xs ;

} return 0:

}

Mit der break - Anweisung innerhalb der while-Schleife kann man die while - Schleife unmittelbar verlassen.

Mit der continue - Anweisung wird nur der aktuelle Schleifendurchlauf beendet und es beginnt ein neuer Durchgang, wobei zunachst die Schleifenbedingung gepruft wird.

Das folgende Beispiel zeigt den Gebrauch von break und continue im Zusammenhang : long double zahl;

while (1) // Endlosschleife { cout << "\nGib eine Zahl ein, Ende mit 0: \n" ; cin >> zahl;

if ( zahl < 0 ) continue; // Neuer Schleifendurchlauf if ( zahl == 0 ) break; // Schleifenende

zahl = sqrt(zahl);

cout << zahl ; }

Im Interesse der strukturierten Programmierung sollte nach Moglichkeit auf die Verwendung von break und continue bei Programmschleifen verzichtet werden: sie konnen zu unubersichtlichen Programmstrukturen fuhren.

Mit dem Funktionsaufruf exit(status); laÜt sich ein Programm beenden; status ist dabei eine int - Gro Üe, der Exit - Code, dessen Wert Null normalerweise fur eine fehlerfreie Ausfuhrung steht.

Mit dem Funktionsaufruf abort(); ,ohne Parameter, wird ein Programm ohne Fehlermeldung abgebrochen: der resultierende Exit - Code hat den Wert 3 .

Hinweis zur cout - Anweisung : in jedem Zusammenhang, in dem der Wert einer Variablen vom bestimmten Typ benutzt werden darf, kann auch ein allgemeiner Ausdruck von diesem Typ stehen, z.B. sqrt(zahl).

3.2 Die for - Schleife ( ref. Beispiel 4 )

Die for - Schleife ist meistens eine Zahlschleife, bei der eine Laufvariable von einem Anfangswert bis zu einem Endwert mit einer bestimmten Schrittweite verandert wird.

for (i=1; i<100; i = i+1) sum = sum + i;

Der erste Ausdruck i = 1 initialisiert die Laufvariable i, im zweiten Ausdruck i<100 wird eine Bedingung abgefragt, im dritten Ausdruck i= i+1 wird die Laufvariable um 1 erhoht. Die for- Anweisung wird so lange durchlaufen, wie der zweite Ausdruck true ist.

Allgemeiner :

for ( Laufv = Anfangswert ; Laufv verglichen mit Endwert; Laufv verandert um Schrittw) Anweisung bzw. Blockanweisung ;

(20)

A quivalent dazu konnten wir auch die folgende while - Schleife formulieren : Laufvariable = Anfangswert;

while ( Laufvariable verglichen mit Endwert ) { Anweisung bzw. Blockanweisung ; Laufvariable verandert um Schrittweite ;

}

Ganz allgemein laÜt sich eine for - Schleife wie folgt formulieren :

for ( Anfang; Laufbedingung; Veranderung) Anweisung ;

Innerhalb der runden Klammer der for-Anweisung stehen also drei Ausdrucke, durch Semikola getrennt.

Der erste Ausdruck wird vor Beginn der Schleife ausgefuhrt. Er bestimmt den Anfangswert der Laufbedingung, vor Antritt der Schleife.

Der zweite Ausdruck, die Laufbedingung, wird vor jedem Schleifendurchlauf bewertet. Ergibt dieser Bedingungsausdruck den Wert 0 (falsch), so ist die for - Schleife beendet : Die Anweisung wird dann nicht mehr durchgefuhrt und der Programmablauf verzweigt unmittelbar zum

anschlieÜenden Programmteil. Ist die Laufbedingung bereits vor Eintritt in die Schleife nicht erfullt, so erfolgt gar kein Durchlauf.

Der dritte Ausdruck, die Veranderung, wird nach jedem Durchlauf neu bewertet: er enthalt grundsatzlich die Veranderung der Laufvariablen. Hinter diesem dritten Ausdruck innerhalb der Klammer steht kein Semikolon !

Hinter der Klammer steht die Anweisung des Schleifenkorpers, bezw. eine Blockanweisung (geschweifte Klammern { } ) .

Programmstruktur : Der Anweisungsblock wird gegenuber for eingeruckt.

Ein Beispiel :

int k, anfang, ende , schrittweite ;

cout << "\n Anfangswert Endwert Schrittweite --> " ; cin >> anfang >> ende >> schrittweite;

for ( k = anfang ; k <= ende ; k = k+schrittweite) cout << "\n " << k;

Auch bei der for - Anweisung kommen break und continue zum Tragen; continue verzweigt hier zunachst zum Veranderungs - Ausdruck.

Einzelne Bestandteile der for -Anweisung konnen entfallen, nicht jedoch die Semikola.

Die Folge

for ( ; ; ) Anweisung ; stellt eine endlose Schleife dar.

Unmittelbar hinter den runden Klammern der for - Schleife darf kein Semikolon stehen , sonst beendet dieses Semikolon die for-Schleife.

Innerhalb einer for-Anweisung kann eine Laufanweisung in C++ auch lokal neu definiert werden : for (int i=1; i<10; i = i+1) ....

Zu beachten ist, daÜ hier die Variable i ihre Gultigkeit bis zum Ende des aktuellen

Programmblocks hat, wie alle anderen in diesem umschlieÜenden Block definierten Namen.

Programmstruktur : Der Anweisungsblock wird gegenuber for eingeruckt.

Noch ein Beispiel : double bogen, grad, s;

for (grad = 20; grad <= 60 ; grad = grad + 1)

(21)

{

bogen = grad * M_PI / 180 ; s = sin(bogen) ;

cout << "\n" << s;

}

3.3 Die do - while Schleife (ref. Beispiel 5)

Bei der do - while -Schleife liegt die Schleifenkontrolle am Schleifenende : die Anweisungen werden also mindestens ein Mal durchgefuhrt. In den Schleifen-Anweisungen muÜ die Laufbedingung so verandert werden, daÜ ein Ende der Schleife erreicht wird.

do

Anweisungen ;

while ( Bedingungsausdruck )

Auf das Kennwort do folgen die Anweisungen bzw. Blockanweisung des Schleifenkorpers. Es konnen hier mehrere Anweisungen, ohne { } stehen, da eine Anweisungsfolge hier durch

do - while eingeklammert ist. Die Blockanweisung hat allerdings den Vorteil, daÜ die Kennworter do und while besser erkennbar sind. Auf das Kennwort while folgt der Bedingungsausdruck, er wird nach jedem Schleifendurchlauf neu bewertet.

int j = 10;

do

{ cout << "\n" << j; // Laufenden Wert ausgeben j = j+1 ;

}

while (i <= 50 ) ; // Schleifenkontrolle

Besonders zu beachten ist hier das Semikolon nach der while - Bedingung.

Auch bei do -while kommen break und continue zur Anwendung, wie bei while .

Die do-Schleife wird hauptsachlich dann benutzt, wenn eine Schleife mindestens einmal durchlaufen werden soll.

Programmstruktur : Anweisung bezw. Blockanweisung gegenuber do einrucken.

while beginnt in gleicher Spalte wie do.

Bei allen programmierten Schleifen lohnt es sich, die Bedingung fur den ersten und den letzten Schleifendurchlauf sorgfaltig zu beachten; hier schleichen sich gerne Fehler ein, welche unter anderem zu endlosen Schleifen fuhren konnen.

3.4 Einfache Schleifenprogramme fur Ein - und Ausgabe, getchar() und putchar(c) Fur die Eingabe und Ausgabe von einzelnen Zeichen dienen die Funktionen getchar() und

putchar(c), welche in stdio .h deklariert sind. getchar() hat keinen Parameter, die Funktion liest ein Zeichen von der Standardeingabe stdin und liefert es als Datentyp int ab. Die Eingabe einer

Zeichenfolge uber die Tastatur wird gepuffert bis 'Enter' gedruckt wird.

(22)

Die Funktion putchar(c) gibt ein Zeichen vom Typ int bezw. char in die Standardausgabe stdout aus.

Beispiel : Ein einfaches Kopierprogramm.

#include <stdio.h>

main() {

int c;

printf("\nBitte, eine Zeichenfolge eingeben, AbschluÜ mit ^Z ->");

c = getchar(); // Eingabe von der Konsole (stdin) while ( c != EOF)

{ putchar (c); // Ausgabe am Bildschirm (stdout) c = getchar();

} return 0;

}

Beispiel : Eingelesene Zeichen zahlen :

#include <stdio.h>

main() {

long nc = 0;

printf("\nBitte, eine Zeichenfolge eingeben, AbschluÜ mit ^Z ->");

while (getchar() != EOF) // EOF resultiert aus Eingabe von ^Z nc = nc + 1 ;

printf("%ld\n", nc); // enspricht cout << nc << endl ; return 0 ;

}

Beispiel : Wiederholende Kontrollschleife bei Eingabe :

#include <iostream.h>

main() {

double xa ; // Einzulesende reelle Gro Üe int fehler; // Schaltervariable

do {

cout << "\nReelle Gro Üe 0 < xa < 100 ->" ; cin >> xa ; // cin : fuhrende Leerstellen werden uberlesen, // Ende bei erster nachfolgender Leerstelle fehler = !( 0 < xa && xa < 100 ) ;

}

while (fehler) ; // Wiederhole , solange fehlerhafte Eingabe return 0;

}

(23)

Beispiel : Wiederholende Leseschleife mit dem Wert 0 als Endemarke :

#include <iostream.h>

main() {

int wert; // einzulesender Wert

int sum = 0, n = 0; // Summe sum und Zaehlvariable n

do {

cout << "\nGanzzahlige Gro Üe, Ende mit 0 " << n+1 <<". Wert -> ";

cin >> wert;

if ( wert != 0 )

{ sum = sum + wert; n = n+1;

} }

while ( wert != 0) ; // Wiederhole , solange keine 0 -Eingabe return 0;

}

4.) Die Entwicklungsumgebung (Einfuhrung )

Die folgenden Unterkapitel behandeln einige haufig benutzte Moglichkeiten der

C++ Entwicklungsumgebung. Sie sind aus dem 'Borland C++ Benutzerhandbuch ' entnommen ; das hier referierte Benutzerhandbuch beschreibt noch eine groÜe Menge von weiteren

Bedienungsmoglichkeiten .

Alle Bedienungsmoglichkeiten konnen auch online im C++ Hilfemenue (F1) nachgelesen werden.

4.1 Einige grundsatzliche Moglichkeiten in der Entwicklungsumgebung

U ber die Menuezeile erreichen Sie alle Menuepunkte. Bei einem Befehl mit Fortsetzungspunkte n (...) wird ein Dialogfenster geoffnet. Bei einem mit Pfeilspitze markiertem Befehl gelangt man in ein Untermenue. Befehle ohne Zusatzzeichen werden unmittelbar ausgefuhrt.

In der Entwicklungsumgebung konnen viele Fenster offen sein. O ffnen Sie dieselbe Datei in mehreren Fenstern, wirken sich Aktionen in einem Fenster auf alle anderen Fenster aus. Auch konnen mehrere Dateien auf einmal geoffnet sein.

Wurde eine Datei im Editor - Fenster geandert, erkennt man dies an einem Sternchen (*) links unten neben der Spalten - und Zeilennummer.

Mit File | DOS Shell kann man C++ verlassen, um in der DOS - Ebene DOS-Befehle einzugeben.

Dabei bleibt C++ im Speicher : mit dem DOS Befehl Exit kommt man wieder zur C++ - Entwicklungsumgebung zuruck.

Referenzen

ÄHNLICHE DOKUMENTE

Es sollen in jeden Korb gleich viele Äpfel verteilt werden... Ein Gärtner erntet 100

Auf der Zahlengeraden können einfache Rechnungen

[r]

Aufbauend auf dem Vektorbegriff sollen Fertigkeiten zur Addition und Subtraktion von Vektoren, ihrer Zerlegung und Komponentendarstellung vermittelt werden..

Viele Probleme lassen sich elegant auf Graphen abbilden.. Materialwissenschaften,

• Formalbezogene Wortschatzbausteine können für eine Unterrichtseinheit oder auch länger auf einem Plakat an der Klassenraumwand hängen, damit die Schüler*innen jederzeit auf

Gib jeweils zwei Trinkbecher Apfelsaft und zwei Trinkbecher Wasser in den leeren Messbecher und lies die Füllhöhe ab.. Notiere die

Die Nutzung ist nur für den genannten Zweck gestattet, nicht jedoch für einen weiteren kommerziellen Gebrauch, für die Weiterleitung an Dritte oder für die Veröffentlichung im