01.09.

2003

Programmierung
Klasse IA02
© by Sebastian Wetzel

©-=]ToT[=-Acid Burn 1

01.09.2003

Erstellen eines C Programms
Jede moderne problemorientierte Sprache stellt ihnen mehrere Dienstprogramme im Rahmen einer Entwicklungsumgebung (IDE) zu Verfügung. Dienstprogramme: - Editor (Quelltext des Programms schreiben (Quellcode) ) Es entsteht eine Datei mit der Endung (erstes.cpp) - Compiler (übersetzen des Quelltextes in eine Maschinen nahe Form) wird auch als Objektcode bezeichnet (es entsteht eine neue Datei erstes.obj) - Linker (dem Programm werden notwendige Funktionen hinzugefügt und ein lauffähiges Programm wird erzeugt (es entsteht eine neue Datei erstes.exe)

Konsolenanwendung in der IDE erstellen
1. Schritt VC starten 2. Schritt Arbeitsbereich und ein Projekt anlegen 3. Schritt Auswählen der Option EIN Leeres Projekt - Fertigstellen Drücken - OK drücken 4. Schritt Aufnehmen einer Quelltextdatei in das Projekt Menübefehl PROJEKT / DEM PROJEKT HINZUFÜGEN / NEU aufrufen Seite Datei anzeigen lassen Name der Datei eingeben Dateityp C++ Quellcode auswählen OK drücken Menübefehl Datei/ Neu aufrufen Seite Projekt anzeigen lassen Pfad auf H:\ umstellen Name für das Projekt eingeben Projekttyp Win32- Konsolenanwendung auswählen OK drücken

©-=]ToT[=-Acid Burn 2

01.09.2003

5. Schritt Quelltext eingeben und Datei speichern 6. Schritt Programm erstellen lassen - Menübefehle ERSTELLEN / Name.exe erstellen Treten Fehlermeldungen auf, zurück zum 5. Schritt 7. Schritt Programm ausführen lassen Befehl ERSTELLEN / AUSFÜHREN VON Name.exe (Tastaturkürzel: Strg + F5)

Eigenschaften von C++
C++ C universell effizient maschinennah portabel

OOP -

Datenabstraktion Datenkapselung Vererbung Polymorphy

©-=]ToT[=-Acid Burn 3

01.09.2003

8-Bit-System Dual 27 128 BJ. 7 0 0 0 26 64 6 0 0 1 0 0 0 25 32 5 24 16 4 0 0 1 23 8 3 0 0 1 22 4 2 0 0 0 21 2 1 0 0 0 20 1 0 0 1 1 0 1 89 Erg.

Umwandlung Dezimalzahl in Dualzahl
Man dividiert fortlaufend die Dezimalzahl durch 2 und notiert sich den Rest der Division. Abbruch wenn der Quotient null ist. Die gesucht Dualzahl ergibt sich aus dem Rest der einzelnen Division wobei links der letzte Divisionsrest steht. Beispiel: 54:2=27 R0 27:2=13 R1 13:2=6 R1 6 : 2=3 R0 3 : 2=1 R1 1 : 2=0 R0 Ergebnis: 00110110

©-=]ToT[=-Acid Burn 4

01.09.2003

Bilden einer negativen Dualzahl
1.Schritt Man bildet die Dualzahl des Betrages der negativen Dezimalzahl 2.Schritt 1ner Kompliment bilden. 3. Schritt +1 rechnen

Grundgerüst eines C++ Programms
#include <iostream> using namespace std; void main ( ) { // einbinden der Bibliotheken // Möglichkeit zur Ein- und Ausgabe // Hauptfunktion Main () // Blockbegrenzer // Anweisung zur Textausgabe

cout <<“Hallo Visual C++!!!!“; }

// Blockbegrenzer

Allgemeines zu Programmen in C++
Quellcode Dateien haben die Dateiendung cpp Die Funktion Main() muss in jedem ausführbaren Programm genau 1mal vorkommen. C++ unterscheidet streng zwischen Groß- und Kleinschreibung.

Syntax der Kommentare
Kommentare beginnen mit einem doppelten Schrägstrich // und enden am Zeilenende. // Dies ist ein Kommentar Kommentare über mehrere Zeilen beginnen mit dem zeichenpaar /* und enden mit */ /* Kommentar über mehrere Zeilen */ ©-=]ToT[=-Acid Burn 5

01.09.2003

Variablen und Konstanten
Deklaration und Definition <Datentyp> Bezeichner; z.B. int var1; Variablennamen können in C++ 32 Zeichen lang sein. Bei der Vergabe eines Bezeichners ist folgendes zu beachten: • • • • Gültige Zeichen sind A-Z, a-z, 0-9 und der Unterstrich_. Umlaute (ä, ö, ü usw.) sind als Bestandteil von Variablennamen nicht gestattet. Variablennamen dürfen nicht mit einer Ziffer beginnen. Schlüsselwörter von C++ (int, switch, usw.) dürfen nicht als Variablennamen verwendet werden. Variablennamen sollten nicht mit einem oder zwei Unterstrichen beginnen

Ganzzahl- Variablentypen Typ Int Long Char Speicheraufwand in Bit 16 32 8 Wertebereich -32768 bis 32767 -2147483648- 2147483648 -128 bis 127 und ASCII Zeichen

Alle Ganzzahlen- Variablentypen kann man auch als unsigned Typen (Vorzeichenlos) verwenden. Ihr Wertebereich verdoppelt sich so im Bereich der positiven Zahlen. z.B. unsigned int var2; //Bereich von 0 bis 65535 Fließkommatypen Typ Float Double Long double Genau 7 15 19 Bit 32 64 80 Wertebereich 3,4*10-38 bis 3,4*1038 1,7*10-308 bis1,7*10308 3,4*10-4932bis3,4*104932

Variablen können an jeder beliebigen Stelle im Programm festgelegt werden. Variablen, die an vielen Stellen der Funktion eingesetzt werden, sollten besser am Anfang der Funktion festgelegt werden. Der Datentyp der Variablen legt den Speicheraufwand, den Wertebereich und die Operatoren, welche auf die Variable angewendet werden dürfen fest. Eine Variable ist nur in dem Block in welchen sie definiert wurde bekannt.

©-=]ToT[=-Acid Burn 6

01.09.2003

Initialisierung von Variablen
Variablen können bei ihrer Definition gleichzeitig initialisiert werden. (d.h. sie erhalten sofort eine Wertzuweisung) z.B. int zahl =12; //zahl erhält Anfangswert 12 char zeichen =’A’ // Zeichen erhält Anfangswert ’A’ Konstanten Definition const Typ NAME= Wert; // Attribut const legt fest das sich der Wert der // Variablen NAME während des gesamten Programms nicht // ändern wir

z.B. const double PI= 3.14259265 ;

Operatoren
Arithmetische Operatoren Operation Addition Subtraktion Multiplikation Division Operationszeichen + * /

Diese Operatoren sind sowohl auf Ganzzahlen als auch auf Gleitkommazahlen anwendbar. Eine Ausnahme bildet der Modulo Operator. Operationszeichen: % Rest bei der Ganzzahligen Division. Vorrangregeln sind wie in der Mathematik Punktrechnung vor Strichrechnung. Höchste Priorität ( )- Klammern. Sind die Operatoren gleichrangig wird von Links nach rechts aufgelöst.

©-=]ToT[=-Acid Burn 7

01.09.2003 Man Beachte: • Sind die Operatoren ganzzahlig so ist auch das Ergebnis ganzzahlig z.B. 1 / 4=0 • Ist ein Operand ganzzahlig und der andere eine Gleitkommazahl so ist das Ergebnis eine Gleitkommazahl z.B. 1.0 / 4=0.25

Berechnung von Ausdrücken
24 / 7+3*2 =9 6-4 / 5+4.0 /2=8.0 1 / 3*2*4=0 5%*3-2*8=-13 a+b 2c
=

(a+b)/(2*c)

h Π r2 3 = Π*r*r*h/3

Vergleichsoperatoren
Operation größer als kleiner als Gleichheit ungleich kleiner gleich größer gleich Operationszeichen > < == != <= >=

Das Ergebnis eines Ausdruckes mit einem Vergleichsoperator ist entweder wahr (Wert=1) oder falsch (Wert =0). Die Vergleichsoperatoren haben einen geringeren Rang als die Arithmetischen Operatoren. Bsp. a=4 b=7 c=5 a<=b 1 b>c<a 1 a= =b 0 5*a<7*b= =0 0

©-=]ToT[=-Acid Burn 8

01.09.2003

Logische Operatoren
Logische Operatoren Verknüpfen in der Regel Ausdrücke welche aus Vergleichsoperatoren bestehen. UND- Operator Verg.1 0 0 1 1 Verg.2 0 1 0 1 UND 0 0 0 1 || Zeichen &&

ODER- Operator

Verg.1 0 0 1 1 Vereinung Verg. ! 0 1 1 0 Rangfolge: 1. ! 2. && 3. ||

Verg.2 0 1 0 1

ODER 0 1 1 1 !

Zuweisungs- Operator

=

Dieser Operator kann nur verwendet werden wenn auf der linken Seite eine Variable steht welche den Ausdruck der Rechten Seite aufnehmen kann.

©-=]ToT[=-Acid Burn 9

01.09.2003

Ausgabe mit cout
Cout ist ein Objekt, welches eine einfache Möglichkeit bietet, Daten z.B. auf dem Bildschirm auszugeben. Eine Ausgabe erfolgt indem der Einfügeoperator << die Daten an cout schickt. Beispiel für Daten: • Zeichenkonstanten „Dies ist ein Text“ • Zeichen ‚A’ • Variablen Bezeichner angeben • Manipulatoren - endl bewirkt Zeilenvorschub - setw(n) bewirkt, dass nachfolgende Zahl, Zeichenkette mit einer Breite von n Zeichen ausgegeben wird - hex, oct, dec bewirken, dass die nachfolgenden Zahlen in der Zahlendarstellung ausgegeben wird. Hinweis: Für den Manipulator setw() muss die Bibliothek <iomanip.h> eingebunden werden.

Eingabe mit cin
Das Objekt cin wir zusammen mit dem Einleseoperator >> verwendet und schickt die Eingabe in die nachfolgende Variable. z. B. cin>>Test; //Test erhält Wert der Eingabe

Das Einlesen von mehreren Variablen, muss über mehrere Einleseoperatoren erfolgen. Aufgabe: Lesen Sie von der Tastatur 3 ganze Zahlen ein. Geben Sie anschließend diese Zahlen als Dezimal-, Octal- und Hexadezimalzahl auf dem Bildschirm in folgender Tabellenform aus. Programm: #include <iomanip.h> #include <iostream.h> void main( ) { int a, b, c; cout<<" Bitte geben sie eine Zahl ein!"; cin>> a; cout<<" Bitte Geben sie ein weitere Zahl ein!!!"; cin>> b; cout<<" Bitte noch mal eine Zahl ein!"; cin>>c; cout<<endl; cout<<setw(20)<<"Hex"<<setw(20)<<"Dez"<<setw(20)<<"Oct"<<endl; ©-=]ToT[=-Acid Burn 10

01.09.2003 cout<<hex<<setw(20)<<a; cout<<dec<<setw(20)<<a; cout<<oct<<setw(20)<<a<<endl; cout<<hex<<setw(20)<<b; cout<<dec<<setw(20)<<b; cout<<oct<<setw(20)<<b<<endl; cout<<hex<<setw(20)<<c; cout<<dec<<setw(20)<<c; cout<<oct<<setw(20)<<c<<endl; }

Programmanalyse: Typ: int Bezeichner: a,b,c Ablauf: Überschrift: Ausgabe ganzer Zahlen Eingabeaufforderung : Bitte 3 ganze Zahlen eingeben. Einlesen: a, b, c Aufgabe: Kreisesberechnung: Der Nutzer ist nach Ausgabe einer Überschrift aufzufordern den Radius eines Kreises in cm einzugeben. Anschließend ist der Umfang und der Flächeninhalt des Kreises zu berechnen und auszugeben. Programmanalyse: Daten (Variablen Konstanten): Konstant: PI double double

Variable: Radius, Umfang, Flächeninhalt

