81
Hochschule München Fakultät 04 Elektrotechnik und Informationstechnik Technische Informatik AD - I - 1/1 - Kr - 0 25.09.2011 Algorithmen und Datenstrukturen - Programmieren Prof. Dr. H. Kristl 1. Daten und Algorithmen 1.1 Information, Nachricht und Daten 1.2 Schritte der Softwareerstellung 1.3 Entwurf und Darstellung von Algorithmen 1.4 Algorithmische Sprachen 1.5 Einführung in Datenstrukturen 2. Programmstrukturen in C 2.1 Grundelemente eines C-Programms 2.2 Wiederholungsstrukturen 2.3 Unstrukturierte Kontrollanweisungen 2.4 Auswahlstrukturen 3. Ausdrücke und Operatoren 3.1 Arithmetische Operatoren 3.2 Vergleichsoperatoren 3.3 Logische Operatoren 3.4 Bitmanipulation 3.5 Zusammengesetzte Zuweisungsoperatoren 3.6 Bedingter Auswerte-Operator 3.7 Rangfole der Operatoren 4. Unterprogramme - Funktionen 4.1 Konzept 4.2 Funktionsdefinition 4.3 Funktionsdeklaration 4.4 Funktionsaufruf und Funktionsparameter 4.5 Ein- und Ausgabe über die Konsole 4.6 Der C Präprozessor 5. Nähere Betrachtung der Datentypen in C Stand Ende des ersten Semesters 5.1 Felder (Arrays) 5.2 Typumwandlung 5.3 Verfügbarkeit und Lebensdauer – Speicherklassen 5.4 Der Zeiger - Pointer 5.5 Der strukturierte Datentyp - struct 5.6 Festlegung von Datentypen mittels „typedef“ 5.7 Aufzählungstypen und Aufzählungskonstanten 5.8 Der "sizeof"-Operator 6. Dateien 6.1 Das Dateikonzept 6.2 Arten von Dateien und grundlegende Aktionen mit Dateien 6.3 Funktionen tur Bearbeitung von Textdateien 6.4 Funktionen zur Bearbeitung von Binärdateien 7. Dynamische Datenstrukturen 7.1 Speicherallokation 7.2 Dynamische Datenstrukturen 7.3 Listen und Bäume 7.4 Unions 7.5 Vorwärtsdeklaration von strukturierten Datentypen

Algorithmen und Datenstrukturen - Programmieren Ilsw.ee.hm.edu/~shaneor/kri-skripten/algodat/vorles/AlgoDatW12.pdf · Hochschule München Fakultät 04 Elektrotechnik und Informationstechnik

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Hochschule München Fakultät 04 Elektrotechnik und Informationstechnik Technische Informatik AD - I - 1/1 - Kr - 0 25.09.2011

Algorithmen und Datenstrukturen - Programmieren

Prof. Dr. H. Kristl 1. Daten und Algorithmen

1.1 Information, Nachricht und Daten 1.2 Schritte der Softwareerstellung 1.3 Entwurf und Darstellung von Algorithmen 1.4 Algorithmische Sprachen 1.5 Einführung in Datenstrukturen

2. Programmstrukturen in C

2.1 Grundelemente eines C-Programms 2.2 Wiederholungsstrukturen 2.3 Unstrukturierte Kontrollanweisungen 2.4 Auswahlstrukturen

3. Ausdrücke und Operatoren

3.1 Arithmetische Operatoren 3.2 Vergleichsoperatoren 3.3 Logische Operatoren 3.4 Bitmanipulation 3.5 Zusammengesetzte Zuweisungsoperatoren 3.6 Bedingter Auswerte-Operator 3.7 Rangfole der Operatoren

4. Unterprogramme - Funktionen

4.1 Konzept 4.2 Funktionsdefinition 4.3 Funktionsdeklaration 4.4 Funktionsaufruf und Funktionsparameter 4.5 Ein- und Ausgabe über die Konsole 4.6 Der C Präprozessor

5. Nähere Betrachtung der Datentypen in C

Stand Ende des ersten Semesters 5.1 Felder (Arrays) 5.2 Typumwandlung 5.3 Verfügbarkeit und Lebensdauer – Speicherklassen 5.4 Der Zeiger - Pointer 5.5 Der strukturierte Datentyp - struct 5.6 Festlegung von Datentypen mittels „typedef“ 5.7 Aufzählungstypen und Aufzählungskonstanten 5.8 Der "sizeof"-Operator

6. Dateien

6.1 Das Dateikonzept 6.2 Arten von Dateien und grundlegende Aktionen mit Dateien 6.3 Funktionen tur Bearbeitung von Textdateien 6.4 Funktionen zur Bearbeitung von Binärdateien

7. Dynamische Datenstrukturen

7.1 Speicherallokation 7.2 Dynamische Datenstrukturen 7.3 Listen und Bäume 7.4 Unions 7.5 Vorwärtsdeklaration von strukturierten Datentypen

Hochschule München Fakultät 04 Elektrotechnik und Informationstechnik Technische Informatik AD - I - 1/2 - Kr - 0 25.09.2011 8. Die Standardbibliothek

8.1 ANSI/ISO-C-Standardbibliothek 8.2 Überblick über die I/O-Funktionen 8.3 Funktionen zum Zeichenklassentest 8.4 Funktionen zur Stringbearbeitung 8.5 Utility-Funktionen 8.6 Mathematische Funktionen 8.7 Datums- und Zeitfunktionen

9. Ausgewählte Algorithmen

9.1 Bestimmung von Nullstellen durch Iteration 9.2 Sortieren

**10. Spezielle Verfahren

**11. Fortgeschrittene Methoden

** ist optional

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 11/1 - 00 - KR - 00 Kapitel 1: Daten und Algorithmen

1.1 Information, Nachricht und Daten 1.1.1 Definitionen 1.1.2 Darstellung von alphanumerischen Zeichen 1.1.3 Zahlendarstellung in der Programmiersprache C

1.2 Schritte der Softwareerstellung

1.2.1 Begriffe der Softwareentwicklung 1.2.2 Vom Problem zur Lösung

1.3 Entwurf und Darstellung von Algorithmen

1.3.1 Programmstrukturen 1.3.2 Programmablaufplan 1.3.3 Struktogramm

1.4 Algorithmische Sprachen

1.4.1 Maschinennahe Sprachen 1.4.2 Problemorientierte Sprachen

1.5 Einführung in Datenstrukturen

1.5.1 Datenorientierte Programmentwicklung 1.5.2 Datentyp 1.5.3 Variable und Konstante 1.5.4 Skalare Datentypen 1.5.5 Strukturierte Datentypen 1.5.6 Übersicht zu den Datentypen in C

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 11/2 - 00 - KR - 00 1. Daten und Algorithmen 1.1 Information, Nachricht und Daten 1.1.1 Definitionen Information: Kenntnis über irgendetwas - bringt Neues zum Ausdruck. Nachricht: Geordnete Zusammenstellung von Symbolen zur Übermittlung von Information. Symbol (Zeichen): Element eines Symbolvorrates zur Darstellung von Nachrichten, mit

vereinbarter Bedeutung. Alphabet: Geordneter Symbolvorrat. Wort: Folge von zusammengehörigen Zeichen, die in einem bestimmten

Zusammenhang als Einheit betrachtet werden. Signal: Physikalische Repräsentation einer Nachricht. Daten: Informationen, die zur Verarbeitung durch ein Datenverarbeitungssystem

bestimmt sind oder/und durch eine solche Verarbeitung entstanden sind. Programm-Daten legen die Art und Reihenfolge der Verarbeitungsschritte fest, Verarbeitungs-Daten dienen der Darstellung der zu verarbeitenden Information

und der Resultate der Verarbeitung. Begriffe für die Darstellung von Zahlen: Ziffer (digit): Element aus einer Menge von Symbolen zur Darstellung von Zahlen (z.B. 0, 1, 2

,3...) Zahl (number): Anordnung von Ziffern, die in einem vereinbarten Zahlensystem einen

bestimmten Wert darstellen. 1.1.2 Darstellung alphanumerischer Zeichen Problemstellung: Darstellung von Groß- und Kleinbuchstaben, Ziffern, Interpunktionszeichen (,;.:?!), Sonderzeichen (%$&§*+-_/) und Steuerzeichen (Wagenrückl. Zeilenvorschub usw.) mittels binärer Codewörter.

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 11/3 - 00 - KR - 00 Wieviele Binäsymbole sind erforderlich? Großbuchstaben 26 Kleinbuchstaben 26 Ziffern 10 Interpunktion 10 Sonderzeichen 20 Steuerzeichen 10 102 Anzahl Binärsymbole: 2n ≥ 102 n ≥ ld 102 n = 7 Sehr häufig verwendeter Code ist der ASCII-Code (American Standard Code for Information Interchange) (Umdruck). Eine Teilmenge der Codewörter ist international genormt, eine weitere Teilmenge steht der nationalen Normung offen. In Mainframes wird häufig der EBCDIC-Code verwendet (Umdruck: V-IF1a-3-6). Zunehmend wird die Zeichendarstellung mittels UNICODE eingeführt, mit der Zielsetzung Symbole aus möglichst vielen Kulturkreisen der Welt darstellen und verarbeiten zu können. Der ASCII-Code bildet darin eine Teilmenge. Einsatzgebiete: Datenübertragung, Textbearbeitung, Dateneingabe, Datenausgabe. Nachteil: Nicht geeignet für die interne Darstellung von Zahlenwerten.

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 11/4 - 00 - KR - 00

ASCII-Code (American Standard Code for Information Interchange)

000 0

001 1

010 2

011 3

100 4

101 5

110 6

111 7

0000 0 NUL DLE SP 0 @ P p 0001 1 SOH DC1 ! 1 A Q a q 0010 2 STX DC2 “ 2 B R b r 0011 3 ETX DC3 # 3 C S c s 0100 4 EOT DC4 $ 4 D T d t 0101 5 ENQ NAK % 5 E U e u 0110 6 ACK SYN & 6 F V f v 0111 7 BEL ETB ‘ 7 G W g w 1000 8 BS CAN ( 8 H X h x 1001 9 HAT EM ) 9 I Y i y 1010 A LF SUB * : J Z j z 1011 B VT ESC + ; K [ k { 1100 C FF FS , < L \ l | 1101 D CR GS - = M ] m } 1110 E SO RS . > N ^ n ~ 1111 F SI US / ? O _ o DEL

z.B.: 0x35 = '5' ; 0x41 = 'A' ; 0x64 = 'd' NUL Null DLE Data Link Escape SOH Start of Heading DC1 Device Control Character 1 STX Start of Text DC2 Device Control Character 2 ETX End of Text DC3 Device Control Character 3 EOT End Of Transmission DC4 Device Control Character 4 ENQ Enquiry NAK Negative Acknowledge ACK Acknowledge SYN Synchronous Idle BEL Bell ETB End of Transmission Block BS Backspace CAN Cancel HT Horizontal Tabulation EM End of Medium LF Line Feed SUB Substitute Character VT Vertical Tabulation ESC Escape FF Form Feed FS File Separator CR Carriage Return GS Group Separator SO Shift-out RS Record Separator SI Shift-in US Unit Separator SP Space

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 11/5 - 00 - KR - 00 Escape-Sequenzen Graphisch nicht darstellbare Zeichen können als sog. Escape-Sequenzen angegeben werden. z.B '\n' für Zeilenwechsel

Zeichen Darstellung ASCII-Code(hex) New Line <LF> \n 0x0A Carriage Return <CR> \r 0x0D Form Feed <FF> \f 0x0C Back Space <BS> \b 0x08 Horizontal Tab <HT> \t 0x09 Vertical Tab <VT> \v 0x0B Bell <BEL> \a 0x07 Backslash \ \\ 0x5C Question Mark ? \? 0x3F Single Quote ‘ \’ 0x27 Double Quote “ \“ 0x22

Bitmuster - hexadezimal: \xss mit ss 1-2 Hexadezimalstellen

1.1.3. Darstellung ganzer Zahlen in der Programmiersprache C Durch die Angabe eines Datentyps wird in Hochsprachen festgelegt welchen Wertebereich ein Zahlenwert annehmen kann und welchen Umfang dessen Darstellung im Speicher einnimmt. C unterscheidet folgende einfache (skalare) Datentypen für die Darstellung ganzer Zahlen, bei vorzeichenbehafteten Typen erfolgt die interne Darstellung im 2er-Komplement:

C-Bezeichner für Ganzzahldatentypen

häufige Darstellungslänge in Bit

kleinster Zahlenwert

größter Zahlenwert

(signed) int 16 -32768 +32767 unsigned int 16 0 65535 (signed) char 8 -128 +127 unsigned char 8 0 255 (signed) long (int) 32 -231 +231-1 unsigned long (int) 32 0 232-1

Alle Variablen müssen vor ihrer Verwendung definiert werden, d.h. es muss für sie ein Name und ihr Datentyp festgelegt werden. Beispiel: int iZaehler, iSchwerpunkt; unsigned long ulTimerticks; char cBuchstabe; Variable des Typs „char“ eignen sich auch zur Aufnahme von ASCII-Codewörtern! Anmerkung: Die englische Bezeichnung für ganze Zahlen lautet „integer“, man spricht auch im Deutschen von

Integergrößen oder Integerwerten.

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 11/6 - 00 - KR - 00 1.1.4 Darstellung von Gleitpunktzahlen in der Programmiersprache C C unterscheidet folgende einfache (skalare) Datentypen für die Darstellung von Gleitpunktzahlen: C-Bezeichner für Gleitpunkt-datentypen

Länge der Charakteristik

Länge der Mantisse +Vz

kleinster positiver Zahlenwert

größter positiver Zahlenwert

float 8 24 1.175494351e-38 3.402823466e+38 double 11 53 2.2250738585072014e-308 1.7976931348623158e+308 long double 15 64 3.3621031431120935063e-4932 1.189731495357231765e+4932 Beispiel für die Vereinbarung von Variablen eines Gleitpunkttyps in C: double dLaenge; /* Standard Gleitpunktgenauigkeit */ float fMesswert; /* Gleitpunktzahl geringerer Genauigkeit */ long double ldPraezis; /* Gleitpunktzahl höchster Genauigkeit */

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 12/1 - 00 - KR - 00 1.2 Schritte der Softwareerstelleung 1.2.1 Begriffe der Softwareerstellung Algorithmus:

Die eindeutige und vollständige Beschreibung des Weges, auf dem ein gewünschtes Resultat bei gegebenen Voraussetzungen durch eine endliche Anzahl von Verarbeitungsschritten erreicht wird.

Programm:

Implementierung eines Algorithmus auf einem Datenverarbeitungssystem. Es steuert den Ablauf von Verarbeitungsprozessen, in deren Verlauf Resultate erarbeitet werden.

Codierung (fälschlich häufig als „Programmierung“bezeichnet):