Ablauf: 1. Ausgabe: Überschrift (Kreisberechnung) 2. Ausgabe: Eingabeaufforderung 3. Einlesen: Radius 4. Berechnung: Umfang 5. Berechnung: Flächeninhalt 6. Ausgabe: Umfang, Flächeninhalt ©-=]ToT[=-Acid Burn 11

01.09.2003 Programm: #include<iomanip.h> #include<iostream.h>

const double PI=3.141592654; void main() { double radius, umfang, flaecheninhalt ; cout<<"Kreisberechnung"<<endl; cout<<"Bitte den Radius in cm eingeben!!"<<endl; cin>>radius; //Berechnung Umfang umfang=2*PI*radius; cout<<"Umfang= "<<umfang<<"cm"<<endl; //Berechnung Flächeninhalt flaecheninhalt=PI*radius*radius; cout<<"Flächeninhal= "<<flaecheninhalt<<"cm²"; } Aufgabe: Lesen Sie 2 Ganze Zahlen ein und geben Sie anschließend alle Aufgaben und Ergebnisse für die arithmetischen Operatoren aus. z.B. Addition: z1+z2 Program: #include <iostream.h> #include <iomanip.h>

void main() { int z1,z2,za,zs,zm,zd,zmo; cout<<"Rechenoperation"<<endl; cout<<"Bitte geben Sie eine Ganzzahl ein!!!"<<endl; cin>>z1; cout<<"Bitte geben Sie noch eine Ganzzahl ein!!"<<endl; ©-=]ToT[=-Acid Burn 12

01.09.2003 cin>>z2; //Addition za=z1+z2; //Subtraktion zs=z1-z2; //Multiplikation zm=z1*z2; //Division zd=z1/z2; //Modulo zmo=z1%z2; cout<<"Additon= "<<z1<<"+"<<z2<<"="<<za<<endl; cout<<"Subtraktion= "<<z1<<"-"<<z2<<"="<<zs<<endl; cout<<"Multiplikation= "<<z1<<"*"<<z2<<"="<<zm<<endl; cout<<"Diviosion= "<<z1<<"/"<<z2<<"="<<zd<<endl; cout<<"Modulo= "<<z1<<"%"<<z2<<"="<<zmo<<endl; }

Arithmetische Zuweisungsoperatoren
Die folgenden Anweisungsform ist üblich: z.B. test= test + zahl; //Addiert zahl zu test Kürzer ist die erlaubte Kombination aus Zuweisungsoperator und arithmetischen Operator, welcher den sich wiederholenden Operanden wegfallen lässt. z.B. test+= zahl; //Addiert zahl zu test Es gibt für alle arithmetischen Operatoren einen entsprechenden arithmetischen Zuweisungsoperator: +=, -=, *=, /= und %=. z.B. test /= 3; //entspricht test = test /

Inkrementoperatoren
Der Operator ++ inkrementiert (addiert 1 dazu) sein Argument. Präfix- und Postfixschreibweise hat eine Bedeutung, wenn es in einer Anweisung auftritt. z.B. test= zahl1 * ++zahl2; //Präfix zahl2 wird vor de3r Multiplikation inkrementiert test= zahl1 zahl2++; //Postfix zahl2 wird nach der Multipl. Inkrementiert ©-=]ToT[=-Acid Burn 13

01.09.2003 oder int zahl= 10 cout<< ++ zahl cout<< zahl ++ cout<< zahl

//Ausgabe 11 //Ausgabe 11 //Ausgabe 12

Dekrementoperator
Der Operator – dekrementiert (subtrahiert 1) sein Argument. Er kann ebenfalls in der Präfix- und Postfixschreibweise verwendet werden.

Zusammenfassung: Operatoren
Rang Operator Bedeutung, Verwendung 1 () Klammern bei Arithmetik, Funktionsaufrufe 2 arithmetische Negation, d.h. negative Zahlen ! logische Negation ++ -Inkrement und Dekrement 3 * / Multiplikation, Division % Modulo bei Ganzahlen 4 + Addition und Subtraktion 6 < <= Kleiner, kleiner gleich usw. bei Vergleichen > >= 7 = = != Prüfung auf Gleichheit bzw. Ungleichheit 11 && logisches UND 12 || logisches ODER 14 = Zuweisungsoperator einschließlich aller verkürzten Formen Was gibt folgendes Programm aus? main() { int x; int y; int z ; x = 100 ; x /= 5 * 2 ; x = 10 ; x = 40 ; x *= y = z = 2 ; x = 80 ; y= 2; z= 2; ©-=]ToT[=-Acid Burn 14

01.09.2003 x = 41 ; x=y==2; x=1; y=2; x = 42 ; x==(y=4); x = 42 ; y=4; Was gibt folgendes Programm aus? main() { int x; int y; int z ; x =10 ; y =0 ; z = -10 ; x = x = = y || x ; x=1 y = !y && z ; y= 1; z = 7 >= 6 >= 5 ; z=0; x = 10 ; y=0; z = -10 ; !x && !y || z // Wert = 1 Welchen wert haben die Ausdrücke? Int x = 2, y = 5, z = 7 ; float z1 = 1.3 ; a.) ( x < 5 ) && ( z > y ) b.) ( y <= x) || !( y < 4 ) c.) ( x != 0 ) && ( z >= y ) d.) y%5 – x e.) z1 * x – y * z ©-=]ToT[=-Acid Burn 15 1 1 1 -2 - 32,4

01.09.2003

Formatiert Ausgabe
( Hinweis : Bibliothek iomanip einbinden ! Gilt für neuere Compiler z.B. VC 6.0!)

Manipulatoren zur Formatierung von Ganzzahlen
Manipulator oct hex dec showpos noshopos uppercase nouppercase Wirkung Oktale Darstellung Hexadezimale Darstellung Dezimale Darstellung (Standard) Positiven Zahlen werden mit Vorzeichen ausgegeben Positiven Zahlen werden ohne Vorzeichen ausgegeben (Standard) Hexadezimale Zahlen in Großbuchstaben Hexadezimale Zahlen in Kleinbuchstaben (Standard)

Manipulatoren zur Formatierung von Gleitpunkzahlen
Manipulator showpoint noshowpoint Wirkung Der Dezimalpunkt wird stets angezeigt. Es werden so viele Ziffern angezeigt, wie es der eingestellten Genauigkeit entspricht. Abschließende Nullen hinter dem Dezimalpunkt werden nicht angezeigt. Folgt dem Dezimalpunkt keine Ziffer, wird der Dezimalpunkt nicht angezeigt. (Standard) Darstellung als Festpunktzahl

fixed

Darstellung in exponentieller Notation secientific setprecision(n) Setzt die Genauigkeit auf n Stellen zur Anzeige (Standard: 6)

Hinweis: fixed in Verbindung mit setprecision (n) Regelt die Nachkommastellen, wobei gerundet wird. cout<<fixed<<setprecision(2)<<12.344 // Ausgabe: 12.34

©-=]ToT[=-Acid Burn 16

01.09.2003

Aufgabe: Erstellen Sie ein Projekt Formatierung in welchen Sie eine Ganze Zahl einlesen und die Manipulatoren showpose und upperacase anwenden. Programm: #include <iomanip> #include <iostream> using namespace std; void main() { int zahl; cout<<"Bitte geben Sie eine Ganzzahl ein! "; cin>>zahl; cout<<"Zahl 1="<<setw(5)<<showpos<<zahl<<endl; cout<<"Zahl 2="<<setw(5)<<hex<<uppercase<<zahl<<endl; } Aufgabe: Projekt Zinsen: Lesen Sie das Kapital den Zinssatz und die Laufzeit in Jahren ein. Berechnen Sie anschließend die Zinsen. Hinweis: verwenden Sie fixed und setprecision zur Formatierung. #include <iostream> #include <iomanip> using namespace std; void main() { double Kapital,Zinssatz,Laufzeit,Zinsen; cout<<"Berechnung von Zinsen"<<endl; cout<<"Bitte geben Sie Ihr Kapital in EUR ein! "; cin>>Kapital; cout<<"Bitte geben Sie den Zinssatz in % ein! "; cin>>Zinssatz; cout<<"Bitte geben Sie die Laufzeit (1 Jahr) ein "; cin>>Laufzeit; //Berechnung Zinsen=Kapital*(1+Zinssatz/100)-Kapital; cout<<"Zinsen : "<<fixed<<setprecision(2)<<Zinsen<<" EURO"<<endl; } ©-=]ToT[=-Acid Burn 17

01.09.2003

Ergebnis: Zur Lösung mit mehreren Jahren benötigt man eine Funktion welche Potenzen berechnen kann. Man benötigt die <cmath>.

Programm mit Funktionen
#include <iostream> #include <iomanip> #include <cmath> using namespace std; void main() { double Kapital, Zinssatz, Laufzeit, Zinsen, Endkapital; cout<<"Berechnung von Zinsen"<<endl; cout<<"Bitte geben Sie Ihr Kapital in EUR ein! :"; cin>>Kapital; cout<<"Bitte geben Sie den Zinssatz in % ein! :"; cin>>Zinssatz; cout<<"Bitte geben Sie die Laufzeit in Jahren ein :"; cin>>Laufzeit; //Berechnung Endkapital=Kapital*pow((1+Zinssatz/100),Laufzeit); Zinsen=Endkapital-Kapital; cout<<"Endkapital : "<<fixed<<setprecision(2)<<Endkapital<<" EURO"<<endl; cout<<"Zinsen : "<<fixed<<setprecision(2)<<Zinsen<<" EURO"<<endl; }

Aufgabe: Schreiben Sie ein Beispielprogramm in welchem Sie eine double Zahl einlesen und anschließend die Manipulatoren zu Formatierung von Gleitpunktzahlen. #include <iomanip> #include <iostream> #include <cmath> using namespace std; void main() { double g; cout<<"Bitte geben Sie ein Gleitpunktzahl ein! "; ©-=]ToT[=-Acid Burn 18

01.09.2003 cin>>g; cout<<"showpoint= "<<showpoint<<g<<endl; cout<<"noshowpoint="<<noshowpoint<<g<<endl; cout<<"fixed="<<fixed<<g<<endl; cout<<"secientific= "<<scientific<<g<<endl; cout<<"setprecision"<<setprecision(3)<<g<<endl; }

Manipulatoren zur Feldausgabe
Manipulatoren setw(n) setfill(ch) left right Internal Wirkung Setzt die Feldbreite auf n Setzt das Füllzeichen auf ch (Standard ist Leerzeichen) Linksbündige Ausgabe im Feld Rechtsbündige Ausgabe im Feld (Standart) Vorzeichen linksbündig, Wert rechtsbündig

Bsp: #include <iostream> #include <iomanip> #include <cmath> using namespace std; void main() { cout<<"Manipulatoren zur Feldausgabe"<<endl; cout<<"Bitte ganze Zahlen eingeben : "; int zahl; cin>>zahl; cout<<"Ausgabe mit setw(20) und setfill('*') : " <<setw(20)<<setfill('*')<<zahl<<endl; cout<<"Ausgabe linksbuendig : "<<setw(20)<<left<<zahl<<endl; cout<<"Ausgabe internal : "<<setw(20)<<internal <<setfill(' ')<<showpos<<zahl<<endl; }

©-=]ToT[=-Acid Burn 19

01.09.2003

cmath wichtig Funktionen
Funktion abs(i) fabs(x) ceil(x) floor(x) pow(x,y) pow10(x) sqrt(x) sin(x) cos(x) tan(x) exp(x) log(x) log10(x) Wirkung |i| Betrag ganzzahlig |x| Betrag reell Aufrunden Abrunden xy Exponentiation x, y reell 10x Exponentiation x ganz Quadratwurzel x > =0 Sinus im Bogen von 0 bis 2 Π Cosinus im Bogen von 0 bis 2Π Tangens im Bogen von 0 bis 2Π Exponentialfunktion ex In x Logarithmus Basis e x >0 log x Logarithmus Basis 10 x > 0

Typkonvertierung
a) in Ausdrücken: Der Typ eines Ausdrucks richtet sich stets nach dem Operanten mit der höchsten Genauigkeit, d.h. Operanten ganzzahlig Ausdruck ganzzahlig. Dies heißt implizite Typumwandlung. b) Ergebnisvariable: Der Typ eines Ausdrucks wird implizit dem Typ der Ergebnisvariablen angepasst, d.h. Ausdruck vom gleichen Typ der Ergebnisvariablen alles OK. Ausdruck vom höheren Typ als Ergebnisvariable Problem da Stellen wegfallen können. Ausdruck geringerer Typ als Ergebnisvariablen alles OK implizite Typumwandlung. Man kann den Typ eines Operanten oder eines Ausdruckes auch explizit ändern mit Hilfe des Cast- Operators ( )

Folge, Anweisung, Sequenz
Darstellung im Strucktogramm: Eine einfache Anweisung wird im Strucktogramm durch ein Rechteck dargestellt. Symbol: Anweisung Eine Folge von Anweisungen wird in einem Strucktogramm durch untereinanderliegende Rechtecke dargestellt. Benutzerfreundlich wird eine Ausgabe auf dem Bildschirm durch ein A: und anschließenden Text, und eine Eingabe durch ein E: mit anschließenden Variablenbezeichner. ©-=]ToT[=-Acid Burn 20

01.09.2003 z.B. A: „ Bitte ganze Zahl eingeben.“ E: Zahl

Hinweis: Text sollte durch doppelte Anführungsstriche gekennzeichnet werden wegen Unterschied zu Variablen. Aufgabe 1: Der Gesamtwiederstand zweier Parallel geschalten Widerstände soll nach Eingabe der beiden Widerstandswerte berechnet werden. Hinweis: Rg=R1*R2/(R1+R2) Erstellen Sie zuerst ein Strucktogramm mit Datenanalyse und schreiben Sie anschließend das Programm. Strucktogramm Parallele Widerstände:
A:" Widerstandsberechnung- Parallelschaltung" A:" Bitte ersten Widerstandswert in Ohm eingeben!" A:" Bitte zweiten Widerstandswert in Ohm eingeben!" E:R1 E:R2 Rg =R1*R2/(R1+R2) A: Rg

Datenanalyse: Double: R1, R2, Rg R1 : Widerstand 1 R2 : Widerstand 2 Rg : Gesamtwiderstand

©-=]ToT[=-Acid Burn 21

01.09.2003

Programm: #include <iomanip> #include <iostream> using namespace std; void main() { double R1,R2,Rg; cout<<"Widerstandsberechnung-Parallelschaltung"<<endl; cout<<"Bitte ersten Widerstand in Ohm eingeben : "; cin>>R1; cout<<"Bitte zweiten Widerstand in Ohm eingeben : "; cin>>R2; Rg=R1*R2/(R1+R2); cout<<"Der Gesamtwidersand betraegt : "<<Rg<<"Ohm"<<endl; }

Aufgabe 2: Entwickeln Sie ein Strucktogramm und ein C++ Programm, welches für ein Rechtwinkliges Dreieck bei Eingabe beliebiger Katheten a und b die Hypotenuse c und die Beiden Winkel Alpha und Beta berechnet und ausgibt. Hinweis: c = √a²+b² ∠Bogen= arctan(b/a) βBogen=arctan(a/b) Der Arcustangens atan (Winkelbogen) Konstante Π: M_PI ∠Grad/360=∠Bogen/2Π

©-=]ToT[=-Acid Burn 22

01.09.2003

Struktogramm und Datenanalyse Dreiecksberechnung Datenanalyse: a,b,c,alpha,beta,PI=3.141592654 a: Seite a b: Seite b c: Seite c alpha: Winkel Alpha beta: Winkel Beta

A:"Dreiecksberechnung" A:"Bitte gebe Sie Kathete a eingeben" A:"Bitte gebe Sie Kathete b eingeben" E:a E:b c2=(a*a)+(b*b); c=sqrt(c2); alpha=(180/Pi)*(atan(b/a)); beta=(180/Pi)*(atan(a/b)); A:"Alpha betraegt" A:"Beta betraegt"

Programm: #include <iostream> #include <iomanip> #include <cmath> using namespace std; void main() { double a,b,c2,c,alpha,beta; double Pi=3.141592654; cout<<"Dreiecksberechnung"<<endl; cout<<"Bitte geben Sie die Kathete a ein : "; cin>>a; cout<<"Bitte geben Sie die Kathete b ein : "; cin>>b; cout<<endl; c2=(a*a)+(b*b); c=sqrt(c2); alpha=(180/Pi)*(atan(b/a)); ©-=]ToT[=-Acid Burn 23

01.09.2003 beta=(180/Pi)*(atan(a/b)); cout<<"Die Hypotenyse betraegt : "<<c<<"cm"<<endl<<endl; cout<<"Alpha betraegt : "<<alpha<<" Grad"<<endl<<endl; cout<<"Beta betraegt : "<<beta<<" Grad"<<endl<<endl; }

Bedingte Programmausführung Auswahl, Selektion
In Abhängigkeit von einer Bedingung werden Anweisungen ausgeführt oder weggelassen diese Bedingungen sind in der Regel an Vergleichsoperatoren geknüpft bzw. durch logische Operatoren verbunden.

Einseitige Auswahl:
Bei der einseitigen Auswahl wird eine Anweisung oder eine Gruppe von Anweisungen nur dann Ausgeführt wenn eine bestimmte Bedingung erfüllt ist. Syntax: If (Bedingung) { Anweisung(en); } Struktogrammsymbol: wahr Bedingung falsch

Anweisung(en)

Aufgabe:
Eine Firma liefert bei einem Bestellwert ab 200€ Porto und Verpackungsfrei. Für Aufträge unter 200€ beträgt die Versandpauschale 3,50€. Ein Programm soll den Rechnungsbetrag in Abhängigkeit vom Bestellwert ausgeben. Fertigen Sie ein Struktogramm mit Datenanalyse und schreiben Sie anschließend das C++ Programm.
Struktogramm und Datenanalyse Bestellwert Datenanalyse: b b=Bestellwert

©-=]ToT[=-Acid Burn 24

01.09.2003

A:“ Bestellwertsberechnung“ A:“ Bitte Bestellwert eingeben“ Bestellwert<200 Wahr Falsch

Anweisung

Programm: #include <iomanip> #include <iostream> using namespace std; void main() { double b; cout<<"Berechnung des Bestellwertes"<<endl<<endl; cout<<"Bitte geben Sie den Bestellwert ein : "; cin>>b; if(b<200){ b+=3.50; cout<<"Der Bestellwert betraegt : "<<b<<"EURO"<<endl; } }

Zweiseitige Auswahl
Bei der zweiseitigen Auswahl wir in der Abhängigkeit davon, ob eine Bedingung erfüllt ist oder nicht jeweils eine bestimmte Anweisung oder Anweisungsgruppe ausgeführt. Syntax: If (Bedingung){ Anweisung(en)1; ©-=]ToT[=-Acid Burn 25

01.09.2003

} else{ Anweisung(en)2; }

Struktogramm: wahr Bedingung falsch

Anweisung(en)1Anweisung(en)2 Aufgabe: Lesen Sie eine Natürliche Zahl ein und geben Sie anschließend aus ob die Zahl gerade oder ungerade ist.(Struktogramm und Programm) Struktogramm und Datenanalyse: Gerade und ungerade Zahlen Datenanalyse: n n= natürliche Zahl A:“Bitte geben Sie eine natürliche Zahl ein „ E:n n % 2 = =0

Wahr A:“Zahl ist gerade“ A:“Zahl ist ungerade“

Falsch

©-=]ToT[=-Acid Burn 26

01.09.2003

Programm: #include <iomanip> #include <iostream> using namespace std; void main() { int n; cout<<"Bitte geben Sie eine natürliche Zahl ein : "; cin>>n; if(n%2==0){ cout<<endl; cout<<"Ihre Zahl ist gerade"<<endl; } else{ cout<<endl; cout<<"Ihre Zahl ist ungerade"<<endl; } }

Aufgabe : Lesen Sie die Koordinaten x, y eines Punktes P ein und Treffen Sie anschließend eine Aussage über die Lage des Punktes in einem Koordinatensystems.

Lade eines Punktes im Koordinatensystem Datenanalyse: double x, y x = x- Koordinate y = y- Koordinate

©-=]ToT[=-Acid Burn 27

01.09.2003

A:Lage eines Punktes im Koordinatensystems A:Bitte x- Koordinate eingeben E:x A:Bitte y-Koordinate eingeben E:y x>0 && y> 0 Wahr A:Punkt im 1.Quadrant x<0 && y> 0 Wahr A: Punkt im 2. Quadrant x<0 && y< 0 Wahr A: Punkt im 3. Quadrant x>0 && y< 0 Wahr A: Punkt im 4. Quadrant x= =0 && y= = 0 Wahr Punkt im Koordinatenursprung x= 0 && y!= 0 Wahr Punkt auf y- Achse x<0 && y> 0 Wahr A: Punkt auf x - Achse ©-=]ToT[=-Acid Burn 28 Falsch Falsch Falsch Falsch Falsch Falsch Falsch

01.09.2003 Programm: #include <iomanip> #include <iostream> using namespace std; void main() { double x,y; cout<<"Bestimmung der Koordinaten "<<endl; cout<<"Bitte die x Koordinate eingeben : "; cin>>x; cout<<"Bitte die y Koordinate eingeben : "; cin>>y; if(x>0 && y>0){ cout<<"Der Punkt liegt im 1. Quadranten!"<<endl; } if(x<0 && y>0){ cout<<"Der Punkt liegt im 2. Quadranten!"<<endl; } if(x<0 && y<0){ cout<<"Der Punkt liegt im 3. Quadranten!"<<endl; } if(x>0 && y<0){ cout<<"Der Punkt liegt im 4. Quadranten!"<<endl; } if(x==0 && y==0){ cout<<"Der Punkt ist im Koordinatenursprung"<<endl; } if(x==0 && y!=0){ cout<<"Der Punkt ist auf der y-Achse"<<endl; } if(y==0 && x!=0){ cout<<"Der Punkt ist auf der x-Achse"<<endl; } }

©-=]ToT[=-Acid Burn 29

01.09.2003 Aufgabe: Lesen Sie die Seiten eines Dreieckes ein. Stellen Sie anschließend fest ob das Dreieck existiert. Wenn das Dreieck existiert stellen Sie fest ob es ein Gleichseitiges, Gleichschenkliges oder Ungleichseitiges ist. Hinweis: Ein Dreieck existiert wenn die Summe 2er Seiten stets größer ist als die 3. Seite (Dreiecksungleichung) Struktogramm und Datenanalyse Dreiecksberechnung Datenanalyse: Double a,b,c; a = Seite a b = Seite b c = Seite c A: Dreiecksberechnung A: Bitte Seite a eingeben E: a A: Bitte Seite b eingeben E: b A: Bitte Seite c eingeben E:c a+b>c && a+c>b && c+b>a Wahr A:Dreieck existiert a==b || a==c || c==b Wahr A: Dreieck ist Gleichschenklig a==b && b==c Wahr A: Dreieck ist gleichseitig a!=b && b!=c Wahr A: Dreieck ist Ungleichseitig Falsch Falsch Falsch Falsch A: Dreieck Existiert nicht

©-=]ToT[=-Acid Burn 30

01.09.2003 Programm: #include <iomanip> #include <iostream> using namespace std; void main() { double a,b,c; cout<<"Dreiecksberechnung"<<endl; cout<<"Bitte die Seite a eingeben! : "; cin>>a; cout<<"Bitte die Seite b eingeben! : "; cin>>b; cout<<"Bitte die Seite c eingeben! : "; cin>>c; if(a+b>c && a+c>b && c+b>a){ cout<<"Das Dreieck existiert"<<endl; } if(a==b || a==c || c==b){ cout<<"Das Dreieck ist Gleichschenklig"<<endl; } if(a==b && b==c){ cout<<"Das Dreicek ist Gleichseitig"<<endl; } if(a!=b && b!=c){ cout<<"Das Dreieck ist Ungleichseitig"<<endl; } } else{ cout<<"Das Dreieck existiert nicht"<<endl; } }

Aufgabe: BMI Im Tafelwerk Seite 141 finden Sie ein Übersicht zur Berechnung des BMI. Entwickeln Sie ein Struktogramm und ein C++ Programm welches nach Eingabe des Gewichtes und der Körpergröße einer Person den entsprechenden Zustand der Person auf dem Bildschirm ausgibt. ©-=]ToT[=-Acid Burn 31

01.09.2003 Struktogramm und Datenanalyse: BMI Datenanalyse: Double bmi, kg, kgw; bmi= Body Mass Index kg= Körpergewicht kgw= Körpergröße A: Berechnung des BMI A: Bitte Koerpergoesse in m eingeben E: kg A: Bitte Koerpergewicht in kg eingeben E: kgw bmi=kgw/(kg*kg) A: Der BMI wert betraegt bmi<20 Wahr A: Sie haben Untergewicht bmi>=20 && bmi<25 Wahr A: Sie haben Normalgewicht bmi>=25 && bmi<30 Wahr A: Sie haben Übergewicht bmi>=30 && bmi<40 Wahr A: Sie haben Fettsucht bmi>=40 Wahr A: Sie haben Massive Fettsucht Falsch Falsch Falsch Falsch Falsch

©-=]ToT[=-Acid Burn 32

01.09.2003 Programm: #include <iomanip> #include <iostream> using namespace std; void main() { double bmi,kg,kgw; cout<<setw(120)<<"Berechnung des BMI"<<endl<<endl; cout<<"Bitte Koerpergoesse in m eingeben : "; cin>>kg; cout<<"Bitte Koerpergewicht in kg eingeben : "; cin>>kgw; cout<<endl; bmi=kgw/(kg*kg); cout<<"Der BMI wert betraegt"<<bmi<<endl<<endl; if(bmi<20){ cout<<"Sie haben Untergewicht"<<endl<<endl; } if(bmi>=20 && bmi<25){ cout<<"Sie haben Normalgewicht"<<endl<<endl; } if(bmi>=25 && bmi<30){ cout<<"Sie haben Übergewicht"<<endl<<endl; } if(bmi>=30 && bmi<40){ cout<<"Sie haben Fettsucht"<<endl<<endl; } if(bmi>=40){ cout<<"Sie haben Massive Fettsucht"<<endl<<endl; } }

©-=]ToT[=-Acid Burn 33

01.09.2003

Mehrseitige Auswahl
Es gibt 2 Formen der Mehrseitigen Auswahl, die sich darin unterscheiden wie man sie programmieren kann. Die erste Art ist sehr speziell und beruht darauf das die einzelnen Fälle sich durch feste Einzelwerte bestimmen lassen. Syntax: Switch (Auswahlvariable) { case Konst 1: Anweisung; break; case Konst n: Anweisung; break; default : Anweisung; } Abarbeitung: Der Wert der ganzzahligen Auswahlvariablen wird fortlaufend mit den Werten der Konstanten nach dem case verglichen. Kommt es zu einer Übereinstimmung werden die Anweisungen des entsprechenden case Zweiges bis zum break ausgeführt. Gab es keine Übereinstimmung werden die Anweisungen des default Zweiges ausgeführt (dieser ist optional). Hinweis: Steht kein break in den case Zweigen werden nach einer Übereinstimmung alle nachfolgenden Anweisungen ohne weitere Prüfung ausgeführt. Struktogramm Auswahlvariable Konst4 Anweisung

Konst1 Anweisung

Konst2 Anweisung

Konst3

Konst n Anweisung

default

Anweisung

Anweisung break break break break break

Anwendung:
Verwendet wird die switch- Anweisung vorwiegend zum Aufbau von Menüs.

©-=]ToT[=-Acid Burn 34

01.09.2003

Aufbau eines Menüs:
#include <iostream> #include <conio.h> //für getch() notwendig #include <iomanip> using namespace std; void main() { //1. Schritt Ausgabe des Menuetextes cout<<endl<<"Berechnung von Flaecheninhalten"<<endl; cout<<"1 Quadrat "<<endl; cout<<"2 Kreis "<<endl; cout<<"3 Rechteck "<<endl; cout<<"Ihre Wahl? "<<endl; //2. Einlesen der Wahl char wahl=getch(); //mit echo getche() //auch mit cin möglich //3. Auswertung der Variablen switch (wahl){ case'1': cout<<endl<<"Berechnung zum Quadrat "<<endl; cout<<"Bitte die Seite des Quadrates eingeben : "<<endl; double a; cin>> a; cout<<"Der Flaecheninhalt des Quadrates betraegt: "<<a*a<<endl; break; case'2': cout<<endl<<"Berechnung zum Kreis "<<endl; //weiter siehe Quadrat break; case'3': cout<<endl<<"Berechnung zum Rechteck "<<endl; //weiter siehe Quadrat break; default: cout<<endl<<"Falsche Auswahl!! "<<endl; } }

Vervollständigen sie das obere Programm!
#include <iostream> #include <conio.h> //für getch() notwendig #include <iomanip> using namespace std; void main() { ©-=]ToT[=-Acid Burn 35

01.09.2003

//1. Schritt Ausgabe des Menuetextes double PI= 3.141592654; cout<<endl<<"Berechnung von Flaecheninhalten"<<endl; cout<<"1 Quadrat "<<endl; cout<<"2 Kreis "<<endl; cout<<"3 Rechteck "<<endl; cout<<"Ihre Wahl? "<<endl; //2. Einlesen der Wahl char wahl=getch(); //mit echo getche() //3. Auswertung der Variablen switch (wahl){ case'1': cout<<endl<<"Berechnung zum Quadrat "<<endl; cout<<"Bitte die Seite des Quadrates eingeben : "<<endl; double a; cin>> a; cout<<"Der Flaecheninhalt des Quadrates betraegt: "<<a*a<<endl; break; case'2': cout<<endl<<"Berechnung zum Kreis "<<endl; double A,r; cout<<"Bitte Radius eingeben "; cin>>r; A=PI*r*r; cout<<"Der Flaecheninhalt betraegt"<<A<<endl; break; case'3': cout<<endl<<"Berechnung zum Rechteck "<<endl; cout<<"Bitte geben sie eine Seite ein! "<<endl; double b; cin>>b; A=b*b; cout<<"Der Flaecheninhalt betraegt "<<A<<endl; break; default: cout<<endl<<"Falsche Auswahl!! "<<endl; } }

©-=]ToT[=-Acid Burn 36

01.09.2003

Aufgabe:
Ergänzen Sie das Programm um ein Obermenü welches als Menüpunkte 1.Berechnung Flächen 2. Berechnung von Körpern Und ein zugehöriges Untermenü welches die Berechnung des Volumens von drei Körpern anbietet. Hinweis: Löschen des Bildschirms mit der Anweisung system(„cls“); // cstdlib einbinden Programm:
#include <iostream> #include <conio.h> //für getch() notwendig #include <iomanip> #include <cstdlib> using namespace std; void main() { double PI= 3.141592654; char wahl; cout<<setw(135)<<"Berechnung von Flaecheninhalt und Volumen"<<endl<<endl; cout<<"1 Flaechen"<<endl; cout<<"2 Koerper "<<endl; wahl=getch(); switch (wahl){ case'1': char wahl2; system("cls"); cout<<endl<<"Berechnung von Flaecheninhalten"<<endl; cout<<"1 Quadrat "<<endl; cout<<"2 Kreis "<<endl; cout<<"3 Rechteck "<<endl; cout<<"Ihre Wahl? "<<endl; wahl2=getch(); switch (wahl2){ case'1': cout<<endl<<"Berechnung zum Quadrat "<<endl; cout<<"Bitte die Seite des Quadrates eingeben : "<<endl; double a; cin>> a; cout<<"Der Flaecheninhalt des Quadrates betraegt: "<<a*a<<endl; break; case'2': cout<<endl<<"Berechnung zum Kreis "<<endl; double A,r; cout<<"Bitte Radius eingeben "; cin>>r; A=PI*r*r;

©-=]ToT[=-Acid Burn 37

01.09.2003
cout<<"Der Flaecheninhalt betraegt"<<A<<endl; break; case'3': cout<<endl<<"Berechnung zum Rechteck "<<endl; cout<<"Bitte geben sie eine Seite ein! : "; double b,A1; cin>>b; A1=b*b; cout<<"Der Flaecheninhalt betraegt "<<A1<<endl; break;

default: cout<<endl<<"Falsche Auswahl!! "<<endl; } break; case'2': system("cls"); cout<<endl<<"Berechnung des Volumens"<<endl; cout<<"1 Würfel "<<endl; cout<<"2 Quader "<<endl; cout<<"3 Kugel "<<endl; cout<<"Ihre Wahl? "<<endl; char wahl3=getch(); switch (wahl3){ case'1': double y; cout<<"Berechnung zum Würfel "<<endl; cout<<"Bitte eine Seite eingeben! : "; cin>>y; cout<<"Das Volumen betraegt : "<<y*y*y<<"cm3"<<endl; break; case'2': double x,d,c; cout<<"Berechnung zum Quader "<<endl; cout<<"Bitte Seite a eingeben : "; cin>>x; cout<<"Bitte Seite b eingeben : "; cin>>d; cout<<"Bitte Seit c eingeben :"; cin>>c; cout<<"Das Volumen betraegt : "<<x*d*c<<"cm3"<<endl; break; case'3': double h; cout<<"Berechnung zur Kugel "<<endl; cout<<"Bitte Raius eingeben : "; cin>>h; cout<<"Das Volumen betraegt : "<<(4/3)*PI*h*h*h<<" cm3"<<endl; break; default: cout<<"Falsche Taste"<<endl; } } }

©-=]ToT[=-Acid Burn 38

01.09.2003

Mehrseitige Auswahl mit verschachtelten if- else Anweisungen
Falls die Auswahlvariable kein abzählbarer Datentyp ist oder die Bedingung für die Einzelnen Fälle komplizierter sind muss auf eine verschachtelte Zweiseitige Auswahl oder auf mehrere If- Anweisungen zurückgegriffen werden.

Aufgabe:
Einzugeben ist die erreicht Punktzahl und die Gesamtpunktzahl. Die entsprechende Prozentzahl ist zu ermitteln und die zugehörige Note ist auszugeben. Note 1- 95% 2- 80% 3- 65% 4- 50% 5- 30% 6- schlechter Programm: #include <iostream> #include <iomanip> using namespace std; void main() { double x,p,gp; cout<<setw(135)<<"Berechnung der Note "<<endl<<endl<<endl; cout<<"Bitte Ihre Punktzahl eingeben : "; cin>>p; cout<<"Bitte die zu erreichenden Punkt eingeben : "; cin>>gp; x=(p/gp)*100; if(x>=95){ cout<<"Sie haben die Note 1 "<<endl; } if(x<95 && x>=80 ){ cout<<"Sie haben die Note 2 "<<endl; } if(x<80 && x>=65 ){ cout<<"Sie haben die Note 3 "<<endl; } if(x<65 && x>=50 ){ cout<<"Sie haben die Note 4 "<<endl; } ©-=]ToT[=-Acid Burn 39

01.09.2003

if(x<50 && x>=30 ){ cout<<"Sie haben die Note 5 "<<endl; } if(x<30){ cout<<"Sie haben die Note 6 "<<endl; } }

Phasen der Programmentwicklung
1. 2. 3. 4. 5. Problemanalyse – Aufgabenstellung Festlegung der Datenstrukturen und Algorithmen Quellcodes, Übersetzung und Fehlerkorrektur Programmtest (Vergleich von Testdaten des Programms) Programmdokumentation

Schleifen
In Abhängigkeit einer Bedingung oder Laufbedingung werden Anweisungen wieder holt dabei unterscheidet man ob die Bedingung am Schleifenanfang oder Schleifenende geprüft werden.

Schleife mit End- Abfrage:
Die Schleife mit End- Abfrage wird mindestens einmal durchlaufen. Sie wird auch Fußgesteuerte Schleife benannt. Die Schleife wird solange wiederholt wie die Laufbedingung war ist. Syntax: do{ Anweisung; // Schleifenkörper }while (<Laufbedingung>); Struktogramm: Anweisung welche bei jedem Durchlauf wiederholt werden

Laufbedingung ©-=]ToT[=-Acid Burn 40

01.09.2003

Anwendung: 1. zur Programmwiederholung char ant; //Variabe außerhalb der Schleife do{ Programm welches wiederholt werden soll cout<<“ Programm wdh j/n“; ant= getch( ); }while (ant != ‘n’);

2.Anwendung der Do- While Schleife
Überprüfung von Eingaben: z.B. ‚j’ oder ‚n’ Syntax: do { ant = getch( ); // Einlesen der Taste if(ant!= ‚j’ && ant!= ‚n’) cout<<(char)7<<(char)7 ; }while (ant != ‚j’ && ant != ‘n’);

Anwendung zur do{}while- Schleife (Schleife mit Endabfrage) A: Soll das Programm wiederholt werden j/n? E: antw (getch) antw != ‚j’ && antw != ‚n’ Wahr A: (char)7 antw != ‚j’ && antw != ‚n’ Falsch

©-=]ToT[=-Acid Burn 41

01.09.2003

Aufgabe: Schreiben Sie ein Programm in welchem der Benutzer Aufgefordert wird eine Natürliche Zahl im Intervall 1- 100 einzugeben. Führen Sie eine Eingabeüberprüfung durch!. Zeichnen Sie zuerst das Strucktogramm.

Bildschirm löschen A: Bitte geben Sie eine natürliche Zahl zwischen 1 und 100 ein!! E: zahl zahl< 1|| zahl> 100 Wahr A: Beep Beep Falsch

zahl<1 || zahl> 100

Programm: #include <iostream> #include <iomanip> #include <conio.h> using namespace std; void main() { int zahl; do{ system("cls"); cout<<"Bitte geben Sie eine natürliche Zahl zwischen 1 und 100 ein!! "; cin>>zahl; if(zahl<1 || zahl>100){ cout<<(char)7; } }while(zahl <1 || zahl >100); } ©-=]ToT[=-Acid Burn 42

01.09.2003

Vorgehensweise zum nutzen der Bibliothek console.h
1. 2. 3. 4. Schritt: Dateien console.h und console.cpp dem Projekt hinzufügen Schritt: #include „console.h“ einbinden Schritt: Speichern der Dateien im Ordner des Arbeitsbereiches mit Speichern unter Schritt: Hinweis: cls( ) zum Bildschirm löschen, setCursor zum Positionieren des Cursors, setColor zum setzen der Zeichenfarbe (0-15 Zeichenfarbe+ von 16255 Hintergrundfarbe jeweils in 16 Schritten), cursorOff (Schaltet Cursor aus), cursorOn (Schaltet Cursor an)

Schleife mit Anfangsabfrage While- Schleife
Bei der While- Schleife kann es vorkommen das der Schleifenkörper nie durchlaufen wird, weil die Schleifenbedingung schon zu Anfang nicht zutrifft. Solange die Bedingung nach dem While wahr ist wird der Schleifenkörper wiederholt. Syntax: While (Bedungung) { Anweisung; } Struktogramm: Bedingung Anweisung

A.................

Anwendung: Die while- Schleife wird verwendet wenn die Anzahl der Wiederholungen unbekannt ist. Und wenn es erforderlich sein kann die Schleife gar nicht zu durchlaufen.

Aufgabe:
Der Benutzer möchte Messwerte in unbekannte Anzahl eingeben. Ein Abbruch der Eingabe erfolg wenn der Messwert dem Wert null erhält. Berechnen Sie anschließend den Durchschnitt der Messwerte. Erstellen sie ein Struktogramm.

©-=]ToT[=-Acid Burn 43

01.09.2003 Datenanalyse: Double Wert ,d; float anz=0 ,sum; Wert= Wert der Eingabe des Benutzers d = Durchschnitt anz = Anzahl der eingegebenen Werte sum= Summe der eingegebenen Werte

A: Berechnung des Wertedurchschnitts zum Beenden Null druecken sum= 0 anz= 0 A: Bitte Wert eingeben E: Wert Wert! =0 anz++ sum= sum+ Wert A: Bitte Die Werte eingeben E: Wert anz = =0 Wahr A: Kein gueltigen Messwerte d=sum/anz A: „Der Durchschnitt betraegt“ Falsch

Programm: #include <iostream> #include <iomanip> using namespace std; double Wert; void main() { double d; ©-=]ToT[=-Acid Burn 44

01.09.2003 float anz=0,sum=0; cout<<setw(40)<<"Berchnung des Wertedurchschnittes" <<endl<<endl; cout<<"Bitte Wert eingeben :"; cin>>Wert; while (Wert!=0){ cout<<"Bitte Wert eingeben :"; cin>>Wert; anz ++; sum=sum+Wert; if(anz==0){ cout<<"Bitte Wert eingeben : "; cin>>Wert; } } if(anz==0){ cout<<"Kein gueltigen Messwerte"<<endl; } else{ cout<<"Der Durchschnitt betraegt "<<sum/anz<<endl; } }

Zähl-Schleife (for- Schleife)
Die Zähl-Schleife ist eine Strucktur bei der von Anfang an fest steht wie viele Wiederholungen ausgeführt werden. Dabei wird ein Zähler (Laufvariable) mitgeführt. Syntax: for( Laufvariable = Anfangswert; Laufvariable= = Endwert; Laufvariable++){ Anweisung; } Die Laufvariable erhält nur einmal zu beginn der Schleife den Anfangswert. Die Laufbedingung Laufvariable <= Endwert wird ausgewertet, ist Sie war wir der Schleifenkörper ausgeführt. Anschließend wird die Laufvariable hochgezählt. Dann wider Test der Laufbedingung usw. Bsp: //Ausgabe 20 Sterne; for (int i=1; i<20; i++){ cout<<”*”; } ©-=]ToT[=-Acid Burn 45

01.09.2003

Struktogramm:

Für Laufvariable von Anfangswert bis Endwert

Anweisung

Für i von 1 bis 20 A: „*“

Aufgabe: Geben Sie auf dem Bildschirm mit Hilfe einer for – Schleife die natürlichen Zahlen von 1- 10 mit ihrem Quadrat und Kubik zahlen aus. Anwendung der for- Schleife: 1. Summe von Natürlichen Zahlen bilden. Aufgabe: Lesen Sie eine natürliche Zahl ein summieren Sie alle natürlichen Zahlen einschließlich dieser Zahl und geben Sie das Ergebnis aus. Programm: #include <iomanip> #include <iostream> using namespace std; ©-=]ToT[=-Acid Burn 46

01.09.2003 void main() { int Zahl; cout<<"Bitte nat. Zahl eingeben!!!! "; cin>>Zahl; int summe=0; for(long i=1; i<Zahl;i++){ summe=summe+i; } cout<<"Summe : "<<summe<<endl; }

Fakultät einer nat. Zahl
Aufgabe: Eine nat. Zahl ist einzulesen und die Fakultät zu berechnen und anschließend auf dem Bildschirm auszugeben. (Produkt von 1 und allen Nachfolgern dieser Zahl) Programm #include <iomanip> #include <iostream> using namespace std; void main() { int Zahl; cout<<"Bitte nat. Zahl eingeben!!!! "; cin>>Zahl; int fakt=1; for(long i=2; i<Zahl;i++){ fakt=fakt*i; } cout<<"Fakultät beträgt : "<<fakt<<endl; }

Teiler einer nat. Zahl
Lesen Sie eine nat. Zahl ein und geben Sie anschließend alle echten Teiler dieser Zahl aus. Programm: #include <iostream> ©-=]ToT[=-Acid Burn 47

01.09.2003 #include <iomanip> using namespace std; void main() { int zahl; cout<<"Bitte geben Sie eine nat. Zahl ein"; cin>>zahl; for(long teiler=2; teiler < zahl;teiler++){ if(zahl % teiler==0){ cout<<" "<<teiler; } } cout<<endl; }

Priemzahl
Aufgabe: Eine nat. Zahl ist einzulesen und anschließend festzustellen ob diese Zahl eine Priemzahl ist. #include <iomanip> #include <iostream> using namespace std; void main() { long zahl; cout<<"Bitte geben sie eine nat. Zahl"; cin>>zahl; int primtest=1; for (long teiler =2; teiler <zahl ;teiler ++){ if(zahl% teiler ==0){ primtest= 0 ; } } if(primtest && zahl>1){ cout<<zahl<<" ist eine Primzahl !"<<endl; } else{ cout<<zahl<<" ist keine Primzahl !"<<endl; } ©-=]ToT[=-Acid Burn 48

01.09.2003 }