Übertragung der abstrakten Beschreibung des Algorithmus in die Maschinensprache meist unter Anwendung einer höheren Programmiersprache oder der Assemblersprache.

Daten:

Informationen, die zur Verarbeitung durch ein Datenverarbeitungssystem bestimmt sind oder/und durch eine solche Verarbeitung entstanden sind.

Software:

Gesamtheit aller Programme für den Betrieb von Systemen, die auf programmgesteuerten Rechnerbaugruppen basieren.

Was ist ein Algorithmus? Der Vergleich mit Bedienungsanleitungen und Kochrezepten dient zur Veranschaulichung. Beispiele für einfache Algorithmen: Beispiel 1: „Kreisumfang“ (K1) Hole den Radius aus der Eingabe. (K2) Multipliziere den Radius mit 2,0 und lege das Ergebnis in der Variablen „Durchmesser“ ab. (K3) Multipliziere den Durchmesser mit π (3,1415926) und bringe das Ergebnis zur Anzeige. Test: Eingabe 7,0 ⇒ Ausgabe: 43,982296 Beispiel 2: Angenommen der Computer beherrscht die Multiplikation nicht ⇒ Algorithmus

für „Multiplikation" von A und B ist erforderlich. (M1) Hole die Zahlen A und B von der Eingabe. (M2) Nimm die höchstwertige Ziffer der Zahl B und setze die Ergebnisvariable nach Null. (M3) Addiere die Zahl A so häufig zur Ergebnisvariablen, wie die höchstwertige Ziffer der Zahl B

angibt. (M4) Falls B noch weitere Ziffern besitzt verschiebe das Ergebnis aus M3 um eine Stelle nach links,

ansonsten setze bei M6 fort. (M5) Nimm die nächste Ziffer von B und setze bei M3 fort.

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 12/2 - 00 - KR - 00 (M6) Zähle beim Ergebnis so viele Stellen von rechts ab, wie die Eingabewerte zusammen

Nachkommastellen besitzen und füge hier das Komma im Ergebnis ein. (M7) Bringe das Ergebnis zur Anzeige. Test und Veranschaulichung für die Eingaben 3,14 und 14,0 3,14 * 14,0 314 314 314 314 314 000 43,960

Der Multiplikationsalgorithmus aus Beispiel 2 wird in Beispiel 1 überall dort verwendet wo „Multipliziere“ steht. Fazit: • Algorithmen sind durch eine endliche Menge von Anweisungen formulierbar • Die Anweisungen werden nacheinander ausgeführt (Sequenz) sofern nicht • eine Bedingung für das Verlassen der sequentiellen Verarbeitung als Anweisung formuliert wird. • Häufig benötigte Aktionen, können durch mehrfach verwendbare „Unteralgorithmen“ realisiert

werden. Ein Programm (A/D -F- 1.3/1) ist die Implementierung des Algorithmus mit folgenden Anforderungen: • An jeder Stelle muss festgelegt sein, welcher Verfahrensschritt als nächster folgt (eindeutig). • Jeder Schritt muss ausführbar sein. • Das Verfahren muss eine endliche Länge besitzen. • Jeder Verarbeitungsschritt legt fest, was womit zu tun ist. 1.2.2 Vom Problem zur Lösung Der Weg von der Aufgabenstellung bis zum nutzbaren Softwareprodukt erfolgt in Schritten die aufeinander abzustimmen sind und das gemeinsame Ziel verfolgen die Anforderungen zu präzisieren und diese eindeutig zu erfüllen. Schritt 1: Konzeption und Modularisierung Der Weg von der Aufgabenstellung bis zu einer ersten Programmversion verläuft in folgenden Schritten: • Aufgabenstellung und deren Analyse: Resultat ist die Aufstellung des Lastenheftes • Spezifikation jeder einzelnen Funktionalität des Programms: Resultat ist ein detailliertes

Pflichtenheft • Untergliedern der Gesamtfunktionalität in Funktionsbausteine (Module) - Dekomposition:

Zerlegung in einzelne möglichst unabhängige Teilprobleme - Funktionen und Objekte. Weiter Zerlegung so, dass ein hierarchisches System entsteht

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 12/3 - 00 - KR - 00

33 32 31 23 22 21 12 11

0

3 21

Schicht 1

Schicht 2

Schicht 3

• Festlegung der Algorithmen - Modulentwurf • Codieren - Umsetzen in die Programmiersprache Schritt 2: Modultest und Integration Dieser Phase der Programmentwicklung folgt die Test- und Integrationsphase in folgenden Schritten: • Modultest - mit geeigneter Modellierung der Testumgebung • Schrittweise Modulintegration und Integrationstest • Programmgesamttest Schritt 3: Abnahme, Einsatz und Optimierung Das funktionsfähige Programm ist nun einsatzbereit und ist gekennzeichnet durch die Schritte • Dauernutzung • Wartung • Erweiterung, Ergänzung, Modifikation Beispiel zum Schritt 1: Aufgabenstellung: Zu einem eingegebenen Datum (Tag, Monat, Jahr) soll ausgerechnet werden, um den wievielten Tag im Jahr es sich handelt. Analyse des Problems anhand konkreter Zahlenbeispiele: Gegeben: Datum = 1.1.2011 Jahrestag = 1 Gegeben: Datum = 17.2.2011 Jahrestag = 31 +17 = 48 Gegeben: Datum = 7.7.2011 Jahrestag = 31 + 28(?) + 31 + 30 + 31 + 30 + 7 = 188 Ergebnisse verallgemeinern und überprüfen: Die Berechnung erfolgt durch Addition der vorangegangenen Monatslängen und der Tage im betrachteten Monat basierend auf den Angaben „Tag“ und „Monat“. Auffällige Randbedingung aus dem eigenen Erfahrungsschatz: Der Februar hat unterschiedliche Anzahl von Tagen, diese hängt ab von der Eingabe „Jahr“.

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 12/4 - 00 - KR - 00 Formulieren des Algorithmus (ein erster natürlich-sprachlich formulierter Algorithmus)

Eingabe von Tag, Monat, Jahr. Addiere die Monatslängen der Vormonate (also bis Monat-1) ohne Februar, WENN Monat GRÖßER 2 DANN Ermittle die Februar-Monatslänge Addiere den Wert der Februar-Monatslänge Addiere den Tageswert des eingegebenen Datums. Gib das Ergebnis aus.

Diese Formulierung enthält bereits die Forderung nach einem weiteren (Teil-)Algorithmus nämlich die Berücksichtigung der Randbedingung: Schaltjahresberechnung - "Februar-Monatslänge". Idee: eigener Teilalgorithmus zur Ermittelung der Februar-Monatslänge. Die (offline-) Recherche in einem Buch führt zu folgender Erkenntnis: Nach dem Gregorianischen Kalender handelt es sich um ein Schaltjahr: wenn die Jahreszahl ohne Rest durch 4 teilbar ist, nicht aber, wenn die Jahreszahl ohne Rest durch 100 teilbar ist; jedoch schon, wenn die Jahreszahl ohne Rest durch 400 teilbar ist. Damit läßt sich die Februar-Monatslänge wie folgt als Algorithmus formulieren:

Eingabe Jahr. setze Merker "NEIN" Falls (Jahr mod 4) GLEICH 0: setze Merker "JA". Falls (Jahr mod 100)GLEICH 0: setze Merker "NEIN". Falls (Jahr mod 400) GLEICH 0: setze Merker "JA". WENN Merker GLEICH "JA" DANN setze Ergebnis 29 SONST setze Ergebnis 28 Gib das Ergebnis aus

Anmerkungen: mod ist der Modulo-Operator ⇒ Rest der Ganzzahldivision. Die einzelnen Monatslängen ließen sich in einer Liste wie folgt speichern: Monat Nr. Anz.Tage Bemerkung Monat Nr. Anz.Tage Bemerkung Jan 1 31 Juli 7 31 Feb 2 0 wird gesondert

ermittelt Aug 8 31

März 3 31 Sept 9 30 April 4 30 Okt 10 31 Mai 5 31 Nov 11 30 Juni 6 30 Dez 12 nicht erforderlich!! - ?

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 12/5 - 00 - KR - 00 1.2.3 Einfache Strukturierungstechniken Modularisierung Ein Modul (Teilalgorithmus) ist in sich abgeschlossen und bearbeitet ein geschlossenes Teilproblem. Es wird beschrieben durch seine „Schnittstelle“ - Eingabe- und Ausgabeparameter - und der zu leistenden Aktion. In welcher Weise das Modul die Anforderungen erfüllt ist meist für den Benutzer des Moduls nicht von Belang - Black-Box. Für die Konzeption von Modulen bieten sich folgende Vorgehensweisen an: • Der Top-Down-Entwurf entspricht der Technik der schrittweisen Verfeinerung (Dekomposition). • Der Bottom-Up-Entwurf geht von verfügbaren Teillösungen der untersten Ebene aus um Schritt für

Schritt die konkrete Lösung anzustreben (Abstraktion). • In den unterschiedlichen Hierarchiestufen des Gesamtprojektes werden beide Entwurfsmethoden

gemischt eingesetzt. Innerhalb der Module ist „Strukturierter Entwurf“ zu realisieren, der ausschließlich Gebrauch von grundlegenden Blöcken macht, bestehend aus: • Anweisungsfolgen - Sequenzen • Verzweigungsanweisungen (WENN (Bedingung) DANN ..... ANSONSTEN ......) • Wiederholungsanweisungen (WIEDERHOLE..............BIS(Bedingung)) • Unterprogrammen. Die Blöcke werden linear hintereinander angeordnet. Schnittstelle Modul Schnittstelle Eingangsparameter Beschreibung der Aktionen Ausgabeparameter

Block 1

Block 2

Block n

Für den Anwender des Moduls ist die Beschreibung der Schnittstelle ausreichend sowie die ausge-führten Aktionen. Der mit der Realisierung des Moduls beauftragte Programmierer leistet die geeignete Untergliederung in Blöcke, definiert die Art und das Zusammenwirken der Blöcke und trägt für die vereinbarungs-gemäße Ausführung der Schnittstelle die Verantwortung.

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 12/6 - 00 - KR - 00 Beispiel: Jahrestag Anwender: Übergibt das Datum (7.7.2011) beim Aufruf, erhält den Jahrestag (188). Programmierer: Formuliert und realisiert die Basis- und Teilalgorithmen (Vormonatstage addieren

aktuelles Datum addieren, „Februar“-Algorithmus einbringen).

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 13/1 - 00 - KR - 00 1.3 Entwicklung und Darstellung von Algorithmen 1.3.1 Programmstrukturen Die durch Programmierung zu lösenden Problemstellungen lassen sich, wie die Beispiele zeigten, stets auf wenige gleichstrukturierte Grundelemente zurückführen: Ausführen einzelner Aktionen nacheinander - Sequenz: verbal PAP Struktogramm

B e fe h l 1

B e fe h l 2

B e fe h l n

Befehl 1

Befehl 2

Befehl 3

Befehl n

MACHE 1. Anweisung; MACHE 2. Anweisung; MACHE n. Anweisung;

Berücksichtigt die sequentielle Arbeitsweise des Systems und formuliert den jeweils nächsten Schritt. In C sind Operationen auf Variable beispielsweise Anweisungen. Bsp: iWert = (iAnzahl + iOffset)*iGewicht; iVerp = iTuete + iVerschl; iWert = iWert + iVerp; Folgeschritt ist abhängig von konkreter Bedingung (einseitige Auswahl): verbal PAP Struktogramm

Bed ingung

Befeh le

ne in

ja

Bedingung ?

Sequenz

ja nein

WENN (Bedingung) DANN { MACHE Anweisung a; MACHE Abweisung b; MACHE Anweisung x; }

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 13/2 - 00 - KR - 00 Formulierung in C: if(Bedingungsausdruck) { Anweisung; Anweisung; } Wiederholungen mit definiertem Abschluß: verbal PAP Struktogramm

B e fe h le

B e d in g u n g

ja

n e in

Sequenz

wiederhole, bis Bedingung erfüllt

WIEDRHOLE { MACHE Anweisung a; MACHE Abweisung b; MACHE Anweisung x; } SOLANGE (Bedingung)

Formulierung in C: do { Anweisung; Anweisung; . } while (Bedingung);

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 13/3 - 00 - KR - 00 1.3.2 Die Symbole des Programmablaufplanes Symbole für Programmablaufpläne (1):

Befehl 1

Befehl 2

Befehl n

Einseitige Auswahl:

Bedingung

Befehle

nein

Sequenz Zweiseitige Auswahl:

Bedingung

janein

Befehl bBefehl a

Mehrfachauswahl:

Bedingung

Befehl cBefehl a Befehl b Befehl y

B=C1 B=C2 B=C3 B=Cn

ja

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 13/4 - 00 - KR - 00

Symbole für Programmablaufpläne (2):

Übergangsstelle:

Grenzstelle:

Ablauflinie:

Zusammenführung:

Kommentar:

Unterprogramm-aufruf:

Befehle

Bedingung

Abweisende Schleife:

Befehle

Bedingung

Nichtabweisende Schleife:

ja

ja

nein

nein

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 13/5 - 00 - KR - 00 1.3.3 Symbole für Struktogramme Struktogramme werden auch Nassi-Schneidermann-Diagramme genannt.

Befehl 1

Befehl 2

Befehl 3

Befehl n

Bedingung ?

Sequenz

Bedingung ?

Sequenz a

ja nein

ja nein

Sequenz b

x = ?W ert 1 W ert 2 W ert 3 sonst

Sequenz a Sequenz b Sequenz c Sequenz d Sequenz y

wiederhole, solange Bedingung erfüllt

Sequenz

Sequenz

wiederhole, bis Bedingung erfüllt

Name des Unterprogrammes

Sequenz Einseitige Auswahl

Zweiseitige Auswahl

Mehrfachauswahl

Abweisende W iederholung Nichtabweisende W iederholung

Unterprogrammaufruf Unterprogramm

Nam e des Unterprogrammes

Sequenz

Beispiel: Jahrestag als Programmablaufplan

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 13/6 - 00 - KR - 00

UPRO: Februar MonatstageStart

Setze Monatszaehler i = 1

Ist aktuelle Monatszahl

groeser Monats-zaehler ?

Hole die Monatstage des Monats i aus der Liste

Belege Jahrestage mit Null vor: AnzJT = 0

Addiere geholte Monatstage zu AnzJT

Erhoehe Monatszaehler i=i+1

Addiere die aktuelle Tageszahl zu AnzJT

Istaktueller Monat

> 2 ?

Hole Februartage des akt. Jahres

Addiere Februartage zu AnzJT

ja

Gib Ergebnis AnzJT aus

Ende

Ist (Jahr mod 4)

=0 ?

Merker = 1

Ist(Jahr mod 100)

=0?

Merker = 0

Ist(Jahr mod 400)

=0?

Merker = 1

Merker = 0

Ende UPRO

Tageszahl = 29

IstMerker ==1

?

Tageszahl = 28

nein

nein

nein

ja

ja

ja

ja

nein

nein

nein

ja

Datum eingeben

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 13/7 - 00 - KR - 00 Beispiel: Jahrestag als Struktogramm

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 14/1 - 00 - KR - 00 1.4 Algorithmische Sprachen 1.4.1 Maschinennahe Sprachen Maschinensprache ist die Menge aller Maschinenbefehle, die ein bestimmter Computer ausführen kann. Der Maschinencode ist die interne Darstellung der Befehle der Maschinensprache. Die Assemblersprache ist eine symbolische, textorientierte Darstellung der Maschinensprache. Den einzelnen Maschinenbefehlen werden dabei feste Abkürzungen zugeordnet, Operanden werden symbolisch angegeben. MOV A, HWERT Hole den Inhalt der Speicherzelle mit der symbolischen Adresse

HWERT in den Akkumulator. JZ LOOP Setze die Programmausführung bei der Adresse LOOP fort falls das

„Zero“-Flag gesetzt ist, ansonsten führe den nachstehenden Befehl aus. INX H Addiere zum 16-Bit-Register H eins hinzu. Die Zuordnung der Assemblerbefehle zu Maschinenbefehlen ist 1:1. Das Assemblerübersetzungsprogramm hat die Aufgabe in Assembler formulierte Programme in den Maschinencode zu übersetzen. 1.4.2 Poblemorientierte Sprachen Assemblersprachen sind maschinenorientiert, d.h. sie erlauben es die Lösung von Aufgabenstellungen optimal an den vorhandenen Prozessor anzupassen Höhere Programmiersprachen sind unabhängig vom Zielprozessor und erlauben damit eine ausschließliche Anpassung der Lösung an das gestellte Problem - problemorientiert. 1.4.2.1 Formale Sprachen Sprachen zur Formulierung von Algorithmen benötigen eine Reihe von Festlegungen - Normierungen: • Festlegung von Zeichen aus einem geordneten Zeichenvorrat - Alphabet • Regeln zur Bildung von Wörtern aus diesem Zeichenvorrat • Regeln zur Bildung von Sätzen aus dem damit vereinbartem Wortvorrat • Formulierung von Programm-Texten aus den Sätzen Dieser streng festgelegte Aufbau von zulässigen sprachlichen Konstrukten wird als Syntax bezeichnet.

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 14/2 - 00 - KR - 00 Beispiel: Bezeichner der Programmiersprache C:

Buchstabe

Buchstabe

Ziffer

_

_ Dieses Syntaxdiagramm hat folgende Bedeutung:

Die Bezeichner in C beginnen mit einem Buchstaben oder einem Unterstrich, diesem folgt entweder eine Reihe von Ziffern und/oder Buchstaben und/oder Unterstrich: ulZahl, v_MakeBit, acTr23List sind gültige C-Bezeichner.

Dabei gilt: Buchstabe = { A,B,.......,Z,a,b,.....,z} Ziffer = {0,1,2,3,4,5,6,7,8,9} Die dazugehörigen Syntaxdiagramme sehen wie folgt aus: Buchstabe: Ziffer:

A

B

Z

a

z

0

1

5

6

7

8

9

2

3

4

b

Die unter Beachtung der Syntaxregeln gebildeten Sätze müssen zusätzlich Forderungen nach eindeutigem Sinngehalt erfüllen - Regeln der Semantik. Syntaxregeln werden symbolisch festgelegt - Syntaxdiagramm. Semantikregeln werden meist verbal formuliert. Neben der Möglichkeit eigene Wörter für die Bezeichnung von Variablen, Funktionen usw. zu formulieren existieren stets auch „reservierte Wörter“, die Schlüsselwörter der Sprache sind, z.B. in C: int signed char double while do for usw.. 1.4.2.2 Programmiersprachen

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 14/3 - 00 - KR - 00 Seit Mitte der 50er Jahre begann die Entwicklung unterschiedlicher höherer Programmiersprachen. Zunächst entstanden die prozeduralen Sprachen, die sich auszeichnen durch Beschreibung des Steuerflusses Variablenbegriff als Bezeichner (Adresse der Speicherzelle) und Wert (Inhalt dieser Zelle). Objektorientierte Sprachen verleihen den Daten den Aspekt der Eigenschaften. Zentrale Konzepte dieser Sprachen sind Objektbildung Datenkapselung Vererbung Polymorphie (Vielgestaltigkeit) Beispiele höherer prozeduraler Programmiersprachen: FORTRAN (FORmula TRANslator): Eine der ersten und am weitesten verbreitete höhere

Progranmmiersprache für technisch-wissenschaftliche Problemstellungen. ALGOL(ALGOrithmic Language): Besonders geeignet für technisch-wissenschaftliche Problem-

stellungen. COBOL (COmmon Business Oriented Language): Standardsprache für kommerzielle Berechnungen. BASIC (Beginners All-purpose Symbolic Instruction Code): Einfache Sprache für den Programmier-

anfänger. LISP (List Processing): Verarbeitung von Listenstrukturen. C: Entwickelt zur Implementierung des Betriebssystems UNIX, standardisiert seit Ende der 80er Jahre.

Realisiert durch Dennis Richie und Kerningham, die objektorientierte Erweiterung zu C++ wurde von Bjarne Stroustrup entwickelt.

PASCAL: Speziell entwickelt für den Einsatz im Unterricht, hervorragende methodische und

didaktische Konzeption. Beispiele höherer objektorientierter Programmiersprachen: C++, ADA, JAVA, C# , Perl.

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 15/1 - 00 - KR - 00 1.5 Datenstrukturen 1.5.1 Datenorientierte Programmentwicklung In komplexen Softwareproblemstellungen ist als wesentlicher Teil der Programmkonzeption der sorgfältige Entwurf und die klare Gliederung der nötigen Daten von hervorragender Bedeutung. Dabei sind folgende Vorgehensweisen zu berücksichtigen: Festlegen der Datenstruktur für jede zu verarbeitende Datenmenge. Berücksichtigung von Zuordnungen. Wie bei den Steuerungsstrukturen (Programmstrukturen) lassen sich auch zu Daten Strukturen angeben: • Sequenzen - ein (komplexer) Datentyp besteht aus Elementen des Subtyps A, gefolgt von B, gefolgt

von C usw. • Wiederholungen - ein (komplexer) Datentyp besteht aus einer Reihe von Elementen eines Subtyps. • Auswahl - ein (komplexer) Datentyp besteht entweder aus einem Element des Subtyps A oder

einem Element des Subtyps B 1.5.2 Datentyp Vor dem Umgang mit Daten, d.h. bevor ein erster Bearbeitungsschritt erfolgen kann, muß festgelegt werden • wo sie sich befinden (Adresse im Arbeitsspeicher) und • welchen Umfang (Anzahl Speicherzellen) sie besitzen und • welchen Wertebereich (vgl. Darstellung von Zahlenwerten und alphanumerischen Zeichen) sie

repräsentieren. Umfang und Wertebereich werden durch den Datentyp festgelegt, wobei die bekannten einfachen Datentypen, strukturierte Datentypen und häufig auch selbetdefinierbare Datentypen verfügbar sind. Der Speicherort wird symbolisch durch freie Namensgebung vereinbart, die physikalische Adresse wird durch den Übersetzungs- und Bindevorgang automatisch festgelegt, der Nutzer benötigt diese Information in der Regel nicht. Beispiel: unsigned int uiZahl1, uiZahl2; /* Dies ist die Definition zweier Variabler */

Datentyp Variablenname Beispiel: double dGrenzwert, dSchwelle; char cAnf_Buchst;

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 15/2 - 00 - KR - 00 1.5.3 Variable und Konstante Variable sind Daten, die im Programmverlauf ihren Wert verändern können, sie nehmen also beispielsweise das Ergebnis von Verknüpfungen auf: dGrenzwert = dSchwelle * 7.5; Das Beispiel zeigt die Multiplikation der Variablen „dSchwelle“ mit der Konstanten 7.5 und die Zuweisung des Ergebnisses an die Variable „dGrenzwert“. Genauer:

Der ab der Adresse „dSchwelle“ im Speicher abgelegte Zahlenwert vom Datentyp „double“ wird mit dem konstanten „double“-Wert 7.5 multiplikativ verknüpft. Der Resultatwert wird ab der Adresse „dGrenzwert“ in dem dafür vereinbarten Typ (double) im Speicher abgelegt und überschreibt damit dessen alten Zahlenwert.

Konstante sind Daten, die während des Programmlaufes unverändert bleiben. Das sind wie im obigen Beispiel etwa Zahlenwerte eines bestimmten Typs aber auch einmal festgelegte symbolische Konstanten. Die Konstanten können deshalb abgesehen von ihrer Definition niemals auf der linken Seite einer Zuweisung auftreten Integerkonstante in C: Dezimalkonstante: 12345 Folge von Dezimalziffern, erste muß <> 0 sein! Oktalkonstante: 01173 Folge von Oktalziffern, erste muß = 0 sein! Hexadezimalkonstante: 0x23AF Folge von Hexadezimalziffern, beginnend mit 0x ! Anmerkung: Durch Anfügen von ‘l’ oder ‘L’ wird „long int“ als Typ erzwungen Durch Anfügen von ‘u’ oder ‘U’ handelt es sich um einen „unsigned“ Typ. Gleitpunktkonstante in C: Beispiele: 13.5 0.7654 3.7E-12 4e+6f 34.7e22L Anmerkung: Es gibt ausschließlich dezimale Gleitpunktkonstante Aufbau:

• ganzzahliger Anteil • Dezimalpunkt • gebrochener Anteil • Exponentenzeichen ‘E’ oder ‘e’ • ganzzahliger Exponent mit oder ohne Vorzeichen • Suffix ‘f’, ‘F’ für den Datentyp „float“, ‘l’, ‘L’ für den Datentyp „long double“, sonst

„double“. Symbolische Konstante in C:

C läßt zwei Möglichkeiten zu symbolische Konstanten zu realisieren: 1.) Die Präprozessordirektive #define #define PI 3.141592653

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 15/3 - 00 - KR - 00

weist den Compiler an die abgeschlossenen Zeichenfolge ‘PI’ durch den Zahlenwert zu ersetzen, überall dort wo sie im Rest des Programmes auftaucht. 2.) Qualifizieren einer „Variablen“ mit dem Schlüsselwort „const“: const double Pi = 3.141592653; Das Gleichheitszeichen dient hier zur Initialisierung (keine Zuweisung!).

1.5.4 Skalare Datentypen und Grundoperationen Die bisher aufgezeigten Datentypen für die Darstellung ganzer Zahlen und Gleitpunktzahlen werden einfach oder skalar bezeichnet, dazu gehören darüberhinaus die Datentypen • „char“ zur Darstellung von Textzeichen (oder Ganzzahlwerten - abhängig von der Interpretation), • „bool“ zur Darstellung Bool’scher Variabler, die den Wert „TRUE“ oder „FALSE“ annehmen

können. Operationen mit Ganzzahlgrößen werden durch folgende Operatoren festgelegt: + Addition - Subtraktion * Multiplikation / Ganzzahldivision (ohne Rest und Rundung!) % Rest der Ganzzahldivision (Modulo-Operator) Operationen mit Gleitpunktgrößen: + Addition - Subtraktion * Multiplikation / Division Operationen mit Bool’schen Größen (Interpretation): && AND || OR ! NOT Anmerkung zum Datentyp „bool“ in C: C kennt keinen standarmäßigen Datentyp „bool“, dieser wird erst durch C++ eingeführt. Er läßt sich in C dadurch darstellen, dass bei Anwendung der Bool’schen Operatoren auf Variable eines skalaren Datentyps folgende Wertentsprechung gilt: == 0 ⇒ FALSE != 0 ⇒ TRUE Das Ergebnis einer Bool’schen Operation besitzt entweder den Ganzzahlwert 1 (TRUE) oder 0 (FALSE).

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 15/4 - 00 - KR - 00 Vergleichsoperatoren besitzen als Ergebnis eine Bool’sche Aussage, ihr Wert ist also 0 oder 1. Vergleiche sind im einzelnen: > größer < kleiner >= größer gleich <= kleiner gleich != ungleich == gleich Beispiel: Bedingungen von Schleifen und Verzweigungen if( iAWert > iBWert) { Anweisungsfolge; } while (cZeich != 0) { Anweisungsfolge; } 1.5.5 Strukturierte Datentypen Strukturierte Datentypen bestehen aus mehreren Komponenten, die von einem skalaren Datentyp oder selbst von einem strukturierten Datentyp sind. 1.5.5.1 Felder - arrays Ein Feld bzw. Array besteht aus einer festen Anzahl von Komponenten des gleichen Datentyps. Arrays können ein- (Vektor) zwei-(Matrix) oder mehrdimensional sein. Der Komponententyp kann selbst ein strukturierter Datentyp sein. 1.5.5.2 Verbunde - structures Eine Variable des Typs „struct“ besitzt eine feste Anzahl von Komponenten unterschiedlichen Datentyps. Jede einzelne Komponente besitzt einen eigenen Namen. Beim Zugriff auf eine Komponente einer „Struktur“-Variablen sind Variablenname und Komponentenname zu kombinieren. 1.5.5.3 Datei - file Eine Variable vom Typ FILE besteht aus einer linearen Folge von Komponenten gleichen Typs, die Anzahl der Komponenten ist nicht festgelegt. FILE dient speziell zum Zugriff auf Massenspeicher.

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik VI - AD - 15/5 - 00 - KR - 00 1.5.6 Übersicht zu den Datentypen in C

einfache Datentypen abgeleitete Datentypen

arithmetische Datentypen void

ganzzahlige Datentypen

Zeiger strukturierte Datentypen

ganzzahlige Basistypen

modifizierte Ganzzahltypen

char int

long ... short ... unsigned ... signed ...

Aufzählungstypen

enum ...

Gleitpunkt- Datentypen

Gleitpunkt-Grundtypen

float double

modifizierter Gleitpunkttyp

arrays

structures

unions

struct ...

union ...

Datentypen in C

long double

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 20/1 - 00 - TH/KR - 00

Kapitel 2: Programmstrukturen in C

2.1 Grundelemente eines C-Programms 2.1.1 Deklarationen und Definitionen 2.1.2 Blockstruktur

2.2 Wiederholungsstrukturen 2.2.1 Die while-Anweisung 2.2.2 Nichtabweisende Wiederholung, do .. while-Anweisung 2.2.3 Die for-Schleife

2.3 Unstrukturierte Kontrollanweisungen 2.4 Auswahlstrukturen

2.4.1 Die if-Anweisung 2.4.2 Mehrfachauswahl, die switch-Anweisung

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 20/2 - 00 - TH/KR - 00