5. Potenz
Aufgabe Lesen Sie die Basis und die ganzzahligen Exponenten einer Potenz ein (Exponent>=0) und berechnen Sie anschließend die Potenz. z.B. 34= 3*3*3*3=81 Lösen Sie die Aufgabe mit Hilfe der for- Schleife. Verwenden Sie nicht Pow. Programm: #include <iomanip> #include <iostream> using namespace std; void main() { double basis; cout<<"Bitte basis eingeben : "; cin>>basis; long exponent; cout<<"Bitte geben Sie die den Exponenten ein : "; cin>>exponent; double potenz=1;

for (long i=1;i<= exponent; i++){ potenz*=basis; } cout<<basis<<" hoch "<<exponent<<" : "<<potenz<<endl; }

For- Schleife mit variabler Schrittweite
Ersetzt man die Inkrementierung der Laufvariablen (Laufvariable++ ) durch einen anderen Inkrementausdruck (Laufvariable +=5) dann ergibt sich eine for- Schleife mit variabler Schrittweite. Aufgabe: Geben Sie eine Wertetabelle für die Funktion f(x)=x²-2 im Intervall von –3 bis +3 aus. Eine geeignete Schrittweite ist vom Benutzer einzugeben.

©-=]ToT[=-Acid Burn 49

01.09.2003 Programm: #include <iomanip> #include <iostream> using namespace std; void main() { double xl,xr; cout<<"Bitte die linke und die rechte Intervalallgrenze eingeb "<<endl; cin>>xl>>xr; double schritt; cout<<"Bitte geben Sie die Schrittweite ein : "; cin>>schritt; cout<<setw(10)<<" x "<<setw(25)<<"f(x)=x*x-2"<<endl; for( double x=xl; x<= xr; x+=schritt){ cout<<setw(10)<<fixed<<setprecision(2)<<x; cout<<setw(20)<<fixed<<setprecision(2)<<x*x-2; cout<<endl; } }

Verschachtelte Schleifen
Von Verschachtelten Schleifen spricht man wenn sich im Körper einer Schleife (äußere Schleife) eine weitere Schleife (innere Schleife befindet). Bei jedem Durchlauf der äußeren schleife wird die innere Schleife vollständig abgearbeitet. Aufgabe: Geben Sie ein Multiplikationstabelle für das kleine 1*1 von 1-10 aus. Programm: #include <iomanip> #include <iostream> using namespace std; void main() { cout<<"Multiplikarionstabelle für das kleine 1*1 von 1-10 "<<endl<<endl; for(int i=1;i<=10;i++){ cout<<setw(4)<<i; for(int j=1;j<=10;j++){ ©-=]ToT[=-Acid Burn 50

01.09.2003 cout<<setw(4)<<i*j; } cout<<endl; } } Aufgabe Primzahlen: Lesen Sie eine nat. Zahl ein und geben Sie anschließend alle Primzahlen aus die kleiner gleich dieser zahl sind. Programm: #include <iomanip> #include <iostream> using namespace std; void main() { long n; cout<<"Bitte geben sie eine nat. Zahl : "; cin>>n; for(int zahl=2;zahl<n ;zahl++){ int primtest=1; for (long teiler =2; teiler <n ;teiler ++){ if(n% teiler ==0){ primtest= 0 ; } } if(primtest && n>1){ cout<<zahl<<" ist eine Primzahl !"<<endl; } else{ cout<<zahl<<" ist keine Primzahl !"<<endl; } } }

©-=]ToT[=-Acid Burn 51

01.09.2003

Andere Steueranweisung für Schleifen
Die Anweisung break Die break- Anweisung bewirkt einen Ausstieg aus einer Schleife, analog wie bei einer switch- Anweisung. Der Ausstieg erfolgt aber nur aus der Konstruktion heraus, in der das break eingebettet ist. z.B. /Primzahlen von 1-100 int test=1; for (int zahl= 2; zahl <= 100; zahl ++){ for (int teiler= 2; teiler <zahl; teiler++){ if( zahl % teiler = = 0 ){ test= 0; break; } } if( test ){ cout<<setw(4)<<zahl; } test= 1; } Die Anweisung continue Die continue- Anweisung kehrt zum Anfang der Schleife zurück und ignoriert den Rest des Schleifenkörpers. z.B. //Einlesen einer Zahl im Bereich 1-100 do{ cout<<“ Bitte Zahl im Bereich von 1-100 eingeben“; cin>>zahl; if(zahl < 1|| zahl> 100 ){ cout<< “ \nZahl ist nicht Bereich von 1-100!“; continue; } }while(0); Die goto- Anweisung Das Schlüsselwort goto gefolgt von einer Sprungmarke, bewirkt, dass das Programm zu dieser Sprungmarke verzweigt. z.B. goto Sprungmarke; //Anweisung (en) ©-=]ToT[=-Acid Burn 52

//Test auf Primzahl //keine Primzahl

01.09.2003 Sprungmarke; //der Sprungmarke muß ein Doppelpunkt folgen //hier wird das Programm fortgesetzt Aufgabe: Der Erfinder des Schachspiels Sessa hatte einen Wunsch frei. Er erbat sich die Summe der Weizenkörner die sich ergibt wenn für das erste Feld 1 Korn für das 2. Feld 2 Körner für das 3. Feld 3 Körner usw. Schreiben Sie ein Programm das für 64 Felder die Gesamtzahl der Körner berechnet. Geben Sie das Gewicht der Körner an, wenn 200 Körner 1g wiegen. Wie viele Eisenbahnwagons bräuchte man für Transport des Weizens und wie lange währe der Zug wenn in einen Eisenbahnwagon 30t passt und 15 Meter lang ist. Programm: #include <iomanip> #include <iostream> using namespace std; void main() { cout<<fixed<<setprecision(0); double Anzahl=1; double Waggonzahl, Gewicht,Laenge; for(long i=1;i<65;i++){ Anzahl*=2; } cout<<" Anzahl der Koerner "<<Anzahl<<" stueck "<<endl; Gewicht=(Anzahl/200)/1000000; cout<<" Gewicht der Koerner "<<Gewicht<<" t "<<endl; Waggonzahl=Gewicht/30; cout<<" Waggonanzahl "<<Waggonzahl<<endl; Laenge=(Waggonzahl*15)/1000; cout<<" Laenge des Zuges "<<Laenge<<endl;

}

Pytagoräische Triepel
Sind nat. Zahlen welche die Gleichung c²=a²+b² erfüllen. Suchen Sie alle Pytagoräische Triepel abc<= 1000. Hinweis: verschachtelte schleifen entfernen Programm: #include <iomanip> #include <iostream> ©-=]ToT[=-Acid Burn 53

01.09.2003

using namespace std; void main() { long a,b,c; for(a=1;a<=100 ; a++){ for(int b=1; b<=100; b++){ for(int c=1;1<=100;c++){ if(a*a+b*b==c*c)&&(a<b)){ cout<<"a : "<<setw(3)<<a <<"b : "<<setw(3)<<b <<"c : "<<setw(3)<<c <<endl; } } } } }

Funktionen bzw. Unterprogramme
Eine Funktion gruppiert eine Reihe von Anweisungen zu einer Einheit und gibt ihr einen Namen. Vorteile: • Programme werden übersichtlicher • Probleme können in kleine Teilprobleme zerlegt werden • Gruppen- arbeit ist möglich • Funktionen können ständig wiederverarbeitet werden • Fehler lassen sich leichter finden

Einfache- Funktionen
Werden ohne Parameter aufgerufen und geben keinen Wert zurück. Es ist in C++ gebräuchlich die Funktion am Anfang des Programms zu deklarieren bzw. den Prototyp der Funktion anzugeben. Hier wird dem Compiler mitgeteilt, dass eine Funktion mit diesem Namen geplant ist. Syntax der Deklaration: void <Namen der Funktion>( ); //Prototyp der Funktion Definition der Funktion Die Definition der Funktion erfolgt in der Regel nach der Hauptfunktion main()

©-=]ToT[=-Acid Burn 54

01.09.2003 Syntax der Definition: void <Namen der Funktion>( ); { Anweisung(en); } Syntax des Aufrufes einer Funktion: <Namen der Funktion>( ); Beispiel: #include … void sternlinie(); void main() { sternlinie(); } void sternlinie() { for(int i=0; i<45; i++){ cout<<“*“; } cout<<endl; } Aufgabe Durchschnittsverbrauch: Gefahrene Kilometer und der Verbrauch in Liter in einer Funktion Eingabe für PKW einzulesen. In einer Funktion Verarbeitung ist der Durchschnittsverbrauch je 100 Kilometer zu berechnen. In einer Funktion Ausgabe ist das Ergebnis auszugeben und einen eine entsprechende Aussage über den Verbrauch zu treffen z.B. bis 8 Liter Verbrauch in Ordnung, 8-10 Liter Verbrauch geht noch, ab 10 Liter Geld kann sinnvoller ausgegeben werden. Programm: #include <iostream> #include <iomanip> using namespace std; void eingabe(); void verarbeitung(); void ausgabe(); int l, km, ges; void main() ©-=]ToT[=-Acid Burn 55 //Aufruf der Funktion //Deklaration der Funktion

01.09.2003 { eingabe(); verarbeitung(); ausgabe(); } void eingabe() { cout<<"Bitte geben sie die gefahrenen km ein: "; cin>>km; cout<<"Und die verbrauchten Liter: "; cin>>l; } void verarbeitung() { ges=(100*l)/km; } void ausgabe() { cout<<"Der Verbrauch auf 100km ist: "<<ges<<" l"<<endl<<endl; if(l<8){ cout<<"Billigwagen!!!"<<endl; } if(l>=8 &&l<10){ cout<<"Mittelklasse wagen!!!"<<endl; } if(l>10){ cout<<"Scheisskarre aber ordentlich PS!!!"<<endl; } }

globale Variablen
Globale Variable werden außerhalb jeder Funktion des Programms deklariert. Sie sind dadurch in allen Funktionen des Programms bekannt und verwendbar. Deshalb sollten Sie ihre Variablen sehr sparsam verwendet werden.

Lokale Variablen
Lokale Variable in C++ sind nur in den Sie einschließenden geschweiften Klammern (Programmblock) bekannt und veränderbar.

Sichtbarkeit von globalen und lokalen Variablen
Haben eine globale und lokale Variable den gleichen Bezeichner so überdeckt die lokale Variable die globale. Möchte man die globale Variable trotzdem sichtbar machen so stellt man hier einen doppelten Doppelpunkt voran.

©-=]ToT[=-Acid Burn 56

01.09.2003

Funktion mit Wertparameter
Bei Funktionen mit Wertparameter hat man die Möglichkeit der Funktion beim Aufruf Werte zu übergeben. Diese Werte werden vom Typ in der Parameterliste angegeben. Syntax Void Fkt (Parameterliste) Die Parameterliste besteht aus Datentypen welche durch Komma getrennt werden und die Art (Typ) und die Reinfolge der Parameter festlegt. Beispiel: void wdhzeichen(char, int); void main() { wdhzeichen(’-’,45); } void wdhzeichen(char ch, int n) { for(int i=0; i!=n; i++){ cout<<ch; } } //Aufruf der Funktion mit Konstanten Werten //Definition der Funktion //Deklaration der Funktion

Aufruf der Funktion
Der Aufruf der Funktion erfolg über den Namen und den in runden stehenden aktuellen Parametern, welche im Typ und Anzahl mit der Parameterliste übereinstimmen müssen. Aktuelle Parameter können sein Konstanten, Variablen, Ausdrücke usw. Zusatz: Der Prototyp teilt dem Compiler den Namen der Funktion die Typen und die Anzahl der Parameter sowie den Typ des Rückgabewertes mit. Definition der Funktion: Weist den Parametern Bezeichner zu unter welchen sie in der Funktion als lokale Variablen benutzt werden können. Hinweis: Bei der Verwendung von Variablen muss der Programmierer genaue Kenntnisse über den Gültigkeitsbereich und Sichtbarkeit besitzen. ©-=]ToT[=-Acid Burn 57

01.09.2003

Beispiel: #include <iomanip> #include <iostream> using namespace std; void wdhzeichen(char, int); void main() { char h; int z; cout<<"Bitte Zeichen eingeben : "; cin>>h; cout<<"wie oft : "; cin>>z; wdhzeichen(h,z); } void wdhzeichen(char ch, int n) { for(int i=0; i<n; i++){ cout<<ch; } } Darstellung im Strucktogramm: Aufruf der Funktion Name der Funktion (aktuelle Parameter)

Name der Funktion Parameterliste Lokale Variable Anweisung

Aufgabe: Schreiben Sie eine Funktion berechne Rechteck welche als Parameter die Seitenlängen a und b erhält und in der Funktion den Flächeninhalt berechnet und ausgibt. Geben Sie zuerst den Prototyp und die Definition der Funktion an, Testen Sie diese Anschließend in einem Programm. ©-=]ToT[=-Acid Burn 58

01.09.2003

Funktionen mit einem Rückgabewert
Eine Funktion mit einem Rückgabewert wird beim Prototyp dadurch gekennzeichnet das vor dem Bezeichner ein Datentyp verschieden von void steht. Nämlich der Datentyp des Rückgabewertes. Prototyp: TypRW <Name> (Parameterliste); z.B. double berechneRechteck(double, double); Definition der Funktion mit Rückgabewert: Im Quelltext der Funktion muss sich mindestens eine Return- Anweisung befinden, welche den Wert von dem aufrufenden Programmteil als Konstante, Variable, Ausdruck ausgibt. Aufruf der Funktion; Beim Aufruf ist zu beachten das der Rückgabewert der Funktion von einer Variablen vom gleichen Typ aufgefangen wird dies geschieht über eine Zuweisung der Funktion. Hinweis: Mit der Return Anweisung wird die Funktion sofort verlassen Aufgabe: Schreiben Sie eine Funktion maximum welche als Parameter 2 int Werte erhält und dem Größeren zurückgibt. Geben Sie Prototyp und Definition an bevor Sie die Funktion testen. Prototyp int Maximum(int,int); Definition; Int Maximum (int a, int b){ If(a>b){ return a; } else { return b; } } Program: #include <iomanip> #include <iostream> ©-=]ToT[=-Acid Burn 59

01.09.2003 using namespace std; double berechneRechteck (double, double); void main() { double laenge,breite; cout<<"Bitte geben Sie die Seite a ein!!! : "; cin>>laenge; cout<<"Bitte geben Sie die Seite b ein!!! : "; cin>>breite; double f; f=berechneRechteck(laenge,breite); cout<<"Quadratmeterpreis : "<<f*94.00<<" Euro "; cout<<endl; } double berechneRechteck(double a, double b) { double fl=a*b; cout<<"Der Flaecheninhalt betraegt "<<fl; return fl; }

Aufgabe: Geben Sie den größten Funktionswert der Funktion f(x)=x3-2x+1 im Intervall von –4 bis 4 aus. Der Intervall soll in einer Schrittweite von 0,1 Durchlaufen werden. Eine Funktion soll die linke und die rechte Intervallgrenze als Parameter erhalten und den größten Funktionswert zurückgeben. Program: #include <iomanip> #include <iostream> using namespace std; double maxy (double, double); void main() { double ymax; ymax=maxy(-4,4); cout<<"Maximaler Funktionswert : "<<ymax<<endl; }

©-=]ToT[=-Acid Burn 60

01.09.2003 double maxy (double l, double r) { double max= l*l*l-2*l*l+1; for(double x=l;x<= r; x=x+0.01){ double t=x*x*x-2*x+1; if( t>max){ max=t; } } return max; } Aufgabe: Schreiben Sie eine Funktion ggt, welche zwei natürliche Zahlen als Parameter erhält und den größten gemeinsamen Teiler der beiden natürlichen Zahlen zurückgibt! Hinweis: Verbale Formulierung des Algorithmuses Die beiden natürlichen Zahlen seien a und b. Solange a verschieden von b ist tue wenn a > b ergibt sich aus a-b sonst ergibt sich aus b-a a ist ggt von a und b Program: #include <iostream> #include <iomanip> using namespace std; double ggt(int, int); void main() { int a, b; cout<<"Eine nat. Zahl: "; cin>>a; cout<<"Bitte eine zweite: "; cin>>b; double ggt1=ggt(a, b); ©-=]ToT[=-Acid Burn 61

01.09.2003 cout<<"Das ggt ist: "<<ggt1; } double ggt(int a, int b) { while(a!=b) { if(a>b) a-=b; else b-=a; } return a; } Aufgabe: Schreiben Sie eine Funktion kgv, welche zwei natürliche Zahlen als Parameter erhält und die kleinste gemeinsame Vielfache der beiden natürlichen Zahlen zurückgibt! Hinweis: Die beiden natürlichen Zahlen seien a und b. Das kgv= (a*b)/ ggt(a,b) Beispiel: ggt (32, 12) a= 32 b=12 a>b a= 32 – 12 = 20 a>b a= 20 – 12 = 8 b>a b= 12 – 8 = 4 a>b a= 8 – 4 = 4 ggt( 32, 12) =4 kgv(32, 12) a= 32 b=12