Programmbeispiel in C

/*------------------------------------------------------- */ /* Programm: ZLAENGE */ /*------------------------------------------------------- */ /* Ermitteln der Laenge von maximal ZZMAX Eingabezeilen */ /* Programmende bei Eingabe des "End of File"-Zeichens */ /*------------------------------------------------------- */ #include <stdio.h> #define ZZMAX 10 int iZeile_ein(void) ; int main(void) { int iLaenge; int iZz=1; do { iLaenge = iZeile_ein(); printf("Laenge der Zeile %2d = %-d\n",iZz,iLaenge); } while((iLaenge >= 0) && (iZz++ < ZZMAX)); return (0); } /*------------------------------------------------------- */ /* int iZeile_ein(void) */ /*------------------------------------------------------- */ /* Ein: keine */ /* Aus: Laenge der Zeile, */ /* -1 falls EOF aufgetreten. */ /*Aktion: Es wird zeichenweise von der Konsole gelesen, */ /* alle Zeichen werden gezaehlt, trifft das */ /* "New Line"-Zeichen ein, so wird der aktuelle */ /* Zaehlerstand zurueckgegeben. Trifft EOF ein, */ /* wird der Zaehlvorgang abgebrochen und -1 */ /* zurueckgegeben. */ /*------------------------------------------------------- */ int iZeile_ein(void) { int iZeich,iZaehl; iZaehl = 0; while(((iZeich=getchar()) != EOF) && (iZeich != '\n')) iZaehl++; if (iZeich == EOF) iZaehl = -1; return (iZaehl); }

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 20/3 - 00 - TH/KR - 00

Struktur eines C-Programmes

Ein C-Programm besteht aus einem oder mehreren Modulen (Programm-Modulen), die getrennt zu übersetzen sind. Genau eines davon enthält die Funktion „main()“- damit beginnt die Programmausführung. main( ) ist das Hauptprogramm in C.

Modul 1

fkt11() { .... ......... } fkt1n() { .... ......... }

Modul 3

fkt31(){ .... ......... } fkt3n(){ .... ......... }

Modul 2

fkt21() { ......... } main() { ......... }

Modul x

fktX1(){ .... ......... } fktXn(){ .... ......... }

Die Informationen, die benötigt werden um ein Modul zu benützen sind in einer "Header-Datei" zusammengefaßt. Diese enthält die erforderlichen Deklarationen und Definitionen, die zur Verwendung des Moduls erforderlich sind. Die Einbindung von Funktionen der Standardbibliothek erfolgt ebenfalls durch Einbinden der geeigneten "Header-Dateien".

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 20/4 - 00 - TH/KR - 00

Struktur eines C-Programm-Moduls Ein C-Modul besteht aus einer beliebigen Folge von • Vereinbarungen: - Deklarationen

- Typdefinitionen - Variablendefinitionen - Funktionsdefinitionen

• Preprozessoranweisungen Aufbau eines C-Moduls:

Preprozessoranweisung

Deklaration

Typdefinition

Variablendefinition

Funktionsdefinition

Vereinbarungen

Deklaration: Festlegung von Namen und Eigenschaften eines Objektes (Typ, Größe, Speicherklasse usw.).

Definition: Deklaration und zusätzlich Bereitstellung von Speicherplatz (⇒ Erzeugung des konkreten Objektes).

Ausnahme: Typdefinition entspricht einer Deklaration. Abschluß jeder Vereinbarung durch Semikolon ; - Ausnahme: Funktionsdefinition.

Anweisungen: Realisieren die Programmstrukturen und sind im Rumpf der Funktionsdefinitionen enthalten (Funktionsrumpf). Der Funktionsrumpf - Block - ist in geschweifte Klammern { und } einzuschließen. Jede Anweisung wird durch Semikolon ; abgeschlossen - Ausnahme: Verbundanweisung. Block: Besteht aus Deklarationen, Typdefinitionen, Variablendefinitionen und Anweisungen jedoch nicht aus Funktionsdefinitionen ⇒ es gibt nur eine Funktionsebene in C, Schachtelung ist nicht möglich. Blöcke treten in zwei Formen auf, als Funktionsrumpf und als Verbundanweisung. Preprozessoranweisungen: Quellcodezeilen beginnend mit # gefolgt von einem Schlüsselwort für die Bearbeitung durch den Preprozessor. Kommentare: Texte eingeleitet durch /* und beendet mit */ werden durch den Compiler ignoriert – Blockkommentar. Eingeleitet durch // wird ein Zeilenkommentar, der durch das Zeilenende abgeschlossen wird (wird nichtdurch jeden Compiler unterstützt!).

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 20/5 - 00 - TH/KR - 00

Anweisungen in C Anweisungen dienen zur Realisierung der Programmstrukturen. • Anweisung: • Ausdrucksanweisung: • Leeranweisung:

Ausdrucksanweisung

Leeranweisung

Verbundanweisung

while-Anweisung

do-Anweisung

for-Anweisung

if-Anweisung

switch-Anweisung

break-Anweisung

continue-Anweisung

goto-Anweisung

return-Anweisung

Marke :

Ausdruck ;

; • Verbundanweisung:

Vereinbarung

Anweisung { }

Die Verbundanweisung ist syntaktisch mit dem Rumpf einer Funktion identisch - kein ; !!

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 20/6 - 00 - TH/KR - 00

Die while-Anweisung Syntaxdiagramm: Realisierung der abweisenden Schleife (Wiederholung - prechecked loop):

Solange die Auswertung des Ausdrucks einen Wert != 0 (entspricht: TRUE) ergibt, wird die Anweisung (Schleifenkörper) ausgeführt. Besitzt der Ausdruck den Wert == 0, wird mit der folgenden Anweisung fortgesetzt.

Die do-Anweisung Syntaxdiagramm:

Ausdruck

Ausdruck

Anweisung

do Anweisung

(

(

while )

) ; while

Realisierung der nicht-abweisenden Schleife (Wiederholung - postchecked loop):

Die Anweisung wird ausgeführt, solange die Auswertung des Ausdrucks einen Wert != 0 (entspricht: TRUE) ergibt, besitzt der Ausdruck den Wert == 0, wird mit der folgenden Anweisung fortgesetzt.

Die for-Anweisung Syntaxdiagramm:

( for Ausdruck1 ; Ausdruck3 ) Anweisung ; Ausdruck2

Ausdruck 1: Anfangsausdruck Ausdruck 2: Bedingungsausdruck Ausdruck 3: Veränderungsausdruck Die for-Schleife ist äquivalent zu folgendem Block mit while-Schleife:

{ Anfangsausdruck; while (Bedingungsausdruck) { Anweisung; Veränderungsausdruck; } }

Typische Anwendung: for (i=0; i<100; i=i+1) printf(“Element %2d hat den Wert: %5.3f\n“, i, aWerte[i]);

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 20/7 - 00 - TH/KR - 00

Programmbeispiel zur while-Anweisung

/*--------------------------------------------------------- */ /* Programm: ZIFFZAHL */ /*--------------------------------------------------------- */ /* Ermitteln der Anzahl von Ziffern einer Integerzahl */ /*--------------------------------------------------------- */ #include <stdio.h> int main(void) { int iZahl; int iStellen=1; printf("\nGib Zahl: "); scanf("%d",&iZahl); while(iZahl = iZahl/10) iStellen++; printf("\n%d Stellen\n",iStellen); return (0); } /*--------------------------------------------------------- */ Ausgabe: Gib Zahl: 23457 5 Stellen

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 20/8 - 00 - TH/KR - 00

Programmbeispiel zur do-Anweisung

/*--------------------------------------------------------- */ /* Programm: GGT */ /*--------------------------------------------------------- */ /* Ermitteln des groessten gemeinsamen Teilers (ggT) */ /* und des kleinsten gemeinsamen Vielfachen (kgV) zweier */ /* natuerlicher Zahlen iA und iB. */ /* Es gilt: kgV(iA,iB) = (iA*iB)/ggT(iA,iB) */ /*--------------------------------------------------------- */ #include <stdio.h> int main(void) { int iA,iB; int iP,iQ,iR; int iGgt,iKgv; printf("\nggT und kgV von: "); scanf("%d%d",&iA,&iB); if(iA>iB){ /* groessere der beiden Zahlen ermitteln */ iP = iA; iQ = iB; } else { iP = iB; iQ = iA; } do { /* Fortgesetzte Division bis Rest gleich 0 */ iR = iP%iQ; iP = iQ; iQ = iR; } while(iR); iGgt = iP; iKgv = iA/iGgt*iB; printf("\nggT(%d, %d) = %d",iA,iB,iGgt); printf("\nkgV(%d, %d) = %d",iA,iB,iKgv); return 0; } /*--------------------------------------------------------- */ Ausgabe: ggT und kgV von: 91 156 ggT(91, 156) = 13 kgV(91, 156) = 1092

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 20/9 - 00 - TH/KR - 00

Verschiedene Formulierungen mittels der for-Anweisung /*-----------------------------------------------------------------*/ for(i=0; i<100;i++) printf("%d\n",i); for(i=0; i<100;) { printf("%d\n",i); i++; } for(i=0; i<100;) printf("%d\n",i++); for(i=0; i<100; printf("%d\n",i++)); for(i=0; i<100; printf("%d\n",i), i++); /*-----------------------------------------------------------------*/ iZaehl = 0; for(iZeich=iErstzeich; iZeich != '\n'; iZaehl++, iZeich=getchar()); for(iZaehl=0,iZeich=iErstzeich;iZeich!='\n';iZaehl++,iZeich=getchar()); iZaehl = 0; for(iZeich=iErstzeich; iZeich != '\n'; iZeich=getchar()) iZaehl++; iZaehl = 0; for(iZeich=iErstzeich; iZeich != '\n'; iZeich=getchar()){ iZeich=getchar(); iZaehl++; } /*-----------------------------------------------------------------*/

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 20/10 - 00 - TH/KR - 00

Sprunganweisungen in C break - Anweisung: Spung aus einer switch-Anweisung zur folgenden Anweisung; Beendigung von Schleifenanweisungen (while,do,for) unabhängig vom Abbruchkriterium. continue - Anweisung: Spung zum Ende des gegenwärtigen Schleifendurchlaufes, d.h.

bei while und do: Sprung unmittelbar zur Auswertung der Schleifenbedingung; bei for: Sprung zur Auswertung des Veränderungsausdrucks.

Beispiel: while (Bedingung1) { Anweisung1; if(Bedingung2) continue; Anweisung2; } kann ersetzt werden durch: while (Bedingung1) { Anweisung1; if(!Bedingung2) Anweisung2; }

oder durch: while (Bedingung1) { Anweisung1; if(Bedingung2); else Anweisung2; }

goto - Anweisung: Sprung zu der durch die Marke gekennzeichneten Anweisung. Das Sprungziel muß innerhalb der gleichen Funktion liegen. Sprünge sind zulässig über Blockgrenzen hinweg, aus Kontollstrukturen heraus (while, do, for, if, switch) und in Kontrollstrukturen hinein. ACHTUNG: Sprünge sind meist schlechter Programmierstil !!

;

;

;

break

continue

Marke goto

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 20/11 - 00 - TH/KR - 00

Verzweigungen in C if - Anweisung

( if

Anweisung2else

) Anweisung1Ausdruck

Realisierung der einseitigen und/bzw. zweiseitigen Verzweigung: Ergibt die Auswertung von „Ausdruck“ einen Wert !=0 (TRUE), so wird „Anweisung 1“ ausgeführt. Besitzt „Ausdruck“ den Wert == 0, so wird „Anweisung2“ ausgeführt (bei vorhandenem else-Zweig) oder keine Anweisung ausgeführt (falls kein else-Zweig vorhanden). switch-Anweisung:

) {( switch Ausdruck

case

default

konst. Ausdruck : }Anweisung Realisierung der Auswahl zwischen mehr als zwei Alternativen. • Der dem „switch“ folgende Ausdruck (Verzweigungsausdruck) muß einen ganzzahligen Wert

ergeben (int oder char). • Der dem „case“ folgende Ausdruck (Fallwert) darf nur konstante Operanden enthalten (konstanter

Ausdruck) und muß ebenfalls ein ganzzahliges Ergebnis haben. • Die Fallwerte müssen unterschiedlich sein, ihre Reihenfolge ist beliebig. • Auch die Position der „default“-Marke ist beliebig. Der Verzweigungsausdruck wird ausgewertet und mit allen Fallwerten verglichen. Bei Überein-stimmung wird das Programm mit der hinter dem entsprechenden Fallwert stehenden Anweisung fortgesetzt. Die Fallwerte dienen als Marke für die Programmfortsetzung. Stimmt keiner der Fallwerte mit dem Wert des „Ausdrucks“ überein, so wird das Programm - mit der Anweisung nach der „default“-Marke fortgesetzt, falls diese vorhanden ist; - ansonsten mit der der „switch“-Anweisung folgenden Anweisung fortgesetzt. Die echte Mehrfachauswahl wird erst durch das Einbeziehen der „break“-Anweisung in die „switch“-Anweisung realisiert.

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 20/12 - 00 - TH/KR - 00

Programmbeispiel zur if-Anweisung

/*--------------------------------------------------- */ /* Programm: COUNT1 */ /*--------------------------------------------------- */ /* Ermitteln der Anzahl von "Blanks" und "Newlines" */ /* aus einem ueber "stdin" eingegebenen Text */ /*--------------------------------------------------- */ #include <stdio.h> int main(void) { int iZbl, iZnl; int iZeich; iZbl=iZnl=0; while ((iZeich = getchar()) != EOF) { if(iZeich == ' ') iZbl++; else if(iZeich == '\n') iZnl++; } printf("\nErgebnisse: %4d Blanks%12sNewlines %4d\n",iZbl," ",iZnl); return (0); } ____________________________ Ausgabe bei Aufruf: count1 <count1.c Ergebnisse: 69 Blanks Newlines 26

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 20/13 - 00 - TH/KR - 00

Programmbeispiele zur switch-Anweisung

/* Programm: Antwort1 */ /* Demonstriert switch-Anweisung ohne breaks */ #include <stdio.h> int main(void) { char cZeich; printf("Ihre Wahl (j,v,n) ? "); cZeich = getchar(); switch(cZeich) { case 'j': case 'J': printf("ja\n"); case 'n': case 'N': printf("nein\n"); case 'v': case 'V': printf("vielleicht\n"); default : printf("unbekannt\n"); } return(0); }

Testlauf: Ihre Wahl (j,n,v) ? n nein vielleicht unbekannt /*--------------------------------------------------------*/ /* Programm: Antwort2 */ /* Demonstriert switch-Anweisung mit breaks */ #include <stdio.h> int main(void) { char cZeich; printf("Ihre Wahl (j,v,n) ? "); cZeich = getchar(); switch(cZeich) { case 'j': case 'J': printf("ja\n"); break; case 'n': case 'N': printf("nein\n"); break; case 'v': case 'V': printf("vielleicht\n"); break; default : printf("unbekannt\n"); } return(0); }

Testlauf: Ihre Wahl (j,n,v) ? n nein

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 30/1 - 00 – TH/KR - 00

Kapitel 3: Ausdrücke und Operatoren

3.1 Arithmetische Operatoren 3.2 Vergleichsoperatoren 3.3 Logische Operatoren 3.4 Bitmanipulation 3.5 Zusammengesetzte Zuweisungsoperatoren 3.6 Bedingter Auswerte-Operator 3.7 Rangfole der Operatoren

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 30/2 - 00 – TH/KR - 00

Ausdrücke und Operatoren

• Unter einem Ausdruck versteht man die Verknüpfung von Operanden mittels Operatoren zu einem

neuen Wert. Ein Ausdruck liefert immer einen Wert.

• C besitzt im Vergleich zu anderen höheren Programmiersprachen ein sehr umfangreiches Ausdrucks- und Operatorkonzept: Es gibt unäre, binäre und einen ternären Operator, so bezeichnet nach der Anzahl von Operanden, die sie verknüpfen.

• Die Zuweisung = ist ein Operator. Der Wert eines Zuweisungsausdrucks ist der Wert, der der linken

Seite zugewiesen wird. Beispiel: a=7 hat den Wert 7

• Jeder mit einem ; abgeschlossene Ausdruck ist in C eine Anweisung ⇒ Ausdrucksanweisung.

Auch die Zuweisung wird erst durch ; zur Anweisung Beispiel: a=7; /* Zuweisungsanweisung */

Arithmetische Operatoren (1) • Binäre Operatoren:

+ Addition - Subtraktion * Multiplikation / Division % Modulo-Operator (Rest der Ganzahldivision)

• Unäre Operatoren:

+ Identität - Negation

• Änderung der Ausführungsreihenfolge (Priorität) durch Klammerung:

Beispiel: a = ( b = c / (d + e)) + f ;

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 30/3 - 00 – TH/KR - 00 Arithmetische Operatoren (2) • Unäre Operatoren:

++ Inkrement (Erhöhung des Operanden um 1) -- Dekrement (Verminderung des Operanden um 1)

Die Operatoren ++ und -- können als Prefix- oder als Postfixoperator verwendet werden. Prefix-Operator: ++n bzw. --n Die Veränderung des Operandenwertes erfolgt zunächst, erst dann wird der

veränderte Wert verwendet. Beispiel: n = 5; x = ++n; entspricht: n=n+1; x=n; /* x = 6 */ Postfix-Operator: n++ bzw. n-- Die Verwendung des ursprünlichen Operandenwertes erfolgt zunächst, erst dann

erfolgt die Veränderung des Operanden. Beispiel: n = 5; x = n++; entspricht: x=n; /* x = 5 */ n=n+1; Vergleichsoperatoren • Binäre Operatoren:

< kleiner > größer <= kleiner gleich >= größer gleich == gleich != ungleich

Ergebnis des Vergleichs:

im „wahren“-Fall 1, der Vergleich ist erfüllt ( 5 > 3 ⇒ 1 ) im „falschen“-Fall 0, der Vergleich ist nicht erfüllt ( 5 > 6 ⇒ 0 )

Beispiel:

#include <stdio.h> int main(void) { int i=3, j=3, k=2; printf(“i==j : %d\n“,i == j); /* i==j : 1 */ printf(“i>k : %d\n“,i > k); /* i>k : 1 */ printf(“i<k : %d\n“,i < k); /* i<k : 0 */ return 0; }

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 30/4 - 00 – TH/KR - 00 Logische Operatoren • Obwohl in C kein logischer Datentyp existiert, gibt es logische Operatoren. Die logischen Werte

werden dabei durch Ganzzahldatentypen nachgebildet: Wert == 0 entspricht FALSE Wert != 0 entspricht TRUE Als Ergebnis einer logischen Operation wird für TRUE immer der Wert 1 erzeugt.

• Binäre Operatoren:

&& UND (AND) || ODER (OR)

• Unärer Operator: ! NEGATION ! konvertiert eine Operanden der != 0 (TRUE) ist in den Wert 0, einen

Operanden dessen Wert 0 (FALSE) ist in den Wert 1. Beispiel für die Anwendung: statt: if ( iSWort == 0 ) kann formuliert werden: if( !iSWort )

• Logische Ausdrücke werden von links nach rechts nur soweit ausgewertet, bis der logische Wert

des Ergebnisses feststeht, d.h. im Ausdruck (x && y++) wird y++ nur ausgeführt falls x != 0 ist ⇒ VORSICHT!!

• Logische Operatoren lassen sich auch auf die Fließpunkt-Datentypen anwenden. Beispiel: #include <stdio.h> int main(void) { int c, iZbu, iZzi, iZst, iZso; iZbu = iZzi = iZst = iZso = 0; while((c=getchar()) != EOF ) { if( c <= '\x1F' || c== '\x7F' ) iZst++; /* Steuerzeichen */ else if( c >= '0' && c <= '9' ) iZzi++; /* Ziffern */ else if(( c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) iZbu++; /* Buchstaben */ else iZso++; /* Sonderzeichen */ } printf("Buchstaben = %4d\n", iZbu); printf("Ziffern = %4d\n", iZzi); printf("Sonderzeichen = %4d\n", iZso); printf("Steuerzeichen = %4d\n", iZst); return 0; }

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 30/5 - 00 – TH/KR - 00 Bit-Operatoren Anwendbar nur auf Ganzzahldatentypen. • Binäre Operatoren:

& bitweise UND | bitweise ODER ^ bitweise EXOR (exklusives ODER)

• Unärer Operator:

~ bitweise Negation (Einer-Komplement) • Anwendung: Setzen, Rücksetzen, Invertieren einzelner Bits bzw. Bitgruppen - Maskieren. Beispiele: 1) Löschen aller höherwertigen Bits, die 7 niedrigwertigsten sollen erhalten bleiben: int c,n; ....... c = n & 0x7F; ...... 2) Umwandlung von Kleinbuchstaben in Großbuchstaben (ASCII-Code: Unterschied nur in Bit 5!): char c ...... if( c >= ‘a’ && c <= ‘z’) c = c & 0xDF; ...... 3) Umwandlung von Großbuchstaben in Kleinbuchstaben (ASCII-Code: Unterschied nur in Bit 5!): char c ...... if( c >= ‘A’ && c <= ‘Z’) c = c | 0x20; ...... 4) Nullsetzen der 6 niederwertigen Bits einer int-Größe: int x; ...... x = x & 0xFFC0; ist nur korrekt bei 16-Bit Integerdarstelleung ...... ⇒ u.U. nicht portabel x = x & ~0x3F; unabhängig von der Integerlänge ⇒ jedenfalls portabel

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 30/6 - 00 – TH/KR - 00 Schiebeoperatoren • Binäre Operatoren:

<< Linksschieben >> Rechtsschieben Der linke Operand wird um soviele Stelle (Bits) nach links bzw. rechts geschoben, wie dies der rechte Operand angibt. Linksschieben: Nachschieben von 0. Rechtsschieben: linker Operand ist unsigned ⇒ Nachschieben von 0 linker Operand ist signed ⇒ Nachschieben gemäß Vorzeichen bzw. Nachschieben von 0 (compilerabhängig)

Beispiele: 1) Linksschieben eines Ganzzahlwertes um 2 ⇒ Multiplikation mit 4 int x; ...... x = x << 2; 2) Rechtsschieben eines Ganzzahlwertes um 3 ⇒ Division mit 8 int x; ...... x = x >> 3; 3) Die folgende Codezeile extrahiert aus uiX das uiN-Bit lange Teilfeld, das bei der Bitposition uiP

beginnt und liefert es rechtsbündig zurück. Das Ergebnis wird uiY zugewiesen: unsigned uiX, uiY, uiP, uiN; ........... uiY = ( uiX >> ( uiP - uiN +1)) & ~(~0 << uiN);

0 ............. ....... 0 uiN Bits

uiP uiP-(uiN-1) 0

(uiN-1) 0

Setzt höherwertige Bits 0 Anzahl der Schiebeschritte

uiN Bits uiX

uiY

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 30/7 - 00 – TH/KR - 00 Zusammengesetzte Zuweisungsoperatoren • Als verkürzte Schreibweise für die häufig vorkommenden Ausdrücke der Form

Variable = Variable Operator Ausdruck lässt C zusammengesetzte Zuweisungsoperatoren zu, sie besitzen die folgende Form: Variable Operator= Ausdruck

Beispiel: statt: x = x + 3;

auch: x += 3; • Binäre Operatoren:

+= -= *= /= %= &= |= ^= <<= >>=

• Ein mit einem zusammengesetzten Zuweisungsoperator gebildeter Ausdruck hat - analog zum einfachen Zuweisungsoperator - den Wert, der der linken Seite zugewiesen wird. Beispiel: x = 3 + 5; /* hat den Wert 8 */ x *= 2; /* hat den Wert 16 */

Bedingter Auswerte-Operator • Ternärer Operator:

? : Mit dem bedingten Auswerte-Operator ist folgende Formulierung möglich: (Bedingungsausdruck) ? (Ausdruck1) : (Ausdruck2) Das Resultat dieses Ausdrucks ist: Ausdruck1 falls der Bedingungsausdruck TRUE (!=0) ist, Ausdruck2 falls der Bedingungsausdruck FALSE (==0) ist.

• Anwendung: Ersatz einer mittels einer if-Anweisung formulierten alternativen Wertzuweisung.

Beispiel: Ermittlung des Maximums zweier Variablen. if (a > b) iMax = a; else iMax = b; kann ersetzt werden durch: iMax = (a>b) ? a : b ;

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 30/8 - 00 – TH/KR - 00

Hierarchie der Operatoren in C

Prioritaet Operator Operation Assoziativitaet ( ) Argumentliste 15 *) [ ] Element (Array) → **) . Element (Structure) -> Element (Structure) ~ bitweises Komplement ! Komplement ++ -- Increment/Decrement ← **) - Negation (arithm.) 14 + Identität (arithm.) * Pointer-Objekt & Adresse (type) Typkonvertierung sizeof Groesse in Bytes

13 * / % Mult./Div./Modulo →

12 + - Addition/Subtrakt. →

11 << >> Verschiebung →

10 < > <= >= Vergleich →

9 == != Vergleich →

8 & bitweises UND →

7 ^ bitweises EXOR →

6 | bitweises ODER →

5 && UND →

4 || ODER →

3 ? : bedingte Auswertung ←

= *= /= %= 2 += -= Zuweisung ← <<= >>= &= |= ^= 1 , sequentielle Auswertung → *) 15 hoechste Prioritaet Achtung: Die Assoziativität bestimmt die Ausführungsreihenfolge von Operationen gleicher Priorität: **) → links nach rechts ← rechts nach links

Sie legt nicht die Reihenfolge der Auswertung der beiden Operanden einer 2-stelligen Operation fest.

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 40/1 - 00 – TH/KR - 00

Kapitel 4: Unterprogramme – Funktionen 4.1 Konzept 4.2 Funktionsdefinition 4.3 Funktionsdeklaration 4.4 Funktionsaufruf und Funktionsparameter 4.5 Ein- und Ausgabe über die Konsole 4.5.1 Formatierte Ein-, Ausgabe 4.5.2 Zeichenweise Ein- und Ausgaben 4.6 Der C Präprozessor

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 40/2 - 00 – TH/KR - 00

Funktionen in C

• Funktionen sind die einzige Art von Unterprogrammen in C und bilden die Grundbausteine für

jedes C-Programm. Jede ausführbare Anweisung befindet sich in einer Funktion. Selbst das Hauptprogramm ist eine

Funktion - „main()“.

⇒ Jedes C-Programm enthält die Funktion „main()“ und besteht zu mindest aus dieser einen Funktion.

• Alle Funktionen eines C-Programmes sind statisch nebeneinander - in einer Ebene - angeordnet. ⇒ Die Definition einer Funktion innerhalb einer anderen Funktion ist nicht möglich. • Da jedoch jede Funktion jede andere Funktion in beliebiger Reihenfolge aufrufen kann, läßt sich

eine dynamisch hierarchische Blockstruktur erzeugen. ⇒ Realisierung der formalen Zerlegung (Algorithmen). • In einer Funktion sind jeweils die zu einer Lösung einer Teilaufgabe gehörenden Anweisungen

zusammenzufassen. Es ist darauf zu achten, daß der Umfang einer Funktion nicht zu groß wird, ggf. ist eine weitere Zerlegung der Aufgabenstellung vorzunehmen.

In der erzeugten dynamischen Blockstruktur können und sollten sich die Stufen der schrittweisen Verfeinerung des Lösungsalgorithmus wiederspiegeln.

• Ein typisches C-Programm besteht meist aus zahlreichen „kleinen“ Funktionen. • C unterstützt die modulare Programmierung. Die Gesamtheit der Funktionen eines Programmes läßt

sich auf mehrere - getrennt zu übersetzende - Module aufteilen. Darüberhinaus lassen sich Bibliothektsfunktionen verwenden, die zum Umfang der Programmier-

sprache C gehören. • Funktionen in C treten in drei Formen auf: - als Funktionsdefinition (function definition) - als Funktionsdeklaration (function declaration, prototype) - als Funktionsaufruf (function call) • Bevor eine Funktion verwendet werden kann muß sie vereinbart, d.h. entweder definiert oder

deklariert sein. Für Funktionen der Standardbibliothek existieren zu diesem Zweck „Header“-Dateien, in denen u.a. die Funktionsdeklarationen der verwendbaren Funktionen enthalten sind.

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 40/3 - 00 – TH/KR - 00

Funktionen in C - Funktionsdefinition • Funktionsdefinition:

Speicherklasse Funktionsname FunktionsrumpfParameterliste Funktionstyp

• Parameterliste:

( void

Parameterdeklaration , ...

) • Parameterdeklaration:

Parametertypangabe

,

Parameterbezeichner • Funktionsrumpf:

Deklaration Anweisung

{ }

Typdefinition

Variablendefinition

• Beispiel:

double dMachWas (int iPrm, float fPrm) { int iLocl; ........ }

• Als Datentyp des Funktionswertes sind zulässig:

- Jeder einfache Datentyp, - alle Pointer-Typen, - „struct“-, „union“-, „enum“-Typen - der Typ „void“, - jedoch nicht der „array“-Typ.

• Als Speicherklasse sind zuläßig: „extern“ (Vorgabe): die Funktion kann auch in anderen Modulen verwendet werden.

„static“: die Funktion kann nur in dem Modul verwendet werden, in dem sie definiert ist.

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 40/4 - 00 – TH/KR - 00