kgv= (32*12) /ggt(32,12) = 32*12/4 kgv (32,12)= 96

©-=]ToT[=-Acid Burn 62

01.09.2003 Program: #include <iostream> #include <iomanip> using namespace std; double ggt(int, int); double kgv(int, int, int); void main() { int a, b; cout<<"Eine nat. Zahl: "; cin>>a; cout<<"Bitte eine zweite: "; cin>>b; double ggt1=ggt(a, b); cout<<"Das ggt ist: "<<ggt1<<endl; int kgv2=kgv(ggt1, a, b); cout<<"Das kgv ist: "<<kgv2<<endl; } double ggt(int a, int b) { while(a!=b) { if(a>b) a-=b; else b-=a; } return a; } double kgv(int ggt1, int a, int b) { int f; f=a*b/ggt1; return f; }

©-=]ToT[=-Acid Burn 63

01.09.2003

Funktionen mit Referenzparametern
Eine Funktion mit Referenzparametern kann auch ohne eine Return- Anweisung einen oder mehrere Werte an den aufrufenden Programmteil zurückgeben. Referenzparameter werden in der Parameterliste durch ein Kaufmanns und (&) (Adressoperator) gekennzeichnet. Beispiel: Prototyp: void lies_int (int &); Definition : Void lies_int (int & a) { cout<< « Bitte einen Int- Wert eingeben » ; cin>> a; } Aufruf: lies_int (zahl); Beim Aufruf wird der Wert des aktuellen Parameters an den Referenzparameter über dessen Adresse übergeben, dadurch ändert jede Änderung des Referenzparameters auch den aktuellen Parameter. #include <iomanip> #include <iostream> using namespace std; void lies_int(int &); void main() { int z; lies_int(z); cout<<"Zahl ist : "<<z; cout<<endl<<endl; } void lies_int(int&a) { cout<<"Int- Wert eingeben : "; cin>>a; } ©-=]ToT[=-Acid Burn 64

01.09.2003

Aufgabe: Ändern Sie die Funktion zur Ermittlung des Wertebereiches so ab das auch das Minimum des Wertebereiches zurückgegeben wird. Verwenden Sie Referenzparameterwiederholung der Begriffe der Funktion Prototyp: legt fest Datentyp des Rückgabewertes, Namen der Funktion, Parameterliste Definition der Funktion: ist der eigentliche Quelltext der Funktion die Datentypen in der Parameterliste erhalten Bezeichner und werden in der Funktion als lokale Variablen verwendet. Aufruf der Funktion: erfolgt mit dem Namen und den aktuellen Parametern welche im Typ, Anzahl und Reihenfolge mit der Parameterliste übereinstimmen. Wird eine Funktion mit Rückgabewert aufgerufen so muss dieser durch eine Variable aufgefangen werden. Arten von Funktionen: Funktionen ohne Rückgabewert und Parameterliste void <Name der Funktion> Ohne Rückgabewert und mit Parametern void Bezeichner <Parameterliste> Hinweis: Parameter können Wert oder Referenzparameter sein Funktionen mit Rückgabewert und Parameterliste Typ des Rückgabewertes <Name der Funktion> (Parameterliste) Parameter: Aktuelle Parameter heißen die Parameter die beim Aufruf der Funktion verwendet werden. Wertparameter: Stehen in der Parameterliste und erhalten den Wert der Aktuellen Parameter als Kopie, sind sonst normale lokale Variablen der Funktion. Referenzparameter: Sind in der Parameterliste durch ein & gekennzeichnet. Erhalten den Wert der aktuellen Parameter über deren Adresse. Jede Änderung des Referenzparameters ändert auch den zugehörigen aktuellen Parameter. Sonst lokale Variablen der Funktion. Aufgabe: Erstellen Sie eine Wertbelegungstabelle und geben Sie die Ausgabe an! ( Zeigt den Inhalt der Variablen während der Abarbeitung des Programms.)

©-=]ToT[=-Acid Burn 65

01.09.2003 Programm: #include <iostream> #include <iomanip> using namespace std; void gemischte_parameter(int&z1,int z3, int&z2) { int a=5; z1=z2+z3; z2=z1-z2; z3=z1+a; }

void main() { int a=10, b=20, c=30; gemischte_parameter(a,b,c); cout<<"Ausgabe : "<<a<<" "<<b<<" "<<c<<endl; gemischte_parameter(c,b,a); cout<<"Ausgabe: "<<a<<" "<<b<<" "<<c<<endl; } Wertbelegungstabelle und mit Debugger testen. Void gemischte_parameter (int& z1, int&z3, int z2, int z4) { int a=5, d=12; z1=z2+z3; z2=z1-z2; z3=z1+a; z4=z3%d+a*4 ; } void main() { int a=15, b=20 , c=45, d=30 ; gemischte_parameter (a, b, c, d) ; cout<< "Ausgabe : "<<a<<" "<<c<<" "<<b; gemischte_parameter(d, c, b, a), cout<<“Ausgabe: „<<a<<“ „<<c<<“ „<<b; }

©-=]ToT[=-Acid Burn 66

01.09.2003

a b c d Z1(a) Z2 Z3(b) Z4 a d 15 20 45 30 15 45 20 30 5 12 65 65 70 70 30 Ausgabe 65 ,70, 45 ,30 a b 65 70 c d 45 30 120 115 Z1(d) Z2 30 70 115 45 Z3(c) Z4 45 65 120 20

Ausgabe 65, 120, 70 Programm zum Blatt: #include <iomanip> #include <iostream> #include "console.h" using namespace std; int ggt(int,int); int kgv(int,int); int erw(int, int, int); int add(int, int); void kuerze(int, int, int,int&,int&); void ausgabe(int, int ,int ,int, int, int); double z1, z2, n1, n2;

void main() { system("Title .....:::::Programm zur Bruchrechnung von Bruechen:::::....."); setColor(15); cout<<setw(55)<<"Programm zur Bruchrechnung von Bruechen"<<endl<<endl; setColor(12); cout<<"Bitte Zaehler von Bruch 1 eingeben : "; cin>>z1; cout<<"Bitte Nenner von Bruch 1 eingeben : "; cin>>n1; cout<<"Bitte Zaehler von Bruch 2 eingeben : "; cin>>z2; cout<<"Bitte Nenner von Bruch 2 eingeben : "; cin>>n2; setColor(9); ©-=]ToT[=-Acid Burn 67

01.09.2003 int gn=kgv(n1,n2); int nz1=erw(z1,n1,gn); int nz2=erw(z2,n2,gn); int sz=add(nz1,nz2); int kz=ggt(sz,gn); int en,ez; kuerze(sz, gn, kz,ez,en); ausgabe(z1,n1,z2,n2,ez,en); cout<<endl; } //Berechnung des kgv int kgv( int a, int b) { int f; f=a*b/a; return f; } //Berechnung des ggt int ggt(int a, int b) { while(a!=b) { if(a>b){ a-=b; } else{ b-=a; } } return a; } //Erweitern auf gemeinsamen Nenner int erw(int z, int n, int gn) { int erwz=gn/n; return erwz*z; } //Addition int add(int z1, int z2) { return z1+z2; } ©-=]ToT[=-Acid Burn 68

01.09.2003 void kuerze (int sz, int gn, int kz, int& ez, int& en) { ez=sz/kz; en=gn/kz; } void ausgabe(int z1, int n1, int z2, int n2, int ez, int en) { cout<<endl<<endl; cout<<setw(35)<<z1 <<-<<n1<<"+"<<z2 <<-<<n2<<"="<<ez <<-<<en<<endl; }

Aufgabe: Erstellen Sie ein Programm zur Bruchrechnung, für die vier Grundrechenarten. Im Bereich der rationalen Zahlen. Hinweis: Es werden nur Brüche betrachtet. Lesen Sie Bruch1 und Bruch2 ein und fragen Sie anschließend in einem die Grundoperation ab. Eine Programmwiederholung soll realisiert werden. Ist das Ergebnis ein unechter Bruch so soll es nach dem kürzen als gemischte Zahl angezeigt werden.

Besonderheiten zu Funktionen
Funktionsdeklaration mit Standartwerten Bei der Deklaration von Funktionen erlaubt C++, einen oder mehrere Parameter mit Standartwerten vorzubeugen. Beim Aufruf der Funktion kann man diese Parameter weglassen. Man beachte, dass die fehlenden Parameter die hinteren sein müssen! z.B. Deklaration void wdhzeichen (char= ‚*’, int =45); //Prototyp mit Standartwerten Definition void wdhzeichen (char ch, int n) //Definition der Funktion { for(int i=0; i<n;i++){ cout<<ch; } cout<<endl; }

©-=]ToT[=-Acid Burn 69

01.09.2003

Aufruf wdhzeichen( ) ; //Druckt 45 Sterne wdhzeichen(‘_‘) ; //Druckt 45 Sterne wdhzeichen(‚+’, 20); //Druckt 20 Pluszeichen wdhzeichen(20); FEHLER!!!!! Inline- Funktionen Um in Kurzen Funktionen Ausführungszeit einzusparen, kann man eine Funktion inline definieren, welches bewirkt das bei jedem Aufruf der Funktion im Quelltext an Stelle des Sprunges zur Funktion der tatsächliche Code der Funktion eingefügt wird. Man beachte das die Funktion vor dem ersten Aufruf definiert sein muss, da sie sonst nicht eingefügt werden kann! z.B. #include......... Definition und Deklaration zusammen Inline void whhzeichen (char ch, int n) //inline- Definition der Funktion { for(int i=0; i<n; i++){ cout<<ch; } cout<<endl; } main( ) //muss der Definition einer inline { //Funktion folgen ….. wdhzeichen(‘*’,45) ; //hier wird Quelltext eingefügt } Überlagerte Funktion Eine überlagerte Funktion führt, abhängig von der Art der an sie übermittelten Daten, unterschiedliche Aktionen durch. Man kann mehrere Funktionen mit dem gleichen Namen deklarieren und definieren ohne eine Fehlermeldung zu erhalten, wenn die Argumente der Funktionen verschieden sind. Für die Signifikanz einer Funktion ist der Name und die Parameterliste entscheidend (ähnlich wie bei Vor- und Nachnamen von Personen) Aufgabe: Schreiben Sie eine Funktion Maximum welche 2 integerwerte enthält und den größten der 2 Werte zurückgibt. Schreiben Sie analog der eine Funktion für Double Werte. Teste Sie die Funktion im Praogramm. ©-=]ToT[=-Acid Burn 70

01.09.2003 Programm: #include <iostream> #include <iomanip> using namespace std; double maximum(double, double); int maximum(int, int); void main() { int a,b; cout<<"Bitte int Wert eingeben : "; cin>>a, cout<<"Bitte weiteren int Wert eingeben : "; cin>>b; int erg=maximum(a,b); cout<<"Maximum der Inwerte : "<<erg<<endl; double z1, z2; cout<<"\n\nBitte double Wert eingeben : "; cin>>z1, cout<<"Bitte weiteren double Wert eingeben : "; cin>>z2; double ez=maximum(z1,z2); cout<<"Maximum der Doublewerte : "<<ez<<endl; } double maximum(double a, double b) { if(a>b){ return a; } else{ return b; } } int maximum(int a,int b) { if(a>b){ return a; } else{ return b; } } ©-=]ToT[=-Acid Burn 71

01.09.2003 Konstante Wert und Referenzparameter Es kommt öfter das bei Funktionen die Wert oder Referenzparameter in der Funktion nicht geändert werden können. Man setzt vor den Datentyp den Spezifiziere Konst um dies zu erreichen. Frage: Warum legt man auch konstante Referenzparameter an (in seltenen Fällen, diese sollen sich ja ändern um den aktuellen Parameter zu verändern).

Rekursikon:

Das besondere daran ist, dass in der Definition von fact bereits die zu definierende Funktion verwendet wird. Eine solche Definition heißt Rekursion. Die Berechnung der Fakultät der Zahl n wird auf die Berechnung der Fakultät n – 1 zurückgeführt. Die Funktion fact besteht aus eine bedingten Anweisung, die im Falle von n größer als 0, wieder die Funktion fact, nun n – 1, aufruft.

Rekursive Berechnung der Fakultät:
long fact(long n) { if(n==0){ return 1; } else{ return n * fact(n -1); } } Rekursion: Rekursive Algorithmen zeichnen sich dadurch aus, das es Funktionen gibt die sich innerhaslb ihres Funktions- Rumpfes selbst wieder aufrufen. Rekursive Algorithmen können daher immer auf Probleme angewandt werden, die sich auf ein gleichartiges, aber einfaches Problem zurückführen lassen. Und es muss eine Lösung für ein elementares Problem existieren.

©-=]ToT[=-Acid Burn 72

01.09.2003

Rekursive Aufrufe der Funktion fact zur Berechnung von 4!

Aufrufe fact(4) = 4 * fact(3) = fact(3) = 3 * fact(2) = fact(2) = 2 * fact(1) = fact(1) = 1 * fact(0) = fact(0) =

Rückgabe 4 * 6 = 24 3*2=6 2*1=2 1*1=1 1

Die richtige Durchführung der Berechnung organisiert der Computer mit Hilfe unserer rekursiven Definition automatisch. Program: #include <iostream> #include <iomanip> long fact(long); using namespace std; void main() { system("Title Berechnung der Fakultaet by Sebastian Wetzel"); long x; cout<<"Bitte Zahl Fakultaet eingeben : "; cin>>x; cout<<fact(x); } long fact(long n) { if(n==0){ return 1; } else{ return n * fact(n -1);; } }

©-=]ToT[=-Acid Burn 73

01.09.2003

Grundgerüst einer Rekursiven Funktion
.............rekursin(......) { if(„wenn Problem kleiner genug Abbruchkriterium erreicht){ // nicht rekursiver Zweig } else{ //rekusiver Zweig mit verkleinertem Problem } } 1. Aufgabe Berechnen Sie die Funktion „Summe der ersten, natürlichen Zahlen“ rekursiv! Betrachten Sie dazu das Programm zur Berechnung der Fakultät. Program: #include <iomanip> #include <iostream> using namespace std; long summe (long n); void main() { system("Title Summe Rekursiver Funktionen"); long y; cout<<"Bitte Zahl eingeben : "; cin>>y; cout<<summe(y)<<endl; } long summe(long n) { if (n==0){ return 0; } else{ return n+summe(n-1); } } Eigenschaften von Rekursiven Algorithmen: • Rekursive Algorithmen rufen sich immer wieder selbst auf es entstehen mehrere Modulexemplare die sich gleichzeitig im Hauptspeicher befinden • Rekursive Algorithmen müssen eine eindeutige Abbruchbedingung besitzen in welcher sich der Algorithmus nicht wieder selbst aufruft • Der Speicherbedarf für rekursive Algorithmen wird um so höher je größer die Anzahl der Aufgerufenen Modul Exemplare ist ©-=]ToT[=-Acid Burn 74

01.09.2003 • Lokale Daten werden bei rekursiven Algorithmen in einer LIFO Struktur (Last in First out) auf dem Systeminternen Stack gespeichert (ein Stack überlauf ist möglich und wenn keine Abbruchbedingung unausweichlich)

2. Aufgabe: Fibonacci – Folge Berechnen Sie die Glieder der Fibonacci- Folge! 0 für fibo(n)=1 für a(n-1)+a(n-2) Program: #include <iostream> #include <iomanip> using namespace std; long fibo(long); void main() { system("Title Berechnung von Fibo"); long f; cout<<"Bitte Fibo eingeben : "; cin>>f; cout<<fibo(f)<<endl; } long fibo(long n) { if(n==0){ return 0; } if(n==1){ return 1; } if(n>1){ return fibo (n-1)+fibo(n-2); } } n=0 n=1 für n>1

©-=]ToT[=-Acid Burn 75

01.09.2003

Rekursikon und Iteration
Unter Iteration versteht man die Programmierung von Wiederholungen mit Hilfe der Wiederholungsanweisung for, While und do- While. Rekursikon ist die Programmierung von Wiederholung in dem sich die Funktion im Funktionskörper wieder selbst aufruft. Es gilt Jede Wiederholung lässt sich sowohl Iterativ als auch Rekursiv programmieren. Aufgabe: Schreiben Sie eine Funktion welche Rekursiv die Quadratzahlen von 1 bis 10 auf dem Bildschirm ausgibt. Program: #include <iostream> #include <iomanip> using namespace std; void quadrat(int); void main() { int x; cout<<"Bitte Zahl eingeben : "; cin>>x; system("Title Berechnung der Quadratzahlen mit Rekursiven Funktionen"); quadrat(x); } void quadrat(int n) { if(n>=0){ quadrat(n-1); cout<<endl<<n*n; } cout<<endl; } Aufgabe: Der größte Gemeinsame Teiler zweier Zahlen läst sich auch sehr schön Rekursiv berechnen. Schreiben Sie eine Funktion ggt, welche Rekursiv den Größten gemeinsamen Teiler berechnet. Schreiben Sie zuerst die Rekursive Formel für ggt auf. Formel a wenn a= =b ggt(a, b)= ggt(a, b –a) wenn b>a ggt (a-b, b) wenn a>b ©-=]ToT[=-Acid Burn 76

01.09.2003 Program: #include <iostream> #include <iomanip> using namespace std; long rekggt(long, long); void main() { long y,x; system("Title Berechnung der ggt mit Rekursiven Funktionen"); cout<<"Bitte a eingeben : "; cin>>x; cout<<"Bitte b eingeben : "; cin>>y; long erg=rekggt(x,y); cout<<"ggt :"<<erg<<endl; } long rekggt(long a, long b) { if(a>b){ return rekggt(a-b,b); } if(b>a){ return rekggt(a,b-a); } if(a==b){ return a; } }

Static Variablen in Funktionen
Deklariert man eine Variable mit dem Spezifizierer static so wird diese Variable nach dem verlassen der Funktion zwischengespeichert d.h. sie behält bis zum nächsten Aufruf ihren Wert. Beispiel: Schreiben Sie eine Funktion mit einer static Variable welche sich im Quelltext der Funktion um 1erhöt und vor dem verlassen der Funktion auf dem Bildschirm ausgegeben wird. Rufen Sie die Funktion mehrfach auf und beobachten Sie das Verhalten. Program: #include <iomanip> #include <iostream> using namespace std; void statikfkt() { ©-=]ToT[=-Acid Burn 77

01.09.2003 static int n=0; n+=1; cout<<n<<endl; } void main() { system("Title static Variablen in Funktionen"); for(int i=1;i<=10;i++) { statikfkt(); } }

Felder in C++
Ein Feld besteht aus Elementen desselben Datentyps. Das einzelne Element trägt keinen Namen, sondern wird über die Position im Feld den Index erreicht.

Deklaration eines Feldes
<Typangabe> Bezeichner[Anzahl]; Anzahl legt fest, wie viele Elemente in einem Feld enthalten sind. Sie muss in eckigen Klammern [] stehen. Der Wert von Anzahl muss ein konstanter Wert sein. Beispiel: const int Anz=10; int zahl[Anz]; float temp[5]; //Festlegung einer Konstanten zur Dimension //Integer-Feld mit 10 Elementen //Float-Feld mit 6 Elementen

Zugriff auf Elemente des Feldes
Der Zugriff erfolgt über den Index, dieser wird in den eckigen Klammern angegeben und beginnt bei Feldern stets mit dem Index 0. Das heißt, dass letzte Feldelement hat den Index Anzahl -1. Beispiel: temp[0]=0.4; temp[1]=0.3; temp[2]=1.4 ; temp[3]=2.6 ; temp[4]=0.2 // OK temp[5]=1.3 ; !!!Falsch !!!!! überschreibt Speicher ohne Warnung

©-=]ToT[=-Acid Burn 78

01.09.2003

Initialisierung von Feldern
Ein Feld kann bei der Definition mit einer durch Kommata getrennten Liste von Werten initialisiert werden, welche in geschweiften Klammern { } steht, Die Anzahl der Elemente braucht nicht angegeben werden. z.B. int wuerfelzahl[]= {1, 3, 4, 6, 3, 2, 1} //Feld mit 7 Elementen

Hinweis: Wird eine Anzahl von Elementen angegeben darf dieses nicht überschritten werden. z.B. int wuerfelzahl[3]={1, 3, 4} int wuerfelzahl[3]={1, 3, 4, 2} int wuerfelzahl[3]={1} //Feld mit 3 Elementen OK //FEHLER zu viele Elemente //Feld mit 3 Elementen, wobei das 1. Element mit 1 //initialisiert die anderen mit 0

Effektiver Zugriff auf ein Feld mit einer for – Schleife
Ein Effektiver Zugriff auf die Elemente eines Feldes erfolgt mit Hilfe einer for- Schleife bei welcher die Zählvariable (z.B. i) verwendet wird um alle Feldelemente anzusprechen. Z.B. füllen eines Integer Feldes mit Zufallzahlen zwischen 1 und 100. // Zufallsgenerator initialisieren // long t; // Srand( time (&T)); const int Anz = 100; int zufall [Anz]; for(int i=0; i< Anz; i++){ zufall[i]= rand% 100+1; } Aufgabe: Schreiben Sie ein Programm welches ein Feld mit Zufallszahlen zwischen 1 und 100 füllt und dieses in einer 2 Schleife mit einer Ausgabenbreite von 8 ausgibt. Program: #include <iomanip> #include <iostream> #include <conio.h> #include <ctime> #include <cstdlib> using namespace std; void main() { // Zufallsgenerator initialisieren long t; srand( time (&t)); ©-=]ToT[=-Acid Burn 79

01.09.2003 const int Anz = 100; int zufall [Anz]; for(int i=0; i< Anz; i++){ zufall[i]= rand()%100+1; } for(int j=0;j<Anz;j++){ cout<<setw(8)<<zufall[j]; } } Aufgabe: Eine Wetterstation erhält Temperaturdaten von 5 verschiedenen Wetterballons. Diese Daten sollen in einem Feld gespeichert werden und anschließend ist a) der Durchschnitt der Temperaturen zu berechnen und auszugeben. Program: #include <iomanip> #include <iostream> using namespace std; void main() { const int anz=5; double ball[anz]; for(int i=0; i<anz;i++){ cout<<setw(2)<<i+1<<" "<<"Bitte Temperatur eingeben "; cin>>ball[i]; } double summe=0.0; for( i=0; i<anz;i++){ summe+=ball[i]; } double durchschnitt=summe/anz; cout<<endl<<"Durchschnittstemperatur :"<<durchschnitt<<endl; } b) Ausgabe der Maximal bzw. Minimal Temperatur. Hinweis: Ermittlung der Maximaltemperatur : • Variable Maximum vom Typ des Feldes anlegen und mit dem Wert des ersten Feldelementes Initialisieren • Vergleich von Maximum mit allen nachfolgenden Feldelementen, ist ein nachfolgendes Feldelement größer so wird es neues Maximum • Ausgabe von Maximum ©-=]ToT[=-Acid Burn 80