Funktionen in C - Funktionsdeklaration • Funktionen, die in einem anderen C-Modul oder im aktuellen Modul erst nach der ersten

Verwendung definiert sind können verwendet werden. Dazu muß die Funktion vor dem ersten Funktionsaufruf deklariert werden. Man unterscheidet folgende Arten von Deklarationen:

Extern - Deklaration: Funktionen eines anderen Moduls oder Bibliotheksfunktion Vorwärts - Deklaration: Definition der Funktion erfolgt im gleichen Modul weiter unten. • Es ist guter Programmierstil alle im Modul verwendeten Funktionen zu Beginn des Moduls zu

deklarieren - Angabe der Funktionsprototypen.. Dies erhöht die Übersichtlichkeit und Lesbarkeit von C-Programmen.

• Funktionsdeklaration:

Speicherklasse Funktionsname ; Parameterliste Funktionstyp

• Parameterliste: ( void

Parameterdeklaration , ...

) • Parameterdeklaration: Parametertypangabe

,

Parameterbezeichner • Ziel: Der Compiler wird in die Lage versetzt Typ und Anzahl der Parameter zu überprüfen. • Beispiel:

double dMachWas (int, float);

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 40/5 - 00 – TH/KR - 00

Funktionen in C - Funktionsaufruf, Parameterübergabe und Funktionswert Funktionsaufruf:

( )

aktueller Parameter oder Ausdruck

,

Funktionsname • Ein Funktionsaufruf kann als Operand in einem Ausdruck stehen, kann aber auch alleine als

Ausdrucksanweisung verwendet werden.

Z.B.: printf(" Servus! \n"); /* Ausdrucksanweisung */

In diesem Fall wird der Funktionswert ignoriert. Funktionen, die keinen Wert zurückliefern ( Funktionen vom Typ "void"), lassen sich nur in Form einer Ausdrucksanweisung anwenden.

Parameter: • Die Anzahl aktueller Parameter muß mit der Anzahl formaler Parameter

übereinstimmen(Ausnahme: Funktionen mit variabler Parameteranzahl). • Der Typ eines aktuellen Parameters muß mit dem Typ des formalen Parameters nach den Regeln

der impliziten Typumwandlung korrespondieren. Z.B. ein aktueller int-Wert kann an einen formalen double-Parameter übergeben werden.

Funktionswert: • Die Erzeugung und Rückgabe eines Funktionswertes erfolgt mittels der „return“-Anweisung

Ausdruck ; return • Beispiel: return a+b; • Hinweis: Der Ausdruck nach „return“ kann in runden Klammern stehen. • Wirkung: Der Ausdruck wird ausgewertete und ggf. in den Typ des Funktionswertes

umgewandelt (Regeln der impliziten Typumwandlung). Anschließend wird die Funktion beendet und bei der aufrufenden Funktion fortgesetzt.

• In einer Funktion kann die „return“-Anweisung auch ganz fehlen, damit wird dieselbe Wirkung

erzielt wie durch das Weglassen des „Ausdrucks“ der „return“-Anweisung. Dies ist lediglich bei Funktionen mit „void“ als Typ des Funktionswertes zulässig.

• Eine Funktion kann auch mehrere „return“-Anweisungen besitzen.

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 40/6 - 00 – TH/KR - 00

Funktionen in C - Beispiele (1)

Name des Quellmoduls: AD7_A.C (Vergleiche AD - V - 20/6) /*------------------------------------------------------ */ /* Funktion: iGgTeil */ /*------------------------------------------------------ */ /* Ermitteln des groessten gemeinsamen Teilers (ggT) */ /* zweier natuerlicher Zahlen iA und iB. */ /* Es gilt: kgV(iA,iB) = (iA*iB)/ggT(iA,iB) */ /*------------------------------------------------------ */ #include <stdio.h> int iGgTeil(int, int); /* Funktionsprototypen am Modulbeginn */ int iKgViel(int, int); /* dienen auch als „Inhaltsübersicht“ */ int iGgTeil(int iA, int iB) { int iP,iQ,iR; int iGgt; if(iA>iB){ /* groessere der beiden Zahlen ermitteln */ iP = iA; iQ = iB; } else { iP = iB; iQ = iA; } do { /* Fortgesetzte Division bis Rest gleich 0 */ iR = iP%iQ; iP = iQ; iQ = iR; } while(iR); iGgt = iP; return iGgt; } /*------------------------------------------------------ */ /* Funktion: iKgViel */ /*------------------------------------------------------ */ /* Ermittelt das kleinste gemeinsame Vielfache (kgV) */ /* zweier natuerlicher Zahlen iA und iB. */ /* Es gilt: kgV(iA,iB) = (iA*iB)/ggT(iA,iB) */ /*------------------------------------------------------ */ int iKgViel(int iA, int iB) { return iA*iB / iGgTeil(iA,iB); }

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 40/7 - 00 – TH/KR - 00

Funktionen in C - Beispiele (2) Modul: AD7.C /*----------------------------------------------------------- */ /* Programm: Rationale Zahlen */ /*----------------------------------------------------------- */ /* Demonstriert den Umgang mit Funktionen */ /*----------------------------------------------------------- */ #include <stdio.h> /* Deklaration der Funktionen des Moduls AD7_A */ int iGgTeil(int, int); int iKgViel(int, int); /* Typdefinition */ struct ratio { int iZaehl; int iNenn; }; /* Deklarationen fuer das aktuelle Modul - Vorwaertsdeklaration */ struct ratio addratio(struct ratio, struct ratio); struct ratio kuerze(struct ratio); int main(void) { struct ratio sA,sB,sC; printf("\nGib Zaehler und Nenner der 1.Zahl: "); scanf ("%d%d",&sA.iZaehl,&sA.iNenn); printf("\nGib Zaehler und Nenner der 2.Zahl: "); scanf ("%d%d",&sB.iZaehl,&sB.iNenn); sC = addratio(sA,sB); sC = kuerze(sC); printf("\n%d/%d + %d/%d = %d/%d", sA.iZaehl,sA.iNenn, sB.iZaehl,sB.iNenn, sC.iZaehl,sC.iNenn); /* Getrennte Darstellung des ganzzahligen und echtgebrochenen Anteils: */ printf(" = %d %d/%d\n ",sC.iZaehl/sC.iNenn, sC.iZaehl%sC.iNenn, sC.iNenn); return(0); } struct ratio kuerze(struct ratio sP) { int iZw; iZw = iGgTeil(sP.iZaehl,sP.iNenn); sP.iZaehl = sP.iZaehl / iZw; sP.iNenn = sP.iNenn / iZw; return sP; } struct ratio addratio(struct ratio sP, struct ratio sQ){ struct ratio sL; sL.iZaehl = sP.iZaehl*sQ.iNenn + sP.iNenn*sQ.iZaehl; sL.iNenn = sP.iNenn*sQ.iNenn; return sL; }

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 40/8 - 00 – TH/KR - 00

Funktionen in C - Beispiele (3) Hinweise zur Weiterarbeit: 1.) Erläutern Sie was geschieht, wenn man die Addition 512/13 + 39/64 durchführt!

Zeigen Sie auf welche Grenzen erreicht werden und wie diese überwunden werden können.

2.) Realisieren Sie die Funktionen kuerze() und addratio() mit vorzeichenbehafteten

Ganzzahlgrößen! 3.) Erweitern Sie die Ratioarithmetik um die Multiplikation mulrat() und die

Division divrat(). 4.) Überlegen Sie sich eine geeignete Datenstruktur zur Darstellung komplexer

Zahlen z, bei der sowohl der Real- als auch der Imaginärteil rationale Zahlen sind.

5.) Realisieren Sie die Grundrechenarten (+,-,*,/) für diese Methode der komplexen

Zahlendarstellung.

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 45/9 - 00 – TH/KR - 00

Formatierte Ein-/Ausgabe Headerdatei: stdio.h • printf()

Formatierte Bildschirmausgabe. Prototyp: int printf (“Formatstring“, Argument1, Argument2, ... , ArgumentN) Der Formatstring steuert die Ausgabe der Argumente. Für jedes Argument ist eine Formatierung erforderlich. Zusätzlich kann der Formatstring Zeichen und Zeichenersatzdarstellungen enthalten. Funktionswert: Anzahl der ausgegebenen Zeichen.

• scanf()

Formatierte Bildschirmeingabe. Prototyp: int scanf (“Formatstring“, &Argument1, &Argument2, ... , &ArgumentN)

Funktionswert: Anzahl der Eingabefelder, die erfolgreich konvertiert werden konnten. EOF wird

zurückgegeben, falls ein Fehler auftrat.

Der Formatstring steuert das Einlesen der Argumente. Für jedes Argument ist eine Formatierung erforderlich. Im Gegensatz zu printf() sind bei scanf() die Adressen der Argumente einzugeben.

• Beispiele:

int iVal; printf (“Hello World!\n“); printf (“Anzahl der Iterationen:“); scanf (“%d “,&iVal);

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 45/10 - 00 – TH/KR - 00

Ein- / Ausgabeformate • Allgemeine Form:

% [Flags] [Breite] [.Präzision] [Argumentgröße] Typ

• Flags - Linksbündige Ausgabe (Standard rechtsbündig). + Ausgabe eines ‚+‘-Vorzeichens bei numerischen Daten. ‚ ‚ Ein führendes Leerzeichen wird bei positiven Zahlen ausgegeben.

• Breite

Minimale Größe des Ausgabefeldes ggf. Ergänzung mit „blanks“. Das Feld wird automatisch erweitert falls die Feldlänge zu gering ist. Beginnt die Breite mit 0 so werden führende Nullen eingesetzt. * als Feldlänge verweist auf die Angabe als Parameter vor dem Ausgabeargument.

• Präzision

.0 Der Dezimalpunkt und überflüssige Nullen bei den Typen e,E,f werden nicht ausgegeben.

.n Ein Gleitkommawert wird mit n Nachkommastellen ausgegeben, ein String mit maximal n Stellen. .* Der nächste ganzzahlige Parameter wird als Genauigkeit interpretiert.

• Argumentgröße h Ganzzahlige Typen werden als „short“ interpretiert (uh für unsigned) l Ganzzahlige Typen werden als „long“ (ul für unsigned), Gleitkommatypen als „double“ interpretiert. L Gleitkommatypen werden als „long double“ interpretiert.

• Typ

d, i Ganzzahlige Dezimalzahl o Ganzzahlige Oktalzahl x, X Ganzzahlige Hexadezimalzahl f Vorzeichenbehaftete Gleitkommazahl e, E Vorzeichenbehaftete Gleitkommazahl, wissenschaftliche Darstellung g, G Vorzeichenbehaftete Gleitkommazahl, längenoptimiert zwischen e- und f-Typ c Zeichen s Stringbezeichner - genauer: Zeiger auf einen String

Beispiele: int iVal = 1; double dVal = 1.2; char* pStr = "Ende der Ausgabe"; printf ("die ganze Zahl %3d, die Gleitkommazahl %10.2lf\n",nVal,dVal); printf ("und ein String: %s\n",pStr); Ausgabe: die ganze Zahl 1, die Gleitkommazahl 1.20 und ein String: Ende der Ausgabe

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 45/11 - 00 – TH/KR - 00

Weitere Beispiele zur formatierten Ein-/Ausgabe:

#include <stdio.h> int main(void) { int iSch,iVal=1; double dVal=1.2; char * psVal = "Ende der Ausgabe"; printf("\nA U S G A B E:\n"); /* A U S G A B E: */ printf(":%+10d:\n",iVal); /* : +1: */ printf(":%10.2lf:\n",dVal); /* : 1.20: */ printf(":%010.2lf:\n",dVal); /* :0000001.20: */ printf(":%+10.2lf:\n",dVal); /* : +1.20: */ printf(":%- 10.2lf:\n",dVal); /* : 1.20 : */ printf(":%10.4lf:\n",dVal); /* : 1.2000: */ printf(":%10.2le:\n",dVal); /* : 1.2e+00: */ printf(":%*.*s:\n",10,5,psVal); /* : Ende : */ iSch = scanf("%d %lf",&iVal,&dVal); /* Eingabe: 2345 7.98 */ printf("Ergebnis: %d Ganzzahlwert: %d FP-Wert: %lf\n",iSch,iVal,dVal); /*Ergebnis: 2 Ganzzahlwert: 2345 FP-Wert: 7.980000*/ }

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 45/12 - 00 – TH/KR - 00

Zeichenweise Ein-/Ausgabe Headerdatei: stdio.h getchar(): Zeichenweise Eingabe von stdin (Tastatur) int getchar(void); Liest das nächste Zeichen von stdin. Funktionswert: Gelesenes Zeichen bzw EOF (==-1) bei Eingabe des Fileendezeichens ( Ctrl Z). putchar(): Zeichenweise Ausgabe nach stdout (Bildschirm) int putchar(int); Parameter: auszugebendes Zeichen. Funktionswert: Ausgegebenes Zeichen, EOF (==-1) im Fehlerfall. Headerdatei: conio.h (keine ANSI-C-Bibliothek) getch(): Ungepufferte Eingabe von der Tastatur. int getch(void); Funktionswert: Gelesenes Zeichen. getche(): Ungepufferte Eingabe von der Tastatur mit Zeichenecho zum Bildschirm. int getche(void); Funktionswert: Gelesenes Zeichen. kbhit(): Wartet auf das Drücken einer Taste (keyboard hit). int kbhit(void); Funktionswert: !=0 falls ein Tastendruck vorliegt (entspricht nicht dem ASCII-Code der Taste). clrscr(): Löscht den Bildschirm (clear screen). void clrscr(void);

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 45/13 - 00 – TH/KR - 00

Zeichenersatzdarstellung

Für Zeichen, die im Quellcode nicht sichtbar dargestellt werden oder Zeichen denen eine feste syntaktische Zuordnung entspricht gibt es zur Darstellung in Strings und für die Ausgabe Zeichenersatzdarstellungen:

Zeichen Darstellung ASCII-Code(hex) New Line <LF> \n 0x0A Carriage Return <CR> \r 0x0D Form Feed <FF> \f 0x0C Back Space <BS> \b 0x08 Horizontal Tab <HT> \t 0x09 Vertical Tab <VT> \v 0x0B Bell <BEL> \a 0x07 Backslash \ \\ 0x5C Question Mark ? \? 0x3F Single Quote ‘ \’ 0x27 Double Quote “ \“ 0x22

Bitmuster - oktal: \zzz mit zzz 1-3 Oktalstellen Bitmuster - hexadezimal: \xss mit ss 1-2 Hexadezimalstellen Beispiele: ‘A’ ↔ ‘\101’ ↔ ‘\x41’ ‘o’ ↔ ‘\60’ ↔ ‘\x30’ ‘\n’ ↔ ‘\x0A’ printf(“\t\t\“Hallo!\“\r\n“);

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 46/14 - 00 – TH/KR - 00

Der C-Präprozessor (1) Vor dem eigentlichen Übersetzungsvorgang wird der Quelltext eines C-Programmes durch den Präprozessor behandelt. Dieser nimmt Manipulationen an dem Quelltext selbst vor. Die Art der Änderungen, die die Quelle dadurch erfährt wird mittels Präprozessoranweisungen (Direktiven) gesteuert. Die Präprozessoranweisungen beginnen mit # als erstem Zeichen einer Zeile. • Einbinden von Textdateien:

#include “dateibezeichnung“ oder #include <dateibezeichnung> Die mit dateibezeichnung spezifizierte Datei wird an der Stelle an der sich diese Direktive im Quelltext befindet eingesetzt. Bei <dateibezeichnung> in spitzen Klammern wird die Datei in einem durch die Implementierung voreingestelltem Directory gesucht. Bei “dateibezeichnung“ in Anführungszeichen erfolgt die Suche zunächst im aktuellen Directory und dann im Systempfad. Anwendung - Header-Dateien: Zusammenfassen von Deklarationen, Typdefinitionen und weiteren Präprozessordirektiven in einer eigenen Datei, die damit für weitere Quelldateien zur Verfügung stehen und z:B. die Schnittstelle zu anderen Modulen beschreiben. Die Vereinbarungen für verfügbare Bibliotheksroutinen werden ebenfalls in „Header-Dateien“ bereitgestellt, die zur Verwendung in den Quelltext einzubeziehen sind. Beispiel: #include <stdio.h>

• Definition eines Namens für eine Zeichenfolge #define NAME zeichenfolge Der Quelltext wird nach „NAME“ durchsucht, jedes Auftreten von „NAME“ wird durch „zeichenfolge“ ersetzt. Innerhalb von Strings erfolgt keine Ersetzung. „NAME“ muß den Syntaxregeln für C-Namen entsprechen. „zeichenfolge“ ist die gesamte restliche Zeile ohne führende und abschließende „Blanks“. Anwendung: Definition symbolischer Konstante, die üblicherweise mit Großbuchstaben geschrieben werden. Beispiel: #define EOF (-1) Eine Neudefinition von Namen ist nur möglich, wenn eine bestehende Definition zuvor aufgehoben wird: #undef NAME

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 46/15 - 00 – TH/KR - 00

Der C-Präprozessor (2) • Parametrisierte Makros:

#define name(parameterliste) zeichenfolge „parameterliste“ enthält durch Kommata getrennt formale Parameter, die in „zeichenfolge“ enthalten sein müssen. Wiederum findet reine Textersetzung statt, wobei die aktuellen Parameter die in „zeichenfolge“ enthaltenen formalen Parameter ersetzen. Anwendung: Ersatz von kurzen einfachen Funktionen. Beispiel: #define sqr(x) ((x)*(x)) der „Aufruf“ sqr(a+b) wird vom Präprozessor durch ((a+b)*(a+b)) ersetzt. Eine Reihe von „Funktionen“ der Standardbibliothek sind tatsächlich als Makros ausgeführt.

• Steuerung des bedingten Preprocessings und der bedingten Kompilierung: #if konst_ausdruck #ifdef name (#if defined name) #ifndef name (#if ! defined name) #elif konst_ausdruck #else #endif Der Quelltext der nach einer der Bedingungsdirektiven steht wird nur dann ausgewertet, wenn die Bedingung zutrifft. Für „konst_ausdruck“ gilt ( != 0 entspricht TRUE). Die Bedingung endet jedenfalls mit #endif, die #if-Direktiven können geschachtelt werden. Beispiel: #ifndef PI #define PI (2*acos(0)) #endif #if (PROZ > P2) printf(“Schnelles System“); #else print(“Langsames System“); #endif

• Weitere Präprozessoranweisungen: #line konstante [“dateiname“] Zeilennummer der Quelle festlegen #pragma zeichenfolge [parameter] Frei für Implementierung #error zeichenfolge Eigene Fehlermeldung formulieren

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 46/16 - 00 – TH/KR - 00

Programmbeispiel /* Berechnung der Fläche unter einer Kurve - bestimmtes Integral */ #include <stdio.h> #include <math.h> #ifndef PI /* falls PI nicht in der Std.Bibliothek enthalten */ #define PI (2*acos(0)) #endif #define dFunc(x) (dPoly(x)) /* Einige weitere Funktionen - Copy-Paste-Neukompilieren !! #define dFunc(x) (dKreis(x)) #define KREIS #define dFunc(x) (d3Eck(x)) */ double dKreis (double); double dPoly (double); double d3Eck (double); double dTrapez_V (double, double, double); /* oberer Halbkreis mit Radius 1 */ /* Flaeche ergibt Pi/2. */ double dKreis (double dX) { double dR = 1.; double dY; if (dX > 1.) return 0.; if (dX < -1.) return 0.; dY = sqrt (dR*dR - dX*dX); return dY; } /* Polynom 2. Grades */ double dPoly (double dX) { return(dX*dX* - 6*dX + 7); } /* Dreieck mit (-1,0) (0,1) (1,0) */ double d3Eck (double dX) { if (dX > 1) return 0; else if (dX < -1) return 0; else if (dX >= 0) return (1-dX); else return (1+dX); } void main(void) { double dXo = 1., dXu = -1.; /* Integrationsgrenzen */ double dEps = 1.e-5; /* Genauigkeit */ double dF; /* Fläche */ dF = dTrapez_V (dXu,dXo,dEps); printf (" Xu: %8.4f, Xo: %8.4f, F: %12.8f Eps: %10.3e\n",dXu,dXo,dF,dEps); #ifdef KREIS printf (" Pi(berechnet): %15.10lf\n, Pi(Biblioth.): %15.10lf\n", 2*dF,PI); #endif }

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 46/17 - 00 – TH/KR - 00

Programmbeispiel (Forts.)

/******************************************************************* Integration mittels Trapezverfahren Eingabe: dXa: Untere Grenze dXb: Obere Grenze dEps: geforderte Genauigkeit Global: double dFunc (double) Funktion, über die zu integrieren ist. Rückgabe: Fläche *******************************************************************/ double dFunc(double); /* Zu integrierende Funktion */ double dTrapez_V( double dXa, double dXb, double dEps ) { long int i; double dFl = 0.; /* letzter Integralwert */ double dFa = 0.; /* aktueller Integralwert */ double dH; /* Schrittweite */ double dX; /* X-Wert */ double dErr; /* Fehler */ long int n = 1; /* Anzahl der Intervalle */ /* Schleife ueber die unterschiedlichen Schrittweiten dH */ do { dH = (dXb - dXa)/n; /* Schrittweite bestimmen */ dFa = (dFunc(dXa) + dFunc(dXb))/2; for (i=1; i < n-1; i++) { dX = dXa + dH*i; dFa += dFunc (dX); } dFa *= dH; if (dFa) dErr = fabs((dFa - dFl)/dFa); printf (" -> Durchlauf %3ld: F = %12.8f (Fehler: %10.3e)\n", n,dFa,dErr); dFl = dFa; n++; } while ( dErr > dEps); return dFa; } /*********************************************************** Ausgabeauszug bei Probelauf mit vorhergehendem main() . . . -> Durchlauf 140: F = 13.98209304 (Fehler: 1.11e-05) -> Durchlauf 141: F = 13.98224518 (Fehler: 1.09e-05) -> Durchlauf 142: F = 13.98239483 (Fehler: 1.07e-05) -> Durchlauf 143: F = 13.98254205 (Fehler: 1.05e-05) -> Durchlauf 144: F = 13.98268689 (Fehler: 1.04e-05) -> Durchlauf 145: F = 13.98282942 (Fehler: 1.02e-05) -> Durchlauf 146: F = 13.98296968 (Fehler: 1.00e-05) -> Durchlauf 147: F = 13.98310774 (Fehler: 9.87e-06) Xu: -1.0000, Xo: 1.0000, F: 13.98310774 Eps: 1.00e-05 ***********************************************************/

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 50/1 - 00 – TH/KR - 00

Kapitel 5: Nähere Betrachtung der Datentypen in C 5.1 Felder (Arrays) 5.1.1 Eindimensionale Arrays 5.1.2 Zeichenketten - Strings 5.1.3 Mehrdimensionale Arrays 5.2 Typumwandlung 5.2.1 Implizite Typumwandlung 5.2.2 Explizite Typumwandlung 5.3 Verfügbarkeit und Lebensdauer – Speicherklassen 5.3.1 Verfügbarkeit und Lebensdauer 5.3.2 Speicherklassen

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 50/2 - 00 – TH/KR - 00

Eindimensionale Arrays

• Syntaxdiagramm für die Vereinbarung einer Array-Variablen (Auszug):

Beispiel: #define ANZ 80

char cKette[ANZ]; double dVektor[2*ANZ+1];

• Die Indexgrenzen sind wie folgt fesgelegt: Untere Grenze: 0 Obere Grenze : Komponentenzahl - 1 Beispiel: int iFeld[5] ⇒ Indexbereich 0 ... 4

Die Abspeicherung der Arraykomponenten erfolgt in aufeinanderfolgenden Speicherplätzen. Beispiel: Array mit 5 Komponenten

• Zugriff zu einer Arraykomponente:

Angabe des Index in eckigen Klammern nach dem Arrayvariablennamen. Beispiel: iFeld [ 3 ], cKette [ i + 2*j ]

• Die Längenangabe in Array-Vereinbarungen darf fehlen: bei der Definition initialisierter Arrays bei Arrays als formale Funktionsparameter (Parameterdeklaration) in Array-Variablen-Deklarationen

• Bei der Definition ist eine gleichzeitige Initialisierung von Arrays möglich. Syntaxdiagramm: Beispiel: #define AWERT 5 int iFeld [ ] = { 2, AWERT, 2*AWERT, -3 }; /* Array mit 4 Komponenten */