01.09.2003 • • Vergleichen von Minimum mit allen nachfolgenden Feldelementen, ist ein nachfolgendes Feldelement kleiner so wird es neues Minimum Ausgabe von Minimum double maximum=ball[0]; for(i=1; i<anz;i++){ if(ball[i]>maximum){ maximum=ball[i]; } } cout<<"Das Maximum betraegt : "<<maximum<<endl; double minimum=ball[0]; for(i=1; i<anz;i++){ if(ball[i]<minimum){ minimum=ball[i]; } } cout<<"Das Minimum betraegt : "<<minimum<<endl; Sortieren von Feldern Sortieren durch Austausch: Man vergleicht das erste Feldelement mit allen nachfolgenden Feldelementen. Ist eine nachfolgendes Feldelement kleiner so tausch es mit dem ersten Feldelement den Platz. Ergebnis: das kleinste Feldelement steht am ersten Platz. Dann vergleicht man das zweite Feldelement mit allen nachfolgenden Feldelementen. Ist ein nachfolgendes Feldelement kleiner, so tauscht es mit dem zweiten Feld den Platz. Ergebnis: das zweitkleinste steht am zweiten Platz. So verfährt man bis zum vorletzten Feldelement.

©-=]ToT[=-Acid Burn 81

01.09.2003 Def.: for(int i=0;i<anz+1;i++){ for( int j=i+1; j<anz;j++){ if(feld[i]> feld[j]){ int hilf= feld[i]; feld[i]= feld[j]; feld[j]= hilf; } } } Aufgabe: Initialisieren sie ein int- Feld mit den Werten aus dem Beispiel. Sortieren Sie das Feld und geben Sie anschließend das sortierte Feld auf dem Bildschirm aus. #include<iostream> #include<conio.h> using namespace std; void main() { int feld[]={3,4,2,1,7}; const int anz=5; for(int i=0;i<anz-1;i++){ for( int j=i+1; j<anz;j++){ if(feld[i]> feld[j]){ int hilf= feld[i]; feld[i]= feld[j]; feld[j]= hilf; } } for(int t=0;t< anz;t++){ cout<<" "<<feld[t]; } cout<<endl; getch(); } }

©-=]ToT[=-Acid Burn 82

01.09.2003 Beispiele: Bubble-Sort (Sprudelmethode) Beschreibung: Beginnend mit dem 1. Element werden fortlaufend je zwei benachbarte Elemente verglichen und dann vertauscht, wenn die nicht in der richtigen Reihenfolge stehen. Dieser „Durchlauf“ wird solange wiederholt, bis keine Vertauschung mehr erforderlich ist. Man erkennt, dass nach dem 1. Durchlauf das größte Element außen rechts steht nach dem 2. Durchlauf steht das zweitgrößte Element richtig nach dem 3. Durchlauf steht das drittgrößte Element richtig usw. Große Elemente haben also die Neigung, wie Luftblasen aufzusteigen. Wiederhole: Sortiert:= wahr; Für von 0 bis <n-1 wenn a[i]>a[i+1] vertausche a[i] mit a[i+1] sortiert= falsch do{ sortiert=1; for(int i=0;i<anz-1;i++){ if( feld[i]>feld[i+1]){ int hilf=feld[i]; feld[i]=feld[j]; feld[j]=hilf; sortiert=0; } } while(sortiert==0); Aufgabe: Schreiben Sie ein Beispielprogramm in welchem Sie eine Funktion Bubble- Sort realisieren welche als Parameter ein Feld von Integer werten erhält und als zweiten Parameter die Anzahl der Elemente des Feldes erhält.

©-=]ToT[=-Acid Burn 83

01.09.2003

Übergabe von Feldern an Funktionen
1 Felder als Funktionsparameter sind grundsätzlich Referenzparameter. 2 Eine Spezielle Kennzeichnung durch & entfällt dadurch. Ein Feld als Referenzparameter wird durch den Datentyp und [ ] gekennzeichnet die Angabe einer Dimension entfällt. In der Regel wird die Anzahl der Elemente als 2. Parameter übergeben. z.B. Prototyp: void bubblesort (int [ ], int) Definition der Funktion: Die Parameter erhalten Bezeichner void bubblesort(inte f[], int anz) { int sortier =0; do{ sortiert=1; for(int i=0;i<anz ;i++){ if( f[i]>f[i+1]){ int hilf=f[i]; f[i]=f[j]; f[j]=hilf; sortiert=0; } while (sortier = =0); } tausch des Feldes sortier= 0;

3. Wird ein Feld beim Aufruf einer Funktion als Aktueller Parameter übergeben, so wird nur der Name des Feldes angegeben. Denn der Name des Feldes ist in C identisch mit der Anfangsadresse des Feldes. Hinweis: zum Testen der Funktion Bubble- Sort füllen Sie in der Funktion Main ein Feld mit 100 Zufallszahlen. Program: #include <iomanip> #include <iostream> #include <ctime> #include <cstdlib> void ausgabe(int[],int); void zufallszahlen(int[], int); void bubblesort(int [ ], int); ©-=]ToT[=-Acid Burn 84

01.09.2003 using namespace std; void main() { const int Anz=100; int zufall[Anz]; zufallszahlen(zufall,Anz); bubblesort(zufall,Anz); ausgabe(zufall,Anz); } void ausgabe(int zufall[], int Anz) { for(int j = 0;j<Anz;j++){ cout<<setw(4)<<zufall[j]; } } void zufallszahlen(int zufall[],int Anz) { long t; srand( time (&t)); for(int i = 0; i< Anz; i++){ zufall[i] = rand()%100+1; } } void bubblesort(int f[], int anz) { int sortier = 0; do{ sortier = 1; for(int i=0;i<anz ;i++){ if( f[i]>f[i+1]){ int hilf = f[i]; f[i] = f[i+1]; f[i+1] = hilf; sortier = 0; } } }while (sortier ==0); }

©-=]ToT[=-Acid Burn 85

01.09.2003 Hinweis zu Bubble- Sort: Der Algorithmus wird effizienter , wenn man beachtet das bei jedem Durchlauf das größte Element nach hinten wandert. Man erreicht dies durch einfügen der Anweisung anzahl-1 am ende der for- Schleife.

Effizienz von Sortierverfahren:
Man kann die verschiedenen Sortierverfahren an hand der folgenden Kriterien auf effiziens vergleichen. 1. Anzahl der benötigten Vergleichs- und Austauschoperatoren in Abhängigkeit von der Anzahl der zu sortierenden Elemente. 2. Bedarf an zusätzlichen Speicherplatz während des Sortierens

Effizinsbetrachtung von Bubble- Sort
Anzahl der Vergleiche: ergibt sich aus der (Anzahl der ElementeC Anzahl der Austauschoperationen: ergibt sich ebenfalls aus (Anzahl der Elemente)2 /2 (abhängig vom Sortierungsgrad)

Selection Sort
Sortieren durch direkte Auswahl. Algorithmus: Finde zuerst das kleinste Element der Datenmenge und tausche es gegen das Feld an platz null aus. Finde danach das zweitkleinste Element und tausche es gegen das Feld an Platz eins aus. Usw. bis das Feld sortiert ist. Selection Sort Daten[], anz Für i von 0 bis anz -2 min = i Für i von i+1 bis anz -1 Daten[j]< Daten[min] W min=j

F

Tausch = Daten [min] Daten[min]= Daten [i] Daten[i]= tausch ©-=]ToT[=-Acid Burn 86

01.09.2003 Währe der Index i vom Anfang bis zum Ende durch das Datenfeld wandert befinden sich die Elemente links von Platz i auf ihrer entgültigen Position im Datenfeld. Selection Sort ist eine einfache Sortiermethode für kleine Datenmengen da jedes Element höchstens nur einmal getauscht wird. Effizienzbetrachtung von Selektion Sort Anzahl der Vergleiche: (Anzahl der Elemente)2 /2 Anzahl der Tauschoperatoren = Anzahl der Elemente Aufgabe schreiben Sie die Funktion Selection Sort anhand des Strucktogrammes #include <iostream> #include <iomanip> #include <ctime> using namespace std;

void selectionsort(int f[], int n) { for(int i=0; i<=n-2; i++) { int min=i; for(int j=i+1; j<=n-1; j++) { if(f[j] < f[min]) { min=j; } } int hilf=f[min]; f[min]=f[i]; f[i]=hilf; } } void zufall(int f[], int n) { long t; srand(time(&t)); for (int i=0; i<n; i++) { f[i]=rand()%n+1; } } ©-=]ToT[=-Acid Burn 87

01.09.2003

void ausgabe(int f[], int n) { for (int i=0; i<n; i++) { cout<<setw(4)<<left<<f[i]<<" "; } cout<<endl; } void main() { const int Anz=100; int Feld[Anz]; zufall(Feld, Anz); selectionsort(Feld, Anz); ausgabe(Feld, Anz); }

Suche
Sequentielle Suche Liegt eine Sammlung von Daten vollkommen unsortiert vor, dann kann man nach einem bestimmten Datensatz nur sequentiell suchen d.h. Jeder einzelne Datensatz muss nacheinander darauf hin betrachtet werden, ob er den Suchbedingungen genügt. Sein Effizienz ist vollständig vom Zufall abhängig. Ablauf: • Suchbegriff bzw. Schlüssel einlesen • Schlüssel mit allen Daten fortlaufend vergleich • Wenn Schlüssel gleich Datensatz • Ausgabe gefunden Aufgabe: Schreiben Sie eine Funktion Sequen_Suche( ), welche als Parameter ein Feld, die Anzahl der Elemente und den Suchschlüssel erhält und festgestellt ob der Schlüssel vorhanden ist. Program: #include <iostream> #include <iomanip> #include <ctime> using namespace std; void sequen_suche(int f[],int anz,int s) { int g=-1; for(int i=0;i<anz;i++){ ©-=]ToT[=-Acid Burn 88

01.09.2003 if(s==f[i]){ cout<<"gefunden an Position "<<i<<" "; g=1; } } if(g!=1){ cout<<"Element nicht vorhanden "; } } void zufall(int f[], int n) { long t; srand(time(&t)); for (int i=0; i<n; i++) { f[i]=rand()%n+1; } } void ausgabe(int f[], int n) { for (int i=0; i<n; i++) { cout<<setw(4)<<left<<f[i]<<" "; } cout<<endl; } void main() { const int Anz=100; int Feld[Anz]; zufall(Feld, Anz); sequen_suche(Feld,Anz,5); ausgabe(Feld, Anz); }

Binäres Suchen
Deutlich effektiver kann man arbeiten, wenn die Datenmengen nach dem Suchschlüssel sortiert vorliegt. Ablauf: 1. Man nimmt an, dass anz Datensätze nach dem Schlüssel sortiert vorliegen. 2. Man betrachtet zunächst das Schlüsselelement im Datensatz genau in der Mitte. anz/2 3. Ist das betrachtete Datenelement kleiner als der gesuchte Schlüssel, betrachten wir lediglich noch die Datensätze von 0 bis anz/2 –1, ist er größer, von anz/2+1bis anz –1. ©-=]ToT[=-Acid Burn 89

01.09.2003 4. Die Schleife 2-3 wiederholt man solange, bis der Suchbegriff gefunden wurde oder die Betrachtungsmenge auf ein Element geschrumpft ist, dass den Suchbegriff nicht enthält. Suchbegriff nicht enthalten!!! Binaeres_Schen Daten[ ], anz, suchw anf=0;ende= anz -1 X= (anf+ende)/2 Suchw<Daten[x] WAHR Ende=X-1 Solange suchw != Daten[x] && anfg<= ende suchw= = Daten[x] WAHR Gefunden an Position x! void binares_suchen(int f[], int n, int schluessel) { int anf=0; int ende=n-1; int x; do { x=(anf+ende)/2; if (schluessel<f[x]) { ende=x-1; } else { anf=x+1; } } while(schluessel!=f[x] && anf<=ende); if (schluessel==f[x]) { cout<<"Gefunden an Position "<<x<<endl; } else { cout<<"Nicht gefunden!"<<endl; } } Nicht gefunden! FALSCH FALSCH

©-=]ToT[=-Acid Burn 90

01.09.2003 Vergleich der Suchalgorithmen: Bei linearer Suche: Anzahl der Vergleiche geht gegen Anzahl der Elemente. Binäre Suche: Anzahl der Vergleiche geht gegen ln von n zur Basis 2

Zweidimensionale Felder
Ein Zweidimensionales Feld ist vorstellbar als Tabelle aus Zeilen und Spalten. Ein Index des Feldes ist demnach die Zeile, der andere Index ist die Spalte. z.B. const int Zeile = 3; const int Spalte = 5; int f[Zeile] [Spalte]; //int Feld besteht aus 3Zeilen und 5 Spalten

Effektiver zugriff auf Zweidimensionale Felder. Erfolgt über zwei verschachtelte for- Schleifen wobei die äußere Schleife den Zeilenindex entsprechen sollte. z.B. for(int i=0; i<Zeile; i++){ for(int j=0;j<Spalte; j++){ cin>>f[i][j]; } } Übergabe von zweidimensionalen Felder an Funktionen. Bei der Übergabe ist zu beachten das bei der Angabe des Feldparameters nur die erste Dimension (der Zeile) leer bleiben darf. Die Spaltendimension muss angegeben werden. Aufgabe: Schreiben Sie ein Funktion Zufall welche als Parameter ein Zweidimensionales Feld erhält mit 3 Zeilen und 5 Spalten sowie Zwei Parametern vom Typ int Zeile und Spalte. Füllen sie das Feld mit Zufallszahlen. Schreiben Sie eine Funktion Ausgabe mit gleichen Parametern welche das Feld Zeilenweise ausgibt. Programm: #include <iomanip> #include <iostream> #include <ctime> ©-=]ToT[=-Acid Burn 91

01.09.2003 #include <cstdlib> using namespace std; const int Zeile=3; const int Spalte=5; void zufall(int feld[Zeile][Spalte],int , int ); void ausgabe(int feld[Zeile][Spalte],int, int); void main() { int feld[Zeile][Spalte]; zufall(feld,Zeile,Spalte); ausgabe(feld,Zeile,Spalte); } void zufall(int feld[Zeile][Spalte],int Zeilen, int Spalten) { long t; srand( time (&t)); for(int i=0; i< Zeilen; i++){ for(int j=0; j< Spalten; j++){ feld[i][j]= rand()%100+1; } } } void ausgabe( int feld[Zeile][Spalte],int d,int f) { cout<<endl; for(int x=0; x< d; x++){ for(int y=0; y< f; y++){ cout<<setw(8)<<feld[x][y]; } cout<<endl; } }

©-=]ToT[=-Acid Burn 92

01.09.2003

Zeichenketten in C
Unter Zeichenketten (String) versteht man ein Feld von Einzelzeichen (Datentyp Char) welches man üblicherweise als zusammenhängende Folge von Zeichen verarbeitet. Definition einer Zeichenkette: const int Max=80; char zk[Max]; Initialisierung einer Zeichenkette: char str[] = „Dies ist eine Zeichenkette“ Beachte: Zeichenketten in C++ erhalten automatisch ein abschließendes Nullzeichen ‚\0’. Dadurch lassen sich nur 79 Zeichen speichern. Eingabe von Zeichenketten: Zeichenketten können mit cin und zweimal dem Eingabeoperator und einem Bezeichner eingelesen werden. Um eine Zeichenkette mit Trennzeichen einzulesen verwendet man die Funktion gets( ); aus der Bibliothek <cstdio>. Beachte: Cin liest die Zeichenkette nur bis zum ersten Leer- / Trennzeichen ein. Die Eingabe einer Zeichenkette darf nicht größer als die reservierten Speicherstellen sein. Ausgabe von Zeichenketten Ausgabe mit cout oder puts(Bezeichner). Hinweis: Möchte man die Zeichenkette Elementweise über eine for- Schleife einlesen so muss man als Letztes Zeichen die Endekennung von selbst anwenden. Auch eine Ausgabe ist Zeichenweise über eine for- Schleife mögliche.

Funktionen zur Manipulation bzw. zur Bearbeitung von Zeichenketten stehen in der <cstring>
Informieren Sie sich in der Hilfe über folgende Funktionen zur Manipulation: • Länge einer Zeichenkette • Umkehren einer Zeichenkette • Anhängen einer Zeichenketten • Kopieren einer Zeichenkette • Vergleichen • Umwandeln in Kleinbuchstaben • Umwandeln in Großbuchstaben Achten Sie besonders auf die Parameter der Funktionen. ©-=]ToT[=-Acid Burn 93

01.09.2003 Länge einer Zeichenkette bestimmen Syntax: strlen(<Bezeichner>); Rückgabe: Anzahl der Zeichen als int Berspiel: char ZK[] = „Hallo“; cout<<“Die Zeichenkette hat: “<<strlen(ZK)<<“Buchstaben“; //Die Ausgabe ist dann 5 Kopieren einer Zeichenkette Syntax: strcpy(<neue Zeichenkette>, <Ursprungs-Zeichenkette>); Beachte: Die Anzahl der reservierten Speicherstellen, der neuen Zeichenkette, muss mindestens gleich der alten Zeichenkette sein! Beispiel: char erste_ZK[] = “Hallo“, zweite_ZK[10]; strcpy(zweite_ZK, erste_ZK); cout<<zweite_ZK; //Ausgabe: Hallo Vergleichen von 2 Zeichenketten Syntax: strcmp(<Bezeichner 1>, <Bezeichner 2>); Rückgabe: einen int Wert < 0 wenn erster Bezeichner < als zweiter Bezeichner 0 wenn Bezeichner = als zweiter Bezeichner > 0 wenn Bezeichner > als zweiter Bezeichner Beispiel: char ZK1[15], ZK2[15]; cout<<“erste Zeichenkette (nicht mehr als 15 Zeichen): “; gets(ZK1); cout<<“zweite Zeichenkette (nicht mehr als 15 Zeichen): “; gets(ZK2); int vergl = strcmp(ZK1, ZK2); if( vergl == 0 ) cout<<“Sie haben zweimal das gleiche eingegeben!“; else cout<<“Ihre beiden Eingaben sind Unterschiedlich!“; ändern von Großbuchstaben in kleine Syntax: strlwr(<Bezeichner>); Beispiel: char ZK[] = “HALLO“; strlwr(ZK); cout<<ZK; //Ausgabe: hallo ändern von Kleinbuchstaben in große Syntax: strupr(<Bezeichner>); Beispiel: char ZK[] = “hallo“; strupr(ZK); cout<<ZK; //Ausgabe: HALLO anhängen einer Zeichenkette an eine andere Syntax: strcat(<erster Bezeichner>, <zweiter Bezeichner>); Beispiel: char zk1[] = “Sebastian= “der Master“; strcat(zk1, zk2); cout<<zk1; //Ausgabe: ’Sebastianer’

©-=]ToT[=-Acid Burn 94

01.09.2003 Umkehren Zeichenkette Syntax: strrev(<Bezeichner>); Beispiel: char zk[] = “Hallo“; strrev(zk); cout<<zk; //Ausgabe: ollaH Aufgabe: Lesen Sie eine Zeichenkette ein und geben Sie anschließend die Länge der Zeichenkette aus, danach überprüfen Sie ob die Eingegebene Zeichenkette ein Pallintron (von beiden Seiten gelesen die gleiche Bedeutung z.B. Otto, Anna) ist. Program: #include<iostream> #include<stdio.h> #include<string> using namespace std; void main() { char zk[999], zk2[999]; cout<<"Bitte einen Text: "; gets(zk); int l=strlen(zk); cout<<"Die Länge ist: "<<l<<endl; strupr(zk); strcpy(zk2, zk); strrev(zk2); int vergl=strcmp(zk, zk2); if(vergl==0) { for(int i=0; i<l; i++) cout<<zk2[i]; cout<<"\nKann man in beide Richtingen schreiben"; } else cout<<"\nSchön!"; } Aufgabe: Deklarieren Sie ein Feld welches Zeichenketten aufnehmen kann (maximale Länge 80 Zeichen) Schreiben Sie anschließend eine Funktion Eingabe welche 8 Namen einließt eine Funktion Ausgabe welche die Zeichenketten ausgibt und eine Funktion Sortieren welche die Zeichenketten Alphabetisch sortiert. Hinweis der Zeichenketten in Großbuchstaben

©-=]ToT[=-Acid Burn 95

01.09.2003

Besonderheiten von Feldern
Felder von Zahlen (int, double, float) Werden über den Index angesprochen und Elementweise bearbeitet. Mathematische Operationen sind auf die einzelnen Elemente anwendbar, entsprechend des Datentyps. Zeichenketten Felder (strings) Werden als ganzes über den Namen des Feldes angesprochen. Besitzen eine ende Kennung. Operatoren bzw. Funktionen für Zeichenketten befinden sich in der <cstring> wie z.B. strlem, strcmp. strcpy. Allgemein Der Programmierer muss darauf achten das bei Feldern vom Compiler keine Bereichsüberprüfung stattfindet. Mehrdimensionale Felder Erhält man durch zufügen einer weiteren Eckigen Klammer mit Dimensionsangabe. Erste Dimension entspricht immer den Zeilen

Zeitmessung
Funktionen zur Zeitmessung clock ( ) <ctime> Liefert uns die vergangenen Milisekunden seit dem letzten Aufruf von clock. Aufgabe: Schreiben Sie eine Funktion Zeitanzeige welche als Parameter die Zeit in Milisekunden erhält und in der Funktion die Milisekunden in Stunden : Minuten : Sekunden : Milisekunden ausgibt. Funktion GetTickCount( ) <windows.h> Liefert die vergangenen Milisekunden seit dem einschalten des PC. Als long Wert. Hinweis: benötigte Variablen siehe Aufgabe 1. Aufgabe: Erstellen Sie ein Beispielprogramm und rufen Sie die Funktion zur darstellen der Zeit auf. #include <iomanip> #include <iostream> #include <ctime> #include <conio.h> using namespace std; void main() { ©-=]ToT[=-Acid Burn 96

01.09.2003 long anf, ende ,zeit,sek,min,st,ms; anf=clock(); getch(); ende= clock(); zeit=ende-anf; st=zeit/360000; min=zeit/6000-st*60; sek=zeit/1000-min*60; ms=zeit-sek*1000; cout<<st<<" : "<<min<<" : "<<sek<<" : "<<ms; }

Struckturen
Eine Struktur ist eine Sammlung einfacher Variablen, welche unterschiedlichen Datentypen besitzen können und Komponenten der Struktur genannt werden. Syntax: Struct Tbezeichner{ DT Bezeichner; DT Bezeichner; }; Bsp. Struktur einers Kontoauszuges Struct Tauszug{ Long kontonr; Char name[30]; Double stand; }

Hinweis: Da Tauszug nur ein neuer eigener Datentyp ist habe ich keinen Zugriff auf die Struckturkomponenten. Dazu muss ich erst eine Variable vom Typ Tauszug anlegen. Anlegen einer Structurvariablen Syntax: Tbezeichner Variablenbezeichner; z.B. Tauszug konto; Hinweis: ©-=]ToT[=-Acid Burn 97

01.09.2003 Die Variable Konto nutzt mir nichts alleine da ich dem Compiler noch mitteilen muss welche strukturkomponente ich verwenden möchte. Zugriff auf Strukturkomponenten Erfolgt über den Punktoperator. Syntax: Variablenbezeichner.Bezeichner Strukturkomponente z.B. Konto.Kontonr=12345; Aufgabe: Deklerieren Sie eine Struktur Tauszug mit den vorgegebenen Komponenten (siehe oben). Legen Sie eine Variable vom Typ Tauszug an, lesen Sie anschließend Werte für die Strukturkomponenten an und geben Sie diese anschließend nochmals auf dem Bildschirm aus. Erweitern Sie das Programm um eine Funktion Eingabe und Ausgabe welche als Parameter die Struktur erhalten. #include <iostream> #include <conio.h> using namespace std; //Deklaration der Struktur struct auszugstruktur{ char name[30]; unsigned long kontonummer; float kontostand; }; void eingabe(auszugstruktur &); void ausgabe(const auszugstruktur &); void main() { //Anlegen einer Variablen auszugstruktur kontoauszug; eingabe(kontoauszug); ausgabe(kontoauszug); } void eingabe(auszugstruktur & kontoauszug) { //Einlesen von Werten cout<<"Bitte Name eingebn :"; gets(kontoauszug.name); cout<<"Bitte Kontonummer eingeben :"; cin>>kontoauszug.kontonummer; cout<<"Bitte Konstostand eingeben :"; ©-=]ToT[=-Acid Burn 98

01.09.2003 cin>>kontoauszug.kontostand; } void ausgabe(const auszugstruktur & kontoauszug) { //Ausgabe der Strukturkomponenten cout<<endl<<"Name : "<<kontoauszug.name; cout<<endl<<"Kontonummer : "<<kontoauszug.kontonummer; cout<<endl<<"Kontostand : "<<kontoauszug.kontostand; cout<<endl; } Der Eigene Datentyp einer Struktur lässt sich im Programm genauso verwenden wie die einfachen Datentypen (int double usw.). Der Unterschied zu den einfachen Datentypen Besteht darin das keine Operatoren zur verfügung stehen. Aufgabe: Definieren Sie eine Struktur welche als Strukturkomponenten den Real und den imaginärteil einer Komplexen Zahl erhält. Schreiben Sie eine Funktion zur ein und ausgabe und zur Addition und Subtraktion von zwei Komplexen Zahlen.

Speichern von Daten auf einem externen Datenträger
1. Dekleration der Dateivariablen (FILE* dat;) 2. Öffnen der Datei in einem Modus und zuweisung an die Dateivariable dat=fopen(„Pfad“,“Modus“); z.B. dat=fopen(„H:\\test.dat“,“wb“); Hinweis: Pfad nach DOS- Konvention Zwei Backslash verwenden (ESC- Sequenz) Modus: „wb“ – zum Schreiben „rb“ – zum Lesen „ab“ – zum Anhängen Befehle zum Schreiben/ Lesen: 3. fwrite( &Variable, sizeof(Variable),1,Dateivariable); &Variable: Adresse der Variablen welche geschrieben werden soll sizeof(Variable): Anzahl der Bytes 1: Anzahl wie oft die Anzahl der Bytes gelesen weden soll Dateivariable: Ist die Variable welche mit der Datei verbunden ist in die geschrieben werden soll fread(&Variable,sizeof(Variable),1,Dateivariable); Bedeutung siehe oben. Datei schließen 4. fclose(&Variable,sizeof(Variable),1,dat); ©-=]ToT[=-Acid Burn 99

01.09.2003 schließt die Dateivariable die mit der Datei verknüpft ist Hinweis: Die Variablen und Funktionen zur Dateiarbeit befinden sich ind der Bibliothek <cstdio> Aufgabe: Schreiben Sie ein Programm welches eine Integer Variable Zahl, mit dem Wert 65 in eine Datei schreibt. Und anschließend den wert aus der Datei in eine Variable Test einließt und auf dem Bildschirm ausgibt. Fehlerabfrage beim öffnen der Datei: Konnte die Datei mit fopen nicht geöffnet werden so liefert fopen als Adresse NULL an den Dateizeiger. z.B. if((dat=fopen(„H:\\test.dat“,“rb“))= =NULL) { cout<<”Fehler!!!”; getch(); exit(0); } else{ fread..... fread…. } Umgang mit ASCII Dateien: Möchte man ASCII Dateien auf dem Bildschirm anzeigen bzw. in diese schreiben so kann man dies zeichenweise mit hilfe einer char Variablen realisieren. Wird die fread Anweisung im Kopf einer while Schleife genutzt, denn fread liefert eine NULL wenn das Dateiende erreicht ist. Aufgabe: Schreiben Sie ein Programm welches sich selbst Zeichenweise auf dem Bildschirm ausgibt. #include <iostream> #include <cstdio> #include <conio.h> using namespace std; void main() { cout<<"Lesen einer ASCII Datei"<<endl; char ch; FILE*dat; if((dat=fopen("H:\\programmierung\\dateiarbeit\\bildschirm\\aufgabe2.cpp","rb"))==NULL) ©-=]ToT[=-Acid Burn 100

01.09.2003 { cout<<"Fehler!!!"; getch(); exit(0); } else{ while(fread(&ch,1,1,dat)){ cout<<ch; } fclose(dat); } } Aufgabe: Schreiben Sie einen einfachen Editor mit welchem sie Zeichen in eine Datei schreiben können. Überlegen Sie sich dabei eine sinnfolle endekennung. Geben Sie anschließend den Text nochmals auf dem Bildschirm aus. #include <iostream> #include <cstdio> #include <conio.h> using namespace std; void main() { cout<<"Schreiben einer ASCII Datei"<<endl; char ch; FILE*dat; if((dat=fopen("H:\\programmierung\\dateiarbeit\\bildschirm\\test\\test.txt","wb"))==NULL) { cout<<"Fehler!!!"; getch(); exit(0); } else{ while((ch=getche())!= 27){ fwrite(&ch,1,1,dat); if(ch==13){ ch=10; cout<<ch; fwrite(&ch,1,1,dat); } } fclose(dat); } cout<<endl<<endl; if((dat=fopen("H:\\programmierung\\dateiarbeit\\bildschirm\\test\\test.txt","rb"))==NULL) { cout<<"Fehler!!!"; ©-=]ToT[=-Acid Burn 101

01.09.2003 getch(); exit(0); } else{ while(fread(&ch,1,1,dat)){ cout<<ch; } fclose(dat); } }