Komponententyp Variablenname konst.Ausdruck ] [

[ 0 ]

[ 1 ]

[ 2 ]

[ 3 ]

[ 4 ]

4

1.Komponente

2. Komponente

3. Komponente

4. Komponente

5. Komponente

iFeld

konst.Ausdruck } {

,

= Arrayvariablendefinition

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 50/3 - 00 – TH/KR - 00

Zeichenketten in C

• Zeichenketten - Strings - in C sind Arrays mit dem Elementtyp char. Die Elemente solcher Arrays

sind die einzelnen Zeichen des Strings abgeschlossen mit dem NUL-Zeichen (‘\0’). Das NUL-Zeichen (‘\0’) markiert das Ende des Strings.

⇒ Eine char-Array-Variable, die einen String aufnehmen soll muss wenigstens um eine

Komponente länger sein, als der String lang ist. Beispiel: char caWort[4]; ⇒ Die Variable caWort kann Strings mit der maximalen Länge 3 aufnehmen, etwa:

d

e

r

\0

caWort ⇒caWort [0] = ‘d’; caWort [0] = ‘e’; caWort [0] = ‘r’; caWort [0] = ‘\0’;

• char-Arrays können mit einer String-Konstanten initialisiert werden:

statt: char caWort[ ] = {‘d’,’e’,’r’,’\0’}; kann auch geschrieben werden: char caWort [ ] = “der“;

• Der Sprachumfang von C enthält keine besonderen Elemente zur Manipulation von Strings. Es ist insbesondere nicht möglich einer char-Array-Variablen einen ganzen String geschlossen zuzuweisen.

• Für die Bearbeitung von Strings existieren eine Reihe von Funktionen in der C-Standard-Bibliothek - <string.h>.

• Für die Ausgabe von Strings können die Funktionen: printf( ) und puts( ) für die Eingabe die Funktionen scanf() und gets( ) verwendet werden (siehe unten).

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 50/4 - 00 – TH/KR - 00

Programmbeispiel zu Strings /*-------------------------------------------------------- */ /* Programm: String-Demo (1) */ /*-------------------------------------------------------- */ /* Demonstriert den Umgang mit Zeichenketten - Strings */ /*-------------------------------------------------------- */ #include <stdio.h> int main(void) { char caSatz[] = "String in C"; int i = 0; printf("\n%s:\n",caSatz); while (caSatz[i] != '\0') { printf("%c = %02x\n",caSatz[i],caSatz[i]); i++; } printf(" = %02x\n",caSatz[i]); return(0); } /*-------------------------------------------------------- */ Ausgabe: String in C: S = 53 t = 74 r = 72 i = 69 n = 6e g = 67 = 20 i = 69 n = 6e = 20 C = 43 = 00

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 50/5 - 00 – TH/KR - 00

Funktionen der C-Standardbibliothek zur Stringbearbeitung (1) Headerdatei: stdio.h • gets ( ): Einlesen eines Strings.

Prototyp: char * gets( char * str); Liest Zeichen von stdin bis das nächste Zeilenende-Zeichen ‘\n’ oder Dateiende EOF auftritt. Der String wird in dem durch den Übergabeparameter str spezifizierten Array ohne ‘\n’ aber mit ‘\0’ abgelegt. Parameter: Zeiger auf char-Array - char * str. Funktionswert: - übergebener Zeiger - NULL-Pointer falls Dateiende ohne vorheriges Lesen erreicht wird, oder sonst ein Lesefehler vorliegt.

• puts( ): Ausgeben eines Strings. Prototyp: int puts( const char * str); Der durch das char-Array - char * str - referenzierte String wird an stdout ausgegeben. Das abschließende ‘\0’-Zeichen wird dabei durch ein ‘\n’-Zeichen ersetzt. Parameter: str Zeiger auf char-Array. Funktionswert: - nicht negativer Wert bei fehlerfreier Ausgabe, - EOF (-1) im Fehlerfall.

Beispiel: /*--------------------------------------------------------- */ /* Programm: String-Demo (2) */ /*--------------------------------------------------------- */ #include <stdio.h> #define MAXL 30 int main(void) { char caWort[MAXL]; int i = 0; printf("\nString eingeben: "); /*scanf("%s",caWort); */ /* liest nur bis zum "white space character" */ /* und bricht also bei blanks und tabs ab */ gets(caWort); /* liest bis zum naechsten '\n' */ printf("o.k.: %s\n",caWort); puts(caWort); /* gibt aus und ersetzt ‘\0’ durch ‘\n’ */ while (caWort[i] != '\0') { printf("%c = %02x\n",caWort[i],caWort[i]); i++; } printf(" = %02x\n",caWort[i]); }

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 50/6 - 00 – TH/KR - 00

Funktionen der C-Standardbibliothek zur Stringbearbeitung (2) Headerdatei: string.h • strcpy( ): String kopieren.

Prototyp: char * strcpy(char * s1, const char * s2); Kopiert String s2 (Quellstring) in den String s1 (Zielstring). Parameter: Pointer auf den Zielstring s1, Pointer auf den Quellstring s2. Funktionswert: Pointer auf den Zielstring s1.

• strcat( ): Anhängen eines Strings. Prototyp: char * strcat( char * s1, const char * s2); Der String s2 wird an den String s1 angehängt. Parameter: Pointer auf den Zielstring s1, Pointer auf den Quellstring s2. Funktionswert: Pointer auf den resultierenden String, d.h. s1.

• strcmp(): Vergleich zweier Strings. Prototyp: int strcmp( const char * s1, const char * s2); Die Strings s1 und s2 werden lexigrafisch verglichen. Parameter: Pointer auf den ersten String s1, Pointer auf den zweiten String s2. Funktionswert: < 0 wenn s1 „kleiner“ als s2, ==0 wenn s1 „gleich“ s2, > 0 wenn s1 „größer“ s2.

• strlen(): Länge eines Strings ermitteln. Prototyp: size_t strlen( const char * s); Ermittelt die Länge des Strings s in Anzahl von Bytes, ohne abschließendes ‘\0’-Zeichen. Parameter: String s. Funktionswert: Anzahl der Bytes des Strings s. Anmerkung: „size_t“ ist der „natürliche Ganzzahltyp“ und in <string.h> definiert.

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 50/7 - 00 – TH/KR - 00

Programmbeispiel zu Stringfunktionen

/*---------------------------------------------------------- */ /* Programm: String-Demo (3) */ /*---------------------------------------------------------- */ /* Demonstriert Funktionen mit Zeichenketten - Strings */ /*---------------------------------------------------------- */ #include <stdio.h> #include <string.h> #define MAXL 40 int main(void) { char caWort1[MAXL] = "Hallo C-Freunde ", caWort2[MAXL]; printf("\nString eingeben: "); gets(caWort2); printf("o.k.: %s\n",caWort2); if (strlen(caWort1)+strlen(caWort2) < MAXL) { strcat(caWort1,caWort2); } else { printf("zu wenig Platz!!\n"); strcpy(caWort1,caWort2); } printf("%s\n",caWort1); } /*------------------------------------------------------------- */ 1. Programmlauf: String eingeben: wie geht's? o.k.: wie geht's? Hallo C-Freunde wie geht's? /*------------------------------------------------------------- */ 2. Programmlauf: String eingeben: Dies ist ein Text, der zu lang ist! o.k.: Dies ist ein Text, der zu lang ist! zu wenig Platz!! Dies ist ein Text der zu lang ist! /*------------------------------------------------------------- */

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 50/8 - 00 – TH/KR - 00

Funktionen der C-Standardbibliothek zur Stringbearbeitung (3) Headerdatei: stdio.h • sscanf( ): Formatierte Eingabe aus einem String.

Prototyp: int sscanf (char * str, “Formatstring“, &Argument1, &Argument2,..., &ArgumentN); Aus dem String str werden die in „Formatstring“ festgelegten Werte entnommen und den Argumenten zugewiesen (exakt wie bei „scanf( )“). Parameter: str: Pointer auf zu bearbeitenden String, Formatstring: Enthält die Formatierung für jedes Argument, Argument: Variable dessen Typ und Format in „Formatstring“festgelegt ist. Funktionswert: Anzahl der Eingabefelder, die erfolgreich konvertiert werden konnten, EOF im Fehlerfall.

• sprintf( ): Formatierte Ausgabe in einen String. Prototyp: int sprintf (char * str, “Formatstring“, Argument1, Argument2,..., ArgumentN); Die in „Formatstring“ festgelegten Formate werden den Argumenten zugewiesen und in dem String str hinterlegt(exakt wie bei „printf( )“), abgeschlossen mit dem ‘\0’-Zeichen. Parameter: str: Pointer auf zu bearbeitenden String, Formatstring: Enthält die Formatierung für jedes Argument (vgl. „printf()“), Argument: Variable dessen Typ und Format in „Formatstring“festgelegt ist. Funktionswert: Anzahl der Zeichen, die in str abgelegt wurden (ohne ‘\0’). EOF im Fehlerfall.

Headerdatei: string.h strchr( ): String nach Zeichen durchsuchen strstr( ): String nach einem Teilstring durchsuchen. Prototypen: char * strchr( const char *str1, int c); char * strstr( const char *str1, const char * str2); Durchsucht den String str auf das erste Auftreten des Zeichens c bzw. des Strings str2. Parameter: str1 zu durchsuchender String, c/str2 zu suchendes/r Zeichen/Teilstring, Funktionswert: Pointer auf die Stelle im String str1, an der c bzw. str2 erstmals auftritt, NULL-Pointer falls c bzw. str2 nicht in str1 enthalten ist.

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 513/9 - 00 – TH/KR - 00

Mehrdimensionale Arrays in C • Elemente von Arrays können wiederum Arrays sein --> 2-dimensionale Arrays Beispiel: int mat [3][4];

⇒ mat ist ein 3-elementiges Array, dessen Elemente int-Arrays mit jeweils 4 Elementen sind 1.Index (=3) Anzahl der Zeilen 2.Index (=4) Anzahl der Spalten

• Entsprechend obiger Interpretation 2-dimensionaler Arrays erfolgt die Speicherung zeilenweise: mat → [0] [0]

[0] [1]

[0] [2]

[0] [3]

[1] [0]

[1] [1]

[1] [2]

[1] [3]

[2] [0]

[2] [1]

[2] [2]

1.Zeile

2.Zeile

3.Zeile

[2] [3]

• Analog können auch mehr als 2-dimensionale Arrays definiert werden. Die Speicherung erfolgt

immer so, daß sich der letzte Index am häufigsten ändert. • Ansprechen einer Array-Komponente: Der Index jeder Dimension ist getrennt in eckigen KLammern anzugeben.

Beispiel: mat[0][1] = 1; mat2[j+3] [k+1] = 7; • Sind mehrdimensionale Arrays Funktionsparameter, so darf in der Parameterdeklaration die

Größenangabe für die 1. Dimension ("Zeile") weggelassen werden. Die Größenangaben für die übrigen Dimensionen sind dagegen immer notwendig.

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 513/10 - 00 – TH/KR - 00

Mehrdimensionale Arrays in "C"(2) * Initialisierung mehrdimensionaler Arrays

• Angabe von sovielen Initialisierungswerten, wie Array-Elemente vorhanden sind. Die Größenangabe für die 1.Dimension ("Zeile") darf entfallen. Die Angabe der Initialisierungswerte kann mit oder ohne Kennzeichnung der Array-Struktur erfolgen.

- Beispiel: int mat[][4] = { { 1, 4, 3, -4 },

{ 2, 0, -3, 1 }, { 0, -5, 6, 0 } };

oder int mat[][4] = { 1, 4, 3, -4, 2, 0, -3, 1, 0, -5, 6, 0 };

⇒ Definition und Initialisierung eines 3*4 int-Arrays.

• Angabe von weniger Initialisierungswerten als Array-Elemente vorhanden sind:

Im allgemeinen sind für alle Dimensionen Größenangaben erforderlich. Bei Eindeutigkeit über die Arraygröße kann die Größenangabe für die 1. Dimension jedoch weggelassen werden. Nicht belegte Elemente werden mit 0 vorbesetzt.

Die Kennzeichnung der Array-Struktur bei den Initialisierungswerten ist notwendig, wenn Elemente "innerhalb" des Arrays durch fehlende Angabe mit 0 initialisiert werden sollen.

- Beispiele:

1.) int mat[3][4] = { { 1, 4, 3, -4 }, { 2, 0, -3, 1 } }; oder: int mat[3][4] = { 1, 4, 3, -4, 2, 0, -3, 1 }; ⇒ Die letzte Zeile (mat[2][0] ... mat[2][3]) wird mit 0 initialisiert. 2.) int mat[3][4] = { { 1, 4, 3 }, { 2, 0, -3 }, { 0, -5, 6 } };

⇒ Die letzte Spalte (mat[0][3], mat[1][3], mat[2][3]) wird mit 0 initialisiert.Die Kennzeichnung der Arraystruktur bei den Initialisierungswerten ist notwendig.

3.) int mat[3][4] = { 1, 4, 3, -4, 2, 0, -3, 1, 0, -5 }; oder: int mat[ ][4] = { 1, 4, 3, -4, 2, 0, -3, 1, 0, -5 };

⇒ Die beiden letzten Elemente der letzten Zeile (mat[2][2], mat[2][3]) werden mit 0 initialisiert.

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - V - 513/11 - 00 – TH/KR - 00

Programmbeispiel zu 2-dimensionalen Arrays: Matrixaddition

/* Programm MATADD */ /* Demonstrationsprogramm Zu 2-dimensionalen Arrays */ /* Matrixaddition */ #include <stdio.h> #define ZEILEN 3 #define SPALTEN 4 void mat_add ( float mat1[][SPALTEN], float mat2[][SPALTEN], float mat3[][SPALTEN]) { int i,j; for (i=0; i<ZEILEN; i++) for (j=0; j<SPALTEN; j++) mat3[i][j]=mat1[i][j] + mat2[i][j]; } void mat_aus( float fmat[][SPALTEN]) { int i,j; for(i=0; i<ZEILEN; i++) { printf("\n{"); for (j=0; j<SPALTEN; j++) printf("%6.2f", fmat[i][j]); printf("}"); } printf("\n"); } int main(void) { float fmat1[][SPALTEN] = { { 1.5, 4.1, 3.4, -4.0 }, { 2.2, 0, -3.7, 1.1 }, { 0, -5.1, 6.6, 0.2 }}; float fmat2[][SPALTEN] = { -1.5, 2.3, 3.7, 2.1, 0.7, 5.5, 3.3,0,0,0,0,0}; float fmat3[ZEILEN] [SPALTEN]; mat_add(fmat1, fmat2, fmat3); mat_aus(fmat3); return 0; } /*****************************************************/ matadd - Probelauf { 0.00, 6.40, 7.10, -1.90, } { 2.90, 5.50, -0.40, 1.10, } { 0.00, -5.10, 6.60, 0.20, }

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - UE - 50/1 - 00 – TH/KR - 00

Sieb des Erathostenes

Problemstellung: Ermitteln von Primzahlen 1. Algorithmus - Grundidee:

Man gebe alle Zahlen in ein Sieb und entferne nach und nach jene Zahlenwerte, die Vielfache von anderen sind. Die übrig bleibenden Zahlen sind die Primzahlen. Randbedingungen: Die Zahlenwerte 1 und 2 werden nicht betrachtet.

Alle Vielfachen von 2 - also alle geraden Zahlenwerte - sind keine Primzahlen und damit ebenfalls nicht zu betrachten.

Die somit im Sieb verbliebenen Zahlen sind also alle ungeraden Zahlen größer 2:

3 5 7 9 11 13 15 17 19 21 23 .... 1001 1003 1005 1007 1009 0 1 2 3 4 5 6 7 8 9 10 .... 499 500 501 502 503

Die zweite Zahlenreihe nummeriert die Position im Sieb. Man sieht, daß zwischen Position i und dem Zahlenwert n folgender Zusammenhang gilt: n = 2*i + 3

2. Algorithmus - Verfeinerung: 2.1. Darstellung der Daten

Realisierung des Siebes als eindimensionales Array. Der Zahlenwert wird (indirekt) durch den Array-Index beschrieben. Der Wert eines Array-Elementes beschreibt ob die Zahl sich noch im Sieb befindet (TRUE) oder nicht (FALSE).

2.2. Aktionen mit den Daten: Suchen der zu entfernenden Zahlen so, daß nur noch die Primzahlen im Sieb sind. Die folgenden Tabellen zeigen für die Primzahlen 3, 5, 7 und 11 auf, welche Zahlen aus dem Sieb zu entfernen sind:

i=0 p = 3: i=1 p=5:

Streich- wert

Streich- position

Streich- wert

Streich- position

9 = 2*3 + 3 25 = 2*11 + 315 = 2*6 + 3 35 = 2*16 + 321 = 2*9 + 3 45 = 2*21 + 327 = 2*12 + 3 55 = 2*26 + 333 = 2*15 + 3 65 = 2*31 + 3

Indexdiff: 3 Indexdiff: 5

i=2 p = 7: i=4 p=11: Streich- wert

Streich- position

Streich- wert

Streich- position

49 = 2*23 + 3 121 = 2*59 + 363 = 2*30 + 3 143 = 2*70 + 377 = 2*37 + 3 165 = 2*81 + 391 = 2*44 + 3 187 = 2*92 + 3

105 = 2*51 + 3 209 = 2*103 + 3

Man sieht, daß der Index der zu streichenden Elemente sich jeweils um den betrachteten Primzahlenwert ändert, so daß für den neuen Index kneu bezogen auf den vorhergehenden Index kalt gilt:

Indexdiff: 11Indexdiff: 7

kneu = kalt + p Der Startwert für die Streichung ist das Quadrat der Primzahl p2 , deren Position im Array ermittelt sich zu: k = (p2 -3)/2

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - UE - 50/2 - 00 – TH/KR - 00

3. Festlegung des Pogrammumfangs:

Das Gesamtprogramm besteht aus den Teilen • Anlegen des Siebs • Ermitteln der Primzahlen • Formatierte Ausgabe der Primzahlen

4. Struktogramm

Wiederhole für alle Elemente des Siebs iaSieb[i] = TRUE Wiederhole für alle Elemente des Siebs ja Ist Element i noch im Sieb? nein iPrim = 2*i+3 (Berechnet Primzahl aus Index) Für alle Indizes k, die Vielfache der Primzahl sind % iaSieb[k] = FALSE Wiederhole für alle Elemente des Siebs ja Ist Element i im Sieb? nein Gib Primzahl aus %

1.Anlegen des Siebs 2.Ermitteln der Primzahlen 3.Ausgabe der Primzahlen

5. Programm in C

iAnzahl = 0; /* Ausgabe */ printf("\n"); for (i=0; i<ANZ; i++) { if (iaSieb[i] == TRUE) { iAnzahl++; printf("%6d",2*i+3); if(!(iAnzahl%ANZPZEIL)) printf("\n"); } } return 0; }

#include <stdio.h>#define ANZ 504l #define ANZPZEIL 12 #define TRUE 1 #define FALSE 0 int main(void) { long i,k,iPrim; int iaSieb[ANZ]; int iAnzahl = 0; for(i=0;i<ANZ;i++) { /* Sieb geeignet vorbelegen */ iaSieb[i] = TRUE; } for (i=0; i<ANZ; i++) { /* Primzahlen ermitteln */ if (iaSieb[i] == TRUE) { iPrim = 2*i+3; for (k = (iPrim*iPrim-3)/2; k<ANZ; k = k+iPrim) { iaSieb[k] = FALSE; } } }

Hochschule München Fakultät Elektrotechnik und Informationstechnik Technische Informatik AD - UE - 50/3 - 00 – TH/KR - 00 6. Ergebnis eines Probelaufes 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947 953 967 971 977 983 991 997 1009