Aufgabe: Füllen Sie ein Feld mit 100 Zufallszahlen zw 1-100. Schreiben Sie anschließend in eine Datei. Versuchen Sie das Feld in eine andere Feldvariable zu lesen.

Aufbau einer Dateiverwaltung
Eine Datenverwaltung zum Thema Telefonverzeichnis ist zu erstellen. Aufbau der Struktur: sei Name Vorname jeweils 30 Zeichen. Telefonnummer 20 Zeichen. In einem Menü sind die Punkte: 1. Eingabe/ Speichern 2. Ausgabe aller Daten 3. Suchen 4. Löschen 5. ESC zum Beenden Anzubieten. Schreiben sie zu den Menüpunkten die Funktionen: Eingabe Ausgabe Suchen Löschen Funktion Eingabe: 1. Dekleration der Variablen vom Typ Ttel Dateivariable vom Typ FILE * 2. Eingabeaufforderung und einlesen der Strkturkomponeneten 3. Öffnen der Datei Ttel.dat im Modus AB 4. Schreiben der Strukturvariablen mit fwrite 5. Schließen der Datei Funktion Ausgabe: 1. Variable vom Typ Ttel und FILE * anlegen 2. Datei öffnen im Modus RB 3. solange die Daten mit fread gelesen werden können ausgabe der Daten 4. Schließen der Datei Funktion Suchen 1. Variablen vom Typ Ttel und FILE * und char 30 (für den Suchbegriff) 2. Suchname einlesen ©-=]ToT[=-Acid Burn 102

01.09.2003 3. Datei öffnen im Modus rb 4. solange Daten mit fread gelesen werden können wenn Suchname = Name dann ausgabe des Datensatzes 5. Schließen der Datei Funktion Löschen 1. Variablen vom Typ Ttel und FILE* und Variable für den Suchnamen 2. Suchname einlesen 3. Datei im Modus rb öffnen datei Hilf.dat im Modus wb öffnen 4. solange man mit fread Daten lesen kann vergleicht man wenn Suchname und name verschieden, schreiben des Datensatzes mit fwrite in die Hilfsdatei 5. schließen der Datei 6. löschen von der der originaldatei remove(„Pfad zur Datei“); 7. umbenennen von Hilf.dat in Tel.dat rename („Altername“,“Neuername“); Aufgabe: Schreiben sie eine Funktion ändern welche es ermöglicht einen Datensatz zu ändern.

Organisation und Implementierung von Header- Dateien
Eingroßes Programm in einer einzigen Datei zu verwalten ist schwierig. Nachteile: lange Übersetzungszeiten unübersichtliche Anordnungen Probleme bei mehreren Personen, welche in einem Programm arbeiten Lösung: Man trennt Programme daher meist in mehrere Dateien auf die auch getrennt von einander Compiliert und getestet werden können. Aufspaltung in Implementierungsdateien (Quelltextdateien) und in Headerdateien welche nur die Deklarationen von Funktionen und Variablen enthalten. Dateiendung.h Header 1. include- guards (um mehrfaches einschließen von Headerdateien zu verhindern) #ifndef Name.h #define Name.h //Deklarationen #endif 2. Deklaration von Funktionen 3. Definition von Inline Funktionen 4. Deklaration von Klassen und dessen Elementfunktionen 5. Deklaration von globalen Variablen extern

©-=]ToT[=-Acid Burn 103

01.09.2003 Header //Name.h #idndef _Name_ #define _Name_ ......Deklarationen........

#endif //Name.cpp //Definitionen #include „Name.h“ //Quelltext

Zeiger
Ein Zeiger ist ein Datentyp dessen Variable eine Adresse als Argument erwartet. Ohne Adresse ist ein Zeiger nutzlos. Deklaration von Ziegervariablen <Datentyp> *<Bezeichner der Zeigervariablen>; Datentyp gibt den Typ der Variablen an dessen Adresse die Zeigervariable aufnehmen soll. z.B. int *zeiger; //Zeigervariable, welche die Adresse von Integervariblen aufnehmen kann Zuweisung einer Adresse Die Zuweisung einer Adresse an die Zeigervariable erfolgt mit Hilfe des & Adressoperators. z.B. zeiger=&intzahl; //Zeiger erhält Adressen von intzahl

Man beachte, den Stern vor der Zeigervariablen muß man weglassen!

©-=]ToT[=-Acid Burn 104

01.09.2003 Zugriff auf den Inhalt der Adresse, welcher der Zeigervariablen zugewiesen wurden erfolgt mit dem Stern vor dem Bezeichner. z.B. *zeiger=123; //weist die Adresse auf welche Zeiger zeigt den Wert 123 zu * als //Inhaltsoperator Skizze int zahl int *zeiger;

FF00 FF04

123 FF00

zahl zeiger

Zeiger=&zahl *zeiger=123

Schreiben Sie ein Beispielprogramm in welchem Sie eine Varible und einen Zeiger anlegen vom gleichen Typ. Anschließend dem Zeiger die Adresse der Variablen zuweisen. Über den Zeiger den Wert der Variablen verändern und auf dem Bildschirm die Adresse der Variablen und Inhalte ausgeben.

Anwendung zu Zeigern • Zur Übergabe von Argumenten an Funktionen, wenn die Funktion diese Argumente verändern soll. (Call by Referenz) • Für den zugriff auf die Elemente eines Vektors • Zur Übergabe von Vektoren und Zeichenketten an Funktionen • Bei der Speicherplatzanforderung an das System • Um Datenstrukturen wie verkettete Listen zu erezeugen

©-=]ToT[=-Acid Burn 105

01.09.2003

Übergabe von Argumenten an Funktionen( Call by Referenz)
Prototyp: void tausch (int *z1, int *z2); Aufruf: tausch(&a, &b); //Argumente sind Zeiger vom Typ der Variablen, welche //übergeben werden sollen

//Übergabe der Adressen von a und b

Definition: void tausch(int *z1, int *z2) //Argumente müssen Zeiger sein { //z1 und z2 zeigen auf die gleiche Adresse int hilf; //wie a und b hilf= *z1; *z1= *z2; *z2= hilf; }

Anwendung von Zeigern
Zeiger auf Felder Man beachte der Datentyp der Feldelemente muß mit dem Datentyp des Zeigers übereinstimmen. z.B. int intfeld[10]; int *zeiger; //Integerfeld //Zeiger vom Typ int

Zuweisung der Anfngsadresse des Feldes Erfolgt in der Regel durch den Bezeichner des Feldes oder auch möglich durch die Zuweisung der Adresse des ersten Feldelementes. z.B. zeiger= intfeld; //üblich oder zeiger=& intfeld[10]; //unüblich Zugriff auf den Inhalt der Adresse bzw. auf die Feldelemente Erfolgt über den Inhaltsoperator *(Derefernezoperator) und die Nutzung der Zeigerarithmetik. z.B. 1.Möglichkeit: for(int i=0; i<10; i++) *(zeiger+i)= rand()%100+1 //Füllt das Feld mit Zufallszahlen von 1-100

©-=]ToT[=-Acid Burn 106

01.09.2003 2.Möglichkeit: for(int i=0; i<10; i++) *zeiger++= rand()%100+1 //Füllt das Feld mit Zufallszahlen von 1-100 //zuerst wird der Inhaltsoperator ausgeführt und anschließend //Postfix ++ Zeigerarithmetik: Erhöht sich der Wert einer Adresse um 1 sorgt die Zeigerarithmetik dafür das sich der Wet der Adresse um 1mal dem des Speicheraufwand des Datentyps erhöht z.B. ein float Zeiger erhöht bei einer Addition um 1 den Wert der Adresse um 4. Aufgabe: Testen Sie beide Zugriffsmöglichkeiten in dem Sie Möglichkeit 1 das Feld mit Zufallszahlen und mit Möglichkeit 2 das Feld ausgeben. Aufgabe: Schreiben Sie ein Programm in Welchem Sie ein Integerfeld mit 20 Zufallszahlen von 1-100 füllen und stellen Sie anschließend in einer Funktion über Zeiger fest wie viele Zahlen <= 50 bzw. >50 waren. void fuenfzig(int *zei, int anz) { int klgl=0, gr=0; for(int i=0; i<anz ;i++){ if(*(zeiti)<=50){ klgl++; } else{ gr++; } } cout<<“Größer“<<gr<<“Kleiner: „<<klgl; }

©-=]ToT[=-Acid Burn 107

01.09.2003 Zeiger auf Zeichenketten Zeiger auf Zeichenkettenkonstanten z.B. D E F V E K \0 char Str1[]=”DEF.VEK.” char *Str2=”DEF.ZEI.” Str1 Str2 D E F V E K \0

Der Unterschied zwischen Str1 und Str2 ist, dass Str1 eine Adresse (daher eine Zeigerkonstante) und Str2 eine Zeigervariale ist. Str2 kann verändert werden aber Str1 nicht. z.B. Str1++ ; Str2++; //geht nicht //geht

Betrachte: Eine Zeichenkette, die als Zeiger definiert wurde lässt sich flexibler verwenden. Zeichenketten als Argumente von Funktionen //Eine Zeichenkette in Zeigerschreibweise darstellen //Prototyp void zeige_kette(char *); void main() { char str[]=“Wer in der Schule sitzt, hat keine Freizeit mehr!“; //Aufruf zeige_kette(str); } //Definition der Funktion void zeige_kette(char *zei) { while( *zei) cout<<*zei++; } Aufgabe: Schreiben und Testen Sie eine Funktion kopier( ), in welcher Sie mit Zeigern eine Zeichenkette kopieren. ©-=]ToT[=-Acid Burn 108

01.09.2003 Zusatz: Schreiben Sie eine Funktion umkehr die Zeichenkette umgekehrt auf dem Bildschirm ausgibt.

Dynamische Speicherplatzanorderung an das System
C++ stellt noch einen anderen Weg zur Verfügung, um Speicherbereiche zu belegen: Den: new- Operator Dieser Operator fordert einen Speicherbereich beim Betriebssystem an und liefert als Ergebnis einen Zeiger af die Anfangsadresse dieses Speicherbereiches. Der Zugriff auf diesen dynamisch angeforderten Speicher erfolgt über den Zeiger. z.B. float *zeiger; //deklarert einen Float- Zeiger zeiger=new float; //erzeugt Adresse mit reservierten Speicherplatz für eine Float-Variable *zeiger=123.456; //belegt Speicher mit inem Wert

Die Freigabe des mit new allozierten Speichers erfolgt mit dem delete- Operator. delete zeiger; Weitere Anwendungen: Dynamisches Integerfeld erzeugen 1. Man fragt erst zur Laufzeit des Programms ab weviel Elemente benötigt werden. int anz; cout<<“Wie viele Daten? :“; cin>>anz; if(anz<=0) exit(0); 2. Reservieren des notwendigen Speichers mit new und zuweisen der Adresse an einen int zeiger. int *pFeld= new int[anz]; 3. Zugriff auf den reservierten Speicher erfolgt über den Zeiger und mit Hilfe der Zeigerarithmetik. Long t; Srand(time(&t)); for(int i=0;i<anz; i++){ *(pFeld+I)= rand( )%100+1; }

©-=]ToT[=-Acid Burn 109

01.09.2003

Aufgabe: Reservieren sie Dynamisch ein integer Feld und füllen Sie es mit Zufallszahlen zwischen 1 und 100. Geben Sie anschließend die Zufallszahlen auf dem Bildschirm aus. #include <iomanip> #include <iostream> #include <ctime> using namespace std; void main() { int anz; cout<<"Wie viele Daten? :"; cin>>anz; if(anz<=0) exit(0); int *pFeld= new int[anz]; long t; srand(time(&t)); for(int i=0;i<anz; i++){ *(pFeld+i)= rand( )%100+1; } for(i=0;i<anz;i++){ cout<<setw(4)<<*pFeld++; } }

Freigabe eines Feldes: Delete[ ]pFeld;

Dialogbasierende Programme
Wichtige Funktionen für EditBox Zeichenkette vom Typ Cstring aus der EditBox holen und in der Edit Variablen ablegen: GetDlgItemText (ObjektID, EditVariable); Umwandlung der EditVariablen in numerische Zielvariable: ZielVariable= atof (EditVariable); //Typ double, float ©-=]ToT[=-Acid Burn 110

01.09.2003 ZielVariable= atoi (EditVariable); //Typ int Umwandlung der numerischen Zielvariablen in EditVariable: EditVariable.Format („%Formatbezeichner“,Zielvariable); Hinweis: Formatbezeichner analog nach printf( ) z.B. int %bd,%bi float %b.nf double%b.nlf b: Breite der Ausgabe n: Anzahl der Dezimalstellen (optional) EditVariable vom Typ Cstring in EditBox SetDLgItemText( objektID, EditVariable); Wichtige Nachrichten für die EditBox: Wo?: Was?: ObjektID z.B: IDC_Name EN_KILLFOCUS -wird aufgerufen wenn IDC_Name den Focus verliert EN_SETFOCUS -wird aufgerufen wenn IDC_Name den Focus erhält Ausgabe von Fehlermeldungen: MessageBox(„Dieser Text wird ausgegeben!“,“Title“); Focus zurückgesetzen bzw. Zeiger auf ein Dialogelement setzen: CWnd*pf= (CWnd*) GetDlgItem (ObjektID); Pf->SetFocus( ); -erzeugt einen Zeiger auf ein Element des Dialogprogramms und wendet die Methode SetFocus ( ) der Class CWnd an. Dialogelemente aktivieren bzw. Deaktivieren Zeiger auf das Element setzen: CWnd * pf=(CWnd*) GetDlgItem(ObjektID); z.B. CWnd * pf= (CWnd*) GetDlgItem(IDC_Berechnen); Methode zum Aktivieren und Deaktivieren EnableWindow(Wahrheiswert) //True, False pf->EnableWindow(False); ©-=]ToT[=-Acid Burn 111

01.09.2003

Allgemeine Funktion zur Abfrage bzw. zum setzen von Inhalten für Dialogelemente
Voraussetzung: Mit Hilfe des Klassenassistenten wurden den Dialogelementen Variablen zugewiesen. UpdateData(BOOL) 1. Möglichkeit UpdateData(TRUE) Liest alle Werte aus den Dialogelementen und weist sie den zugehörigen Variablen zu. 2. Möglichkeit UpdateData(FALSE) Schreibt die Werte der Variablen in die zugehörigen Dialogelemente. Anwendung: Taschenrechner Aufgabe: Realisieren sie einen Taschenrechner für die Grundrechenarten für double Zahlen. Verwenden sie zum lesen und schreiben der Inhalte der Dialogelemente die Funktion UpdateData

Erstellung und Aufruf eines neuen Dialogfensters
1. Schritt: Erstellen eines neuen Dialogfenster 1.1 Ein Dialogfenster ist eine Ressource, mit Einfügen -> Ressource öffnen wir ein Auswahlfenster, wählen dort Dialog und erhalten ein neues Dialogfenster, welches man bearbeiten kann. 1.2 Ändern der IDD über Eigenschaften wie bekannt 1.3 Hinzufügen einer Klasse Cneu als Ableitung von Cdialog über Klassen- Assistenten 2. Schritt: Aufbau des neuen Dialogfensters mit entsprechenden Steuerelementen 3. Schritt: Aufruf des neuen Dialogfensters z.B. über einen Button 3.1. In den Ausgangsdialog wechseln und mit Hilfe des Klassen- Assistenten dem Button ID_.... über BN_CLICKED eine neue Funktion hinzufügen 3.2. In der Funktion folgende Anweisungen hinzufügen Cneu dlg; //Objekt von CNEu erstellen //Ausführen des neuen Dialoges

Int erg=dlg.DoModal( ); If(erg= = IDOK) { ©-=]ToT[=-Acid Burn 112

//Aktionen wen mit OK beenden

01.09.2003 //nur als Platzhalter hier könnte auch die Übergabe von Variablen stehen MessageBox(„Dialog mit OK beendet!“,“Zur Information“); } if( erg= = IDCANEL) //Aktionen wenn mit Abbrechen beendet { //nur als Platzhalter gedacht MessageBox(„Dialog mit Abbrechen beendet!“,“Zur Information“); } 3.3. Einfügem der Anweisungen von #include „Neu.h“ in die Quelldatei damit die Klasse Cneu bekannt ist.

Einfügen von Drehfeldern
1. Drehfeld aus der Toolbox einfügen 2. Spinbuttons sind immer int-Zähler 3.
m_dE.. = m_dE.. = 5.0 ; CString help ; help . Format ( "%2.1f" , m_dE…. ) ; SetDlgItemText ( IDC_E_…. , help ) ; SetDlgItemText ( IDC_E_…. , help ) ; CSpinButtonCtrl * pSpin = ( CSpinButtonCtrl * ) GetDlgItem ( IDC_SPIN_…. ) ; pSpin -> SetRange ( 10 , 100 ) ; pSpin -> SetPos ( 50 ) ;

pSpin = ( CSpinButtonCtrl * ) GetDlgItem ( IDC_SPIN_…. ) ; pSpin -> SetRange ( 10 , 100 ) ; pSpin -> SetPos ( 50 ) ;

return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX-Eigenschaftenseiten sollten FALSE zurückgeben

©-=]ToT[=-Acid Burn 113