Sie sind auf Seite 1von 864

Technische Informatik

- Grundlagen der Informatik -


- ANSI C 2.0 Grundlagen Programmierung -
- Einführung -

Prof. Dr.-Ing. Frank Artinger


frank.artinger@hs-karlsruhe.de
Hinweise:
Die vorliegende Vorlesung – ANSI C 2.0 Grundlagen
Programmierung - basiert in wesentlichen Teilen auf dem
gleichnamigen Skriptum des HERDT-Verlages für IT-
Schulungsunterlagen. Die ständige Aktualisierung sichert
gleichzeitig die Aktualität der Lehrinhalte (ANSI-Standard).

Hyperlink: http://www.herdt4you.de/
Inhalt der Vorlesung
Einführung
Einführung
Organisatorisches
Literatur, WWW Resources
Motivation (Primär, Aktuelle Trends, Arbeitsmarktanalyse, Globalisierung)
Inhaltsübersicht der Informatik Vorlesung
Was ist Informatik?
Begriff „Informatik“
Information und Daten
Ingenieur- und/oder Strukturwissenschaft?
Teilgebiete der Informatik
Daten und Algorithmen
Programmiersprachen (Genealogie)
Beispielalgorithmus
Warum C/C++ Programmierspache erlernen?

Frank Artinger Informatik - Einführung 3


Technische Informatik und Programmieren
Organisatorisches MT

• 5 SWS (6 cp)
• Abschließende Klausur (90 min Dauer) (PL, TF)
• Vorlesung/Übung (3 SWS, 3 cp)
• Labor (2 SWS, 3 cp) (gem. Terminplanung)
• Hinweis: Vorlesung und Labor im PC-Pool (F101)
• Downloads zur Vorlesung (Powerslides, etc.) liegen unter:
\\ads\dfs\MMT\public\Mitarbeiter\Artinger\Vorlesungen\Informatik
• Seminar-Unterlage zur Vorlesung:
ANSI C 2.0 Grundlagen Programmierung, HERDT-Verlag
• Erreichbarkeit
Telefon: (0721) 925 - 1716 / - 1701, Fax: (0721) 925 - 1707
Sekretariat (Fr. Loykowski): (0721) 925 - 1708
eMail frank.artinger@hs-karlsruhe.de
Sprechzeit Di 12:30 – 13:30h oder nach Vereinbarung

Frank Artinger Informatik - Einführung 4


Technische Informatik und Programmieren
Labor MT (SL)

Labortermine und Inhalte (Aufgabenblätter)


\\ads\dfs\MMT\public\Mitarbeiter\Artinger\Vorlesungen\Informatik\Uebu
ng\Allgemeines (Excel-Tabelle MT)

„Spielregeln“ für den Erhalt der Studienleistung BE


a) Laborvorbereitung
Bearbeitung der Multiple-Choice Aufgaben (2-er / 3-er Gruppe)
HINWEIS: Jede Antwort zu einer Multiple-Choice Frage ist zu begründen!

MT: Abgabe der bearbeiteten Aufgabenblätter spätestens am vereinbarten Tag vor


dem Labortermins bis 10:00h (Postfach im Sekretariat) (je 2-er/3-er Gruppe)

b) Teilnahme am Labor
Kontrolle durch Anwesenheitsliste
mehr als 1 unentschuldigtes Fehlen führt automatisch zum NB
mehr als 1 unentschuldigte Nicht-Abgabe führt autom. zum NB

Frank Artinger Informatik - Einführung 5


Technische Informatik und Programmieren
Übung MT (SL) (1)

Übungsblätter über e-Learning Plattform ILIAS


Parallel zur Vorlesung werden Sie eigenständig Übungsblätter
(Programmieraufgaben) bearbeiten

Hierfür steht ein vorgegebener Zeitraum zur Verfügung (ca.


jeweils 1 Monat)

Die Abgabe Ihrer Lösungen (innerhalb des Bearbeitungs-


zeitraumes) ist verpflichtend und wird mit einer
abschließenden SL (Studienleistung) bewertet

Die Organisation der Übung erfolgt über die e-Learning


Plattform ILIAS

Frank Artinger Informatik - Einführung 6


Technische Informatik und Programmieren
Übung MT (SL) (2)

FAQs zu ILIAS

Wo befindet sich ILIAS?


http://www.ilias-karlsruhe.de/

Wie funktioniert ILIAS?

Adobe Acrobat 7.0


Document

Anmeldung bei ILIAS


Nachfolgend wird der Anmeldevorgang bei ILIAS (allgemein) und die
notwendigen Schritte zum Beitritt zur Übungsveranstaltung in Snaphots
erläutert.

Frank Artinger Informatik - Einführung 7


Technische Informatik und Programmieren
Übung MT/FT (SL) (3)

Danach: Anmeldung mit Benutzername / Passwort

Erstmalig: Neues Benutzerkonto anlegen


(als Benutzername bitte unbedingt IZ-Kürzel
(z.B. arfr0001) verwenden! (Passwort frei
wählbar)

Frank Artinger Informatik - Einführung 8


Technische Informatik und Programmieren
Übung MT (SL) (3)

Sicht auf Persönlichen Schreibtisch

Jetzt anwählen (falls nicht verfügbar bitte


unter Magazin auswählen)

Frank Artinger Informatik - Einführung 9


Technische Informatik und Programmieren
Übung MT/FT (SL) (3)

hier sind bereits die LV in Fakultät


MMT sichtbar..

Jetzt Gruppe der MMT-Studenten beitreten


Passwort: MMT-<Kalenderjahr z.B. 09><ss, ws>
Beispiel: WS0910: MMT-09ws

Frank Artinger Informatik - Einführung 10


Technische Informatik und Programmieren
Bitte Pfad folgen bis GDI (Grundlagen der
Informatik)

hier bitte MT LV wählen


und Beitreten
Passwort MT: MTB241

Frank Artinger Informatik - Einführung 11


Technische Informatik und Programmieren
z.B. Übungsblatt 1 mit Angabe des
Bearbeitungszeitraums!

hier bitte Übungsblatt (*.doc)


herunterladen

Frank Artinger Informatik - Einführung 12


Technische Informatik und Programmieren
Einreichung auswählen zum Upload Ihrer
Lösung(en)

hier Ihren lokalen Pfad


eingeben/auswählen

Frank Artinger Informatik - Einführung 13


Technische Informatik und Programmieren
Übersicht: Termine - Themen

Termine - Themen
W Thema W Thema
L3: Steuer-
1 Einführung und Organisation 9 Zeiger (Grundlagen)
strukturen
Grundlagen (IDE, „Hello Funktionen
Zeiger (Dynamische
2 world“, Ein-/Ausgabe, 10
Speicherplatzverwaltung)
Funktionen)
L1: Grundlagen /
Datentypen Datentypen und Operatoren
3 11 Zeiger (Anwendungen) L4: Zeiger
Teil 1
Vektoren
Datentypen und Operatoren
4 12 Modulare Programmierung
Teil 2
Nützliche Funktionen und Spezialitäten (Überladung,
L2: Ein-Ausgabe 5 13
Speicherklassen inline, etc.)
Operatoren
6 Steuerstrukturen (Teil 1) 14 Standardbibliotheken

7 Steuerstrukturen (Teil 2) 15 Noch Fragen ?

8 Komplexe Datentypen
W: Woche

Frank Artinger Informatik - Einführung 14


Technische Informatik und Programmieren
Klausur MT

Prüfungsmodalität
• Schriftliche Prüfung (ohne PC)
• Verständnisfragen (Multiple Choice), Fehlersuche im Code
und eigenständige Programmierung
Prüfungsinhalte
• Sprachumfang ANSI-C/C++
• prozedural (ohne Objektorientierung)
• Klausuraufbau vgl. Labor/Übungsblätter
Bewertungskriterien
• logischer Gedankenfluss (vor allem bei Programmier-
aufgaben)
• Syntax wird natürlich bewertet, aber keine Panik!
Nicht Bestandteil der Prüfung
• UML

Frank Artinger Informatik - Einführung 15


Technische Informatik und Programmieren
Organisatorisches

Bezugsmöglichkeiten der begleitenden Seminar-Unterlage

Alternative 1:
direkte Bestellung beim HERDT-Verlag
Kosten: 16,50 € (Stand: 09/07)

Alternative 2:
HERDT-Verlag kooperiert seit ca. 10 Jahren mit dem Rechenzentrum der
Universität Hannover (RRZN)
RZ Karlsruhe (TH) bietet als Partner einen vergünstigsten Bezug
ausgewählter Seminar-Unterlagen an (Liste verfügbarer Handbücher
unter: http://www.rz.uni-karlsruhe.de/publikationen/2817.php)
Studenten- Titel: C Die Programmiersprache C, Ein Nachschlagewerk
ausweis +
Kosten: ca. 3,60 €, bargeldlos im Foyer beim BIT8000 erhältlich
Mensakarte

Frank Artinger Informatik - Einführung 16


Technische Informatik und Programmieren
Literatur
Grundlagen Informatik

Grundlagen der Informatik


H.Balzert: Lehrbuch Grundlagen der Informatik. Spektrum
Lehrbuch, Heidelberg 2005.
C.Vogt: Informatik. Eine Einführung in Theorie und Praxis.
Spektrum Lehrbuch, Heidelberg 2004.
P.Levi,U.Rembold: Einführung in die Informatik für Ingenieure und
Naturwissenschaftler. Carl Hanser Verlag, München 2003.
(Informatik Vorlesung Uni Karlsruhe, Stuttgart)
P.Rechenberg: Was ist Informatik? Eine allgemeinverständliche
Einführung. Carl Hanser Verlag, München 2000.
H.-P.Gumm, M.Sommer: Einführung in die Informatik. Oldenbourg,
2002

Frank Artinger Informatik - Einführung 17


Technische Informatik und Programmieren
Literatur
C/C++ Programmierung
Grundlagen der C/C++ Programmierung
ISO/IEC 14882-1998, International Standard –Programming Language –
C++. (elektronisch über http://www.ansi.org erhältlich)
U.Breymann: C++ Eine Einführung. Carl Hanser Verlag, München 1999.
(http://www.informatik.hs-bremen.de/~brey)
P.Prinz, U.Kirch-Prinz: C++ Lernen und professionell anwenden. mitp-
Verlag, Bonn, 2002.
P.Prinz, U.Kirch-Prinz: C für PCs Einführung und professionelle
Anwendung. mitp-Verlag, Bonn, 2002.
B.Stroustrup: Die C++ Programmiersprache. Addison-Wesley, München,
2000. (http://www.research.att.com/)
A.Willms: C++ Programmierung. Addison-Wesley, München, 1997
S.Qualline: Praktische C++ Programmierung. O‘Reilly, Köln, 2004
B.Eckel: Thinking in C++. 2nd Edition, Volume 1 + 2, Prentice Hall, 2000.
(http://bruceeckel.com kostenlos erhältlich)
C/C++ Tutorials im Web: http://www.c-plusplus.de
HERDT-Verlag: ANSI C 2.0 http://www.herdt.de

Frank Artinger Informatik - Einführung 18


Technische Informatik und Programmieren
Literatur
weiterführend..
Objektorientierte Analyse und Design (OOA/OOD)
G.Booch: Objektorientierte Analyse und Design. Addison-Wesley,
München, 1995

Software-Technik
H. Balzert: Lehrbuch der Software-Technik. Spektrum
Akademischer Verlag, Heidelberg, 2000

Frank Artinger Informatik - Einführung 19


Technische Informatik und Programmieren
Literatur
weiterführend..

UML, SW-Entwicklungsprozess, Patterns


G.Booch, J.Rumbaugh, I.Jacobson: The Unified Modeling Language
User‘s Guide. Addison Wesley 1999 (ISBN 0-201-57168-4)
G.Booch, J.Rumbaugh, I.Jacobson: The Unified Modeling Language
Reference Manual. Addison Wesley 1999 (ISBN 0-201-30998-X)
G.Booch, J.Rumbaugh, I.Jacobson: The Unified Software Development
Process. Addison Wesley 1999 (ISBN 0-201-30998-X)
M.Fowler, K.Scott: UML Distilled, Addison Wesley 1997 (ISBN 0-201-
32563-2)
B.Oestereich: Objektorientierte Software-Entwicklung, Oldenburg Verlag
1998 (ISBN 3-486-24787-5)
E.Gamma, R.Helm, R.Johnson et.al.: Design Patterns, Addison Wesley
1995 (ISBN 0-201-63361-2)

Frank Artinger Informatik - Einführung 20


Technische Informatik und Programmieren
WWW Resources
weiterführend..
www.omg.org Object Management Group
www.rational.com Firma Rational
www.cetus-links.org Links zu „Objects & Components“
www.hillside.net/pattern Patterns Home Page
sunset.usc.edu Center for Software Engineering
www.esi.es European Software Institute
www.sei.cmu.edu Software Engineering Institute

Frank Artinger Informatik - Einführung 21


Technische Informatik und Programmieren
Motivation – Primäre Sicht

Erwartungen, Beweggründe -> Ihre Meinung ist gefragt !

Antwort 1) „Steht im Lehrplan, da muß man durch!“

Antwort 2) „Seitdem ich die Sprachhierarchie von Noam


Chomsky studiert habe liebe ich formale
Sprachen!“

Antwort 3) „Warum spielt die Objektorientierung eine so


große Rolle? Wie unterstützt eine Sprache das?
Was steckt hinter informationstechnischen
Trends wie XML, component-based, UML und
Enterprise Solution Development?“

Frank Artinger Informatik - Einführung 22


Technische Informatik und Programmieren
Motivation – Aktuelle Trends

Thema: Software in der Automobilindustrie


“… zentrales Thema .. der Gesellschaft für Informatik ist daher der
Anwendungsbereich Automobil: Software und Elektronik sind die wichtigsten
Innovationsfaktoren in der Automobilindustrie. Sie steuern sowohl das Bordnetz
als auch Fahrwerk und Antrieb. Sie übernehmen nicht nur das Motormanagement,
sondern auch Sicherheitsaufgaben und sorgen für mehr Komfort beim Fahren. Dazu
kommen Navigations- und Telematiksysteme als Teile des neuen Infotainment im
Auto…

Laut aktuellen Marktforschungen wird der Wertschöpfungsanteil der Elektronik am


Fahrzeug in den nächsten 15 Jahren von derzeit 20 auf 40 Prozent wachsen, der
Anteil von Automobilsoftware soll sich sogar von rund 25 Milliarden Euro im Jahr
2000 auf 100 Milliarden Euro im Jahr 2010 vervierfachen...

Hier ist ganz besonders die Informatik herausgefordert. Der Entwicklungsprozess


für Software ist methodisch aufwändiger als in der Mechanik, insbesondere
brauchen wir zur Qualitätsverbesserung einen herstellerübergreifenden
Standardisierungsprozess„ (GI-Präsident Heinrich C. Mayr)..“

(Quelle: Jahrestagung INFORMATIK 2003, VDI Pressemitteilung Oktober 2003)

Frank Artinger Informatik - Einführung 23


Technische Informatik und Programmieren
Motivation – Aktuelle Trends

Thema: Software in der Automobilindustrie


Interview mit Fa. VALEO zur New Yorker Motorshow zum Thema Ausrüstung von
Nissans Infiniti Modelle mit einem Fahrspurerkennungssystem/Fahrassistenzsystem:

„... Neben der Hardware spielt, gerade bei Fahrerassistenzsystemen, die Software
eine Rolle. Wie bedeutend ist diese Rolle?

Sehr. Wir unterteilen aber das Softwareengineering: in Systemengineering. Dies


beschreibt das Systemverhalten und orientiert sich sehr nah an der Anwendung und
erfordert daher ein tiefes Verständnis des Produkts. Und Programmierung. Also der
Übersetzung in die Maschinensprache mit all den Einschränkungen der Hardware.
Software ist auch das Herz künftiger Assistenzsysteme. Es ist wie der Zucker im
Kaffee, essenziell und unsichtbar.

Demnach gehört die Softwareentwicklung zum Kerngeschäft?

Definitiv ja.

Frank Artinger Informatik - Einführung 24


Technische Informatik und Programmieren
Motivation – Aktuelle Trends

... Fortsetzung ...


Sehen Sie die Automobilbranche genügend gut aufgestellt, um die Anforderungen an
die Softwareentwicklung zu meistern?

Ich sehe das Thema nicht ganz so kritisch, wie es manchmal dargestellt wird. Die
auftretenden Probleme lassen sich oftmals natürlich als Softwareproblem darstellen.
Aber es sind vielmehr nicht verstandene Systemaspekte. Ich erwähnte bereits die
immense Anzahl möglicher Konfigurationen im Fahrzeug, die nicht mehr alle
erprobt werden können, in der Konzeptphase der Entwicklung müssen sie daher
sehr systematisch vorgehen und genau wissen was für Optionen sie benötigen und
wie diese zusammen spielen. Oftmals bereitet nicht das alleinstehende Produkt das
Problem, vielmehr das Produkt im Zusammenspiel mit anderen Systemen.”

(Quelle: AUEL – AUTOMOBIL-Elektronik, Heft 3/2004, S. 16-17)

Frank Artinger Informatik - Einführung 25


Technische Informatik und Programmieren
Motivation – Der Arbeitsmarkt

Arbeitsmarktsituation

(Quelle: CDI – Deutsche Private Akademie für Wirtschaft GmbH, Stellenmarktanalyse 2003)

Frank Artinger Informatik - Einführung 26


Technische Informatik und Programmieren
Motivation – Der Arbeitsmarkt

Arbeitsmarktsituation

(Quelle: CDI – Deutsche Private Akademie für Wirtschaft GmbH, Stellenmarktanalyse 2003)

Frank Artinger Informatik - Einführung 27


Technische Informatik und Programmieren
Motivation - Globalisierung

Stichwort „Globalisierung“
• Steigende Integration weltweiter Volkswirtschaften durch
Handel und Finanzströme
• „Ungleichheit“ (insbes. Pro-Kopf-Einkommen) führt zur
Verlagerung („outsourcing“, „off-shoring“, etc.) lohnkosten-
intensiver Arbeitstätigkeiten (insbes. Fertigung)

Microsoft
owerPoint Presentatio

Lessons learned
• Konzentration auf höherwertige Tätigkeiten (Entwicklung,
Forschung)
• „Jede Kultur besitzt ihre einzigartigen Vorzüge“
(Quelle: International Monetary Fund, Globalisierung: Bedrohung oder Chance?)

Frank Artinger Informatik - Einführung 28


Technische Informatik und Programmieren
Inhalt der Vorlesung
Einführung

Einführung
Was ist Informatik?
Warum C/C++ Programmierung erlernen?
Grundlagen Rechnerarchitektur
Maschinen und Maschinenmodelle
Grundlagen Programmierung
Zahlensysteme
Zeichencodes
ANSI C/C++ Programmierung
Einleitung
Das erste Programm in C
Konstanten
Einfache Datentypen
Unterprogramm-Technik
Nützliche Funktionen

Frank Artinger Informatik - Einführung 29


Technische Informatik und Programmieren
Inhalt der Vorlesung
Einführung

Steuerstrukturen
Typvereinbarungen von Variablen
Zeiger
Der Präcompiler
Modulare Programmierung
Entwicklungsumgebungen
Standardbibliotheken
Anhang

Frank Artinger Informatik - Einführung 30


Technische Informatik und Programmieren
Was ist Informatik?
Orientierung
Einführung
Was ist Informatik?
ORIENTIERUNG
Warum C/C++ Programmierung erlernen?
Grundlagen Rechnerarchitektur
Maschinen und Maschinenmodelle
Grundlagen Programmierung
Zahlensysteme
Zeichencodes
ANSI C/C++ Programmierung
Einleitung
Das erste Programm in C
Konstanten
Einfache Datentypen
Unterprogramm-Technik
Nützliche Funktionen
Steuerstrukturen
Typvereinbarungen von Variablen

Frank Artinger Informatik - Einführung 31


Technische Informatik und Programmieren
Was ist Informatik?
Ziele

¾ Wissenschaftliche Einordnung des Begriffs „Informatik“


¾ Welche wichtigen Teilgebiete der „Informatik“ gibt es?
¾ Was bedeutet Informationsverarbeitung?
¾ Wofür benötigen wir Programmiersprachen?
¾ Wie unterscheiden sich die Programmiersprachen?
ZIELE

¾ Zum Beispiel ein Beispiel..

Frank Artinger Informatik - Einführung 32


Technische Informatik und Programmieren
Was ist Informatik?
Inhalt
Was ist Informatik?
Begriff „Informatik“
Information und Daten
Ingenieur- und/oder Strukturwissenschaft?
Teilgebiete der Informatik
INHALT

Daten und Algorithmen


Programmiersprachen
Beispielalgorithmus

Frank Artinger Informatik - Einführung 33


Technische Informatik und Programmieren
Was ist Informatik?
Begriff „Informatik“
Begriff Informatik und „Computer-Führerschein“
• Begriff „Informatik“ mittlerweile fester Bestandteil des deutschen
Wortschatzes, wird i.A. aber sehr unspezifisch gebraucht

• Häufig verbunden mit „Fertigkeit in der Bedienung eines Computers“ ->


z.B. „Computer-Führerschein“ Eurpean Computer Driving
License (ECDL)
• Genauso wenig wie Inhaber eines Kfz-Füherscheins automatisch
Experte für Kfz-Technik ist, macht die reine Bedienung des Computers
noch keinen „Informatiker“ aus

• es fehlt der tiefere Einblick „unter die Motorhaube“ wie man ihn an
Unis/Fachhochschulen vermittelt (grundlegende Prinzipien, Modelle und
Methoden der systematischen Verarbeitung von Informationen und ihre
Anwendung in der Praxis)

Frank Artinger Informatik - Einführung 34


Technische Informatik und Programmieren
Was ist Informatik?
Begriff „Informatik“
Balanceakt zwischen „Breite“, „Tiefe“, „Überschaubarkeit“
• Informatikvorlesung (gerade im Nebenfach) steht immer in dem
Spannungsfeld von 3 konkurrierenden Forderungen:

• A) Breit angelegt: Möglichst alle Themen ansprechen, die in der


modernen Informatik bedeutsam sind
• Klassische Themen: Zahlencodierung, Maschinen- und
Sprachmodelle, Algorithmen
• Moderne Themen: objektorientierte-SW-Entwicklung, Rechnernetze,
verteilte Systeme (Client-Server, Web-basierte Systeme), Multimedia

• B) Tiefgängig: Themenkomplexe möglichst detailliert behandeln,


möglichst wenig Fragen offen lassen

• C) Überschaubar: Themen übersichtlich strukturieren, Ermüdungs-


erscheinungen vorbeugen

Frank Artinger Informatik - Einführung 35


Technische Informatik und Programmieren
Was ist Informatik?
Begriff „Informatik“
Ziele der Informatik 1 Vorlesung
• Konzentration auf ein modernes Thema der Informatik:
„Programmierung in der Sprache C/C++“

• Keine Beschränkung auf die rein formalen Sprachelemente, sondern


Fokussierung auf die Denkweise der OOP1

• Weiterhin gehen wir auch auf das in der Praxis äußerst wichtige Thema
des „Programmierstils“ ein

• Für Themen, die sich aus Zeitgründen einer tiefergehenden Betrachtung


entziehen erfolgen Hinweise auf weiterführende Literatur/Links im WWW

1
: Objekt-Orientierte Programmierung

Frank Artinger Informatik - Einführung 36


Technische Informatik und Programmieren
Was ist Informatik?
Information und Daten
Information
• besitzt Bedeutung für den Nutzer
• beinhaltet etwas Neues, Unbekanntes
• vermehrt Wissen und beeinflusst Verhalten
• z.B. Öldruckmessgerät im Fahrzeug liefert Information über den Öldruck
Daten
• Formale Darstellung der Information
• Repräsentation / Codierung von Information
• z.B. Anzeige im Analogmessgerät oder Ziffernfolge in digitaler Anzeige

Repräsentation

Codierung

Frank Artinger Informatik - Einführung 37


Technische Informatik und Programmieren
Was ist Informatik?
Information und Daten
Kerninhalte der Informatik
• Speicherung, Verarbeitung und Übertragung von Informationen in
Form von Daten
¾stellt grundlegende Prinzipien, Modelle bereit
¾Praktisch-technische Umsetzung mit Methoden und Geräten
¾Ermöglicht die Anwendung in vielen Bereichen

Zentrales Werkzeug

Datenverarbeitung im „großen Stil“

„Computerwissenschaft“

„Computer Science“ (U.S.)


Digitalrechner

Frank Artinger Informatik - Einführung 38


Technische Informatik und Programmieren
Was ist Informatik?
Ingenieur- und/oder Strukturwissenschaft?
Ingenieurwissenschaft
• Technisch-konstruktive Aspekte im Vordergrund

¾Entwurf, Realisierung und Einsatz technischer Geräte/Systeme


(Computer, PDAs, Spielekonsolen, Prozessoren für Gerätesteuerung)

¾Konzepte der Elektrotechnik, Mikroelektronik, neuerdings auch Optik,


Quantenphysik, Genetik (z.B. Evolutionäre Algorithmen)

¾Software Engineering: ing.-mäßiges Entwickeln großer SW-


Anwendungen

¾Kommunikationssysteme (Übertragungstechnik, Vernetzung von


Computern) -> Nachrichtentechnik

Frank Artinger Informatik - Einführung 39


Technische Informatik und Programmieren
Was ist Informatik?
Ingenieur- und/oder Strukturwissenschaft?
Strukturwissenschaft
• Schaffung von Ordnungsprinzipien („Denkschule“): Modelle, Methoden,
Regeln, Verfahren zur Datenspeicherung, -verarbeitung, -übertragung

¾Systematische Verarbeitung von Information durch Strukturierung von


Daten (z.B. Binärcodierung, Filesystem, Database)
¾Algorithmen: Rechenvorschriften für Transformation Eingabedaten ->
Ausgabedatensysteme (Grob- / Feinstruktur)
¾Systeme: Einbettung von Daten und Algorithmen (Schnittstellen,
Dienste, Komponenten, Hierarchie und Modularisierung)
¾Abstraktion: Systementwicklung über das Modell (Entwurf der
Systemstruktur) zur Realisierung (Implementierung)
¾Formale Beschreibung: Dokumentenbeschreibungssprachen (HTML,
XML), Programmiersprachen (C, C++, Java, C#)

Frank Artinger Informatik - Einführung 40


Technische Informatik und Programmieren
Was ist Informatik?
Teilgebiete der Informatik (Curriculum)
Theoretische Informatik
• Mathematisch geprägt (formale Maschinen-/Berechnungsmodelle)
• Berechenbarkeit und Komplexität von Algorithmen
• Theorie der formalen Sprachen (Hierarchie der Grammatiken)
• Automatentheorie

Technische Informatik
• Logischer Entwurf und technische Realisierung von Computern
(Rechnerarchitektur) und Rechennetzen
• Digitale Schaltnetze, Prozessoren, Speicher, Peripheriegeräte

Frank Artinger Informatik - Einführung 41


Technische Informatik und Programmieren
Was ist Informatik?
Teilgebiete der Informatik (Curriculum)
Praktische Informatik
• Programmierung von Computern
• Entwicklung von Programmiersprachen-/verfahren
• Compiler-/Interpreterbau
• Software-Engineering (Leitlinie für komplexe Systeme)
• Systemsoftware, Betriebssysteme, SW-Entwicklungsumgebungen
(IDE1s), UI (User-Interface), Bedienoberflächen
• Datenbank- und Informationssysteme (Documentation-Management)
• Distributed Systems (verteilte Systeme)
• Real-Time Systems (Echtzeitsysteme)

Angewandte Informatik
• Lösungen für spezielle Benutzerprobleme (Büroautomatisierung,
Computergraphik, Multimedia, Simulationen, medizinische Informatik)

1
: Integrated Development Environment

Frank Artinger Informatik - Einführung 42


Technische Informatik und Programmieren
Was ist Informatik?
Daten und Algorithmen als Kernbegriffe der Informatik

Benutzer

Algorithmen: Strukturierte Verarbeitung ...

... von Information

Daten: Strukturierte Darstellung ...

Mathematik / Logik Elektrotechnik / Nachrichtentechnik


Linguistik Physik: Optik, Quantenmechanik
Biologie: Genetik, Neurologie

Frank Artinger Informatik - Einführung 43


Technische Informatik und Programmieren
Was ist Informatik?
Programmiersprachen - Definition

Programm: Übertragung eines durch einen Algorithmus lösbaren


Problems auf den Computer.
Die erforderlichen Anweisungen werden in einer für den
Computer verständlichen Programmiersprache formuliert

.. oder etwas anders ausgedrückt ..


• dem Rechner mitteilen, was und wie er etwas tun soll
• Programm ist damit eine Software, die bei ihrer Ausführung die
Hardware steuert
• Programm ist ein „Kochrezept“ für die Ausführung von Anweisungen,
geschrieben in einer besonderen d.h. formalen Sprache
• Schwerpunkt liegt auf den einzelnen Schritten/Anweisungen, die der
Rechner zur Lösung der Aufgabe ausführen muß

Frank Artinger Informatik - Einführung 44


Technische Informatik und Programmieren
Was ist Informatik?
Genealogie – Entstehung von Programmiersprachen

Frank Artinger Informatik - Einführung 45


Technische Informatik und Programmieren
Was ist Informatik?
Programmiersprachen - Sprachklassen
Maschinensprachen
Hardwarenahe z.B. Intel- und SPARC-CPUs
1./2. Gen.
Sprachen Assemblersprachen
z.B. Intel- und SPARC-CPUs

Imperative Rein prozedurale Sprachen


Höhere Sprachen z.B. C, Pascal
Sprachen Objektorientierte Sprachen
z.B. C++, Java, C#
3. Gen.
Scriptsprachen
z.B. Perl, VBS

nichtimperative funktionale Sprachen


Sprachen z.B. LISP
Logiksprachen
4. Gen. z.B. Prolog
Anfragesprachen
z.B. SQL

Frank Artinger Informatik - Einführung 46


Technische Informatik und Programmieren
Was ist Informatik?
Beispielalgorithmus - Definition
Algorithmus für „Größten gemeinsamen Teiler (ggT)“

Algorithmus basiert auf 3 mathematischen Regeln:

ggT (x,y) = ggT (x,y-x) für x < y; x, y ∈ Ν


ggT (x,y) = ggT (x-y,y) für x > y:
ggT (x,y) = x für x = y;

Beispiel:
x = 28; y = 42;

1. Schritt ggT (28,42) = ggT (28,14);


2. Schritt ggT (28,14) = ggT (14,14);
Ergebnis ggT (28,42) = 14;

Das ist noch kein Algorithmus, es fehlen:


• Reihenfolge der Ausführung (Kontrollstruktur)
• Explizite Operationen wie Wertzuweisungen od. Ausgaben

Frank Artinger Informatik - Einführung 47


Technische Informatik und Programmieren
Was ist Informatik?
Beispielalgorithmus - Beschreibungsformen

Umgangssprachliche (textuelle) Beschreibung:


1) Lies 2 natürliche Zahlen ein und speichere sie in den Variablen x und y
2) Sind die Werte der Variablen x und y gleich, so gib x als Resultat aus und
beende die Ausführung.
3) Ist der Wert der Variablen x kleiner als der Wert der Variablen y, so
speichere in der Variablen y den Wert y-x und setze die Ausführung bei
Schritt 2) fort.
4) Ist der Wert der Variablen x größer als der Wert der Variablen y, so
speichere in der Variablen x den Wert x-y und setze die Ausführung bei
Schritt 2) fort.

Das ist ein Algorithmus, denn:


• Anwendbar auf beliebige Paare natürlicher Zahlen (Allgemeine
Problemstellung)
• Endliche Beschreibung, d.h. A. terminiert
• Einfache Einzelschritte, d.h. A. besitzt Kontrollstruktur
• ABER: äh, wie führt der Computer den A. aus???

Frank Artinger Informatik - Einführung 48


Technische Informatik und Programmieren
Was ist Informatik?
Beispielalgorithmus - Beschreibungsformen
Programmablaufplan (PAP, flowchart) Struktogramm
Nassi-Shneiderman-Diagramm
BEGINN

Zwei natürliche Zahlen


Zwei natürliche Zahlen in die Variablen x,y einlesen
in die Variablen x,y einlesen
Solange x ≠ y
ja
x = y?
x < y?
nein ja nein
nein y ← y-x x ← x-y
x < y?
ja x ausgeben
y ← y-x x ← x-y

x ausgeben
Hinweis zur Notation:
x ← x-y ist eine Zuweisung des
ENDE Wertes x-y an die Variable x

Frank Artinger Informatik - Einführung 49


Technische Informatik und Programmieren
Was ist Informatik?
Beispielalgorithmus - Beschreibungsformen
Bruchrechnen rein prozedural (ggt als Unterprogramm im C-Programm)
#include <stdio.h> /* Einbindung Ein-/Ausgabefunktionen */
int ggt (int x, int y) { /* Funktion/Unterprogramm zur
Berechnung des ggT */
while (x!=y)
if (x<y)
y = y-x;
else x = x-y;
return x;
}

void main(void) { /* Hauptprogramm */


int zaehler,nenner,teiler; /* Variablen-Deklaration */
printf(″Bitte Zähler und Nenner eingeben: ″); /* format.Ausgabe */
scanf(″%d %d″, &zaehler,&nenner); /* format.Eingabe (input) */
teiler=ggt(zaehler,nenner); /* Funktionsaufruf */
zaehler=zaehler/teiler;
nenner=nenner/teiler;
printf(″gekürzter Bruch: %d/%d″,zaehler,nenner); /* et voila.. */
}

Frank Artinger Informatik - Einführung 50


Technische Informatik und Programmieren
Was ist Informatik?
Beispielalgorithmus - Beschreibungsformen
Bruchrechnen objektorientiert (als C++-Klasse)
class Bruch { // z.B. in bruch.h
public: // alles oeffentlich..
int zaehler,nenner; // das sind die Daten.. (Attribute)
int ggT() { // die bekannte ggT-Methode
int x,y;
x=zaehler;
y=nenner; // Deklaration und Definition
while (x!=y) // innerhalb der Klasse
if (x<y) // wird auch als inline-Mechanismus
y=y-x; // bezeichnet
else x=x-y;
return x;
}
void kuerzen() { // jetzt wird gekuerzt
int teiler = ggt(); // z.B. Bruch einBruch
zaehler = zaehler/teiler; // einBruch.zaehler = 28;
nenner = nenner/teiler; // einBruch.nenner = 42;
} // einBruch.kuerzen();
}; // -> zaehler = 2, nenner = 3

Frank Artinger Informatik - Einführung 51


Technische Informatik und Programmieren
Was ist Informatik?
Beispielalgorithmus – Erkenntnisse?
Zusammenfassung und Methodik
• Beispiel zeigt prinzipielle Methode auf („top-down“ Methode, „vom
Groben zum Feinen“)
• Gesamtproblem (Lösung durch Algorithmus) wird in immer kleinere
Teilprobleme zerlegt
• Schließlich bleiben elementare Grundstrukturen (Sequenzen,
Kontrollstrukturen) zurück
• Im Falle relativ kleiner Algorithmen: Visualisierung z.B. durch PAP oder
Struktogramm (NS-Diagramm) möglich
• Im Falle komplexer Algorithmen: Teilgebiet Software-Engineering,
Modellierung mit UML, Nutzung von CASE Tools (z.B. RationalSuite)
Erkenntnis
• Zuerst auf allgemeine Struktur der Problemlösung konzentrieren, danach
in Details der konkreten programmiersprachlichen Formulierung
„abtauchen“

Frank Artinger Informatik - Einführung 52


Technische Informatik und Programmieren
Warum C/C++ Programmierung erlernen?
Orientierung

Einführung
Was ist Informatik?
ORIENTIERUNG
Warum C/C++ Programmierung erlernen?
Grundlagen
Zahlensysteme
Zeichencodes
ANSI C/C++ Programmierung
Einleitung
Das erste Programm in C
Konstanten
Einfache Datentypen
Unterprogramm-Technik
Nützliche Funktionen
Steuerstrukturen
Typvereinbarungen von Variablen

Frank Artinger Informatik - Einführung 53


Technische Informatik und Programmieren
Warum C/C++ Programmierung erlernen?
Inhalt
Warum C/C++ Programmierung erlernen?
Einige Zahlen ..
und einige Argumente ..
INHALT

Frank Artinger Informatik - Einführung 54


Technische Informatik und Programmieren
Warum C++ Programmierung erlernen?
.. einige Zahlen ..
here we are: Bjarne Stroustrup, Erfinder und Designer von C++

Homepage: http://www.research.att.com/~bs/homepage.html
• 1979 Beginn der Arbeiten an der Sprache (AT&T Labs, New Jersey)
• 1985 – 1991 Entwicklung von C++ („C mit Klassen“)
• 1998 Standardisierung ISO/IEC 14882 (u.a. auch ANSI1, BSI2, DIN3)
• 2002 Aktualisierung des Standards ISO/IEC 14882:2002 (noch nicht
ratifiziert)
1
: American National Standards Institute
2
: British Standards Institute
3
: Deutsches Institut für Normung

Frank Artinger Informatik - Einführung 55


Technische Informatik und Programmieren
Warum C++ Programmierung erlernen?
.. einige Argumente ..
Vorzüge
• C++ ist der deFacto Standard in der SW-Entwicklung
• C++ Compiler sind plattformübergreifend verfügbar (UNIX, Windows,
Macintosh, OpenBSD)
• C++ ist eine stark typisierte Sprache
• C++ deckt sowohl Systemprogrammierung (hardwarenah) als auch
Anwendungsprogrammierung ab
• C++ unterstützt die Objektorientierung (Datenabstraktion,
Klassenkonzept, Vererbung)

Nachteile
• C++ ist eine komplexe Sprache (Fehleranfälligkeit!)
• C++ Compiler sind komplexe Programme, C++ Code ist i.d.R.
umfangreicher und langsamer als mit C erzeugter Code
• Kompatibilität von C++ mit C beinhaltet einige Einschränkungen

Frank Artinger Informatik - Einführung 56


Technische Informatik und Programmieren
Maschinen und Maschinenmodelle
Orientierung

Einleitung
Von-Neumann-Rechnerarchitektur
ORIENTIERUNG
Technischer Aufbau von Computern
Universalrechner
Hauptspeicher
Hauptprozessor
Befelsausführungszyklus
Beispiel: Maschinenprogramm zur Addition zweier Zahlen
Virtuelle Maschinen und Betriebssysteme
Schnittstellen und virtuelle Maschinen
Systemsoftware und Betriebssystem
Virtuelle Hardware
Turing-Maschinen

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 1


Technische Informatik und Programmieren
Maschinen und Maschinenmodelle
Ziele

¾ Welche grundlegenden Modelle zur automatischen


Verarbeitung von Information kennt die Informatik?
¾ Welche konkreten, technisch realisierbaren
Computerarchitekturen gibt es?
¾ Welche abstrakten Maschinenmodelle dienen
ZIELE

theoretischen Untersuchungen?

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 2


Technische Informatik und Programmieren
Maschinen und Maschinenmodelle
Einleitung
Informatik: Zentrale Rolle der „Rechenmaschinen“

Technische Informatik Praktische Informatik

Programmierung
Realisierung

Lösung von
Prinzipielle Fragen zur Anwendungsproblemen
maschinellen Bearbeitung

Theoretische Informatik Angewandte Informatik

Wie ist der Rechner aufgebaut?

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 3


Technische Informatik und Programmieren
Maschinen und Maschinenmodelle
Von-Neumann-Architektur
Variationen von moderner Computer
• Personal Computer (PCs) -> Arbeitsplatzrechner für einzelnen Benutzer
• Workstations -> Arbeitsplatzrechner oder auch „Multi-User“ fähig
• Großrechner / Supercomputer -> rechenintensive Anwendungen
• Mobile Systeme (PDAs, Mobiltelephone) -> Versorgung nicht-ortsfester
Benutzer mit Computerdiensten
• Eingebettete Systeme (embedded systems) -> Steuerungsaufgaben in
Geräten z.B. Fahrzeuge, Haushalt etc.

Trotz unterschiedlicher Ausrichtung haben die meisten Computer


ein gemeinsames Organisationsprinzip: Architektur

Kern der Architektur: Von-Neumann-Prinzip

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 4


Technische Informatik und Programmieren
Maschinen und Maschinenmodelle
Von-Neumann-Architektur
Technischer Aufbau von Computern
CPU: Central Processing Unit main memory: direkter, rascher CPU-Zugriff
-> alle Operationen auf Daten -> Eingabe-/Ausgabedaten für Operationen

optional:
Cachespeicher

Hardware-Struktur eines heutigen Computers

¾ Zentraleinheit und Peripherie sind durch einen / mehrere Busse verbunden


(Bus: Leitungen mit zugehöriger Steuerungselektronik für Daten / Signale)
¾ Grenzen zwischen Zentraleinheit / Peripherie verschwinden zusehends..
¾ Alles, womit gearbeitet werden soll, muß im Hauptspeicher sein!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 5


Technische Informatik und Programmieren
Maschinen und Maschinenmodelle
Von-Neumann-Architektur
Universalrechner
Steuerung der Hardware
durch Software

Software

PCs, Workstations, Großrechner:


UINVERSALRECHNER

nicht auf ein spezifisches Flexibilität durch Programmierung


Anwendungsproblem ausgerichtet (der Hardware)

John von Neumann (1946):


Konzept für den Aufbau eines programmierbaren Universalrechner
(genauer: Zentraleinheit d.h. Prozessor & Hauptspeicher)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 6


Technische Informatik und Programmieren
Maschinen und Maschinenmodelle
Von-Neumann-Architektur
Von-Neumann-Architektur

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 7


Technische Informatik und Programmieren
Maschinen und Maschinenmodelle
Von-Neumann-Architektur
Von-Neumann-Architektur - Hauptspeicher

== Arbeitsspeicher (RAM: random access memory)


-> wahlfreier Zugriff Lesen und
Schreiben!

Feld (Array) aus Daten + Programme (Operationen)


Speicherzellen -> Kostenersparnis!
einheitlicher
Größe (z.B. 32 Bits)
direkter Zugriff
durch CPU

binäre Werte

schnelle Busanbindung
zur CPU

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 8


Technische Informatik und Programmieren
Maschinen und Maschinenmodelle
Von-Neumann-Architektur
Von-Neumann-Architektur - Hauptprozessor

== CPU (Central Processing Unit)

Programmzähler

Control Unit:
Maschinen- steuert Ausführung der
programm Maschinenbefehle
(Daten + (z.B. Reihenfolge,
Maschinen- Einlesen des
befehle) nächsten Befehls
aus Hauptspeicher)

Daten + Anweisungen
aus Hauptspeicher

Register == kleiner Speicher innerhalb der CPU

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 9


Technische Informatik und Programmieren
Maschinen und Maschinenmodelle
Von-Neumann-Architektur
Von-Neumann-Architektur - Hauptprozessor
Steuerwerk (Leitwerk bzw. Control Unit)
• steuert die Ausführung der Verarbeitungsschritte mit Hilfe von Registern
Befehlszählerregister (Programmzähler bzw. Program Counter):
• hier steht die Speicheradresse (RAM) des nächsten (Maschinen)Befehls
• Befehlszähler wird nach Befehlsausführung inkrementiert
• d.h. ohne Sprunganweisungen (jumps) entspricht Befehlsreihenfolge im
RAM der Ausführungsreihenfolge in der CPU
Befehlsregister (Instruction Register):
• enthält den aktuell auszuführenden Maschinenbefehl
• Maschinenbefehl beschreibt Operationen und Operanden (Daten)
• evtl. müssen zusätzliche Daten aus RAM ausgelesen werden
Zustandsregister (Program Status Word):
• Zusatzinformation zum Ergebnis der zuletzt ausgeführten Operation
(z.B. null oder negativ etc.)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 10


Technische Informatik und Programmieren
Maschinen und Maschinenmodelle
Von-Neumann-Architektur
Von-Neumann-Architektur - Hauptprozessor
Rechenwerk (ALU bzw. Arithmetic Logic Unit)
• führt einfache Operationen auf Daten aus
Typische Operationen:
• arithmetische Op. (Addition, Subtraktion, Multiplikation, Division)
• logische Op. (UND, ODER, XOR etc.)
• Shift-Op. (Links-/Rechtsschieben einer Bitgruppe)
• Register-Op. (Inkrementieren / Dekrementieren des Registerinhalts)
Eingangsregister:
• hier stehen die Operanden d.h. Daten (nur kurzfristig)
Ausgangsregister:
• hier steht das Ergebnis der Op. (nur kurzfristig)
Arbeitsregister:
• kann Daten länger als Eingangs-/Ausgangsregister halten

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 11


Technische Informatik und Programmieren
Maschinen und Maschinenmodelle
Von-Neumann-Architektur
Befehlsausführungszyklus

Steuerwerk
Maschinenbefehl 0

Maschinenbefehl 1 Befehlszyklus
Maschinenbefehl n

Maschinenprogramm

Phase 1: Steuerungsphase Phase 2: Ausführungsphase


ƒ Befehlsauswahl ƒ Operanden laden (RAM oder xx Register)
ƒ Was ist zu tun? ƒ Operation ausführen (ALU)
ƒ Womit ist es zu tun? ƒ Ergebnis in xx Register schreiben

klassische von Neumann-Architektur:


streng sequentielle Abarbeitung des Maschinenprogramms
(neuere Architekturen z.B. Multi-Prozessor PCs unterstützen
sog. Nebenläufigkeit d.h. gleichzeitige Bearbeitung mehrerer Anweisungen)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 12


Technische Informatik und Programmieren
Maschinen und Maschinenmodelle
Von-Neumann-Architektur
Beispiel: Maschinenprogramm zur Addition zweier Zahlen

Summand 1
Summand 2 Daten
Ergebnis

Maschinen-
programm

Akkumulator

Zustand des Rechners nach Ausführung der Addition,


vor Rückspeicherung des Ergebnisses in den Hauptspeicher
Hinweis: Daten und Maschinenprogramm sind
symbolisch dargestellt (binäre Codierung in Realität)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 13


Technische Informatik und Programmieren
Maschinen und Maschinenmodelle
Von-Neumann-Architektur
Beispiel: Maschinenprogramm zur Addition zweier Zahlen

Akkumulator: spezielles Arbeitsregister


Ein-Adressbefehle
z.B. LDA: beschreibt die Operation (load accumulator)
xx0000: Operandenteil, also Daten, mit denen die Operation ausgeführt
werden soll

Beschreibung der Maschinenbefehle:


LDA XX0000: kopiert Inhalt der Speicherzelle 0 in den Akkumulator
ADD XX0001: addiert Inhalt der Speicherzelle 1 zum Akkumulatorinhalt
STA XX0002: kopiert Akkumulatorinhalt in Speicherzelle 2 (STA store akkumulator)
STP: Stopp-Befehl

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 14


Technische Informatik und Programmieren
Maschinen und Maschinenmodelle
Von-Neumann-Architektur
Beispiel: Maschinenprogramm zur Addition zweier Zahlen
Eingangsregister enthalten noch die Summanden

BZ wurde bereits inkrementiert

Befehlszähler: Speicherzelle des nächsten Befehls


Befehlsregister: Addition wird gerade ausgeführt

Ausgangsregister enthält Ergebnis


(bereits zusätzlich im Akkumulator)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 15


Technische Informatik und Programmieren
Maschinen und Maschinenmodelle
Virtuelle Maschinen und Betriebssysteme
Motivation
Hardware bietet dem Programmierer/Benutzer Dienste an

Dienste nutzen

Laden/Ausführen
Maschinenprogramm
Hardware Programmierer / Benutzer

Hardware-
schnittstelle

Probleme:
• kein einheitlicher Standard für Hardwareschnittstellen (z.B.
unterschiedliche Prozessorfamilie INTEL x86 oder Mac?)
• Dienste der Hardwareschnittstelle sehr primitiv (Maschinenbefehle..)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 16


Technische Informatik und Programmieren
Maschinen und Maschinenmodelle
Virtuelle Maschinen und Betriebssysteme
Lösung durch Abstraktion (Virtualisierung)
z.B. Dateien erzeugen, löschen, editieren

„Veredelung“

nur Maschinensprache bzw. primitive Dienste

Virtualisierung durch Abstraktion der realen Hardware

Anwendungsbeispiel: HAL in Win-Treiberprogrammierung


Vorteile:
• Benutzer/Programmierer verwenden leichter nutzbare und übertragbare
Schnittstelle (nicht mehr die reale Hardwareschnittstelle)
¾ Software spiegelt die Schnittstelle vor (sog. Emulation)
¾ es handelt sich um eine virtuelle Maschine

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 17


Technische Informatik und Programmieren
Maschinen und Maschinenmodelle
Virtuelle Maschinen und Betriebssysteme
Beispiele für Virtualisierung

Systemsoftware (Betriebssysteme)
• setzt auf HW auf, Anwender bedient ereignisorientiert über graphische
Oberfläche (komfortable Emulation..)

höhere Programmiersprachen (C, JAVA, C# etc.)


• keine Maschinenbefehle sondern Compilation bzw. Interpretation zur
Bildung plattformspezifischer Maschinenbefehlsfolgen

Netzwerkprotokolle
• virtuelles Kommunikationsnetz durch paketorientierte Protokolle wie
TCP/IP abstrahieren von reiner Netzhardware (elektrische, optische
Signale)

schauen wir uns die Systemsoftware etwas näher an ..

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 18


Technische Informatik und Programmieren
Maschinen und Maschinenmodelle
Virtuelle Maschinen und Betriebssysteme
Systemsoftware und Betriebssystem
Systemsoftware
• alle Programme für den komfortablen Gebrauch des Computers (z.B.
Programmierumgebung, Webbrowser, Betriebssysteme etc.)
• setzt unmittelbar auf der Hardware auf und bietet „nach oben“
Schnittstellen (== Grundlage für Anwendungsprogrammierung z.B. Office)

Hauptaufgaben des Betriebssystems (operating system)


• Verwaltung aller Hard-/Softwarekomponenten (Betriebsmittel)
• Realisierung von Schnittstellen (z.B. UI user interface für Benutzer oder
auch sog. API Application programming interfaces d.h. System- bzw.
Programmierschnittstellen)
Win32-API
z.B. Zugriffe auf File system oder Zeitgeber (Counter) ..

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 19


Technische Informatik und Programmieren
Maschinen und Maschinenmodelle
Virtuelle Maschinen und Betriebssysteme
Grobstruktur und Schnittstellen eines Betriebssystems

Virtualisierung 1: Benutzer

kernel Virtualisierung 2: Programmierer

Beispiele: MS Windows, UNIX, Linux

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 20


Technische Informatik und Programmieren
Maschinen und Maschinenmodelle
Virtuelle Maschinen und Betriebssysteme
Wichtigste Bestandteile eines Betriebssystems
Dateisystem (file system)
• strukturierte Ablage von Daten auf einem Speichermedium (z.B. FAT,
NTFS, etc.)
• dazu: strukturierter Namensraum (Dateibaum) für geordneten Zugriff
Prozeßsystem
• Organisation aller Aktivitäten, die auf einem Rechner ablaufen
(insbesondere: Zuteilung der Betriebssystemressourcen)
• z.B. laufendes Programm (Application) benötigt Prozessorzeit,
Speicherplatz; Koordination mit anderen laufenden Programmen
• jede Aktivität läuft in einem geschützten „Prozeßraum“
• Zugriffe über Prozeßgrenzen hinweg bedürfen spezieller Mechanismen
z.B. IPC (inter-process communication) wie pipelining oder shared
memory ...

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 21


Technische Informatik und Programmieren
Maschinen und Maschinenmodelle
Virtuelle Maschinen und Betriebssysteme
Virtuelle Hardware
Prinzip der virtuellen Maschinen:

System-/Anwendungssoftware Virtuelle Maschine

Veredelung der „primitiven“ HW-Schnittstelle

reale Hardware

2 Grundkonzepte sind typisch:

(1) Mehrere virtuelle Hardwareschnittstellen für dieselbe Hardware

(2) Dieselbe virtuelle Hardwareschnittstelle für unterschiedliche reale


Hardwareplattformen

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 22


Technische Informatik und Programmieren
Maschinen und Maschinenmodelle
Virtuelle Maschinen und Betriebssysteme
Virtuelle Hardware (Variante 1)

z.B. Gerätetreiber

Anwendungsbeispiele:
• Multi-user Zugriffe auf Geräte z.B. Soundkarte (e.g. DirectX)
• VM-Ware: komplette Emulation des Betriebssystems inkl. Hardware (z.B.
1 Windows-Instanz und 1 Linux-Instanz auf einer PC-Hardware)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 23


Technische Informatik und Programmieren
Maschinen und Maschinenmodelle
Virtuelle Maschinen und Betriebssysteme
Virtuelle Hardware (Variante 2)

Anwendungsbeispiel:
• Java-Applets: liegen in sog. Byte-Code vor (intermediate code) und
können auf der JVM (Java Virtual Machine) auf jeder unterstützten
Plattform (Sun, Unix, Linux, Windows etc.) ablaufen

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 24


Technische Informatik und Programmieren
Grundlagen der Informatik I
- Grundlagen Programmierung -

Prof. Dr.-Ing. Frank Artinger


frank.artinger@hs-karlsruhe.de
Hinweise:
Die vorliegende Vorlesung – Grundlagen Programmierung -
basiert in wesentlichen Teilen auf dem gleichnamigen
Skriptum des HERDT-Verlages für IT-Schulungsunterlagen.
Die ständige Aktualisierung sichert gleichzeitig die Aktualität
der Lehrinhalte (ANSI-Standard).

Hyperlink: http://www.herdt4you.de/
Grundlagen
Orientierung

Grundlagen
Grundlagen der Software-Entwicklung
ORIENTIERUNG
Programmiersprachen
Werkzeuge der Software-Entwicklung
Grundlegende Sprachelemente
Darstellungsmittel für Programmabläufe
Kontrollstrukturen
Elementare Datenstrukturen
Prozeduren und Funktionen
Algorithmen
Spezielle Algorithmen
Objektorientierte Programmierung

Frank Artinger Informatik - Basics 3


Technische Informatik und Programmieren
Grundlagen
Ziele

¾ Was sind Programme?


¾ Welche verschiedenen Zahlensysteme gibt es?
¾ Welche Zeichencodes gibt es?
¾ Wie werden Daten innerhalb des Computers dargestellt?
ZIELE

Frank Artinger Informatik - Basics 4


Technische Informatik und Programmieren
Grundlagen
Inhalt
Grundlagen
Grundbegriffe
Warum programmieren?
Zahlensysteme
Dezimalsystem
Dualsystem
INHALT

Oktalsystem
Hexadezimalsystem
Programme basieren auf Zahlen
Digitales Rechnen
Zeichencodes
Übung

Frank Artinger Informatik - Basics 5


Technische Informatik und Programmieren
Grundlagen
Grundbegriffe
Computer im Zentrum der Informatik (Computer Science)
• Computer alleine löst keine Probleme
• Vorgabe eines Rechenwegs (Algorithmus) notwendig
• Programme beinhalten des Lösungs-/Rechenweg

Bedeutung des Computers - Entwicklung


• vor einigen Dekaden ging es im wesentlichen um die Lösung
mathematischer Problemstellungen
• steigende Leistungsfähigkeit (Integrationsdichte) und kostengünstige
Verfügbarkeit öffneten den Einsatz für Routineaufgaben (viele Bereiche des
täglichen Lebens, E-Commerce, C2C, B2C, B2B, Internet-Banking, E-
Learning, etc.)

Marktdurchdringung mit Internetanschlüssen > 50%


(Stand E2004)

Frank Artinger Informatik - Basics 6


Technische Informatik und Programmieren
Grundlagen
Definition eines Programms
Was ist ein Programm überhaupt?
• Bearbeitungsvorschrift (Algorithmus) für einen Computer zur Lösung einer
vorgegebenen Aufgabe
• Formulierung in einer speziellen (sog. formalen) Sprache ==
Programmiersprache
• für verschiedene Anwendungsgebiete existieren unterschiedliche
(spezialisierte) Programmiersprachen
• vor der Programmausführung ist eine Übersetzung (Compilation oder
Interpretation) des Programms in eine für den Computer verständliche Form
(sog. Maschinensprache) notwendig

Programm ist eine Bearbeitungsvorschrift (Algorithmus),


dessen Anweisungsfolge in einer Programmiersprache
formuliert ist.

Frank Artinger Informatik - Basics 7


Technische Informatik und Programmieren
Grundlagen
Definition von Software
Was ist dann Software?
• Software ist umfassender als Programm

Software umfaßt alle immateriellen Teile eines Computers


(Programme + zugehörige Daten + Dokumentation)

Beispiel: Aufbau eines E-Learning-Systems

Quelle: VSI-System, Uni Erlangen-Nürnberg

Frank Artinger Informatik - Basics 8


Technische Informatik und Programmieren
Grundlagen
EVA-Prinzip
EVA-Prinzip (Eingabe – Verarbeitung – Ausgabe)
• Grundprinzip der Datenverarbeitung
Eingabe:
• Benutzer, andere Programme oder Applikationen, Datenbanken
Verarbeitung:
• Datenfilterung, algorithmische Verarbeitung (Datenveredelung)
Ausgabe:
• Ergebnisse der Verarbeitung, Ausgabe an Benutzer, andere Programme
oder Datenbank(en)

Eingabe Verarbeitung Ausgabe

Datenfluß durch ein Programm

Frank Artinger Informatik - Basics 9


Technische Informatik und Programmieren
Grundlagen
Motivation
Warum programmieren?
• -> s. Motivationsfolien im Intro

Standard-Software anpassen
• Tätigkeitsfeld der Unternehmensberater (Geschäftsprozeßoptimierung mit
gleichzeitiger Erneuerung des „information backbones“ im Unternehmen
z.B. durch Einführung eines SAP-Systems)
• Standard-Unternehmenslösung muß an individuelle betriebliche
Gegebenheiten angepaßt werden

Automatisierung
• im Zeitalter der Globalisierung wird im verstärkten Automatisierungsgrad
ein high potential für Kostensenkungsprogramme gesehen
• ca. 60% der Investitionskosten für Automatisierung werden für die SW-
Erstellung verwendet

Frank Artinger Informatik - Basics 10


Technische Informatik und Programmieren
Grundlagen
Motivation
Warum programmieren?
Produkt-SW-Entwicklung als Business
• hohe Entwicklungskosten stehen sehr geringen Stückkosten gegenüber
• bei geeigneten Marktbedingungen eine erfolgversprechende geschäftliche
Tätigkeit

Individual-Software als Business


• meist auch als „Software für Projekte“ bezeichnet
• geeignet für Märkte, die mit systematischen Standards nicht oder nur
unzureichend zu durchdringen sind
• größte (finanzielle) Gefahr liegt in den oft unterschätzten Aufwendungen
für Wartung & Pflege individueller Projektlösungen

Frank Artinger Informatik - Basics 11


Technische Informatik und Programmieren
Grundlagen
Motivation
Warum programmieren?
Erhöhte Nachfrage nach Software
• jährliche Nachfragesteigerung bei Software beträgt ca. 10-25%
• demgegenüber steht eine Produktivitätssteigerung bei der SW-
Entwicklung von ca. 4%

Qualitativ hochwertige Software ist ein Engpaß der


Informationstechnik geworden!

Typisches Beispiel:
• Verfügbarkeit äußerst leistungsfähiger Computer in Mehrprozessortechnik
• eine optimale Ausnutzung durch die SW-Technik gelingt nur teilweise

Frank Artinger Informatik - Basics 12


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Zahlensysteme
• Darstellung quantitativer Merkmale (Gegenstände, Vorgänge, etc.) erfolgt
durch Zahlensysteme
• eine Zahle wird nach den Regeln des Zahlensystems als Folge von Ziffern
dargestellt
• man unterscheidet zwischen Additionssystemen und Stellenwertsystemen
(Positionssysteme)

Bekannte Zahlensysteme in Europa:


• Römisches Zahlensystem (I, II, III, IV, V, ...) -> Additionssystem
• Arabisches Zahlensystem (0, 1, 2, 3, ...) -> Stellenwertsystem

jünger, aber bekannter in Europa


(leistungsfähiger für Rechenoperationen)

Frank Artinger Informatik - Basics 13


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
AUSFLUG: Römisch-etruskisches Zahlensystem
• Vertreter des Additionssystems (Zahl entspricht der Summe der Werte ihrer
Ziffern)

I 1
V 5
X 10 Ziffern nach abnehmender Wertigkeit geordnet
L 50 z.B. 2002 entspricht MMII
C 100
D 500
M 1000

Nachteile: Zahlen können sehr lang werden, Rechenoperationen


entsprechend aufwendig

Historie: bis ins 15. Jahrhundert in Europa verwendet

Frank Artinger Informatik - Basics 14


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Grundlagen zum Stellenwertsystem (Positionssystem)
• die Stelle (Position) der Ziffer impliziert den Wert
• die „niederwertigste“ Position steht i.a. rechts
Nennwerte:
• Ziffern und Zeichen, die in einem Zahlensystem vorkommen können
• alle Zahlen sind zusammengesetzt aus Nennwerten

Basis des Zahlensystems:


• Anzahl der Nennwerte == Basis b des Zahlensystems
• Ziffern laufen von 0 bis b-1

Stellenwert (Potenz):
• jede Ziffernposition hat einen Wert, der einer Potenz der Basis entspricht
(sog. Stellenwert)
• n-te Position hat den Wert von bn-1

Frank Artinger Informatik - Basics 15


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Dezimalsystem (Stellenwertsystem)
• abgeleitet aus der menschlichen Physiologie („10 Finger“)
Basis: b = 10 (d.h. 10 Nennwerte von 0...9)
Nennwerte:

0123456789

Beispiel zum Aufbau einer Dezimalzahl:

59647 = 7* 100 -> 7


+ 4* 101 -> 40
+ 6* 102 -> 600
+ 9* 103 -> 9000
+ 5* 104 -> 50000
= 59647

Frank Artinger Informatik - Basics 16


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Dualsystem (Binärsystem) (Stellenwertsystem)
• 17. Jahrhundert, entwickelt von Gottfried Wilhelm Leibniz
• arbeitet nur mit Ziffern 0 und 1
• durch Kombination ist jede natürliche Zahl darstellbar
Basis: b = 2 (d.h. 2 Nennwerte von 0...1)
Nennwerte:
01

Beispiel zum Aufbau einer Dualzahl:

110110101 = 1* 20 -> 1
+ 0* 21 -> 0
+ 1* 22 -> 4
+ 0* 23 -> 0
+ 1* 24 -> 16
+ 1* 25 -> 32

Frank Artinger Informatik - Basics 17


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Dualsystem (Binärsystem) (Stellenwertsystem)

+ 0* 26 -> 0
+ 1* 27 -> 128
+ 1* 28 -> 256
= (437)10

Hinweis:
Zur Vermeidung von Mißverständnissen, welchem Zahlensystem
Ziffernfolgen angehören, wird häufig die Basis tiefgestellt rechts neben der
Zahl angegeben (z.B. (101)10, (101)2 oder (5)8 )

Umwandlung Dualzahl -> Dezimalzahl


• Addition der Stellenwerte (s.o.)

Frank Artinger Informatik - Basics 18


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Dualsystem (Binärsystem) (Stellenwertsystem)
Umwandlung Dezimalzahl -> Dualzahl
• Division der Dezimalzahl durch 2 und Rest notieren
• solange wiederholen, bis das ganzzahlige Ergebnis 0 beträgt

Beispiel zur Umwandlung (426)10 -> Dualzahl


426 / 2 = 213 Rest 0 0
213 / 2 = 106 Rest 1 1
106 / 2 = 53 Rest 0 0
53 / 2 = 26 Rest 1 1
26 / 2 = 13 Rest 0 0
13 / 2 =6 Rest 1 1
6/2 =3 Rest 0 0
3/2 =1 Rest 1 1
1/2 =0 Rest 1 1
= 1 1 0 1 0 1 0 1 0

Frank Artinger Informatik - Basics 19


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Oktalsystem (Stellenwertsystem)
Motivation: Länge von Dualzahlen ist unhandlich, Oktal- bzw.
Hexadezimalsystem fassen mehrere Stellen einer Dualzahl zusammen!
• codiert 3 Stellen einer Dualzahl (8 Kombinationen von 000 - 111)
• Oktalsystem früher führend in DV, heute veraltet
Basis: b = 8 (d.h. 8 Nennwerte von 0...7)
Nennwerte:
01234567

Beispiel zum Aufbau einer Oktalzahl:

1213 = 3* 80 -> 3
+ 1* 81 -> 8
+ 2* 82 -> 128
+ 1* 83 -> 512
= (651)10

Frank Artinger Informatik - Basics 20


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Oktalsystem (Stellenwertsystem)
Umwandlung Oktalzahl -> Dezimalzahl:
• Addition der Stellenwerte (s.o.)

Umwandlung Dezimalzahl -> Oktalzahl:


• vgl. Dualzahl: Division der Dezimalzahl durch 8 und Rest notieren
• solange wiederholen, bis das ganzzahlige Ergebnis 0 beträgt

Beispiel zur Umwandlung (30571)10 -> Oktalzahl

30571 / 8 = 3821 Rest 3 3


3821 / 8 = 477 Rest 5 5
477 / 8 = 59 Rest 5 5
59 / 8 =7 Rest 3 3
7/8 =0 Rest 7 7
= 7 3 5 5 3

Frank Artinger Informatik - Basics 21


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Hexadezimalsystem (Stellenwertsystem)
• codiert 4 Stellen einer Dualzahl (16 Kombinationen von 0000 - 1111)
• mit Einführung des Byte (8 Bits) wurde das Oktal- durch das
Hexadezimalsystem weitgehend abgelöst
• 1 Byte wird durch 2 Hexadezimal-Zahlen dargestellt

1010 1111 1111 1110


A F F E
Aufbau einer Hexadezimalzahl
Basis: b = 16 (d.h. 16 Nennwerte von (0 .. 15) )
Nennwerte:
• da das arabische Zahlensystem nur 10 Ziffern besitzt wurde vereinbart,
die übrigen Ziffern mit Buchstaben zu bezeichnen:
10 = A, 11 = B, 12 = C, 13 = D, 14 = E und 15 = F

0123456789ABCDEF

Frank Artinger Informatik - Basics 22


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Hexadezimalsystem (Stellenwertsystem)
Beispiel zum Aufbau einer Hexadezimalzahl:

7B1 = 1* 160 -> 1


+ 11 * 161 -> 176
+ 7* 162 -> 1792
= (1969)10

Umwandlung Hexadezimalzahl -> Dezimalzahl


• Addition der Stellenwerte, d.h. Summe der Potenzen zur Basis 16 (s.o.)

Umwandlung Dezimalzahl -> Hexadezimalzahl


• vgl. Dualzahl: Division der Dezimalzahl durch 16 und Rest notieren
• solange wiederholen, bis das ganzzahlige Ergebnis 0 beträgt

Frank Artinger Informatik - Basics 23


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Hexadezimalsystem (Stellenwertsystem)
Beispiel zur Umwandlung (251277)10 -> Hexadezimalzahl:

251277 / 16= 15704 Rest 13 D


15704 / 16 = 981 Rest 8 8
981 / 16 = 61 Rest 5 5
61 / 16 =3 Rest 13 D
3 / 16 =0 Rest 3 3
= 3 D 5 8 D

(251277)10 = (3D58D)16

Frank Artinger Informatik - Basics 24


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Hexadezimalsystem (Stellenwertsystem)
Umwandlung Hexadezimalzahl <-> Dualzahl

A) Umwandlung (AFFE)16 -> Dualzahl


2 Hex-Ziffern entsprechen 1 Byte

1010 1111 1111 1110 jede Hexziffer entspricht 4 Bits


A F F E
B) Umwandlung (1010 1111 1111 1110)2 -> Hex-Zahl

A (10) 1010
F (15) 1111
F (15) 1111
E (14) 1110
= 1010 1111 1111 1110

Frank Artinger Informatik - Basics 25


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Programme basieren auf Zahlen
Analoge Daten
• analoge Daten werden durch eine kontinuierliche Funktion (z.B.
Zeigerdarstellung der Uhr oder Skala beim Thermometer) dargestellt
• analog bedeutet: entsprechend, vergleichbar

Digitale Daten
• immer durch Ziffern dargestellt (digit == Ziffer)
• Datenverarbeitung im Computer erfolgt nur digital!

Frank Artinger Informatik - Basics 26


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Problem der begrenzten Rechengenauigkeit
Beispiel:

2.0 / 3.0 * 3.0 = ?


• math. exaktes Ergebnis: 2
• berechnetes Ergebnis im Computer u.U.: 1.999999998

Ursache:
• eine Zahl wird im Rechner nur mit einer begrenzten Anzahl von
Dezimalstellen dargestellt (z.B. wird das periodische Ergebnis 2/3 = 0.66666
abgeschnitten)
• die weitere Berechnung erfolgt auf Basis der genäherten Zahlenwerte
(Folgefehler durch begrenzte Rechengenauigkeit)

Praxisbezug: Zeichenprogramme für Vektorgraphik

Frank Artinger Informatik - Basics 27


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Vorteile des Dualsystems für die rechnerinterne Darstellung
Vorteile:
• binär codierte Daten sind einfach und mit sehr niedriger Fehlertoleranz auf
verschiedene Arten darstellbar, weiterzugeben, weiterzuverarbeiten

Beispiele zur Verarbeitung digitaler Daten:

Nutzungsart Ziffer 0 entspricht Ziffer 1 entspricht


Speicherung mit Spannung Keine Spannung Ca. 6 Volt Spannung
Speicherung mit Magnetismus Magnetisches Feld vorhanden Veränderung der Polarität

Übertragung mit Tönen Kurzer Ton Langer Ton


Speicherung mit Relais Schaltung offen Schaltung geschlossen
Optische Speicherung auf Medium undurchsichtig (kein Medium durchsichtig (Loch)
Lochstreifen, Karte Loch)
Optische Speicherung auf Kein Übergang von oder zu Übergang von oder zu einer
CD, DVD einer Vertiefung („pits & falls“) Vertiefung

Frank Artinger Informatik - Basics 28


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Warum nicht im Dezimalsystem codieren?
• prinzipiell kann (statt mit 2 z.B. 0V .. 6V) auch mit 10 Zuständen (z.B. 0V,
1V, 2V, 3V, etc.) gearbeitet werden

Probleme:
• höherer technischer Aufwand wegen größerer Anzahl an Signal-
/Spannungspegeln
• Fehlerwahrscheinlichkeit steigt (Pegeldifferenzen sinken) 2.5V -> ?

Frank Artinger Informatik - Basics 29


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Bits & Bytes
Bit:
• kleinste Speichereinheit in einem Computer oder auf einem Datenträger
(HD, CD etc.)
• Bit == binary digit, Binärziffer, Dualziffer

Byte:
• Zusammenfassung von 8 Bits -> 1 Byte
• 1 Byte kann intern exakt 1 Zeichen (Ziffern, Buchstaben, Sonder-
/Steuerzeichen) darstellen
• Zeichen werden durch sog. Zeichencodes abgebildet (z.B. Buchstabe ‘A‘
entspricht der Zahl (65)10 etc.)
mit 2 Byte können alle auf der Welt
Word (Wort): bekannten Zeichen codiert werden
• Zusammenfassung von 2 Byte -> 16 Bits
• z.B. Internationalisierung der Zeichendarstellung (vgl. Unicode)

Frank Artinger Informatik - Basics 30


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Bitmuster
• Folge von Bits wird auch als Bitmuster bezeichnet
• muß nicht notwendigerweise eine 8-Bit-Folge sein

Bit Bit Bit Bit Bit Bit Bit Bit

8 Bits = 1 Byte

1 KByte = 1024 Byte = 210 Byte


1 MByte = 1024 KByte = 220 Byte
1 GByte = 1024 MByte = 230 Byte

417024000 Bytes / (1024)2 ≈ 397 MByte

Frank Artinger Informatik - Basics 31


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Praxisbezug: Paritätsbit
• Störungen in der Übertragung von Bitmustern (Nachrichtenkanal z.B.
Leitung LAN oder Luft WLAN) können das Bitmuster verändern
• z.B. Bit kippt durch „Schaltfehler“ von 0 -> 1 oder umgekehrt

Paritätsbit zur Fehlererkennung:


• zur Erkennung von Übertragungsfehlern wird ein sog. Prüfbit (Paritätsbit) an
das Daten-Bitmuster angehängt
• ein sog. „parity-check“ gibt Aufschluß über die Datenqualität
gerade Parität: Paritätsbit 0, wenn Anzahl der 1 im Bitmuster gerade
ungerade Parität: Paritätsbit 1, wenn Anzahl der 1 im Bitmuster ungerade

dieses einfache Verfahren hilft allerdings nicht bei der Rekonstruktion, da


unbekannt ist, welches Bit verändert wurde (i.d.R. wird das Bitmuster oder
Datenpaket erneut vom Sender angefordert)

Frank Artinger Informatik - Basics 32


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Praxisbezug: Paritätsbit
Beispiel:

1 10001111
PB Bitmuster

Zustand des Paritätsbits:


Summe der Einsen = 5
5 modulo 2 = 1 -> Paritätsbit = 1

modulo: Rest einer Ganzzahldivision

Frank Artinger Informatik - Basics 33


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Digitales Rechnen
• sämtliche Daten und der Programmcode liegen in binärer Form vor (Zahlen,
Speicheradressen, Maschinenbefehle etc.)
• Verarbeitung heißt: Rechnen mit binären Daten

Addition von Dualzahlen


• ähnlich der schriftlichen Addition von Dezimalzahlen

Beispiel: 0+0=0
0+1=1
45 101101 1+0=1
+ 58 + 111010 1 + 1 = 0, Übertrag 1
------------------- ---------------------------
Übertrag: 10 Übertrag: 1110000 Ergebnistabelle
------------------- ---------------------------
103 1100111

Dezimalsystem Dualsystem

Frank Artinger Informatik - Basics 34


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Komplementbildung
• sehr häufig benötigte Operation im Computer (vgl. Subtraktion ff.)
• man unterscheidet 2 Arten von Komplementbildungen für eine positive Zahl
Z mit der Basis b

(b-1) Komplement
• häufig für gebrochen rationale Zahlen verwendet (Zahlen mit
Nachkommastellen)
• Binärsystem: 1er-Komplement (Invertierung des Bits, Negation)

b – Komplement
• häufig für die Subtraktion ganzer Zahlen verwendet
• Binärsystem: 2er-Komplement

Frank Artinger Informatik - Basics 35


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Bildung des b-Komplements
Das b-Komplement der positiven n-stelligen Zahl Z mit der Basis b wird wie
folgt gebildet:

bn – Z für Z≠0
0 für Z=0

Beispiele:
10er-Komplement der Zahl 4637:

104 - 4637 = 5363


? -> siehe Subtraktion auf
den folgenden Folien!
2er-Komplement der Zahl 11010101:

28 - 11010101 =
100000000 - 11010101 = 00101011

Frank Artinger Informatik - Basics 36


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Subtraktion von Dualzahlen
• Verfahren der schriftlichen Subtraktion für digitale Rechner ungeeignet
• stattdessen wird eine Addition mit dem b-Komplement ausgeführt

0–0=0
Kochrezept: 1–0=1
Es soll der Ausdruck für Z1 – Z2 gebildet werden. 0 – 1 = 1, Übertrag – 1
1–1=0
(1) b-Komplement von Z2 bilden
(2) Addition von Z1 und Komplement Z2 Ergebnistabelle

(3) Übertrag an der höchsten Stelle wird weggelassen


zu (3)Tritt an der höchsten Stelle kein Übertrag auf, wird vom Ergebnis der
Addition das b-Komplement gebildet und mit einem negativen Vorzeichen
versehen.

Der negative Übertrag wird im Computer in einem speziellen Bit (sog.


Borrowbit) gespeichert!

Frank Artinger Informatik - Basics 37


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Subtraktion von Dualzahlen
Beispiel 1: 58 – 45

Z1 = 58, Z2 = 45
(1) Komplement von 45: 10² - 45 = 100 – 45 = 55
(2) 58 + 55 = 113
(3) Übertrag streichen: 113
-> Ergebnis: 58 – 45 = 13

TRICK (Erklärung folgt)


Beispiel 2: 111010 – 101101

Z1 = 111010, Z2 = 101101
(1) Komplement von 101101: 26 - 101101 = 1000000 – 101101 = 10011
(2) 111010 + 10011 = 1001101
(3) Übertrag streichen: 1001101
-> Ergebnis: 111010 – 101101 = 001101 = 1101

Frank Artinger Informatik - Basics 38


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Subtraktion von Dualzahlen
Beispiel 3: 101001 – 110001 (negativer Übertrag!) TRICK (Erklärung folgt)

Z1 = 101001, Z2 = 110001
(1) Komplement von 110001: 26 – 110001 = 1000000 – 110001 = 1111
(2) 101001 + 1111 = 111000
(3) kein Übertrag, Komplement des Ergebnisses: 000111 + 1 = 1000
-> Ergebnis: 101001 – 110001 = - 1000

Frank Artinger Informatik - Basics 39


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
TRICK zur einfachen Berechnung des 2er Komplements (2K, K2)

Kochrezept:
• sämtliche Ziffern negieren (aus 0 -> 1, aus 1 -> 0)
• zur negierten Zahl + 1 addieren

2K von 110001: 001110 + 1 = 1111


2K von 111000: 000111 + 1 = 1000

Frank Artinger Informatik - Basics 40


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Weitere Bedeutung des 2er-Komplements
• 2er-Komplement ist eine Möglichkeit, negative Zahlen im Binärsystem
darzustellen (ohne zusätzliche Symbole wie „+“ oder „-“)
• 2er-Komplement ist die vorherrschende Art, wie negative Zahlen im
Computer dargestellt werden

Funktionsprinzip:
• sowohl die eigentliche Zahl als auch das negative Vorzeichen werden in der
binären Kodierung dargestellt
• üblicherweise wird für den Betrag der Zahl (positiv und negativ) eine feste
Stellenzahl (n) verwendet, das führende Bit (auch MSB most significant bit)
wird für das Vorzeichen VZ verwendet

Vorzeichenbehaftete Ganzzahl
VZ (z.B. signed short int)

7-Bits für den Zahlenbereich [0 .. 27 – 1]

Frank Artinger Informatik - Basics 41


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Weitere Bedeutung des 2er-Komplements
Zahlendarstellung:
Positive Zahlen sind durch 0 im VZ-Bit gekennzeichnet
0 1 1 1 1 1 1 1 (1111111)2 = (127)10
7-Bits für den Zahlenbereich [0 .. 27 – 1]

Negative Zahlen sind durch 1 im VZ-Bit gekennzeichnet; der Zahlenwert


wird im 2er-Komplement dargestellt!

1 1 1 1 1 1 1 1 2K(1111111)2 = (1)2 = (1)10


7-Bits für den Zahlenbereich [0 .. 27 – 1]
(-1)10

1 0 0 0 0 0 0 0 2K(0000000)2 = (10000000)2 = (128)10


7-Bits für den Zahlenbereich [0 .. 27 – 1]
(-128)10

Frank Artinger Informatik - Basics 42


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Weitere Bedeutung des 2er-Komplements
Zahlendarstellung, weitere Beispiele:
+410 = 00000100
-410 = 11111011 + 1 = 11111100
-110 = 11111111
12710 = 01111111
-12810 = 10000000

Großer Vorteil der 2er-Komplementdarstellung:


Es gibt nur eine Darstellung für die Zahl 0!
(0 0000000)

Frank Artinger Informatik - Basics 43


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Weitere Bedeutung des 2er-Komplements
Zahlendarstellung, nochmal Beispiele:
-• 4Addition
+ 3 = -1undführt
Subtraktion
zu benötigen keine Fallunterscheidung (Überträge,
Überläufe werden abgeschnitten)
11111100
+ 00000011
= 11111111;

+ 4 – 4 = 0 führt zu
00000100
+ 11111100
=100000000
-> durch Abschneiden des Übertrags 1 wird daraus 00000000 = 0

Frank Artinger Informatik - Basics 44


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Multiplikation von Dualzahlen
• Multiplikation wird im Rechner durch bitweise Verschiebungen (bit shift) und
Addition realisiert
• ähnlich der schriftlichen Multiplikation
0*0=0
1*0=0
Beispiele: 0*1=0
1*1=1
58 * 115 111010 * 101 Ergebnistabelle
------------ ------------------
58 111010
+ 58 left shift und
+ 000000
+ 290 + 111010 Addition
------------ ------------------
6670 100100010
Dezimalsystem Dualsystem

Wie wird die Multiplikation im Rechenwerk des Computers realisiert?

Frank Artinger Informatik - Basics 45


Technische Informatik und Programmieren
Grundlagen
Zahlensysteme
Multiplikation von Dualzahlen
Multiplikation im Computer:
• Zwischenergebnisse der Multiplikation werden sofort addiert (Adder)
• die Zwischenergebnisse werden im Akkumulator (Speicher für
Rechenergebnisse) gespeichert
• wenn alle Zwischenergebnisse addiert wurden, steht das Endergebnis im
Akkumulator

¾ Multiplikation wird durch Linksverschieben und Addition realisiert

Frank Artinger Informatik - Basics 46


Technische Informatik und Programmieren
Grundlagen
Zeichencodes
Zeichencodes
Warum Zeichencodes?
• da der Rechner Daten nur in binärer Form verarbeiten kann, müssen
Zeichen (Ziffern, Buchstaben, Sonderzeichen etc.) binär kodiert werden
• die Interoperabilität (d.h. die Zusammenarbeit) zwischen Rechnern,
Datenaustausch, plattformübergreifende Ablauffähigkeit von Applikation
etc. erfordern kompatible standardisierte Zeichencodes

Definition eines Zeichencodes:


Ein Zeichencode stellt eine Zuordnungsregel dar, mit deren Hilfe jedes
Zeichen eines Zeichenvorrates eindeutig durch bestimmte Zeichen
eines anderen Zeichenvorrates dargestellt werden.

Beispiele für standardisierte Zeichencodes:


• ASCII-Code, ANSI-Code, Unicode etc.

Frank Artinger Informatik - Basics 47


Technische Informatik und Programmieren
Grundlagen
Zeichencodes
Praxisbezug: Zeichencodes
Stichwort: Globalisierung in der Software-Entwicklung
80% aller Großunternehmen
besitzen „Offshoring“
Aktivitäten

mit zweistelligen
Wachstumsraten
sorgt SEA für
marktwirtschaftl.
Expansion

Exportchancen von SW werden entscheidend


durch die Unterstützung der Landessprache beeinflußt!

Frank Artinger Informatik - Basics 48


Technische Informatik und Programmieren
Grundlagen
Zeichencodes
Der ASCII-Code
• ASCII == American Standard Code for Information Interchange
• als ANSI-Standard X3.4 von Bob Bemer1 (1968) eingeführt
• amerikanischer Normcode auf 7-Bit-Basis (binäre Ganzzahlen, mit 7 Ziffern
dargestellt), sehr weit verbreitete Textdarstellung im Computer u.a.
technischen Geräten
• Standard-ASCII Code umfaßt damit: 27 = 128 Zeichen (im wesentlichen
lateinisches Alphabet, Steuerzeichen)
Was ist mit nationalen Sonderzeichen wie z.B. deutsche Umlaute?
• ASCII-Code wurde später auf 8-Bit (28 = 256 Zeichen) erweitert (sog.
erweiterter ASCII-Code oder „IBM character set“)
• darin sind auch einige nationale Sonderzeichen (sog. diakritische Zeichen)
enthalten
• HINWEIS: international ist nur der Standard-ASCII Code zugesichert!
Werfen wir einen Blick auf die ASCII Code Tabelle..
1
: Computerpionier, berühmt durch Publikationen zum Y2K-Problem (2-stellige Angabe der Jahreszahl)

Frank Artinger Informatik - Basics 49


Technische Informatik und Programmieren
Grundlagen
Zeichencodes
Dezimal-Code
Standard-ASCII-Code (0 – 127) Hex-Code
Zeichen

32 Steuerzeichen (0-31)
(keine Schriftzeichen,
z.B. Steuerung von
Druckern,
0x07 BEL: Glocke,
0x20 SP: space, blank)

druckbare Zeichen (33-126)


(Buchstaben, Ziffern,
Satzzeichen)

„Löschzeichen“ (DEL)
(Historie: Lochstreifen)

Frank Artinger Informatik - Basics 50


Technische Informatik und Programmieren
Grundlagen
Zeichencodes
Erweiterter-ASCII-Code (128 – 255) (Codepage CP437)

diakritische Zeichen
(nationale Sonderzeichen,
z.B. dt. Umlaute)

Graphikzeichen
(vgl. WANG-Maschinen)

Frank Artinger Informatik - Basics 51


Technische Informatik und Programmieren
Grundlagen
Zeichencodes
Praxisbezug: Direkte Eingabe von ASCII-Zeichen in MS Windows

Im Windows-Betriebssystem kann ein ASCII-Zeichen direkt über die


Tastatur eingegeben werden:

¾ bei gedrückter ALT-Taste den ASCII-Wert über den numerischen


Tastaturblock eingeben

Frank Artinger Informatik - Basics 52


Technische Informatik und Programmieren
Grundlagen
Zeichencodes
EBCDI-Code (IBM)
• EBCDI == Extended Binary-Coded Decimal Interchange länderspezifische
• 8-Bit-Code vor allem auf Großrechnern verwendet Zeichensätze
• es existieren mehrere Varianten (Codepages) um Sprachunterschiede
auszugleichen
• EBCDI ist dem ASCII-Code sehr ähnlich ABER: es gibt keine gleichen
Teilmengen
• die Codeumwandlung ASCII <-> EBCDI muß mit Hilfe von
Kodierungstabellen erfolgen

Frank Artinger Informatik - Basics 53


Technische Informatik und Programmieren
Grundlagen
Zeichencodes
ANSI-Code (vgl. erweiterter ASCII-Code)
• ANSI == American National Standards Institute (vgl. zur DIN)
• 8-Bit-Code, character set von Microsoft Windows

Hinweis:
• MS-DOS verwendet den Standard-ASCII-Code
• MS Windows (auch XP) verwendet den erweiterten ASCII/ANSI-Code
• -> beim Datenaustausch zwischen DOS und Windows-Applikationen kann
es u.U. zu Konvertierungsproblemen kommen!

Frank Artinger Informatik - Basics 54


Technische Informatik und Programmieren
Grundlagen
Zeichencodes
Unicode (ISO: Universal Character Set UCS)
• internationaler Standard für die digitale Kodierung aller sinntragenden
Zeichen aller bekannten Schriftkulturen und Zeichensysteme
• wird als Lösung bislang inkompatibler länderspezifischer Zeichencodes
angesehen

Motivation:
• mit den bisherigen Zeichencodierungen (ASCII, ANSI etc.) können nur
wenige Sprachen gleichzeitig in einem Text dargestellt werden (Folge:
Behinderung des internationalen Datenaustauschs)

Beteiligte Organisation:
• Unicode Consortium (www.unicode.org)
• ISO (International Organization for Standardization) Norm: ISO 10646

Frank Artinger Informatik - Basics 55


Technische Informatik und Programmieren
Grundlagen
Zeichencodes
Unicode (ISO: Universal Character Set UCS)
Funktionsprinzip und Charakteristika
• aktueller Standard ist ein 16-Bit-Code (Coderaum 216 = 65536 Zeichen)
• hebräische, lateinische, chinesische Buchstaben sind Zeichensatzwechsel
darstellbar
• AKTUELL: Arbeiten an Unicode Version 4.0 (32-Bit-Code)
• Speicherung / Übertragung von Unicode erfolgt in unterschiedlichen
Formaten:
UTF-8 (Unicode Transformation Format) -> Webbrowser, Betriebssysteme
UTF-7 -> Umsetzung aus vorhandenen 7-Bit-Codes
UTF-EBCDIC -> Umsetzung von EBCDIC in Unicode

¾WICHTIG: einmal kodierte Zeichen dürfen niemals wieder entfernt


werden (Langlebigkeit digitaler Daten), vor der Normierung eines
Zeichens erfolgt eine sorgfältige Prüfung (kann Jahre dauern..)

Frank Artinger Informatik - Basics 56


Technische Informatik und Programmieren
Grundlagen
Zeichencodes
Praxisbezug: Unicode und Alternativen in MS Windows
Plattformen ab MS Windows 2000 (NT-Basis)
• volle Unterstützung des 16-Bit-Unicodes
• jedes Zeichen wird immer durch 2 Bytes dargestellt (dadurch immanent
höherer Speicherbedarf, aber international erweiterbar!)
Plattformen MS Win95, 98, ME etc.
• keine Unterstützung von Unicode
• nur MBCS (multibyte character set) möglich (Obermenge des ASCII-
Zeichencodes, manche Zeichen werden mit 2 Bytes, manche mit 1 Byte
kodiert)

EMPFEHLUNG:
Wenn immer möglich, sollte die Implementierung auf Unicode-Basis
vorgenommen werden!

Frank Artinger Informatik - Basics 57


Technische Informatik und Programmieren
Grundlagen
Übung
Vorlesungsbegleitende Übung
(1) Was ist ein Programm?
(2) Was verstehen Sie unter dem EVA-Prinzip?
(3) Erstellen Sie eine Tabelle mit 4 Spalten. Tragen Sie in die erste Spalte
die Dezimalzahlen von 1 bis 16 ein. In die zweite Spalte sind dann die
entsprechenden Dualzahlen, in der dritten Spalte die Oktalzahlen und in
der vierten Spalte die Hexadezimalzahlen einzutragen.
(4) Wandeln Sie die Dezimalzahl 12345 in eine hexadezimale Zahl um.
(5) Geben Sie die hexadezimale Zahl 1F binär im Dualsystem an.
(6) Welchen dezimalen Wert hat die Oktalzahl 1357?
(7) Rechnen Sie die Dezimalzahl 735 in das Dual- und Oktalsystem um.
(8) Stellen Sie die Binärzahl 1101 1100 1011 1010 in hexadezimaler Form
dar.
(9) Was verstehen Sie unter dem Begriff Bit und Byte?
(10) Addieren Sie die Dualzahlen 11011011 und 1010011001.

Frank Artinger Informatik - Basics 58


Technische Informatik und Programmieren
Grundlagen
Übung
Vorlesungsbegleitende Übung
(11) Lösen Sie die folgende Aufgabe: 1101111 – 111111 und
1011000 – 1100011
(12) Multiplizieren Sie die Zahlen 1011110 und 110010.
(13) Rechnen Sie um: 3600 Bytes in KByte, sowie 1,44 MByte in Byte.
(14) Warum mußte das Unicode-Zeichensystem entwickelt werden?

(Lösung: ueb01.pdf)

Frank Artinger Informatik - Basics 59


Technische Informatik und Programmieren
Grundlagen der Informatik
- ANSI C 2.0 Grundlagen Programmierung -

Prof. Dr.-Ing. Frank Artinger


frank.artinger@hs-karlsruhe.de
Hinweise:
Die vorliegende Vorlesung – ANSI C 2.0 Grundlagen
Programmierung - basiert in wesentlichen Teilen auf dem
gleichnamigen Skriptum des HERDT-Verlages für IT-
Schulungsunterlagen. Die ständige Aktualisierung sichert
gleichzeitig die Aktualität der Lehrinhalte (ANSI-Standard).

Hyperlink: http://www.herdt4you.de/
Einleitung
Orientierung
Einleitung
Das erste Programm in C
ORIENTIERUNG
Konstanten
Einfache Datentypen
Unterprogramm – Technik –
Nützliche Funktionen
Steuerstrukturen
Typvereinbarungen von Variablen
Zeiger
Der Präcompiler
Modulare Programmierung
Entwicklungsumgebungen
Standardbibliotheken
Anhang

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 3


Technische Informatik und Programmieren
Einleitung
Ziele

¾ Woraus ist die Programmiersprache C entstanden?


¾ Zusammenhang zwischen Algorithmus und Programm
¾ Wie wird ein Programm erstellt?
¾ Wie wird ein Programm mit dem Compiler übersetzt?
ZIELE

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 4


Technische Informatik und Programmieren
Einleitung
Inhalt
Einleitung
Systemimplementierungssprachen
Entstehung von C (und C++)
Übersicht zu C / C++
Designhinweise (Stärken & Schwächen von C)
INHALT

Algorithmus und C-Programm


Erstellen des Maschinenprogramms
Vom Quellcode zum Maschinenprogramm
Kommentare
Präcompiler
Übung

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 5


Technische Informatik und Programmieren
Einleitung
Vorwort
ANSI-Standard
• Der vorliegende C-Programmierkurs hält sich streng an die Vorgaben des
ANSI Standard Buches von Brian Kernighan und Dennis Ritchie „The C
Programming Language, second edition“
Erweitertes C
• es wird grundsätzlich die erweiterte C-Schreibweise verwendet, also mit
ANSI C++ Erweiterungen auf prozeduraler Ebene

WICHTIGER HINWEIS:
Die Übersetzung von Quellcode mit ANSI C++
Erweiterungen erfordert einen C++ Compiler!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 6


Technische Informatik und Programmieren
Einleitung
Systemimplementierungssprachen
Systemprogramme vs. Anwendungsprogramme
• traditionell wird zwischen beiden unterschieden
• Grenze verläuft allerdings unscharf

Typische Systemprogramme
Anforderung an ƒ Effizienz
• Betriebssysteme (OS)
ƒ Hardwarenähe
• Compiler, Interpreter Programmierung ƒ Zuverlässigkeit
• Editoren
• Treiberprogramme für Peripheriegeräte

Typische Anwendungsprogramme
ƒ gute Anpassung
• Textverarbeitung (z.B. MS Word) Anforderung an an das Problem
• Tabellenkalkulation, Finanzbuchhaltung ƒ leichte
• Maschinensteuerungen (z.B. SPS) Programmierung Erlernbarkeit
ƒ Wartbarkeit

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 7


Technische Informatik und Programmieren
Einleitung
Systemimplementierungssprachen
Konsequenzen
• abhängig vom Bereich haben sich spezielle Sprachen etabliert

Anwendungsprogrammierung

Sprache Anwendung
COBOL Kommerzielle Anwendungen
Fortran Wissenschaftlich-technische Aufgabenstellungen
Pascal, Modula Lehr- und „general purpose“ Sprachen
Java, C# Plattform unabhängige Sprachen

Systemprogrogrammierung C / C++ Anwendungsgrammierung

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 8


Technische Informatik und Programmieren
Einleitung
Systemimplementierungssprachen
Systemprogrammierung
• tlw. heute noch Assemblerprogrammierung in extrem zeitkritischen
Anwendungen (z.B. Echtzeitanforderungen bei Steuerungsaufgaben durch
Mikrocomputer1)
• in den meisten Fällen ist aber die Verwendung einer höheren Sprache
(z.B. C / C++) aus Gründen der Zuverlässigkeit und Wartbarkeit möglich!
(viele Mikrocontroller-Hersteller bieten C-Compiler und Entwicklungs-
umgebungen an siehe auch INTEL 8051)

Die Verwendung strukturierter Sprachen ist bei der


Entwicklung großer Systeme ein wesentliches Hilfsmittel
zur Bewältigung der exponentiell wachsenden Komplexität
solcher Programme.

1
: Verweis auf Vorlesung Grundlagen Mikrocomputer v. Prof. Walter

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 9


Technische Informatik und Programmieren
Einleitung
Entstehung von C (und C++)
Geschichte von C und C++
• Ursprünge von C (vgl. Ada1) in Europa
• ausgehend von der Sprache BCPL (Basic Combined Programming
Language, Entwurf durch Martin Richards, 1967) für Systemaufgaben
enstand in den Forschungslaboratorien von Bell Telephone (USA) die
Sprache B, aus der dann schließlich C reslutierte (Anfang 70er Jahre)

In demselben Labor entstand in den 1970ern das


wichtigste Standard-Betriebssystem neben der Microsoft
Welt: UNIX (anfangs noch in Assembler geschrieben,
spätere Implementierung in C (dadurch rel. leicht
portierbar)
Viele Kernel aktueller Betriebssysteme sind in C
geschrieben.
1
: Ada: erste strukturierte standardisierte Hochsprache (Ada83, Ada95), Mitglied der Pascal-Familie,
Einsatz in sicherheitsrelevanten Bereichen wie Flugsicherung, Raumfahrt etc.)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 10


Technische Informatik und Programmieren
Einleitung
Entstehung von C (und C++)
Geschichte von C und C++
• Väter von C: Brian Kernighan & Dennis Ritchie (Verfasser des
Standardwerks über C: „The C Programming Language“, Prentice Hall) ->
frühe 1970er Jahre
Überblick und wichtige Eigenschaften von C:
• C steht auf fast allen Computersystemen zur Verfügung
• die Syntax von C wurde mit ANSI1-C (ab 1989) genormt, d.h. es gibt rel.
einheitliche Implementierungen über die Plattformen hinweg
• die Norm regelt z.B. einheitlich die Aufrufreihenfolge der Inkrement-
/Dekrementoperatoren (++ / --) und legt die C-Bibliotheken fest!
• 1990 wurde die ANSI-C Norm fast vollständig durch die ISO2 (ISO/IEC
9899:1990 (C89), aktuell: 9899:1999 auch als C99 bekannt) übernommen
• ANSI-C ist die Sprachbasis für alle C-Derivate, auch für die Erweiterung
C++, die zusätzlich objektorientierte und generische Methoden einführt
1
: ANSI: American National Standards Institute
2
: ISO: International Organization for Standardization

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 11


Technische Informatik und Programmieren
Einleitung
Entstehung von C (und C++)
Bestandteile eines C/C++ Compilers
• zusammen mit einem C/C++ Compiler werden jeweils auch immer:
¾Präprozessor
¾Library-Funktionen (C-Bibliotheken)
ausgeliefert.
• beide sind nicht Bestandteil der Sprache C/C++
• die ANSI-Norm erstreckt sich aber auch auf die compilerexternen
Komponenten

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 12


Technische Informatik und Programmieren
Einleitung
Übersicht zu C / C++
Übersicht zu C / C++
• Vorlesung verwendet grundsätzlich ANSI-C
• wo es sinnvoll erscheint, werden C++ Elemente (erweitertes C) verwendet

Erweiterungen zu ANSI-C werden


im Quelltext kursiv gekennzeichnet

• Objektorientierung ist allerdings nicht Bestandteil dieser Vorlesung


(Informatik II)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 13


Technische Informatik und Programmieren
Einleitung
Übersicht zu C / C++
Designhinweise für die Praxis mit C / C++
C/C++ ist nicht restriktiv, Einschränkung der Portabilität
Problem:
• im Gegensatz zu Sprachen wie Pascal, Modula-2 etc. setzt C/C++ kein
sehr restriktives Type-Checking durch
• wichtigstes Beispiel: C-Sprachdefinition gibt die Speichergröße von
Datentypen nicht explizit vor! (Vorgabe erst in ISO:C99) -> große
Probleme bei der Portierung auf andere Prozessoren (16 bit -> 32 bit ->
64 bit)
Lösung:
• durch konsequentes Deklarieren und Definieren kann jedoch der
Programmierer dem Compiler das Type-Cheking ermöglichen
• Fehlermedungen und Warnungen des Compilers werden sehr viel
hilfreicher und zielführender sein!
• Verwendung eines C99-kompatiblen Compilers

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 14


Technische Informatik und Programmieren
Einleitung
Übersicht zu C / C++
Designhinweise für die Praxis mit C / C++
C/C++ lebt von Nebeneffekten
Problem:
• grundsätzlich ist die gezielte Ausnutzung sprachlicher Schwächen
(Nebeneffekte) zu vermeiden (Portabilität wird dadurch eingeschränkt)
Lösung:
• werden Nebeneffekte dennoch ausgenutzt (z.B. aus Gründen der
Effizienz), sollten diese unbedingt klar dokumentiert werden
(Kommentare!!)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 15


Technische Informatik und Programmieren
Einleitung
Übersicht zu C / C++
Designhinweise für die Praxis mit C / C++
C/C++ unterstützt Goto‘s
Problem:
• die Verwendung unbedingter Sprunganweisungen (Goto) in
Steuerstrukturen erzeugen schwer lesbaren, unübersichtlichen „Spagettie-
Code“
Lösung:
• Verzicht auf Goto‘s (Nachweis z.B. durch Nassi-Shneiderman
Struktogramme)
¾die eigentliche Gefahr ensteht durch denjenigen, der damit umgeht und
die Art und Weise des Umgangs!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 16


Technische Informatik und Programmieren
Einleitung
Übersicht zu C / C++
Designhinweise für die Praxis mit C / C++
C/C++ hat Pointer (Zeiger)
Problem:
• Zeiger können auf beliebige Speicheradressen (Daten) zeigen
• dadurch können sehr schwer zu diagnostizierende Fehler entstehen (z.B.
fälschliches Überschreiben eines Speicherblockes einer anderen
Anwendung)
Lösung:
• genereller Verzicht ist nicht möglich (z.B. C-Zeichenketten, C-Felder,
dynamische Speicherverwaltung, etc.)
¾ein gezielter und konsistenter Umgang ist aber unerläßlich!

Gleichzeitig einer der größten Vorteile von C:


hardwarenahe Programmierung möglich durch direkten
Speicherzugriff (Bits, Bytes), Speicherarithmetik möglich!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 17


Technische Informatik und Programmieren
Einleitung
Übersicht zu C / C++
Designhinweise für die Praxis mit C / C++
C/C++ ist kurz & bündig
Problem:
• C-Programme können sehr kompakt (damit schwer lesbar) geschrieben
werden
• viele Symbole werden nicht mit Schlüsselwörtern sondern mit
Sonderzeichen dargestellt (z.B. Anweisungsblock statt BEGIN, END wird
{..} verwendet
Lösung:
• sinnvolle Variablennamen, eingerückte Darstellung, klare Kommentare
¾in der professionellen SW-Entwicklung: Einführung & Durchsetzung sog.
Development-Styleguides

F:\
hschule\FH_KA-Lehr

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 18


Technische Informatik und Programmieren
Einleitung
Übersicht zu C / C++
Designhinweise für die Praxis mit C / C++
C/C++ Felder und Zeichenketten
Problem:
• C kennt zwar den Datentyp Feld und erlaubt die Definition von mit
Konstanten vorbelegten Feldern
• intern werden Felder aber als Zeiger verwaltet!
• eine evtl. notwendige dynamische Speicherverwaltung muß vom
Programmierer selbst implementiert werden
• Feldgröße wird beim Zugriff nicht geprüft (illegale Feldzugriffe möglich!)
• Zeichenketten werden in C als Zeichenfeld (mit terminierender \0)
implementiert (kein integrierter „String“-Datentyp)
Lösung:
• sorgfältigen Umgang erlernen, konsistente Behandlung

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 19


Technische Informatik und Programmieren
Einleitung
Algorithmus und C-Programm
Algorithmus und C-Programm
• C ist eine imperative Programmiersprache

Anweisung 1 Anweisung 2 Anweisung 2 Anweisung n

jede Anweisung kennt die Folgeanweisung

• Anweisungsfolge (Sequenz) wird durch einen Algorithmus vorgegeben

Was ist ein Algorithmus? umgangssprachlich, grob: Handlungsschritte

Ein Algorithmus ist eine Folge von genau beschriebenen


Anweisungen, die unter gleichen Ausgangswerten nach
endlich vielen Schritten in einer endlichen Zeit das
gesuchte Ergebnis ermitteln.

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 20


Technische Informatik und Programmieren
Einleitung
Algorithmus und C-Programm
Beispiel für einen einfachen Algorithmus:
...
int summe;
int a = 12;
int b = 33;
summe = a + b;
printf("Ausgabe: Summe ist %d.", summe);
...

Beschreibung der Anweisungssequenz:


• Werte der Variablen a und b (12 und 33) addieren
• Ergebnis der Variablen Summe zuweisen
• Anschließend den Wert in der Variablen Summe auf dem Bildschirm
ausgeben

Demo VC++ .NET: \K1_Einleitung\Bsp1\Bsp1.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 21


Technische Informatik und Programmieren
Einleitung
Algorithmus und C-Programm
Deklarative Sprachen als Alternative zu imparativen Sprachen
Beispiel: PROLOG (Programming in Logic, logische Progr.sprache)
„Maschinensprache eines Logik-Prozessors“
Grundprinzip:
• PROLOG Programme bestehen aus einer Datenbasis (Fakten und Regeln)
• Benutzer formuliert Anfragen an die Datenbasis, der PROLOG-Interpreter
benutzt die Fakten und Regelen, um systematisch eine Antwort zu finden
• POSITIVES RESULTAT („YES“): Antwort logisch ableitbar
• NEGATIVES RESULTAT („NO“): Antwort aufgrund der Datenbasis nicht
möglich
• -> nicht vergleichbar mit prozeduralen (imparativen) Sprachen
• -> Anwendung vor allem in sog. Expertensystemen (Bereich KI Künstliche
Intelligenz, Computerlinguistik)
z.B. Unterstützung bei medizinischer Diagnose
oder Wetterbeobachtung / fore cast
(XPS stellt eine große Wissensbasis bereit)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 22


Technische Informatik und Programmieren
Einleitung
Algorithmus und C-Programm
Beispiel für ein PROLOG-Programm:
I) Datenbasis (Fakten und Regeln):

mann(adam).
mann(tobias).
mann(frank).
frau(eva).
frau(daniela).
frau(ulrike).
vater(adam,tobias).
vater(tobias,frank).
vater(tobias,ulrike).
mutter(eva,tobias).
mutter(daniela,frank).
mutter(daniela,ulrike).

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 23


Technische Informatik und Programmieren
Einleitung
Algorithmus und C-Programm
Beispiel für ein PROLOG-Programm:
II) PROLOG-Programm besteht aus dem Stellen logischer Anfragen:

?- mann(tobias).
yes.
?- mann(heinrich). heinrich existiert nicht in Datenbasis
no.
?- frau(X). Variablen: Token mit GROSSBUCHSTABEN
X=eva ;
X=daniela ;
X=ulrike ;
yes. (keine weiteren Antworten).

Neben Fakten können auch Regeln spezifiziert werden:


grossvater(X,Y) :-
vater(X,Z), X ist Großvater von Y, wenn es ein Z gibt, so daß
X Vater von Z ist und Z Vater von Y. Damit ist der
vater(Z,Y).
Großvater väterlicherseits definiert

Regeloperator

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 24


Technische Informatik und Programmieren
Einleitung
Algorithmus und C-Programm
Weitere Alternative: Funktionale Programmiersprache
Beispiel: LOGO (speziell für Kinder entwickelte, mit LISP verwandte
Sprache)

Grundprinzip:
• nur wenige Befehle sind systemseitig vorgegeben
• der Anwender definiert neue Befehle
• durch die Kombination von bereits „gelernten“ Befehlen zu wieder neuen
Befehlen erweitert sich die Leistungsfähigkeit der Sprache ständig
Beispiel:
to fakultaet :n
if :n = 0 [make "n 1]
if :n > 1 [make "n :n * fakultaet :n - 1]
output :n
bekannt: Turtlegraphics
end
(virtuelle Schildkröten,
die Linien hinterlassen)
print fakultaet 6 Aufruf

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 25


Technische Informatik und Programmieren
Einleitung
Erstellen des Maschinenprogramms
Natürliche vs. formale Sprache
• im Gegensatz zu natürlichen Sprachen (Englisch, Deutsch, etc.) müssen
formale Sprachen (Programmiersprache) eindeutig sein! z.B. verlesen als
• jede formale Sprache besitzt eine Reihe reservierter Wörter „falsch lesen“ oder
„auslesen“ oder
„aussortieren“
-> Homonym

Übersicht der Schlüsselwörter (reservierten Wörter) in C / C++:

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 26


Technische Informatik und Programmieren
Einleitung
Erstellen des Maschinenprogramms
Fortsetzung: Schlüsselwörter in C / C++

CAVE: alles
kleinschreibung!!

Schlüsselwörter (Keywords) in ANSI-C und ANSI-C++

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 27


Technische Informatik und Programmieren
Einleitung
Erstellen des Maschinenprogramms
Wie entsteht ein C-Programm technisch?
1. Schritt: C-Quellprogramm
• C-Programm wird als Quelltext (Textform!) in einem Editor erstellt
• Sprachbefehle (z.B. Schlüsselwörter) können nicht beliebig angeordnet
werden, die „Befehls-Syntax“ bezeichnet das Regelwerk, das die Notation
einer Anweisung festlegt
• Quelltext in Datei speichern, Dateierweiterung: *.c / *.cpp

empfehlenswert:
Syntax-Highlighting

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 28


Technische Informatik und Programmieren
Einleitung
Erstellen des Maschinenprogramms
Wie entsteht ein C-Programm technisch?
2. Schritt: Übersetzung des C-Quellprogrammes in Maschinensprache
• ein Programm wird durch den Prozessor ausgeführt (z.B. INTEL x86 o.a.)
• Prozessor verarbeitet aber nur die ihm bekannte Maschinensprache
(Plattformabhängigkeit!)
• hierzu muß der C-Quelltext „übersetzt“ werden (Textform ->
Maschinensprachbefehle)

Compiler Interpreter

ƒ Kompletter Quelltext wird in ƒ Zeilenenweise Übersetzung und


Maschinensprache (ausführbarer Code Ausführung des Programmcodes
für eine Prozessor-Plattform) übersetzt ƒ Meist langsamer (weniger optimiert) als
ƒ Schneller, kompakter binärer compilierter Code aber universeller!
Maschinencode (Optimierungen!) ƒ Z.B. viele Scriptsprachen (JavaScript,
ƒ C == Compiler-Sprache VisualBasicScript, etc.)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 29


Technische Informatik und Programmieren
Einleitung
Vom Quellcode zum Maschinenprogramms
Wesentliche Einzelschritte der technischen Programmerzeugung
Folgende Schritte werden durchlaufen, um aus einem C-Programm ein
ausführbares Maschinenprogramm (Application) zu erzeugen:

(2) Quellcode (3) Objectcode (4) Maschinen-


(1) Header-Datei
-Datei -Datei programm-Datei
(Application)
Dateierweiterung:
Dateierweiterung: Dateierweiterung:
<name>.h
<name>.c <name>.o Dateierweiterung:
<name>.hpp
<name>.cpp <name>.obj <name>.exe

Präcompiler Linker
C/C++ Compiler
(Präprozessor) (Binder)

Loader (5) Ausführung der Applikation


(Laden in RAM-Speicher
(Lader) des Betriebssystem)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 30


Technische Informatik und Programmieren
Einleitung
Vom Quellcode zum Maschinenprogramms
Erläuterung der Einzelschritte...
(1-2) Header-Dateien (Textform!) werden durch den Präcompiler
(Präprozessor) in die Quellcode-Datei eingefügt. Dadurch können
Standardbibliotheken und fremde Funktionen in das C-Programm
eingebunden werden ohne Quelltext zu kopieren! Der Präcompiler wird
über Direktiven gesteuert, die alle mit dem Zeichen # („Gartenzaun“)
beginnen.

(2-3) Der Compiler übersetzt den Quellcode (Quellcode-Datei inkl. Header-


Datei) in eine Objektdatei (Objectcode), eine Art binärer Zwischencode
(intermediate code), der allerdings noch nicht ausführbar ist (Lage im
Hauptspeicher (RAM) des Rechners muß durch den Linker noch
angepaßt werden).

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 31


Technische Informatik und Programmieren
Einleitung
Vom Quellcode zum Maschinenprogramms
Erläuterung der Einzelschritte...
(3-4) Der Linker (Binder) erstellt das ausführbare Hauptprogramm
(Application). Dabei werden evtl. weitere Objektdateien (*.o, *.obj)
verbunden und die Adresslage des Programms im Haupt-
/Arbeitsspeicher (RAM) wird eingerichtet. Das Programm kann in dieser
übersetzten und gelinkten Form direkt vom Prozessor abgearbeitet
werden.

(5) Der Loader (Lader) ist eine Funktion des Betriebssystems, die für das
Laden der Applikation in den Arbeitsspeicher verantwortlich ist. Der
Lader wird implizit (verdeckt) z.B. durch Doppelklicken auf eine *.exe
aufgerufen.

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 32


Technische Informatik und Programmieren
Einleitung
Das erste Programm – Lauffähig..
Problembeschreibung

Analyse und Entwurf Modellbildung


(SW-Entwicklung) (Datenstrukturen,
Algorithmen), später
Klassen, Objekte

Editor Quellprogramm editieren


weitere
Quellprogramm-Module..
Übersetzen Fehlerkorrektur
Compiler
-> object code Vervollständigung
Bibliotheks-Module..
Binden der object code(s)
Linker
-> ausführbares Programm

Ausführen und Testen des


Lader
Programms

fertiges Programm

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 33


Technische Informatik und Programmieren
Einleitung
Notepad-Coding
Einzelschritte in der Kommandozeile...
(1) Anzeige des Quellcodes (z.B. mit type-Befehl)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 34


Technische Informatik und Programmieren
Einleitung
Notepad-Coding
Einzelschritte in der Kommandozeile...
(2) Aufruf des C-/C++ Compilers (inkl. Präprozessor) -> Common Object
File Format (COFF) object (.obj) files

VS.NET 2008 (neu):


/c /P erzeugt nur noch Präprozessor-Output
/c anschließend zur Erzeugung des obj-files

ƒ cl.exe ruft den C/C++ Compiler auf


ƒ Optionsschalter /c: Compilation ohne Linken: Compilation ohne Linken
ƒ Optionsschalter /P: Präprozessor-Output wird in eine Datei geschrieben

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 35


Technische Informatik und Programmieren
Einleitung
Notepad-Coding
Einzelschritte in der Kommandozeile...
(3) Aufruf des Linkers mit LINK.exe -> Linkvorgang erstellt aus
HelloWorld.obj und stdio.lib die ausführbare Datei HelloWorld.exe

ƒ link.exe ruft den LINKER auf


ƒ dieser sorgt dafür, dass die benötigten Bibliotheksfunktionen
(hier: printf(), getchar() ) aus der Standardbibliothek
eingebunden werden

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 36


Technische Informatik und Programmieren
Einleitung
Kommentare in C / C++
Kommentare in C / C++
Was sind Kommentare?
• umgangssprachliche Zusatzinformationen im Quelltext
• können sich über mehrere Zeilen erstrecken
• werden vom Compiler nicht übersetzt und müssen daher besonders
gekennzeichnet werden
Warum sollten Kommentare in den Quelltext eingefügt werden?
• Kommentare dienen der Verständlichkeit und sollen beschreiben, was der
Programmierer sich bei der Problemlösung gedacht hat
• ausführliche Kommentare sind exorbitant wichtig bei der Wartung & Pflege
größerer SW-Projekte (LOC1 > 10.000)
• erleichtert das Lesen des Quellcodes und die spätere Fehlersuche enorm
(„es gibt keine fehlerfreie Software..“)
• i.A.wird viel zu wenig Zeit für das Schreiben guter Kommentare
aufgewendet
1
: LOC: Lines of Code Anzahl der Quellcodezeilen (ohne Kommentare etc.), Komplexitätsmaß von SW

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 37


Technische Informatik und Programmieren
Einleitung
Kommentare in C / C++
Kommentare in C / C++
Wie werden Kommentare gekennzeichnet?

Kommentare in ANSI-C:
/* ...alles Kommentar... */ Variante a) einzeilig
/* ............... Variante b) mehrzeilig
.....alles Kommentar.....
*/
/*...alles bis zum Dateiende Variante c) auch mehrzeilig
Kommentar

zusätzlich in ANSI-C++:
//... einzeiliger Kommentar

Demo VC++ .NET: \K1_Einleitung\Kommentar\Kommentar.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 38


Technische Informatik und Programmieren
Einleitung
Präcompiler (Präprozessor)
Präprozessor / -compiler (Kurzeinführung)
Was ist der Präprozessor und was macht er?
• Vor dem eigentlichen Übersetzungsvorgang (C-Compiler) startet der
Präprozessor seine Aktivitäten

Wesentliche Aufgaben:
• Einfügen von Header-Dateien in den Quellcode
• Bereitstellen verschiedener Definitionen (auch Konstanten)
• dadurch wird u.a. auch die Compilation vorbereitet (z.B. ist die Konstante
_DEBUG gesetzt, erzeugt der C-Compiler beim Übersetzen einen Debug-
Stand)

Wichtigste Merkmale:
• besitzt eine eigene Syntax ≠ C/C++ Syntax
• alle Präprozessor-Anweisungen beginnen mit dem Zeichen #

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 39


Technische Informatik und Programmieren
Einleitung
Präcompiler (Präprozessor)
Präprozessor / -compiler (Kurzeinführung)
Einbinden von Standard-Funktionen (Standard-Header)

#include <stdio.h> /* Ein-/Ausgabe in ANSI-C */


#include <iostream> // Ein-/Ausgabe in ANSI-C++

Makro (Textersetzung)

#define Name Wert

• jedes Auftreten der Zeichenfolge Name im Quelltext wird durch Wert


ersetzt (reine Textersetzung!)
/* Beispiel: Definition von Konstanten */
#define MOUNT_EVEREST 8848
#define MWST 0.16

#define ist im gesamten Programm gültig!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 40


Technische Informatik und Programmieren
Einleitung
Präcompiler (Präprozessor)
Präprozessor / -compiler (Kurzeinführung)
Code-Beispiel: Demo VC++ .NET:\K1_Einleitung\Bsp2\Bsp2.vcproj
#include <stdio.h> /* notwendig für printf() Funktion */
#include <iostream> // notwendig für cout-Stream
#define PI 3.14 /* definiert die Konstante PI */
using namespace std; // importiert Namensraum std

int main(void) /* Beginn des Hauptprogramms */


{
double umfang; /* definiert Gleitkommavariable */
int d = 5; /* definiert Ganzzahlvariable */
umfang = PI * d; /* Wertzuweisung (Anweisung) */
/* ANSI-C */
printf("Umfang des Kreises mit d=%d beträgt %f.\n", d, umfang);
// ANSI C++"
cout << "Umfang des Kreises mit d=" << d << "beträgt " << umfang
<< endl;
getchar(); /* wartet auch Zeicheneingabe */
return 0; /* Rückgabewert 0 an main()-Funktion */
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 41


Technische Informatik und Programmieren
Einleitung
Übung
Vorlesungsbegleitende Übung
(1) Erstellen Sie für den Präprozessor eine Anweisung zur Vereinbarung
des Euro-DM-Umrechnungskurses in einer Konstanten (1 EURO =
1,95583 DM)
(2) Übernehmen Sie das Programm Bsp2.c in Ihren Quelltexteditor und
ergänzen Sie die 2. Zeile mit einem Kommentar zur Erklärung der
Konstanten PI.
(3) Realisieren Sie mit den Kommentarzeichen im Beispiel Bsp2.c, daß die
Ausgabe auf dem Bildschirm nicht stattfindet. Kommentieren Sie dazu
die Zeile mit der printf-Anweisung (bzw. cout-Anweisung) aus.

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 42


Technische Informatik und Programmieren
Das erste Programm in C
Orientierung
Einleitung
Das erste Programm in C
ORIENTIERUNG
Konstanten
Einfache Datentypen
Unterprogramm – Technik –
Nützliche Funktionen
Steuerstrukturen
Typvereinbarungen von Variablen
Zeiger
Der Präcompiler
Modulare Programmierung
Entwicklungsumgebungen
Standardbibliotheken
Anhang

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 1


Technische Informatik und Programmieren
Das erste Programm in C
Ziele

¾ Wie wird ein Algorithmus erstellt?


¾ Wie ist ein C-Programm aufgebaut?
¾ Wie wird das Programm gestartet?
¾ Wie werden Daten auf dem Bildschirm ausgegeben?
ZIELE

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 2


Technische Informatik und Programmieren
Das erste Programm in C
Inhalt
Das erste Programm in C
Erklärungen
Das erste Programm in C
Erstellen und Ausführen des C-Programms in verschiedenen Systemen
Datenausgabe mit der Funktion printf
INHALT

Übung

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 3


Technische Informatik und Programmieren
Das erste Programm in C
Erklärungen
Algorithmus als Grundlage der Programmierung
• mit Hilfe der Hochsprache C implementieren Sie einen Algorithmus
• der Algorithmus liefert die Lösung für eine gegebene Aufgabenstellung
• ein gutes Programm zeichnet sich durch einen effektiven und effizienten
Algorithmus aus
• der Entwurf eines Algorithmus kann durch eine graphische Darstellung
erleichtert werden (Hilfsmittel z.B. PAP Programmablaufplan, Struktogramm)

Beispiel: Algorithmus bestehend aus einer Sequenz

Start Autotür öffnen Platz nehmen Kupplungspedal betätigen Motor starten

Fahrt beginnen Langsam einkuppeln Handbremse lösen Gang einlegen

Einfache Anleitung (Algorithmus) zum Starten eines Autos


(Sequenz oder gerichteter Graph)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 4


Technische Informatik und Programmieren
Das erste Programm in C
Das erste Programm in C
Struktur eines C-Programms
Präprozessoranweisungen (z.B. #include)
Deklaration von globalen Variablen (z.B. Konstanten)
Funktionsprototypen (Schnittstelle zu Unterprogrammen)
Hauptprogramm
auch an einer Implementierung (eigentliche Problemlösung):
Stelle möglich int main ()
{
Folge von Anweisungen (einschl. Deklaration)
}
Funktionsdefinition (Unterprogrammcode)

• globale Variablen können überall in der Programmdatei benutzt werden


• es gibt genau eine main() Funktion (Hauptprogramm), damit beginnt der
Programmablauf
• das kleinste gültige Programm: int main() { }
• ein Programm besteht meist aus vielen Dateien

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 5


Technische Informatik und Programmieren
Das erste Programm in C
Das erste Programm in C
Zerlegung einer C-Funktion ! prozedurale Programmierung !

• der wichtigste Baustein eines C-Programms ist die Funktion


• die Aufgabe einer Funktion ist es, einen Wert zu berechnen und ihn an den
Aufrufer zurückzuliefern
• C-Programme sind eine Sammlung von Funktionen (Reihenfolge bzw.
Sortierung spielt keine Rolle!)

Beispiel: Funktion sqr() zur Berechnung des Quadrats einer ganzen Zahl

int sqr(int n)
{ Kurzbeschreibung:
int result; sqr() ist eine einfache Funktion
(aber nicht Bestandteil von C/C++),
sie übernimmt die ganze Zahl n
result = n * n;
und liefert n*n an den Aufrufer
return result;
zurück
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 6


Technische Informatik und Programmieren
Das erste Programm in C
Das erste Programm in C
.. die Einzelteile der C-Funktion
Funktionstyp (Typ des Rückgabewerts)
Funktionsname
Parametertyp
Parametername
int sqr(int n) Funktionskopf (Funktionsprototyp)
Parameterdeklaration

{ /* hier beginnt der Anweisungsteil der Fkt. */


int result; /* Variablendefinition */
Funktions-
result = n * n; körper
return result; /* C-Anweisung (Rückgabe an den Aufrufer) */
} /* hier endet der Anweisungsteil der Fkt. */

Anweisungen werden in C/C++ mit einem Semikolon ; abgeschlossen!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 7


Technische Informatik und Programmieren
Das erste Programm in C
Das erste Programm in C
.. die Einzelteile der C-Funktion
(1) Funktionskopf int sqr (int n)besteht aus:
• Funktionstyp == Datentyp des Rückgabewertes (return value)
• hier: Ganzzahl (int), repräsentiert durch Variable result vom Typ int
• Funktionsname, mit diesem wird die Funktion aufgerufen (unterliegt den
Regeln der Namensgebung in C/C++ für Variablen, Funktionsnamen, etc.
-> allg. Bezeichner (identifier)
• Parameterliste, eingefaßt durch Klammerpaar (..), Liste kann z.B. leer
sein (void); void ist der leere Datentyp; Liste kann auch mehrere
Parameter umfassen; jeder Parameter muß mit Datentyp und Namen
aufgeführt sein
• hier: 1 Parameter vom Typ int (int n)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 8


Technische Informatik und Programmieren
Das erste Programm in C
Das erste Programm in C
.. die Einzelteile der C-Funktion
(2) Funktionskörper (Funktionsrumpf)
• umgeben von geschweiften Klammern { .. } (sog. Block, Anweisungsblock
oder auch Verbundanweisung)
• zu Beginn des Blocks: Deklarationen, Definitionen von Variablen etc.
• im Anschluß folgen die Anweisungen (z.B. Berechnungen)

Ordnungsprinzip der prozeduralen Programmierung: Hierarchischer Aufbau

im wesentlichen setzt sich eine C-Funktion aus einer


Anzahl von Anweisungen zusammen. Ein C-Programm
seinerseits besteht aus einer Reihe von C-Funktionen.

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 9


Technische Informatik und Programmieren
Das erste Programm in C
Das erste Programm in C
Struktur eines ANSI-C Programms

Präprozessoranweisung #include <stdio.h>


#define MOUNT_EVEREST 8848

Konstantendeklaration const int K = 17;


Variablendeklaration int preis, anzahl;
-------------------------------
Funktionsdefinition Funktion(Parameter)
{
Anweisung1; Pseudo-Code
Anweisungsteil (Block) Anweisung2;
}
-------------------------------
Hauptfunktion == int main()
Beginn des {
Hauptprogramms
Anweisung1;
Anweisungsteil (Block) Anweisung2; Pseudo-Code
return 0;
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 10


Technische Informatik und Programmieren
Das erste Programm in C
Das erste Programm in C
Struktur eines ANSI-C Programms .. einige Erläuterungen
(1) Präprozessoranweisungen
• an erster Stelle zum Einbinden von Dateien oder Textersetzungen
(2) Globale Variablen und Konstanten
• alle Variablen und Konstanten außerhalb der main() Funktion sind global
gültig d.h. innerhalb des gesamten Programms
(3) Globale Funktionen
• diese Funktionen (eingeführt mit Funktionsnamen, Parameter etc.) können
im Hauptprogramm mit ihrem Funktionsnamen aufgerufen werden
• im Anweisungsteil (Funktionskörper) wird festgelegt, was die Funktion tut
(4) Main()-Funktion
• Hauptprogramm == Eintrittspunkt nach dem Programmstart
• mit ihr beginnt die Abarbeitung
• bei fehlerfreier (erfolgreicher) Ausführung gibt die Funktion den
Rückgabewert 0 an das Betriebssystem (Loader) zurück

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 11


Technische Informatik und Programmieren
Das erste Programm in C
Das erste Programm in C
zum Beispiel ein Beispiel..
#include <stdio.h>
int main(void)
{
printf("Guten Tag!"); ANSI-C
getchar(); TRICK: Verhindert, daß main() sofort verlassen
return 0; wird!
}

Erläuterungen:
• #include <stdio.h> bindet die C-Standard Header-Datei (Bibliothek mit
einer Anzahl von Standardfunktionen) ein (d.h. fügt den Inhalt von stdio.h
ein) -> printf() ist eine Standard-Funktion!
• main() ist der Eintrittspunkt; void bedeutet, daß die main() keinen
Parameter übernimmt
• printf() gibt einen Text auf dem Bildschirm aus
• nach erfolgreicher Abarbeitung wird 0 an das OS zurückgegeben (return)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 12


Technische Informatik und Programmieren
Das erste Programm in C
Das erste Programm in C
noch ein Beispiel (erweitertes ANSI-C)..
#include <iostream>
#define EINS 1 ANSI-C++
using namespace std;
short int fak(short int);
/*******************************************************
* Funktionsname :main
* Beschreibung :fragt nach einer Zahl, liest sie ein
* und druckt die Fakultaet davon aus
* Parameter :keiner
* Rückgabewert :0
*******************************************************/
int main()
{
short int zahl; // Definition lokaler Variablen
short int resultat;

cout << endl << "Zahl eingeben (Prg-Abbruch : Zahl < 0) : ";
cin >> zahl;

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 13


Technische Informatik und Programmieren
Das erste Programm in C
Das erste Programm in C
noch ein Beispiel (erweitertes ANSI-C)..
while(zahl >= 0)
{ ANSI-C++
resultat = fak(zahl);
cout << zahl << "! = " << resultat << endl;
cout << endl << "Zahl eingeben (Prg-Abbruch : Zahl < 0) : ";
cin >> zahl;
}
return 0;
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 14


Technische Informatik und Programmieren
Das erste Programm in C
Das erste Programm in C
noch ein Beispiel (erweitertes ANSI-C)..
/*******************************************************
* Funktionsname :fak ANSI-C++
* Beschreibung :berechnet die Fakultaet (rekursiv)
* Parameter :die zu berechnende Zahl
* Rückgabewert :die Fakultaet
*******************************************************/
short int fak(short int n)
{
short int resu;
short int resultat;
if(n == 0)
resu = EINS;
else
resu = n * fak(n – EINS);
return resu;
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 15


Technische Informatik und Programmieren
Das erste Programm in C
Das erste Programm in C
Erläuterungen zum ANSI C++ Beispiel (Zeile für Zeile)

#include <iostream>

• Präprozessoranweisung, fügt den Inhalt des Textfiles iostream ein, das


Deklarationen für alle I/O-Funktionen enthält

using namespace std;

• erleichtert den Zugriff auf die I/O-Funktionen


• Alternative: jedem Funktionsaufruf std:: voranstellen, also: std::cout
<< std::endl etc.

#define a b

• Präprozessoranweisung, im Rest des files Token a durch String b zu


ersetzen
• kann mit #undef a widerrufen werden!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 16


Technische Informatik und Programmieren
Das erste Programm in C
Das erste Programm in C
Erläuterungen zum ANSI C++ Beispiel (Zeile für Zeile)

short int fak(short int);

• zeigt eine Funktionsdeklaration (function prototype)


• interessant: ohne Angabe von Variablennamen!

/* ... */ bzw. //

• Kommentare bzw. Bsp. für einen Kommentarkopf

main

• besondere Funktion, jedes Programm hat genau eine main-Funktion


• gleichzeitig Anfangspunkt für die Ausführung des Programms

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 17


Technische Informatik und Programmieren
Das erste Programm in C
Das erste Programm in C
Erläuterungen zum ANSI C++ Beispiel (Zeile für Zeile)

{ ... }

• umschließen den Funktionstext (Block) (vgl. BEGIN, END in PASCAL)

short int zahl;

• Definition einer Variablen mit Namen zahl, vom Typ short int
• WICHTIG: C/C++ verlangt die Deklaration/Definition aller verwendeten
Objekte (Variablen, Funktionen, etc.) vor deren Gebrauch
• Definition oder Deklarationen erfolgen durch Aweisungen, die mit Semikolon
; abgeschlossen werden

cout << "TEXT" << zahl << endl;

• Funktion cout druckt Texte und Variablen (default: Ausgabe auf dem
Bildschirm); << ist der „Sende nach..“-Operator, endl erzeugt ein „newline“

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 18


Technische Informatik und Programmieren
Das erste Programm in C
Das erste Programm in C
Erläuterungen zum ANSI C++ Beispiel (Zeile für Zeile)

cin >> zahl;

• Funktion zum Einlesen von Variablen (default: Eingabekanal == Tastatur),


ohne weitere Manipulatoren wird der eingegebene Wert als Dezimalzahl
interpretiert

while(zahl >= 0)

• Schleifenanweisung, die Schleife wird wiederholt, solange zahl >= 0 wahr


ist (d.h. bis zahl einen negativen Wert hat)
• der Schleifenkörper besteht aus mehreren Einzelanweisungen, die zu einem
Block (Aunweisungsblock) { .. } zusammengefaßt sind

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 19


Technische Informatik und Programmieren
Das erste Programm in C
Das erste Programm in C
Erläuterungen zum ANSI C++ Beispiel (Zeile für Zeile)

resultat = fak(zahl);

• Aufruf der Funktion fak(); fak() übernimmt ein Argument (zahl) vom
Typ short int und gibt einen Wert vom Typ short int zurück an den
Aufrufer (Hauptprogramm)
• der Rückgabewert wird der Variablen resultat zugewiesen
• es ist obligatorisch, daß die fak() bereits zuvor deklariert wurde (die
Definition der Funktion folgt nach der main()-Funktion!)

if(n == 0)

• testet die Variable n auf Gleicheit mit 0 (logische Bedingung)


• WICHTIG: Unterschied zwischen Gleichheitsoperator == und
Zuweisungsoperator =
• in der if-Bedingung wird also der Inhalt des Ausdrucks n == 0 logisch
(d.h. wahr oder falsch) ausgewertet
Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 20
Technische Informatik und Programmieren
Das erste Programm in C
Das erste Programm in C
Erläuterungen zum ANSI C++ Beispiel (Zeile für Zeile)

• ANSI-C: im Gegensatz zu ANSI C++ gibt es keinen logischen Boole‘schen


Datentyp; 0 entspricht false, alle anderen Werte entsprechen true

Ausdruck liefert Wert Wert liefert Ausdruck


wahr -> 1 <> 0 -> wahr
falsch -> 0 0 -> falsch

short int fak(short int n)

• Funktionsdefinition von fak()


• WICHTIG: im Gegensatz zur Deklaration müssen die Parameternamen
(hier: n) mitangegeben sein!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 21


Technische Informatik und Programmieren
Das erste Programm in C
Das erste Programm in C
Erläuterungen zum ANSI C++ Beispiel (Zeile für Zeile)

resu = n * fak(n – EINS);

• Beispiel für einen rekursiven Funktionsaufruf (Funktion fak() wird


innerhalb der Funktion fak() erneut aufgerufen)

return resu;

• liefert den in der Funktion berechneten Wert an den Aufrufer zurück


• mit return wird die Funktion verlassen

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 22


Technische Informatik und Programmieren
Das erste Programm in C
Das erste Programm in C
EINSCHUB: Syntax vs. Semantik einer Sprache

Syntax:
• befaßt sich mit den grammatikalischen Aspekten (Format, Aufbau von
Sätzen etc.)

Semantik:
• befaßt sich mit der Aussage, der Bedeutung von sprachlichen Konstrukten
Bedeutung

Wesentliche Aufgabe des Compilers ist die syntaktische Prüfung


(Erkennung syntaktischer Fehler).
Die Kontrolle der Semantik liegt alleine in der Verantwortung des
Programmieres!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 23


Technische Informatik und Programmieren
Das erste Programm in C
Erstellen und Ausführen des C-Programms
Hinweise zur Verwendung der IDE1s
• C ist eine weit verbreitete Hochsprache
• für die verschiedenen Betriebssysteme (OS) gibt es Programmier-
umgebungen unterschiedlicher Hersteller

Link zu Anleitungen für die Entwicklungsumgebungen


¾Microsoft Visual Studio 6.0 (weit verbreitet, aber bereits abgelöst durch..)
¾Microsoft Visual Studio .NET (aktuelle Umgebung seit 2002)

\\Nt-mt-
01\mitarbeiter\Artinger\public\Vorlesungen\Informatik_I\Uebung\Allgemeines\Intro-
MS-Visual_C++_V60_DOTNET.pdf

1
: IDE: Integrated Development Environment (integrierte Entwicklungsumgebung)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 24


Technische Informatik und Programmieren
Das erste Programm in C
Datenausgabe mit der Funktion printf
Datenausgabe mit der Funktion printf (ANSI-C)
• printf() ist eine Funktion der C-Standardbibliothek und ist im Standard-
Header File stdio.h deklariert
• printf() dient zur Ausgabe von Zeichen auf dem Bildschirm
• die Syntax von printf() erscheint zu Beginn etwas kompliziert
• printf() ist die Textausgabe gem. ANSI-C

Beispiele zur Verwendung von printf():


Formatstring

printf(“Dieser Text wird ausgegeben.“);


printf(“Der Berg ist: %d Meter hoch.“, hoehe); ANSI-C
printf(“Nach dem Zeilenumbruch \n“);
printf(“wird in der naechsten Zeile weitergeschrieben.“);
printf(“Ausgabe in eine Tabelle:\n“);
printf(“Spalte1\tSpalte2\tSpalte3\t\n“);
printf(“Die Summe aus %d und %d betraegt %d.“,s1,s2,s);

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 25


Technische Informatik und Programmieren
Das erste Programm in C
Datenausgabe mit der Funktion printf
Erläuterungen zum Beispiel mit printf()

printf( Formatstring,(Variablen) );

• als Erstes steht der Funktionsbezeichner printf


• in den Klammern ( .. ) folgt der Formatstring
• Formatstring enthält den Text, der auf dem Bildschirm ausgegeben werden
soll (doppelte Anführungszeichen " quotation marks)
• im Formatstring kann auch das Zeichen % (Platzhalter) gefolgt von einem
Formatbeschreiber (Datentypbezeichner) auftauchen; dies kennzeichnet die
Stelle, an der der Inhalt einer Variablen oder Konstanten innerhalb des
Textes ausgegeben werden soll
• die Textausgabe kann mit ESC-Sequenzen (Escape) gesteuert werden
(ESC-Sequenzen werden mit einem \ eingeleitet z.B. \n für „newline“ oder
\t für einen Tabulator)
• nach dem Formatstring folgen durch Kommata getrennt die Variablen oder
Konstanten in der Reihenfolge der Platzhalter

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 26


Technische Informatik und Programmieren
Das erste Programm in C
Datenausgabe mit der Funktion printf
Code-Beispiel zur Verwendung von printf
#include <stdio.h> /* notwendig wegen printf */
int faktor = 10; /* globale Variable vom Typ int */
int main(void)
{ ANSI-C
printf("DEMO..."); /* gibt den Text DEMO aus */
printf ("Berechnung eines Quadrates\n"); /* ..neue Zeile */
printf ("aus der Zahl %d\n\n",faktor); /* Wert von faktor */
printf ("Das Quadrat der Zahl %d betraegt %d\n", faktor,
faktor*faktor);
getchar(); /* TRICK, damit Programm nicht sofort beendet wird*/
return 0;
}

Demo VC++ .NET: \K2_Das_erste_C-Programm\printf\printf.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 27


Technische Informatik und Programmieren
Das erste Programm in C
Übung
Vorlesungsbegleitende Übung
(1) Schreiben Sie ein Programm, das den Text Hallo Welt! auf dem
Bildschirm ausgibt.
(2) Verändern Sie das Programm printf.c so, daß auf dem Bildschirm ein
vollständiger Satz für die Addition ausgegeben wird, z.B. Die Summe
aus 5 und 7 ist 12.
(3) Geben Sie einen Tabellenkopf aus, der die Spaltenüberschriften Name,
Vorname und Ort enthält und füllen Sie die Tabelle mit den Angaben zu
3 Personen.

Variation: Verwenden Sie anstelle von printf() ANSI-C


die cout-Methode von ANSI C++

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 28


Technische Informatik und Programmieren
Das erste Programm in C
Übung
Vorlesungsbegleitende Übung (Fortgeschrittene..)
(4) Identifizieren Sie in nachstehender Funktion die vorgestellten
Funktionsbausteine (Kopf, Block, Funktion, Parameter, Rückgabewert)
und versuchen Sie den Ablauf (Reihenfolge) dieses Programms zu
verstehen. ANSI C++

/**********************************************************
* HEADER FILES
**********************************************************/
#include <iostream>
using namespace std;
/**********************************************************
* DEFINITIONEN, DEKLARATIONEN
**********************************************************/
int suche(char);

Demo VC++ .NET:\K2_Das_erste_C-Programm\Uebung4\Uebung4.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 29


Technische Informatik und Programmieren
Das erste Programm in C
Übung
Vorlesungsbegleitende Übung (Fortgeschrittene..)
/**********************************************************
* FUNKTIONSNAME :main
* BESCHREIBUNG :fragt nach dem Buchstaben, liest ihn ein
* und druckt die Position aus
* PARAMETER :keiner
* RÜCKGABEWERT :keiner
**********************************************************/
int main(void)
{
char buchstabe;
int position;

cout << endl << "Buchstabe eingeben (A..Z) : ";


cin.get(buchstabe);
position = suche(buchstaben);
cout << endl;
cout << "Buchstabe " << buchstabe << " ist an der " << position;
cout << ". Position" << endl;
return 0;
}
Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 30
Technische Informatik und Programmieren
Das erste Programm in C
Übung
Vorlesungsbegleitende Übung (Fortgeschrittene..)
/**********************************************************
* FUNKTIONSNAME :suche
* BESCHREIBUNG :sucht Position eines Buchstaben im Alphabet
* PARAMETER :der Buchstabe
* RÜCKGABEWERT :die Position des Buchstaben
**********************************************************/
int suche(char zeichen)
{
int zaehler;
char alpha;

zaehler = 1;
alpha = 'A';
while(zeichen != alpha)
{
zaehler = zaehler +1;
alpha = alpha + 1;
}
return zaehler;
}
Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 31
Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Orientierung
Einleitung
Das erste Programm in C
ORIENTIERUNG
Konstanten
Einfache Datentypen
Unterprogramm – Technik –
Nützliche Funktionen
Steuerstrukturen
Typvereinbarungen von Variablen
Zeiger
Der Präcompiler
Modulare Programmierung
Entwicklungsumgebungen
Standardbibliotheken
Anhang

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 1


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Ziele

Was sind Konstanten?


Wie werden Konstanten vereinbart?
Wie werden Konstanten im Programm verwendet?
Welche Einschränkungen gibt es?
Wie werden Variablen deklariert und verwendet?
ZIELE

Welche Grunddatentypen gibt es?


Welche Operationen sind mit verschiedenen Typen
möglich?
Wie werden formatierte Ausgaben auf dem Bildschirm
durchgeführt?

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 2


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Inhalt
Konstanten
Grundlagen
Vereinbarungen
Verwendung
Einschränkungen
Übung
INHALT

Einfache Datentypen
Einfache Variablentypen in C
Vereinbarung
Wertzuweisung
Arithmetische Operationen
Bitoperationen
Zuweisungsoperatoren
Umwandlung eines Datentyps
Formatierte Ausgabe
Speicherbedarf, Wertebereich, Genauigkeit
Übung

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 3


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Grundlagen
Wesentliche Grundkonzepte aller Programmiersprachen

(1) Datenkonzept
• Daten sind die (rechner-)interne Repräsentation der Außenwelt
• Daten sollen in bestimmter Weise verarbeitet werden (EVA1-Prinzip)
• die rechnerinterne Darstellung von Daten ist sehr unterschiedlich
• wichtig ist die Unterscheidung zwischen der internen Repräsentation und
dem sog. Datentyp (Interpretation der Repräsentation)

(2) Kontrollstrukturen
• folgt später ☺

1
: EVA: Eingabe – Verarbeitung – Ausgabe, Grundprinzip des Rechners

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 4


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Grundlagen
Wesentliche Grundkonzepte aller Programmiersprachen
Beispiel zur Unterscheidung von Repräsentation (Wert) / Datentyp
Bitfolge eines 16-Bit Wortes

1111 1111 1111 1111 FFFF

binäre Bitfolge Hexadezimalzahl


(Dualzahl)

(1) Interpretation als vorzeichenbehaftete Ganzzahl (signed int)


• Wert -1 in 2erKomplement-Darstellung (MSB1 dient dem Vorzeichen!)
(2) Interpretation als vorzeichenlose Ganzzahl (unsigned int)
• Wert 65535 (216 – 1)
(3) – (n) ...

mehr zu diesem Thema im Abschnitt „Einfache Datentypen“

1
: MSB: most significant bit

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 5


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Grundlagen
Symbolische Konstanten
Anwendung von symbolischen Konstanten
• im Programm soll ein bestimmter Wert (z.B. Naturkonstante wie
Erdbeschleunigung ERDE = 9,81 m/s, PI = 3,14 etc.) mehrmals verwendet
werden
• Kennzeichen: der Wert ändert sich während der Programmausführung nicht!
• für die Konstante wird ein Bezeichner eingeführt (z.B. ERDE oder PI)
• der Wert wird durch diesen Bezeichner (Aliasnamen) repräsentiert

Vorteile von symbolischen Konstanten


• einmalige Definition des Wertes der Konstanten z.B. am Anfang des
Programmes
• zentrale Änderbarkeit: der Wert einer Konstanten kann (falls notwendig)
zentral an nur einer Stelle aktualisiert werden; der Rest des Programms
bleibt „untouched“

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 6


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Vereinbarung
Symbolische Konstanten
Beispiel für symbolische Konstanten (benannte Konstanten):
Schlüsselwort const (Qualifizierer)
Datentyp
Name, Bezeichner, Aliasname
Wert der symbolischen Konstanten
const double PI = 3.14; PI = 5.5 /* Fehler! */
const double MWST = 1.16; MWST = MWST+0.02 /* Fehler! */
const double ERDE = 9.81;
const int VERSION = 6; TIPP: möglichst aussagekräftige
Namen verwenden! (evtl.zusätzl.
const char ZEICHEN = ‘J‘;
immer GROSSSCHRIFT verwenden)

• wird bei der Deklaration eines Objekts (z.B. Typ) const vorangestellt, wird
das Objekt nicht als Variable sondern als Konstante spezifiziert!
• da eine Konstante während des Programmablaufs nicht mehr verändert
werden darf -> Deklaration und Initialisierung gleichzeitig!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 7


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Verwendung
Verwendung von symbolischen Konstanten im Programm
Beispiel: Berechnung von Kreisumfang und Kreisfläche

#include <stdio.h>
symbolische Konstante vom Typ
int main()
double (Gleitkommazahl)
{
const double RADIUS = 14.0;
const double PI = 3.14;
printf("Der Kreisumfang betraegt: %f .", 2*PI*RADIUS);
printf("Die Kreisflaeche betraegt: %f .", PI*RADIUS*RADIUS);
getchar();
return 0;
}

stilistischer Nachteil: Umfang und Fläche können nur für einen fest
vorgegebenen Kreisradius berechnet werden

Demo VC++ .NET: \K34_Konstanten_Datentypen\Fleache\Fleache.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 8


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einschränkungen
Einschränkungen und Designhinweise

symbolische Konstanten sollten am Anfang des Programms (Quellcode)


definiert werden

geben Sie der Konstanten einen möglichst aussagekräftigen Namen


(Bezeichner) und heben Sie die besondere Bedeutung z.B. durch
GROSSCHREIBUNG hervor

zur Laufzeit (d.h. während das Programm ausgeführt wird) kann der Wert
der Konstanten nicht verändert werden

Verwenden Sie möglichst immer das Schlüsselwort const und nicht die
Präprozessordirektive #define (Begründung: nur C/C++ Anweisungen
unterliegen der Typprüfung durch den Compiler!!)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 9


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Übung
Vorlesungsbegleitende Übung
(1) Schreiben Sie ein Programm, das Temperaturangaben von Kelvin [K] in
°C umrechnen kann. Vereinbaren Sie hierzu Konstanten für den
umzurechnenden Temperaturwert und den Umrechnungswert (0 °C =
273 K).
Welchen Vorteil hat die Angabe des Typs für die Fehlerprüfung?
(2) Welche Einschränkungen gibt es bezüglich des Wertes der Konstanten?

Variation: Verwenden Sie anstelle von printf() ANSI-C


die cout-Methode von ANSI C++

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 10


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Einfache Variablentypen in C/C++
Grundlagen Variable:
• Sinn der DV besteht in der Manipulation von Daten (z.B. Berechnung der
Summe, Division etc.)
• dazu müssen Werte aus dem Speicher des Rechners (meist RAM) gelesen,
verändert und anschließend wieder gespeichert werden
• diese Aufgabe wird durch sog. Variablen erfüllt
• jede Variable benötigt Speicherplatz, der Umfang ist abhängig vom Inhalt
(Datum), der gespeichert werden soll
• Variablen müssen vor ihrer Verwendung vereinbart (deklariert) werden

int zahl1, zahl2, ergebnis;


zahl1 = 17;
zahl2 = 100;
ergebnis = zahl1 + zahl2;

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 11


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Charakteristika von Variablen (Rundreise)
Unterscheidung zwischen Deklaration und Definition:
• C/C++ unterscheidet streng zwischen der Datendeklaration (Einführung
eines Bezeichners, Namen oder Eigenschaft wie Datentyp) und der
Datendefinition (mehr als die reine Einführung eines neuen Bezeichners
z.B. Anfordern des benötigten Speicherplatzes für eine Variable)
Geltungsbereich (scope):
• jede Variable ist nur innerhalb eines gewissen Programmabschnittes
sichtbar (visible)
Lebensdauer (lifetime):
• die Variable „lebt“, wenn sie im Speicher des Rechners existiert
Name (identifier oder Bezeichner):
• jede Variable besitzt einen eindeutigen Namen
Wert (value):
• jede Variable enthält einen Wert (zugewiesen entweder durch das
Programm oder per default systemgeneriert durch den Compiler)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 12


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Charakteristika von Variablen (Rundreise)
Speicherplatz für Variablen:
• jedes definierte Datenobjekt (Variable, für die Speicherplatz bereit gestellt
wurde) benötigt eine bestimmte Anzahl an Speichereinheiten
• die Größe der Speichereinheit ist maschinenabhängig (i.d.R. 1 Byte = 8
Bits)
• der sizeof Operator liefert die Anzahl der Speichereinheiten, die ein
Objekt belegt

addressierbare (direkt
ansprechbare) Einheit

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 13


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Standard-/Grunddatentypen (elementare Datentypen)
Datentyp == Menge darstellbarer Werte
• wird bei der Deklaration einer Variablen oder Konstanten festgelegt
• gibt an, welche Werte die Variable aufnehmen kann (z.B. ganze Zahlen oder
Zeichenketten (Texte) etc.)

Klassifikation

(1) Numerische Datentypen (Ganzzahlen, reelle Zahlen)

(2) Zeichen-Datentyp (ASCII- oder Unicode-Zeichen)

(3) Logischer Datentyp (Wahrheitswerte der booleschen Algebra true /


false)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 14


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
(1) Numerische Datentypen

• Unterscheidung zwischen ganzen Zahlen (Integer) und reellen Zahlen (Real,


Gleitkomma, Gleitpunkt oder Fließkomma)

• Wertebereiche und Genauigkeit sind durch die Festlegung des


Speicherbereichs (Bittiefe) begrenzt

• ANWENDUNG: für Berechnungen, Aufzählungen und Nummerierungen

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 15


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Integer-Datentypen
• Ganzzahlen ohne Nachkommastelle
• Wertebereich wird durch die Größe des reservierten Speicherplatzes
bestimmt

Vorzeichenloser (unsigned) Integer-Datentyp


• Wertebereich (kleinster bzw. größter darstellbarer Wert)

0 .. 2x - 1
0 2x - 1
Wertebereich unsigned Integer
x:= Speichergröße in Bit Darstellung auf der Zahlengeraden

Beispiel: Speichergröße 2 Byte (16 Bits)


• kleinster Wert: 0
• größter Wert: 216 – 1 = 6553510

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 16


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen

Vorzeichenbehafteter (signed) Integer-Datentyp


• Wertebereich (kleinster bzw. größter darstellbarer Wert)

- 2x-1 .. 2x-1 - 1
-2x-1 0 2x-1 - 1
Wertebereich signed Integer
x:= Speichergröße in Bit Darstellung auf der Zahlengeraden

1 Bit für Vorzeichen VZ!

Beispiel: Speichergröße 2 Byte (16 Bits)


• kleinster Wert: -215 = 3276810
• größter Wert: 215 – 1 = 3276710
VZ

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 17


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Was passiert beim Überschreiten des Wertebereichs?
• sog. Speicherüberlauf (overflow) oder Unterlauf (underflow)
• meist wird keine Fehlermeldung generiert!

Beispiel: Addition

Ringpuffer

Mögliche Fälle bei Addition von 2 signed Integer (Summand1, Summand2 sind gültige Zahlen)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 18


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Integer-Datentypen in ANSI-C/C++ (32-Bit Umgebung)

Datentyp Größe Bezeichnung Wertebereich


[Bit]
short 16 Integerwert -32768 ... 32767
signed short 16 Integerwert -32768 ... 32767
unsigned short 16 Integerwert 0 ... 65535
int 32 Integerwert -2147483648 ... 2147483647
signed int 32 Integerwert -2147483648 ... 2147483647
unsigned int 32 Integerwert 0 ... 4294967295
long int 32 Integerwert -2147483648 ... 2147483647
signed long int 32 Integerwert -2147483648 ... 2147483647
unsigned long int 32 Integerwert 0 ... 4294967295

4 GByte (Grenze des addressierbaren


Speicherbereichs in 32-Bit-Systemen)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 19


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Die 3 Darstellungsmöglichkeiten für ganze Zahlen
dezimal
• Folge von Dezimalzeichen, die nicht mit 0 beginnt
oktal
• wenn die Zahl mit 0 beginnt, wird sie als Oktalzahl interpretiert
• Folge von Oktalzeichen {0, .. 7}, beginnend mit einer 0
• z.B. 0377 = 3·82 + 7·81 + 7·80 = 25510 (dezimal)
hexadezimal
• wenn die Zahl mit 0x oder 0X beginnt, wird sie als Hex-Zahl interpretiert
• Folge von Hex-Zeichen {0 ..9, a .. f, A .. F}
• z.B. 0x89ab, 0X9aBc = 9·163 + 10·162 + 11·161 + 12·160 = 3961210

Suffix:
• nachgestelltes l oder L steht für long (z.B. 10L )
• nachgestelltes u oder U für unsigned (vorzeichenlos) (z.B. 10u )

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 20


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Real-Datentypen (Gleitkomma, Gleitpunkt, Fließkomma)
• reelle Zahlen mit Nachkommastellen
• neben begrenztem Wertebereich (Größe des reservierten Speicherplatzes)
auch begrenzte Genauigkeit (Nachkommastellen werden abgeschnitten oder
gerundet -> Rundungsfehler auch bei rel. einfachen Berechnungen)

Einfache Genauigkeit (single precision) Datentyp (z.B. float in C/C++)

VZ Exponent (8 Bits) Mantisse (23 Bits)

Aufbau einer Gleitkommazahl (single precision)


(32 Bits)
entscheidend für den
Wertebereich Genauigkeit ->
entspricht 7 Dezimalstellen!
typische Größe bei 32 Bit Prozessoren
(i.a. maschinenabhängig!)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 21


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Wie wird eine Gleitkommazahl im Rechner gebildet?
• vor der Speicherung erfolgt eine Transformation (sog. Normalisierung)
dabei wird das Komma der Zahl in Binärdarstellung hinter die erste 1 gesetzt
und ein Exponent berechnet; die erste Ziffer (1) wird nicht gespeichert

Beispiel:
nicht normalisierte Binärzahl: 1 1 0 1 0 , 1 0 1 1 0

normalisierte Binärzahl:

0 0 0 0 0 1 0 0 1 0 1 0 1 0 1 1 0 0 0 0

VZ Exponent Mantisse

auf diese Weise wird jede Gleitkommazahl normalisiert,


bevor sie gespeichert wird!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 22


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Real-Datentypen in ANSI-C/C++ (32-Bit Umgebung)

Datentyp Größe Vorzeichen Exponent Mantisse Wertebereich Präzision


[Bit] [Bit] [Bit] [Bit] [Stellen10]
float 32 1 8 23 -3,4 · 1038 … 7
3,4 · 1038
double 64 1 11 52 -1,7 · 10308 … 15
1,7 · 10308
long 80 1 15 64 -3,4 · 104932 … 19
double 3,4 · 104932

Design-Hinweis: Eine analytische Abschätzung des


voraussichtlichen Wertebereichs von Variablen im
Programm beugt Speicherplatzverschwendung vor! In
vielen Fällen ist double (double precision) völlig
ausreichend.

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 23


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Darstellungsformen von Gleitpunktzahlen
Ganzzahl!
Syntax der Gleitpunktkonstanten:

sign(opt) integer_part . fraction_part e/E sign(opt) exponent

• vom integer_part (Vorkommastellen) bzw. fraction_part (Nachkommastellen)


kann einer entfallen
• Exponententeil kann ganz wegfallen
• Dezimalpunkt oder Exponententeil müssen vorhanden sein

== 4.5 · 10-5 (Exponent == Zehnerpotenz)


Beispiele:
1.2 1.2e+10 4.5E-5 3E7
1. .2 .3E6 .9e-27

auch mit Suffix möglich:


-123.789e6f 1.8L Suffix f,F (float) oder l,L (long) optional
(ohne Angabe: double)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 24


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
(2) Zeichen-Datentypen
• können beliebige Zeichen des ASCII-Zeichensatzes (auch Sonderzeichen!)
enthalten
• Wertzuweisung von einzelnen Zeichen (sog. Zeichen-Literale ==
Zeichenkonstante) erfolgt durch Einschluß in einfache Hochkommata

Zeichen-Datentypen in ANSI-C/C++
deckt Standard ASCII (7-Bit-Code) ab

Datentyp Größe Bezeichnung Wertebereich


[Bit]
char 8 Integerwert -128 ... 127
signed char 8 Integerwert -128 ... 127
unsigned char 8 Integerwert 0 ... 255

geeignet für ANSI-Code (8-Bit-Code)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 25


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Darstellungsformen von Zeichenkonstanten in char (character)
• wie bereits aus der Tabelle ersichtlich wird ein Zeichen im Typ char intern
als Integerwert (Ganzzahl) repräsentiert
• der Wert entspricht dem entsprechenden Zeichen im ASCII-Code
• wie mit int kann mit char auch gerechnet werden (z.B. Addition etc.)
• i.d.R. wird char aber ausschließlich für die Repräsentation von (Satz-)
Zeichen verwendet

Zeichenkonstanten (Literale) (Einschluß in Hochkommata)


‘A‘ ‘a‘ ‘0‘ ‘*‘

Escape-Sequenzen:
• ASCII-Code Tabelle enthält einige Sonderzeichen (z.B. nicht druckbare
Steuerzeichen)
• bestimmte Sonderzeichen können mit Hilfe des „Fluchtsymbols“ \
(Backslash) dargestellt werden
„entkommt“ dem Ausdruck..

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 26


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Übersicht der wichtigsten Escape-Sequenzen
Escape-Sequenz Hex-Wert (ASCII-Name) Bedeutung
\a 0x07 (BEL) Klingelzeichen, Signalton (alert)
\n 0x0A (LF) LF line feed, neue Zeile (new line)
\t 0x09 (HT) HT – horizontal tabulator,
\v 0x0B (VT) VT – vertical tab (Zeilensprung)
\b 0x08 (BS) BS - backspace
\r 0x0D (CR) CR – carriage return (Zeilenrücklauf)
\0 0x00 (NUL) Nullbyte (leeres Byte)
\000 000 Oktal number
\x00 xhh Hexadecimal number ( ‘0‘ identisch mit
‘\x30‘ )
\\, \‘, \?, \“ 0x5C, 0x27, 0x3F, 0x22 Stellt das zweite Zeichen dar ( \, ‘, ?,
“ )
Für die Darstellung von Escape-Sequenzen werden zwar 2 Zeichen verwendet,
ABER: intern beanspruchen sie nur 1 Byte an Speicherplatz

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 27


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Zeichenkettenkonstanten (string)
• Zeichenkette == Aneinanderreihung mehrerer Zeichen
• kommt in C/C++ sehr häufig vor und wird in doppelte Hochkommas
eingeschlossen

Zeichenkettenkonstante (String-Literal) (doppelte Hochkommata)

“Das ist eine Zeichenkette“

Wie ist eine Zeichenkette aufgebaut?


• intern als Feld (Array) von einzelnen (ASCII-)Zeichen
• das letzte Zeichen ist eine binäre 0 ( ‘\0‘ )
• diese sog. terminierende NULL kennzeichnet das Ende des Strings
• auch die Zeichenkette kann Sonderzeichen (Escape-Sequenzen)
enthalten

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 28


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Unicode („Wide Characters“) und Multibyte (MBCS)
• viele bildsprachliche Zeichen (japanische, chinesische, Thai-Zeichen)
können nicht durch ein char-Zeichen (1 Byte) dargestellt werden

Lösung(en):

Variante 1) Unicode („Wide Characters“)


• Datentyp wchar_t mit fester Länge (16 Bits = 2 Bytes)

char schar = 'x'; /* A character constant */


wchar_t wchar = L'x'; /* A wide-character constant for
the same character */
‘L‘ leitet eine wide character Konstante ein

• alle Basisfunktionen der Standard-Bibliothek für char gelten


gleichermaßen für wchar_t

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 29


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Unicode („Wide Characters“) und Multibyte (MBCS)
Variante 2) Multibyte character set (MBCS)
• ältere (aber immer noch anzutreffende) Variante für die Darstellung
internationaler Zeichen
• multibyte Zeichen haben keine feste Länge (entweder 1 Byte oder 2 Bytes)
• es gibt länderspezifische DBCS (double byte character sets), auch Code-
Pages genannt z.B. für japanisch, chinesisch, koreanisch

leading byte trailing byte Aufbau eines MBCS-Zeichens

jede Länderregion (z.B. Japan) besitzt eine eigene Code-Page


(Zeichentabellen), diese bestimmt den Zahlenbereich des „leading
bytes“

MS-IDE: MS bietet den Datentyp TCHAR an. Gesteuert durch Präprozessor-


konstanten werden Zeichen alternativ als Unicode oder als MBCS übersetzt!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 30


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
(3) Logischer Datentyp
• George Bool entwickelte im 19. Jahrhundert die nach ihm benannte
boolesche Algebra
• Grundgedanke: es gibt nur die beiden Wahrheitswerte wahr (true) und
falsch (false)
• eine Variable, die nur diese beiden Werte annehmen kann ist vom logischen
Datentyp boolean

Logischer Datentyp in ANSI-C++


Datentyp Größe Bezeichnung Wertebereich
[Bit]
bool 8 Boolescher Wert true oder false

obwohl 1 Bit hinreichend wäre (2 Zustände) ist 1 Byte die kleinste


nur in ANSI-C++! adressierbare (direkt ansprechbare) Einheit im Rechner

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 31


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Logischer Datentyp in ANSI-C
ANSI-C bietet keinen elementaren logischen Datentyp

Lösung:
• logische Wahrheitswerte werden über ganzzahlige Variablen verwaltet

Logisch falsch (false) -> 0


Logisch wahr (true) -> ≠ 0 (alle anderen Werte,
meist 1)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 32


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Vereinbarung (Deklaration)
• Festlegung von Bezeichner (Namen) und der Typ der Variablen
• es wird noch kein Speicherplatz reserviert!
keine Leerzeichen oder Schlüsselwörter
(for, int, main etc.) zulässig!
Hinweis zur Namensgebung in C/C++:
• Namen (identifier) bestehen aus einer Menge von Alpha-Zeichen (a-z,
A..Z), numerischen Zeichen (0..9) und dem Unterstrich (under score) _
• erstes Zeichen muß ein Buchstabe oder Unterstrich sein
• klein- und GROSSCHREIBUNG werden unterschieden (case sensitive)
• mind. die ersten 31 Zeichen eines internen Namens werden unterschieden
• bei externen Namen (z.B. Funktionen, globale Variablen) werden nur die
ersten 6 Zeichen garantiert (meist können auch hier längere Namen
verwendet werden)

EMPFEHLUNG: Variablennamen immer klein schreiben, nicht mit _


beginnen! häufig systeminterne Variablen!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 33


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Beispiel für gültige / ungültige Bezeichner (Namen)

/* gültige Namen */
i name GROSS GeMiScHt k2 abc_txt _small

/* ungültige Namen */
1b ABC.TXT -sonderzeichen
- nicht zulässig
. nicht zulässig
Name muß mit Alpha-Zeichen beginnen!

/* gültige Variablendeklaration == Definition */


int i;
int i, j, k;
/* entspricht:
int i;
int j;
int k;
*/

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 34


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Syntax der Variablendeklaration (-vereinbarung)
Variablentyp
Namen, Bezeichner (identifier)
Deklaration in Listenform

Datentyp Name;
Datentyp Name1, Name2; jede Anweisung mit ; abschließen
Datentyp Name = Ausdruck;
Wertzuweisung (Initialisierung)

Sobald im Programm eine Variable vereinbart (deklariert)


ist, kann sie verwendet werden.
Vor der Vereinbarung ist die Variable unbekannt!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 35


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Besonderheit bei Grunddatentypen in C/C++
• C/C++ kennt eine Reihe von Grunddatentypen (elementare Datentypen),
d.h. Typen, die durch die Hochsprache selbst vorgegeben sind (z.B. int für
Ganzzahl, double für Gleitkommazahl, char für ein Zeichen etc.)
• die Deklaration eines Grunddatentyps ist immer gleichzeitig eine Definition,
der Compiler reserviert den für die Variable erforderlichen Speicherplatz in
einem Schritt
bei Grunddatentypen werden Deklaration / Definition synonym verwendet
ACHTUNG: DAS GILT NUR BEI GRUNDDATENTYPEN!!!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 36


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Wertzuweisung (Initialisierung & Zuweisung)
Teil 1) Initialisierung

Frage: Welchen Wert besitzt die nachfolgend definierte Ganzzahlvariable?

int i;

Antwort: Variable i besitzt keinen vereinbarten Anfangswert, der Compiler


weist i beim Erzeugen einen zufälligen (nicht allg. vorhersagbaren) Wert zu

Lösung durch Initialisierung


• wird einer Variablen bei der Definition sofort ein konstanter Wert (Anfangs-
/Startwert) zugewiesen -> Initialisierung!
Zuweisungsoperator
int i = 10;
double d_gewicht = 83.304;
char zeichen = ‘e‘;
Dezimalpunkt ist ein PUNKT . (kein Komma!)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 37


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Designhinweis zur Initialisierung

Alle Objekte (z.B. Variablen) sollten bei ihrer Definition mit


einem sinnvollen Ausgangs-/Anfangswert initialisiert
werden.

Vorteile:
• Fehleranalyse: versehentliche Definitionen können sehr leicht erkannt
werden
• Teamorientierte SW-Entwicklung: einheitliche, systematische
Vorgehensweise erleichtert den Austausch / Übernahme von SourceCode

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 38


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Wertzuweisung (Initialisierung & Zuweisung)
Teil 2) Zuweisung
• eine Wertzuweisung an ein bereits definiertes Objekt (Variable) ist eine
normale Zuweisung (keine Initialisierung)

/* Initialisierung */
int summand = 17;
/* Zuweisung (keine Initialisierung) */
summand = 100;

Code-Beispiel: auch möglich: main() Fkt. ohne Rückgabewert!


void main( void )
{
int summand; /* Deklaration & Definition vom Typ int */
double quotient = 12.34; /* Gleitkommazahl + Initialisierung */
char antwort = 'J'; /* Variable antwort als Zeichenvariable */
summand = 17; /* Zuweisung des Wertes 17 an int-Variable */
}
Demo VC++ .NET:\K34_Konstanten_Datentypen\Variable\Variable.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 39


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Ergänzung zur Zeichenvariablentyp char
• Zeichen werden im Rechner intern über den ASCII-Zeichencode verwaltet

void main( void )


{
...
char antwort = 'J'; /* Variable antwort als Zeichenvariable */
char antwort = 74; /* identisch vgl. ASCII-Code */
}

auch möglich: direkte Angabe des ASCII-


Codes als Variablenwert

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 40


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Übersicht über die sechs C/C++ Grunddatentypen nicht in ANSI-C!
Bereich Typ Quellcode Erklärung
Logischer Wert bool bool aussage Boolscher Wert, der wahr oder falsch ist
(true / false sind vordefiniert)
Ganze Zahlen (signed) int summand Integer (Ganzzahl), Länge entspricht i.a.
int einem Maschinenwort bzw. Register
Reelle Zahlen float float simple Gleitkomma-/punktzahl einfacher
Genauigkeit
double double ext Gleitkomma-/punktzahl doppelter
Genauigkeit
Leerer Typ void void nix Pseudotyp, der auf einen beliebigen Typ
(oder eine Funktion ohne Rückgabewert)
zeigt
Zeichen (signed) char zeichen Einzelnes Byte zur Speicherung eines
char (z.B. ASCII-) Zeichens

Zeichenkonstante (Zeichen-Literale) werden in einfache


Hochkommas '.. ' (Apostrophe) eingeschlossen z.B. 'a' 'A' '0' '*'

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 41


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Modifizierer (modifier) für C/C++ Datentypen
• C/C++ kennt eine Reihe festgelegter Modifizierer, d.h. Ergänzungen, die
zusätzliche Eigenschaften beschreiben
• hier: Vorzeichen und Bittiefe der Binärdarstellung
Modifizierer zum Datentyp Quellcode Erklärung
short int short int Regelt die Bittiefe der Binärdarstellung
short int ≤ int ≤ long int
long int long int Regelt die Bittiefe der Binärdarstellung
double long double short int ≤ int ≤ long int
float ≤ double ≤ long double
signed int signed int vorzeichenbehaftet (default)
char signed char
unsigned int unsigned int vorzeichenlos
char unsigned char

absolute Größe (Anzahl Bits) ist plattformabhängig!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 42


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Speicherbereich, Wertebereich und Genauigkeit

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 43


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Speicherklassen in C/C++
Code-Beispiel:

int g, h = 3;
static int sti = 5;
extern int G;

void main( void ) Fragen über Fragen...


{ z.B.
int i, k = 12; In welchem Abschnitt sind welche Variablen gültig?
static int m = 35; Was bedeuten die „Schlüsselwörter“ (Qualifizierer)
vor den Variablen?
i = k + G + h; Welche Regeln gibt es in C/C++ ?

m = m + sti;
}

einige Antworten hierzu ...

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 44


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Speicherklassen in C/C++
Was sind Speicherklassen?
regeln den Gültigkeitsbereich (scope) und die Lebensdauer von Variablen
C/C++ unterscheidet zwischen statischen und dynamischen Daten
Speicherplatzbedarf zwar zum Übersetzungszeitpunkt bekannt,
Speicherplatz wird aber erst zur Laufzeit des Programms reserviert!
Dynamische Daten (auto, register) :
Qualifizierer Erklärung

auto auto == „automatisch“, alle nicht globalen und nicht static-Variablen


sind „automatische“ auto Variable
auto Variablen werden innerhalb von Blöcken { .. } (z.B. Funktionen,
auch main() ) definiert;
Lebensdauer: werden beim Betreten des Blocks mit undefiniertem Wert
(also ohne mit 0 initialisiert zu werden) angelegt und beim Verlassen
wieder (automatisch) freigegeben (zerstört)
Hinweis: Der Funktionskörper wird nach return zwingend verlassen.

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 45


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Speicherklassen in C/C++
Dynamische Daten (auto, register) :
Qualifizierer Erklärung
register mit register gekennzeichnete Variablen sind auch auto Variablen
Zusatz register ist ein Hinweis an den Compiler, aus
Geschwindigkeitsgründen die Variable direkt in einem internen CPU-
Register zu speichern
Hinweis: Der Compiler ist an den Hinweis nicht gebunden. Wenn z.B. kein
freies Register verfügbar ist, erfolgt keine „Sonderbehandlung“.

Anwendung vorwiegend in der hardwarenahen Systemprogrammierung

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 46


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Speicherplatz wird bereits
Speicherklassen in C/C++ zum Übersetzungszeitpunkt reserviert
Statische Daten (extern, static) :
Qualifizierer Erklärung
extern globale Variablen „leben“ von der Definition bis zum Verlassen des
Programms
mit extern können globale Variablen außerhalb und innerhalb von
Funktionen deklariert werden
die Initialisierung globaler Variablen erfolgt (immer außerhalb von
Funktionen) dort, wo sie definiert werden und ohne Voranstellen von
extern
globale Variablen sind in allen Funktionen bekannt
Hinweis: Linker führt eine Liste der Variablen, an besonderem Platz stehen
dort auch die globalen Variablen.

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 47


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Speicherplatz wird bereits
Speicherklassen in C/C++ zum Übersetzungszeitpunkt reserviert
Statische Daten (extern, static) :
Qualifizierer Erklärung
static Bedeutung 1:
eine mit static gekennzeichnete Variable innerhalb einer Funktion
dient als „Gedächtnis“ (behält den Wert von einem Funktionsaufruf zum
nächsten)
Bedeutung 2:
eine mit static gekennzeichnete Variable außerhalb jeder Funktion
(Top-Level) ist in der gesamten Datei bekannt (Gültigkeit auf Datei
beschränkt!)

Initialisierung von static Variablen:


statische Variablen dürfen nur mit Konstanten vorbelegt werden
nicht vorbelegte statische Variablen werden mit 0 initialisiert

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 48


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Speicherklassen in C/C++
nochmals das Code-Beispiel:

int g, h = 3; // Definition (globale Variable)


static int sti = 5; // Definition (nur in der Datei bekannt)
extern int G; // Deklaration (global bekannt, in einem
anderen Modul/Datei definiert

void func( void ) // Funktionsdefinition (global bekannt)


{
int i, k = 12; // Definition (lokale Variablen, nur in
func() bekannt
static int m = 35; // Definition (lokale Var., statisch
d.h. Gedächtnis!
i = k + G + h; // auto int i wird die Summe aus auto
int k, global int G und global int h
zugewiesen
m = m + sti; // lokal statisch, zu m wird sti
addiert, beim nächsten Aufruf von
func() hat m den Wert 40
}
Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 49
Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Speicherklassen in C/C++
ein wenig Überblick..

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 50


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Operatoren in ANSI-C/C++
• Operatoren (vgl. Mathematik) verknüpfen Datenobjekte
• Operatoren sind Zeichen, die zusammen mit Operanden für die Berechnung
eines Ausdrucks verwendet werden

Folgende Operatoren können unterschieden werden:

(1) Vorzeichen-Operatoren (z.B. +, - )


(2) Arithmetische Operatoren (z.B. +, -, * etc.)
(3) Logische Operatoren (z.B. logisches UND)
(4) Vergleichende (relationale) Operatoren (<, > <= etc.)
(5) Bitweise Operatoren (z.B. ~, |, &, <<, >> etc.)
(6) Zuweisungsoperatoren (z.B. = )

step by step: Was ist ein Ausdruck?

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 51


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Was ist ein Ausdruck?

• Ausdruck (Expression) == Vorschrift zur Manipulation von Daten


• Kombination aus einem oder mehreren Operanden und Operatoren
• WESENTLICH: jeder Ausdruck liefert ein Ergebnis (Wert), der an die Stelle
des Ausdrucks tritt
• einfachster Ausdruck: Konstante, Variable oder Literal (s. Beispiele)
• bei zusammengesetzten Ausdrücken (bestehend aus mehreren
Teilausdrücke) wird die Reihenfolge der Abarbeitung durch die Rangfolge
(Präzedenz, Hierarchie der Operatoren) der Operatoren bestimmt (z.B.
“Punkt vor Strich”, “geklammerte Ausdrücke zuerst auswerten”)
• Datentypkonsistenz: Operationen müssen zu den Operanden passen
• gehört zu den kleinsten ausführbaren Einheiten eines Programms

Schauen wir und einige Beispiele für Ausdrücke an..

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 52


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Beispiele für Ausdrücke in C/C++:

// einfache Ausdrücke
17
1 + 17
“Textliteral“

// zusammengesetzter Ausdruck
a = 1 + 17;

Operand 2 (Zahl-Literal 17)


Operator + resultierender Wert des Ausdrucks: 18
Operand 1 (Zahl-Literal 1)

Schachtelungstiefe von
Anweisung, bestehend aus dem Ausdrücken ist zwar nicht
Ausdruck 1 + 17 und der Zuweisung des explizit begrenzt.
resultierenden Wertes an die Variable a ABER: Zum guten Stil gehören
lesbare Ausdrücke (KISS keep it
simple, stupid)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 53


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Klassifikation von Operatoren
• Operatoren können ferner nach ihrer Stelligkeit unterschieden werden

Unäre (einstellige) Operatoren


• werden auf nur einen Operanden angewendet

Beispiel:
- 56
Ausdruck
Operand
Vorzeichen-Operator

• Vorzeichenoperator ist unär: er ändert das Vorzeichen des ihm folgenden


Operanden (Umwandlung in eine negative Zahl)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 54


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Klassifikation von Operatoren

Binäre (zweistellige) Operatoren


• werden auf zwei Operanden angewendet

Beispiel:
12 + 56
Ausdruck
Operand 2
Additions-Operator +
Operand 1
• Additionsoperator ist binär: es werden zwei Operanden verknüpft

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 55


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Klassifikation von Operatoren
relativ selten in C/C++ und Java
Ternäre (dreistellige) Operatoren
• werden auf drei Operanden angewendet

Beispiel:
Ausdruck ? b : c
Ausdruck
Operand 3
Operand 2
?-Operator (Bedingungsoperator)
Operand 1 (Bedingung)

• ?-Operator ist ternär: der Ausdruck wird auf Wahrheitsgehalt geprüft, ist der
Ausdruck wahr wird b als Wert geliefert, andernfalls c

äquivalente Bedingungsanweisung lautet: if (Ausdruck) b; else c;

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 56


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Operatoren in ANSI-C/C++
Vorbemerkung:
• C/C++ ist als Implementierungssprache konzipiert
• die verfügbaren Operatoren konzentrieren sich auf Basisoperationen und
nicht auf höhere Funktionen (die sich durch Basisoperationen darstellen
lassen)

Kurzform-Operatoren:
• C/C++ unterstützt eine Kurzschreibform für Operatoren (s. ff.)
• dies erlaubt sehr effiziente Ausdrücke, erschwert aber die u.U. die
Lesbarkeit des Codes!
• TIPP: sparsam einsetzen

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 57


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
(1) Vorzeichen-Operatoren
• C/C++ kennt kein positives Vorzeichen
• im ANSI-C99 Standard wurde neu der unäre Operator + eingeführt
(entspricht in der Schreibweise dem positiven Vorzeichen)

Operator Quelltext (Beispiel) Bedeutung


+ +a Unäres Plus (optional), positives Vorzeichen
(entspricht a)
- -a Unäres Minus, negatives Vorzeichen (kehrt das
Vorzeichen um)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 58


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
(2) Arithmetische Operatoren
• C/C++ unterstützt folgende (primitive) arithmet. Operatoren
• gültig für Ganzzahlen (short, int, long)
• gültig für Gleitpunktzahlen (float, double, long double)
(Einschränkung: Modulo s. u.)

Operator Quelltext (Beispiel) Bedeutung


+ i + 2 Binäres Plus (Addition)

- i - 5 Binäres Minus (Subtraktion)

* 5 * i Multiplikation

/ i / 6 Division

% i % 4 Modulo (Rest der ganzzahligen Division)

WICHTIG: nicht für Gleitkommazahlen!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 59


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
(2) Arithmetische Operatoren
Code-Beispiel:
#include <stdio.h>
int main(void)
{
int summand1, summand2, summe;
summand1=18; /* Zahl-Literal */
summand2=56; /* Zahl-Literal */
printf("Addition zweier Zahlen:\n\n" );
printf("Der erste Summanden ist a = %d.\n", summand1);
printf("Der zweite Summand ist b = %d.\n", summand2);
summe = summand1 + summand2;
printf("Das Ergebnis lautet: %d + %d = %d.\n ", summand1,
summand2, summe);
getchar();
return 0; WICHTIG: Ergebnis der Operation ist vom
} gleichen Typ wie die Operanden!

Demo VC++ .NET:\K34_Konstanten_Datentypen\Addition\Addition.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 60


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
(2) Arithmetische Operatoren (Modulo-Operator)
Sonderfall: Division von Ganzzahlen (sog. Ganzzahldivision)
• C/C++ verwendet bei Division von Ganzzahlen (z.B. int) die sog.
Ganzzahldivision
• d.h. die Nachkommastellen eines gebrochen rationalen Ergebnisses
werden („brutal“) abgeschnitten
Beispiel:
• Ergebnis von 15 / 2 = 7 (statt 7,5)
Lösung:
• Division mit Rest, der über den Modulo-Operator ermittelt werden kann!
• 15 % 2 = 1 (Rest der Ganzzahldivision 15 / 2 = 7, Rest 1)

Modulo-Operator: Rest bei einer Ganzzahldivision


Modulo = a – (a / b) * b
z.B. a = 10; b = 3
10 / 3 -> 3 10 % 3 -> 1

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 61


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
(2) Arithmetische Operatoren
Code-Beispiel zur Ganzzahldivision und Restermittlung:
#include <stdio.h>
int main(void)
{
int divident, divisor, quotient, rest;
divident = 56;
divisor = 18;
printf("\n\nDivision zweier Zahlen:\n\n");
printf("Der Divident ist a = %d.\n", divident);
printf("Der Divisor ist b = %d.\n", divisor);
quotient = divident / divisor;
printf("Das Ergebnis lautet: %d : %d = %d ", divident, divisor,
quotient); Modulo-Operator
rest = quotient = divident % divisor;
printf("Rest: %d\n\n\n", rest);
getchar();
return 0;
}

Demo VC++ .NET:\K34_Konstanten_Datentypen\DivisionMitRest\DivisionMitRest.vcproj


Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 62
Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
(2) Arithmetische Operatoren (Kurzformoperatoren)
• C/C++ unterstützt folgende arithmet. Kurzform-Operatoren
• gültig für Ganzzahlen (short, int, long)
• gültig für Gleitpunktzahlen (float, double, long double)
(Einschränkung: Modulo s. u.)

Operator Quelltext (Beispiel) Bedeutung


+= i += 5 i = i + 5

-= i -= 5 i = i - 5

*= i *= 5 i = i * 5

/= i /= 5 i = i / 5

%= i %= 5 i = i % 5

WICHTIG: nicht für Gleitkommazahlen!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 63


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
(2) Arithmetische Operatoren (Inkrement-/Dekrementoperatoren)
• Addition / Subtraktion von 1 zu einer Variablen ist eine sehr häufige
Operation
• C/C++ bietet dafür 2 spezielle (unäre) Operatoren an:
Inkrement-Operator ++ BESONDERHEIT: Präfix- und Postfix-
Dekrement-Operator -- notation möglich!

Operator Quelltext (Beispiel) Bedeutung


++ ++i Vorherige Inkrementierung (Präinkrement)

i++ Nachfolgende Inkrementierung (Postinkrement)

-- --i Vorherige Dekrementierung (Prädekrement)

i-- Nachfolgende Dekrementierung (Postdekrement)

in beiden Fällen wird die Variable um 1 erhöht bzw. erniedrigt,


nur die Reihenfolge ist umgekehrt -> s. Beispiel ..

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 64


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
(2) Arithmetische Operatoren (Inkrement-/Dekrementoperatoren)
Beispiel zum Prä-/Postinkrement bzw. –dekrement:

int a, i = 5;
a = ++i; /* i erst inkrementieren, dann zuweisen: a = i = 6 */

int b, j = 2;
b = j++; /* j erst zuweisen, dann inkrementieren: b = 2, j = 3 */

Präfix-Version: Wert der Variablen wird verändert


(erhöht/ernierdrigt) bevor der Wert benutzt wird!

Postfix-Version: Wert der Variablen wird erst verändert


(erhöht/erniedrigt), nachdem die Variable benutzt wurde!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 65


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
(3) Logische Operatoren
• logische Operatoren verknüpfen Wahrheitswerte (Ergebnis ist immer ein
logischer Wert!)
• in C/C++ gilt: Wert 0 -> false (falsch), alle anderen Werte -> true (wahr)

Operator Quelltext (Beispiel) Bedeutung


&& X && Y Logisches AND (UND)
true, falls X und Y = true
|| X || Y Logisches OR (ODER)
true, falls X oder Y = true
! !X Negation, true falls X = false und
umgekehrt

unär (einstellig)

gültig nur für Ganzzahlen oder Datentyp bool (nur ANSI-C++)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 66


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
(3) Logische Operatoren - Beispiel
• Ausdrücke mit logischen Operatoren sind oft komplexer, bestehen aus vielen
Teilausdrücken (zusammengesetzter Ausdruck)
/* zusammengesetzter logischer Ausdruck */
e1 && e2 && e3 && e4 -> true, falls alle ei == true

e1 || e2 || e3 || e4 -> false, falls alle ei == false

• manchmal kann das Ergebnis des Gesamtausdrucks bereits vorliegen, wenn


noch nicht alle Teilausdrücke ausgewertet wurden:
/* logischer Ausdruck in einer if-Bedingung */
if (x != 0 && (y / x) > 3)
y = 4;

falls x = 0 wird der Ausdruck (x / y) gar nicht mehr ausgewertet, das


Ergebnis des Gesamtausdrucks ist false

logische Ausdrücke werden von „links nach rechts“ ausgewertet (linksassoziativ)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 67


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
(4) Vergleichende (relationale) Operatoren
• vergleichen Ausdrücke miteinander und liefern ein logisches Ergebnis
(entweder true oder false)
• in C/C++ gilt: im Fall von true wird der Wert 1 geliefert
• gültig für Ganzzahlen (short, int, long)
• gültig für Gleitpunktzahlen (float, double, long double)

Operator Quelltext (Beispiel) Bedeutung


< i < j Kleiner als
> i > j Größer als
<= i <= j Kleiner gleich
>= i >= j Größer gleich
== i == j Gleich
!= i != j Ungleich

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 68


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
(5) Bitoperatoren (Einleitung)
Bit
• Rechnerprozessoren bestehen aus vielen Schalttransistoren (realisiert als
Integrated Circuit IC)
Zustandstabelle:

Schaltzustand Kennzeichen Logischer Wert

- AUS - Keine Spannung 0 (false)


- EIN - Spannung vorhanden 1 (true)

Dualsystem (Stellenwertsystem mit Basis 2) ist besonders für die


Zahlendarstellung geeignet

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 69


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
(5) Bitoperatoren (Zahlendarstellung)
Beispiel zur Zahlendarstellung im Dezimal- und Dualsystem

Dezimalsystem:
25 = 2*101 + 5*100

Dualsystem:
25 = 1*24 + 1*23 + 0*22 + 0*21 + 1*20

Anzahl Bits Einheit Zustände


11001
1 Bit 2
Speicherung der fünfstelligen Dualzahl 8 BYTE 28
benötigt 5 Speicherstellen (Bits)
16 WORT 216
(word)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 70


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
(5) Bitoperatoren (bitweise Operationen)
• C/C++ bietet die sehr wichtige Möglichkeit, einzelnen Bits bzw. Gruppen von
Bits zu manipulieren (unterstützt eine hardwarenahe Programmierung!)
• die bitweisen Operatoren ermöglichen dies mit Hilfe von logischen
Basisoperationen

Übersicht logische Basisoperationen:

Operator Beschreibung
& Bitweises AND (UND)
| Bitweises OR (ODER) WICHTIGE EINSCHRÄNKUNG:
bitweise Operatoren dürfen
^ Bitweises XOR (Exklusiv-ODER) nicht auf Gleitpunktzahlen
<< angewendet werden!
Schieben links
>> Schieben rechts
~ 1-Komplement (Negation)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 71


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
(5) Bitoperatoren (bitweise Operationen)
Wirkungsweise anhand von Wahrheitstabellen

UND-Verknüpfung a & b ODER-Verknüpfung a | b


1. Bit 1 1 0 0 1. Bit 1 1 0 0
2. Bit 1 0 1 0 2. Bit 1 0 1 0
Ergebnisbit 1 0 0 0 Ergebnisbit 1 1 1 0
true (1), wenn beide Operanden true (1), wenn mind. einer der beiden
true (1) sind, sonst false (0) Operanden true (1) ist, sonst false (0)

Exclusiv-ODER-Verknüpfung a ^ b
1. Bit 1 1 0 0
true (1), wenn nur einer der beiden
2. Bit 1 0 1 0 Operanden true (1) ist, sonst false (0)
Ergebnisbit 0 1 1 0

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 72


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
(5) Bitoperatoren (Übersicht inkl. Kurzformoperatoren)

Operator Quelltext (Beispiel) Bedeutung


<< i << 2 Linksschieben
>> i >> 1 Rechtsschieben
& i & 7 Bitweises UND
| i | 7 Bitweises ODER
^ i ^ 7 Bitweises XOR (Exklusiv-ODER)
~ ~i Bitweise Negation
<<= i <<= 3 i = i << 3
>>= i >>= 3 i = i >> 3
&= i &= 3 i = i & 3 Kurzform
^= i ^= 3 i = i ^ 3
|= i |= 3 i = i | 3

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 73


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
(5) Bitoperatoren – Beispiel für die Anwendung
• bitweise Operationen sind schneller als arithemtische Operationen!

Beispiel zur Multiplikation:


• linksschieben um x Stellen entspricht der Multiplikation mit Faktor 2x

Beispiel:

ganze Zahl (short,16-Bit) als Bitvektor


short c,k;
k = 5; //0000 0000 0000 0101
c = k << 2; // 2 bit nach links von rechts wird mit 0 aufgefüllt!
-> c = 20; //0000 0000 0001 0100
-> entspricht Multiplikation
mit 22 = 4

c & k //0000 0000 0000 0100 (410)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 74


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
(5) Bitoperatoren – Beispiel für die Anwendung
VORSICHT!!
Ergänzender Hinweis zum Rechtsschieben >>:
• vorzeichenlose (unsigned) Zahlen: von links mit 0 nachgeschoben
• vorzeichenbehaftet (signed) Zahlen: implementierungsabhängig, meist
wird das VZ-Bit nachgeschoben

Beispiel:
Beispiel zur Multiplikation:
• linksschieben
ganze um 2 Stellen
Zahl (short,16-Bit) alsentspricht
Bitvektor der Multiplikation mit Faktor 2² = 4
short c,k;
k = 5; //0000 0000 0000 0101
c = k << 2; // 2 bit nach links
-> c = 20; //0000 0000 0001 0100
-> entspricht Multiplikation
mit 22 = 4

c & k //0000 0000 0000 0100 (410)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 75


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
(5) Bitoperatoren – Code-Beispiel
#include <stdio.h>
int main(void)
{ Demo VC++ .NET:\K34_Konstanten_Datentypen\Bit\Bit.vcproj
int e, x = 9;
printf("Ausgabe Ausgangswert: %d\n", x);
e = x & 3;
printf("Ausgabe UND-Verknuepfung mit 3: %d\n", e);
e = x | 3;
printf("Ausgabe ODER-Verknuepfung mit 3: %d\n", e);
e = x ^ 3;
printf("Ausgabe EXCLUSIV-ODER-Verknuepfung mit 3: %d\n", e);
e = x << 1;
printf("Ausgabe Linksschieben um 1 Stelle: %d\n", e);
e = x >> 3;
printf("Ausgabe Rechtsschieben um 3 Stellen: %d\n", e);
e =~ x; sog. 1er Komplement für Dualzahlen!
printf("Das unaere Komplement ist: %d\n", e);
getchar();
return 0;
}
Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 76
Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
(5) Bitoperatoren – Code-Beispiel (Erklärung der Ausgabe)

// x = ... 0000 1001


// 3 = ... 0000 0011
// x & 3 = ... 0000 0001 = 1 (dez)
// x | 3 = ... 0000 1011 = 11 (dez)
// x ^ 3 = ... 0000 1010 = 10 (dez)
// x << 1 = ... 0001 0010 = 18 (dez)
// x >> 3 = ... 0000 0001 = 1 (dez)
// ~x = 1 111 1111 1111 1111 1111 1111 1111 0110
// 2K(~x) = 000 0000 0000 0000 0000 0000 0000 1010 = -10 (dez)

2er Komplement (VZ-Bit unberücksichtigt,


Negation des Rests + 1 addieren)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 77


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
(6) Zuweisungsoperatoren
• Wertzuweisung an eine Variable erfolgt mit dem Zuweisungsoperator

Operator Quelltext (Beispiel) Bedeutung


= i = 3 + j Zuweisung

Hinweis:
C/C++ unterstützt die Kopplung des Zuweisungsoperators mit anderen
Operatoren -> vgl. Kurzformen-Operatoren bei arithmetischen und bitweisen
Operatoren

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 78


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Umwandeln eines Datentyps
• bei Operation mit Operanden unterschiedlichen Datentyps gibt es definierte
Regeln in C/C++, nach denen eine sog. (implizite) Typumwandlung erfolgt
• man kann auch explizite Typumwandlungen (cast-Anweisung)
vornehmen erfolgt durch den Compiler!

Anweisung Bedeutung
int i; i ist eine Variable vom Typ int
(double)i; Umwandlung des Wertes der Variablen i vom Typ int in den Typ
double
double a, b; in der Variablen x wird das Ergebnis einer Ganzzahldivision als
double x = Gleitkommazahl gespeichert
(double) ((int)a /
(int)b);

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 79


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Zusatz: Regeln in C/C++ für die implizite Typumwandlung
• arithmetische Typen (Ganzzahl oder Gleitpunktzahlen) können in
Operationen gemischt werden
• der Compiler nimmt dann automatisch eine implizite Typumwandlung vor

Grundsatz:
„kleinere“ Datentypen werden in „größere“ Datentypen umgewandelt
das ist dann auch der Typ des Ergebnisses
(AUSNAHME: Zuweisungen, s. später)

in jedem Ausdruck zunächst Ganzzahlerweiterung


Ganzzahlerweiterung:

char, unsigned char, short int

unsigned short int (falls int gleich long)


unsigned int (falls int gleich short)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 80


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Zusatz: Regeln in C/C++ für die implizite Typumwandlung
Beispiel zur Ganzzahlerweiterung:

char c;
c < ‘a‘; /* vor dem Vergleich wird c in int erweitert */

Weitere implizite Typanpassungen


• sind nach der Ganzzahlerweiterung immer noch unterschiedliche
Datentypen vorhanden -> Anpassung nach Datentyp-Hierarchie (s. nächste
Folie)
• der Datentyp, der am weitesten oben in der Hierarchie steht ist maßgebend!

AUSNAHME: Zuweisungsoperator und logische Operatoren && sowie ||

keine Regel (in C/C++) ohne Ausnahme.. ☺

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 81


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Zusatz: Regeln in C/C++ für die implizite Typumwandlung
Hierarchie der Datentypen

long double
↑ gem. ANSI C99 nicht gefordert,
double aber durch viele Compiler
↑ unterstützt!
float

unsigned long

long

unsigned int

int

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 82


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Zusatz: Regeln in C/C++ für die implizite Typumwandlung
Implizite Typumwandlung bei Zuweisungen

int i = 100; long l;


l = i + 50; //Ergebnis vom Typ int wird in long gewandelt

long l = 0x654321; short s;


s = l; // 0x4321 wird an s zugewiesen

double d = -2.345;
int i; unsigned int ui;
i = d; // Zuweisung von -2
ui = d; // -2 nicht in ui darstellbar

double d = 1.23456789012345;
float f;
f = d; // 1.234568 wird an f zugewiesen

auch jetzt ist dieses Thema noch nicht erschöpfend behandelt, aber dafür gibt es
weiterführende Literatur..

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 83


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen

a) Vorrangregeln der
Algebra
b) linksassoziativ
c) Ausnahme: Ränge 2
und 15
(rechtsassoziativ)

||

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 84


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen

Beispiele:

a = b + d + c; identisch mit a = ((b+d) + c); -> linksassoziativ


a = b = d = c; identisch mit a = (b = (d = c)); -> rechtsassoziativ

Reihenfolge der Auswertung von Unterausdrücken untereinander


(auch Klammerausdrücke) ist undefiniert!

(Negativ-)Beispiele:

int total = 0;
sum = (total = 3) + (++total); -> entweder 4 oder 7 ??

int i = 2;
i = 3*i++; -> entweder 7 oder 6 ??

HINWEIS: Compiler bestimmt schon eine Lösung, die aber durch die Sprache nicht
vorgegeben ist!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 85


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Formatierte Ausgabe (ANSI C)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 86


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Tabelle(n) mit Ausgabemöglichkeiten zu printf() (ANSI C)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 87


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Tabelle(n) mit Ausgabemöglichkeiten zu printf() (ANSI C)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 88


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Tabelle(n) mit Ausgabemöglichkeiten zu printf() (ANSI C)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 89


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Tabelle(n) mit Ausgabemöglichkeiten zu printf() (ANSI C)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 90


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Tabelle(n) mit Ausgabemöglichkeiten zu printf() (ANSI C)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 91


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Tabelle(n) mit Ausgabemöglichkeiten zu printf() (ANSI C)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 92


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Einfache Datentypen
Ein-/Ausgabe in ANSI-C++: Streaming-Technik

Verweis auf PowerSlides C++:

Microsoft
owerPoint Presentatio

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 93


Technische Informatik und Programmieren
Konstanten und Einfache Datentypen
Übung
Vorlesungsbegleitende Übung
(1) Schreiben Sie ein Programm, das die Addition, Subtraktion,
Multiplikation und Division für zwei Gleitkommazahlen ausführt und die
Ergebnisse mit 5 Stellen und 3 Nachkommastellen auf dem Bildschirm
ausgibt. Die beiden Zahlen sind als Konstanten im Programm
festgelegt.
(2) Geben Sie die Zahl 1258 als int-Zahl, double-Zahl in
Exponentenschreibweise und als Hexadezimalzahl aus.
(3) Ermitteln Sie das Ergebnis einer EXCLUSIV-ODER-Verknüpfung zweier
Variablen vom Typ char und geben Sie das Ergebnis aus. Wiederholen
Sie nun diese Operation ein weiteres Mal mit dem Ergebnis und der
zweiten Variablen. Was stellen Sie fest?

Hinweis: Verwenden Sie bitte printf() ANSI-C zur Ausgabe!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 94


Technische Informatik und Programmieren
Unterprogramm-Technik
Orientierung
Einleitung
Das erste Programm in C
ORIENTIERUNG
Konstanten
Einfache Datentypen
Unterprogramm – Technik –
Nützliche Funktionen
Steuerstrukturen
Typvereinbarungen von Variablen
Zeiger
Der Präcompiler
Modulare Programmierung
Entwicklungsumgebungen
Standardbibliotheken
Anhang

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 1


Technische Informatik und Programmieren
Unterprogramm-Technik
Ziele

Wie ist eine Funktion aufgebaut?


Wie wird eine Funktion definiert und aufgerufen?
Was sind Parameter einer Funktion?
Wie werden Parameter an eine Funktion übergeben?
ZIELE

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 2


Technische Informatik und Programmieren
Unterprogramm-Technik
Inhalt
Unterprogramm-Technik
Einführung mit einem Beispiel
Definition einer Funktion
Aufbau einer Funktion
Syntax der Funktionsvereinbarung
INHALT

Verwenden einer Funktion


Unterprogrammaufruf als Auftrag der Hauptfunktion
Funktion mit und ohne Ergebnisrückgabe
Parameter einer Funktion
Rückgabe von Werten
Mehrere Werte mit einer Funktion zurückgeben
Referenzen als Parameter
Funktionsprototypen
Syntax des Prototypings
Übung

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 3


Technische Informatik und Programmieren
Unterprogramm-Technik
Einführung mit einem Beispiel
Brutto-Nettopreis-Beispiel
Problembeschreibung:
Es sind für verschiedene Artikel, deren Nettopreise (ohne MwSt.) bekannt
sind, die Bruttopreise auf dem Bildschirm (ähnlich einem Kassenbon)
auszugeben und die Gesamtsumme mit der zugehörigen Mehrwertsteuer ist
auszuweisen.

Lösungsansatz:
• Strukturierung der Problembeschreibung (Finden eines Algorithmus)
• Erstellen eines Struktogramms als Grundlage für den Programmentwurf

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 4


Technische Informatik und Programmieren
Unterprogramm-Technik
Einführung mit einem Beispiel
Struktogramm: Artikelpreis netto in brutto umrechnen
Aufnahme des Nettopreises von Artikel 1 in eine Variable Abarbeitungsrichtung
Berechnung des Bruttopreises

Einzelschritte treten mehrfach auf!


Ausgabe des Bruttopreises auf dem Bildschirm

Aufnahme des Nettopreises von Artikel 2 in eine Variable

Berechnung des Bruttopreises

Ausgabe des Bruttopreises auf dem Bildschirm

Aufnahme des Nettopreises von Artikel 3 in eine Variable

Berechnung des Bruttopreises

Ausgabe des Bruttopreises auf dem Bildschirm

Berechnung des Gesamtbruttopreises

Ausgabe des Gesamtbruttopreises

Lösungsidee: Quelltext für mehrfache Einzelschritte in eine Funktion auslagern!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 5


Technische Informatik und Programmieren
Unterprogramm-Technik
Einführung mit einem Beispiel
Vorteile des Auslagerns in eine Funktion
• es wird kein Quelltext kopiert -> Quelltext an einer Stelle konzentriert
• Quelltext muß nur an einer zentralen Stelle gepfelgt werden (Änderungen,
Fehlerkorrekturen etc.)
• Programm wird übersichtlicher
• Flexibilität: Funktion kann Parameter übernehmen, das Funktionsergebnis
ändert sich dadurch abhängig von den Parametern

Prozedurale Programmierung beruht auf extensivem


Gebrauch von Funktionen.
Wann immer möglich, sollten Aufgaben in Teilaufgaben
zerlegt werden!
Prinzip: „Teile und herrsche!“

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 6


Technische Informatik und Programmieren
Unterprogramm-Technik
Definition einer Funktion
Aufbau einer Funktion

Funktionskopf Typ des Rückgabewertes Name der Funktion (Parameter)


Blockzeichen {
Anweisung 1;
Anweisungsteil Anweisung 2; { Pseudocode }

Rücksprungzeile return wert;


Blockzeichen }

Syntax der Funktionsvereinbarung


int add(int z1, int z2)
{
return(z1 + z2);
} ( .. ) wegen berechneter Ausdruck (optional)

Typ im return muß mit dem Rückgabetyp im Funktionskopf übereinstimmen

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 7


Technische Informatik und Programmieren
Unterprogramm-Technik
Definition einer Funktion
Wichtige Hinweise zur Definition von Funktionen
• Funktionskopf folgt nach den Präcompiler-Anweisungen (#..)
• an 1. Stelle: Rückgabetyp der Funktion (muß mit Return-Typ d.h. dem Wert
nach der Anweisung return identisch sein)
• an 2. Stelle: Name der Funktion (gem. Namensgebung für Bezeichner vgl.
Variablennamen)
• in ( .. ): Parameterliste, d.h. hier werden Werte an die Funktion übergeben,
mehrere Werte sind durch Kommata getrennt
• Parameter besteht aus a) Datentyp und b) Bezeichner (Parametername)
• Parameter kann innerhalb der Funktion (Anweisungsblock) wie eine Variable
verwendet werden
• default: Parameterübergabe per Wert (Call-by-value), d.h. in der Funktion
wird eine Kopie des übergebenen Wertes angelegt (Original des
Hauptprogramms wird nicht verändert)
• Anweisungsblock { .. }: hier steht, was die Funktion tut!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 8


Technische Informatik und Programmieren
Unterprogramm-Technik
Definition einer Funktion
Wichtige Hinweise zur Definition von Funktionen
• am Ende des Anweisungsblocks: Rücksprung zur funktionsaufrufenden
Anweisung (z.B. Hauptprogramm)
• Wert nach return-Anweisung wird als Rückgabewert der Funktion
zurückgegeben (Ergebniswert der Funktion)

WICHTIG: Die Funktion wird nach nach dem ersten return


verlassen (Rücksprung an den Aufrufer!) Anweisungen
nach return werden nicht ausgeführt.

Trotzdem kann eine Funktion mehrere return-Anweisungen enthalten.


Dadurch sind verschiedene Positionen zum Verlassen der Funktion möglich!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 9


Technische Informatik und Programmieren
Unterprogramm-Technik
Definition einer Funktion
Verwenden einer Funktion
• Funktionsaufruf (z.B. aus Hauptprogramm) erfolgt durch den
Funktionsnamen und eine Liste mit Variablen, Konstanten oder Ausdrücken,
deren Werte an die Funktion übergeben werden sollen (Parameter)

int main(void) Parameteranzahl und -datentyp


{ muß mit Funktionsdefinition
{ Pseudocode }
... übereinstimmen!
/* Aufruf ohne Rückgabewert */
Funktionsname(Parameter1, Parameter2, ..);
...
/* Aufruf mit Wertrückgabe */
Var = Funktionsname(Parameter1, Parameter2, ..);

return 0; Rückgabewert der Funktion wird an eine Variable


} übergeben (Zuweisung)

Um die Funktion zu verwenden, muß sie mind. deklariert sein!


(s. Funktionsprototyp später ☺ )

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 10


Technische Informatik und Programmieren
Unterprogramm-Technik
Definition einer Funktion
Unterprogrammaufruf als Auftrag der Hauptfunktion
HAUPTPROGRAMM

Das Hauptprogramm gibt einen UNTERPROGRAMME


Auftrag an ein Unterprogramm

Auftrag FUNKTION

Auftrag FUNKTION

Das Unterprogramm führt den


Auftrag für das Hauptprogramm
aus.

• Unterprogramm beinhaltet einen Algorithmus, der mehrfach in der


Programmausführung benötigt wird
• Vorteil des Auslagerns (Funktion): Algorithmus nur einmal codiert!
• Flexibilität: kann mit variierenden Parametern (Argumenten) aufgerufen
werden
• -> übersichtlicher, kompakter Quellcode!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 11


Technische Informatik und Programmieren
Unterprogramm-Technik
Definition einer Funktion
Funktion mit und ohne Ergebnisrückgabe
(1) Funktionsaufruf mit Ergebnisrückgabe

HAUPTPROGRAMM FUNKTION
{ Aufruf der Funktion
Anweisung1; int Funktion1()
1 2
Anweisung2; {
...; Anweisung4;
Abarbeiten
Anweisung5; 3
A = Funktion1(); der Funktion
...; Anweisung6;
4
Anweisung3; ...
...; return Ergebnis;
5 Rückgabe eines
} }
Ergebnisses

• Funktionsaufruf: Verlassen des Hauptprogramms (alle Registerinhalte,


Stapelspeicher (stack) etc. werden zwischengespeichert)
• Rückgabewert der Funktion „tritt an die Stelle des Aufrufers“
• Register- und Speicherinhalten im Hauptprogramm werden wieder
„restauriert“

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 12


Technische Informatik und Programmieren
Unterprogramm-Technik
Definition einer Funktion
Funktion mit und ohne Ergebnisrückgabe
(2) Funktionsaufruf ohne Ergebnisrückgabe

HAUPTPROGRAMM FUNKTION
{ Aufruf der Funktion
Anweisung1; void Funktion()
1 2
Anweisung2; {
...; Anweisung4; Abarbeiten
3
Funktion(); Anweisung5; der Funktion
...; Anweisung6;
Anweisung3; 4 ...
...; }
}

Funktion enthält keine return-Anweisung

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 13


Technische Informatik und Programmieren
Unterprogramm-Technik
Definition einer Funktion
Beispiel: Netto-Bruttopreis-Berechnung
#include <stdio.h> /* wg. printf-Funktion */
#define MWST_SATZ 0.16 /* Konstanten vereinbaren */
#define ARTIKEL_1 7.20 /* Alt.: const double dArtikel_1 = 7.20 */
#define ARTIKEL_2 1.40
#define ARTIKEL_3 5.60 außerhalb jeder Funktion!

double preis; /* globale Variable Nettopreis (sichtbar in mwst() ) */


int mwst(void) Unterprogramm (Funktionsdefinition, keine Parameter -> void)
{
printf("\n+\t%f DM\n", preis * (MWST_SATZ + 1)); /* Bruttopreis */
return 0;
}
int main(void) /* Beginn des Hauptprogramms */
{
...

HINWEIS: Rückgabewert in mwst() hier nicht notwendig!


Alternative: void mwst(void) oder void mwst()

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 14


Technische Informatik und Programmieren
Unterprogramm-Technik
Definition einer Funktion
Beispiel: Netto-Bruttopreis-Berechnung
...
int main(void) /* Hauptprogramm */
{
preis=ARTIKEL_1; /* Zuweisung Artikelpreis an Variable preis */
mwst(); /* Aufruf der Funktion mwst() -> Bruttopreis
berechnen und ausgeben */
preis=ARTIKEL_2; /* nächster Artikelpreis zuweisen + berechnen */
mwst();
preis=ARTIKEL_3; /* dito s.o. */
mwst();
printf("---------------------");
preis=ARTIKEL_1+ARTIKEL_2+ARTIKEL_3;
mwst();
printf("=====================");
getchar();
return 0;
}
Demo VC++ .NET:\K5_Unterprogramm_Technik\NettoBrutto1\NettoBrutto1.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 15


Technische Informatik und Programmieren
Unterprogramm-Technik
Parameter einer Funktion
Parameter einer Funktion
• über die im Funktionskopf vereinbarten Parameter können Werte oder
Konstanten an die Funktion übergeben werden
Code-Beispiel:

int add(int z1, int z2) Funktionsdefinition


{ Parameterübergabe
return(z1 + z2);
}
...
int main(void)
{
int a = 2, b = 3, e;
e = add(a,b); /* e = 5 */
e = add(a,5); /* e = 7 */
... Aktualparameter = Konstante
return 0;
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 16


Technische Informatik und Programmieren
Unterprogramm-Technik
Parameter einer Funktion
Beispiel: Netto-Bruttopreis-Berechnung (Fortsetzung)
• Erweiterung unseres Beispiels: Jetzt wird der Funktion mwst() ein Parameter
(hier: Netto-Preis) übergeben
• die Funktion mwst() wird dann in main() für jeden Artikel aufgerufen
#include <stdio.h>
#define MWST_SATZ 0.16
#define ARTIKEL_1 5.20
#define ARTIKEL_2 1.25
#define ARTIKEL_3 0.50
int mwst(double preis) Parameter preis vom Typ double
{
printf( "\n*\t%5.2f EUR\n", preis * ( MWST_SATZ + 1 ) );
return 0;
} innerhalb der Funktion wird der
int main() Parameter wie eine Variable
... behandelt
\n Zeilenumbruch, * anschließend Tab,
danach Wert der berechneten Variablen
(5-stellig, 2 Nachkommastellen), danach
EUR-Kennzeichnung

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 17


Technische Informatik und Programmieren
Unterprogramm-Technik
Parameter einer Funktion
Beispiel: Netto-Bruttopreis-Berechnung (Fortsetzung)
...
int main() Parameterübergabe (hier: Konstante)
{
mwst(ARTIKEL_1);
mwst(ARTIKEL_2); gestrichelte Linie (Optik!)
mwst(ARTIKEL_3); zuerst Summe berechnen, dann als
printf("-----------------\n"); Parameter übergeben
mwst(ARTIKEL_1+ARTIKEL_2+ARTIKEL_3);
printf( "=================\n\n" ) ;
getchar();
return 0;
}

Demo VC++ .NET:\K5_Unterprogramm_Technik\NettoBrutto2\NettoBrutto2.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 18


Technische Informatik und Programmieren
Unterprogramm-Technik
Rückgabe von Werten
Rückgabe von Werten
• Funktionen geben ihren Rückgabewert über die return-Anweisung an den
Aufrufer zurück
• nach der return-Anweisung wird die Funktion sofort verlassen
• wird kein Wert zurückgegeben (void func() ) kann auf die return-
Anweisung verzichtet werden
Code-Beispiel (Umrechung eines Preises von DM -> EUR):
#include <stdio.h>
#define EURO_SATZ 1.95583
#define ARTIKELPREIS 23.45
double ergebnis; /* Vereinbarung Variable ergebnis vom Typ double */
double euro(double preis) /* Rückgabetyp: double */
{
return preis/EURO_SATZ; /* Berechnung des Preises in EUR +
Rückgabe an den Aufrufer */
}
int main()
...

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 19


Technische Informatik und Programmieren
Unterprogramm-Technik
Rückgabe von Werten
Rückgabe von Werten
#include <stdio.h>
#define EURO_SATZ 1.95583 Demo VC++
#define ARTIKELPREIS 23.45 .NET:..\K5_Unterprogramm_Technik\DMEuro
double ergebnis; \DMEuro.vcproj
double euro(double preis)
{
return preis/EURO_SATZ;
}
int main() Rückgabewert der Funktion wird an Variable ergebnis zugewiesen
...{
ergebnis = euro(ARTIKELPREIS);
printf("Der Artikelpreis betr„gt %5.2f DM \n das entspricht %5.2f
EURO.\n" ,ARTIKELPREIS, ergebnis);
printf("------oder direkt-----\n");
printf("Der Artikelpreis betr„gt %5.2f DM \ndas entspricht %5.2f
EURO.\n" ,ARTIKELPREIS, euro(ARTIKELPREIS));
getchar();
return 0; auch möglich: Funktion in printf() aufrufen
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 20


Technische Informatik und Programmieren
Unterprogramm-Technik
Rückgabe von Werten
Mehrere Werte mit einer Funktion zurückgeben
• eine Rückgabe von mehreren Werten ist mit den bis dato bekannten
Techniken (Call-by-value) nicht möglich

double euro(double preis)


{ .. }
Übergabe per Wert (Call-by-value)

Alternativen:
1. Parameterübergabe per Referenz (Call-by-reference)
2. Verwendung globaler Variablen
eindeutige Bezeichner im gesamten Programm
SW-Entwicklung im Team!
zu 2. Verwendung globaler Variablen
• werden außerhalb von main() vereinbart, sind überall im Programm
bekannt
• NACHTEIL: jeder kann auf die Variablen zugreifen -> im Fehlerfall
schwer nachvollziehbar, wer „Schuld“ ist

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 21


Technische Informatik und Programmieren
Unterprogramm-Technik
Rückgabe von Werten
Code-Beispiel zu Alternative 2: globale Variablen
• Manipulation von 2 (globalen) Variablen innerhalb einer Funktion; da die
Variablen global sind, können sie direkt geändert werden -> Parameter
nicht notwendig!
#include<stdio.h>
int zahl1; /* globale Variable */
int zahl2; /* globale Variable */
int add() /* Rückgabewert könnte entfallen */
{
zahl1+=15; /* Addition von 15 zum bisherigen Wert von zahl1 */
zahl2=zahl1 * 2;
return 0;
} zahl1, zahl2 sind hier sichtbar + zugreifbar (-> global)
int main(void) /* Beginn Hauptprogramm */
...

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 22


Technische Informatik und Programmieren
Unterprogramm-Technik
Rückgabe von Werten
Code-Beispiel zu Alternative 2: globale Variablen
...
int main(void)
{ zahl1, zahl2 auch hier sichtbar + zugreifbar (-> global)
zahl1=1;
zahl2=1; zahl1 = zahl2 = 1
printf("Zahl1= %d\n", zahl1);
printf("Zahl2= %d\n", zahl2);
add(); Funktion manipuliert zahl1, zahl2
printf("Zahl1= %d\n", zahl1);
printf("Zahl2= %d\n", zahl2);
getchar();
zahl1 = 1 + 15 = 16
return 0;
zahl2 = 2 * zahl1 = 32
}

Demo VC++ .NET:\K5_Unterprogramm_Technik\Berechnung\Berechnung.vcproj

NACHTEIL: globale Variablen sind überall im Programm bekannt


(schlechter Programmierstil)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 23


Technische Informatik und Programmieren
Unterprogramm-Technik
Rückgabe von Werten
Alternative 1: Referenzen als Parameter (Call-by-reference)
• elegantere Lösung als globale Variablen: Parameter als Referenz
übergeben

Speicherbereiche mit Adressen Name == symbolische Adresse, unter der ein


Wert gefunden werden kann
Wert Adresse Name
mit dem Adreßoperator & kann direkt auf die
...

10123 Adresse zugegriffen werden


17 10124
Inhalt
100 10125 a
2 10126 b symbolische Adressen
102 10127 summe
4009 10128
0 10129
...

10130
Deklaration und Definition von Variablen
(Objekte): Reservieren von Speicherplatz

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 24


Technische Informatik und Programmieren
Unterprogramm-Technik
Rückgabe von Werten
Alternative 1: Referenzen als Parameter (Call-by-reference)
• Call-by-reference: anstelle einer Kopie des Parameters wird ein Zeiger
übergeben (& Adreßoperator)
• dadurch kann die Funktion den Speicherort der übergebenen Variablen im
Arbeitsspeicher ausfindig machen und den Wert direkt im Arbeitsspeicher
ändern
• nach Rückkehr zur aufrufenden Funktion arbeitet diese mit den gleichen
Variablen und den neuen Werten (Arbeitsspeicher) weiter
• im Funktionskopf muß der Parameter als Zeiger (*-Operator)
gekennzeichnet sein

ein Beispiel bitte..

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 25


Technische Informatik und Programmieren
Unterprogramm-Technik
Rückgabe von Werten
Code-Beispiel zur Übergabe per Referenz
Hauptfunktion Arbeitsspeicher Funktion add
#include<stdio.h> Adresse int add(int z1, int *z2)
int zahl1; /* globale */ {
int zahl2; /* global */ 0C000H Speicher- zahl1 = 17;
int main(void) 0C001H bereich für z1+=15;
{ Variable *z2 += 15;
0C002H
zahl1=1; /* lokal */ zahl1 return 0;
zahl2=1; /* lokal */ 0C003H }
printf("Zahl1= %d\n",zahl1);
printf("Zahl2= %d\n",zahl2); Dereferenzierung
add(zahl1,&zahl2); 0C004H Speicher- (Zugriff auf den Wert
printf("Zahl1= %d\n",zahl1); 0C005H bereich für an einer Adresse)
printf("Zahl2= %d\n",zahl2); Variable
0C006H
getchar(); zahl2
return 0; 0C007H
}

HINWEIS: &zahl2 liefert die Anfangsadresse des reservierten Speicherbereichs von int zahl2

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 26


Technische Informatik und Programmieren
Unterprogramm-Technik
Rückgabe von Werten
#include<stdio.h>
int zahl1;
int zahl2;
int add(int z1, int *z2)
{
verändert Wert von zahl1 (global)
zahl1 = 17;
z1+=15; verändert Wert des temporären Objekts (Variable z1) in der
*z2 += 15; Funktion (nur innerhalb der Funktion gültig)
return 0;
Zugriff auf den Wert an der Adresse von z2 -> Veränderung des
}
Originals!
int main(void)
{
zahl1=1;
zahl2=1;
printf("Zahl1= %d\n",zahl1);
printf("Zahl2= %d\n",zahl2);
add(zahl1,&zahl2); Übergabe der Adresse von zahl2 an die Funktion
printf("Zahl1= %d\n",zahl1);
printf("Zahl2= %d\n",zahl2);
getchar();
return 0;
}
Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 27
Technische Informatik und Programmieren
Unterprogramm-Technik
Rückgabe von Werten
Erklärungen zum Code-Beispiel Übergabe per Referenz
• Parameterübergabe per Referenz (Zeiger, Pointer) für den 2. Parameter
(*z2) -> keine globale Variable mehr notwendig, Veränderungen am
Original!
• Veränderungen am Wert des übergebenen Parameters z1 innerhalb der
add()-Funktion hat außerhalb der Funktion add() keine Auswirkung (Call-
by-value: z1 wird innerhalb von add() kopiert!)
• Veränderungen an *z2 wirken auf das Original, d.h. sind auch außerhalb
der Funktion add() wirksam

Wie sieht die Bildschirmausgabe aus?

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 28


Technische Informatik und Programmieren
Unterprogramm-Technik
Rückgabe von Werten

Demo VC++ .NET:\K5_Unterprogramm_Technik\Referenz\Referenz.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 29


Technische Informatik und Programmieren
Unterprogramm-Technik
Rückgabe von Werten
Verfahren ohne Parameterübergabe (Typ void)
• sollen keine Parameter übergeben werden, wird der Typ void verwendet

int mwst(void) { .. } /* ohne Parameter */


int mwst() { .. } /* auch ohne Parameter */
void bsp(void) { .. } /* ohne Rückgabe, ohne Parameter */
void hallo(int) { .. } /* ohne Rückgabe */

Typumwandlung bei return


• stimmt der Datentyp in der return-Anweisung nicht mit dem Rückgabetyp
der Funktion überein -> Typumwandlung
int mwst(void)
{
..
return 1.58; (int) 1.58 = 1 d.h. Wert 1 wird an Aufrufer zurückgeliefert
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 30


Technische Informatik und Programmieren
Unterprogramm-Technik
Funktionsprototypen
Funktionsprototypen
Problemstellung:
• Verwendung von 2 Funktionen, die sich gegenseitig aufrufen -> eine der
beiden Funktionen kennt die andere nicht wegen der fehlenden
Vereinbarung!
• Compiler meldet einen Fehler mit dem Hinweis, daß eine unbekannte
Funktion verwendet wird

Lösung:
• Prototyping (sog. einfache Funktionsdeklaration)
• unvollständige Funktionsdefinition, die den Compiler über Rückgabewert
und die Datentypen der Parameter informiert -> Compiler prüft die
korrekte Verwendung der Funktion (sog. Typprüfung)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 31


Technische Informatik und Programmieren
Unterprogramm-Technik
Funktionsprototypen
Syntax des Protoypings

/* Alternative 1 */
Rückgabewert FktName (Datentyp1 Name1, Datentyp2 Name2, ..);
/* Alternative 2 */
Semikolon!
Rückgabewert FktName (Datentyp1, Datentyp2, ..);
{ Pseudocode }

• Funktionskopf (vgl. Fkt.-definition) wie bisher


• abschließen die Anweisung mit Semikolon!
• keine Block- oder Verbundanweisung { .. }, die besagt, was die Funktion tut
(-> Unterschied zwischen Fkt.-Deklaration und Fkt.-Definition)
• Alt. 1: Angabe der Parameternamen (Bezeichner)
• Alt. 2: Weglassen der Parameternamen (Bezeichner) (-> akzeptiert der
C/C++ Compiler)

HINWEIS: Angabe der Parameternamen (Alt. 1) erhöht die Lesbarkeit des Codes
(z.B. Zweck des Parameters durch den Namen dokumentieren)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 32


Technische Informatik und Programmieren
Unterprogramm-Technik
Funktionsprototypen
Beispiel zum Protoyping
void Ausgabe(int Ausgabewert); /* Prototyp */
int add(int Summand1, int Summand2)
{
Ausgabe(Summand1 + Summand2);
return(Summand1 + Summand2);
} Name darf sich vom Prototyp unterscheiden!
void Ausgabe(int Wert) /* Definition */
{
printf(“Die Summe ist %d“, Wert);
}

• Funktion add() kann die Fkt. Ausgabe() vor ihrer Implementation


aufrufen, da der Compiler den Prototyp von Ausgabe() in add() bereits
kennt!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 33


Technische Informatik und Programmieren
Unterprogramm-Technik
Funktionsprototypen
Weiterführender Hinweis: Modulare Programmierung
• Verwendung von Prototypen == Grundlage für die modulare
Programmierung, d.h. Trennung von Funktionsdeklaration und
Funktionsdefinition (Implementation) in unterschiedliche Dateien
Typische Anwendung:
• Funktionsdeklaration -> *.h (Header-File)
• Funktionsdefinition -> *.c / *.cpp (Implementations-File)
• Einbinden der Funktionsschnittstelle (Deklaration) mittels Präprozessor
(#include)
Vorteile:
• Trennung von Schnittstelle & Implementierung
• *.c / *.cpp Files können vorcompiliert werden (binär) und z.B. als
Bibliotheken ausgeliefert werden -> Implementierungsdetails sind
geschützt!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 34


Technische Informatik und Programmieren
Unterprogramm-Technik
Übung
Vorlesungsbegleitende Übung
(1) Schreiben Sie eine Funktion, die die Werte zweier Variablen vertauschen
kann. Verändern Sie die Werte durch die Übergabe von
Referenzen.
(2) Schreiben Sie ein Programm, das eine Lohnrechnung simuliert. Dabei
werden in einzelnen Funktionen nach der Übergabe des Bruttogehaltes
die errechneten Kosten für Lohnsteuer, Rentenversicherung,
Pflegeversicherung, Krankenversicherung etc. auf dem Bildschirm
ausgegeben. Geben Sie außerdem den Netto- und Bruttoverdienst aus.

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 35


Technische Informatik und Programmieren
Nützliche Funktionen
Orientierung
Einleitung
Das erste Programm in C
ORIENTIERUNG
Konstanten
Einfache Datentypen
Unterprogramm – Technik –
Nützliche Funktionen
Steuerstrukturen
Typvereinbarungen von Variablen
Zeiger
Der Präcompiler
Modulare Programmierung
Entwicklungsumgebungen
Standardbibliotheken
Anhang

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 1


Technische Informatik und Programmieren
Nützliche Funktionen
Ziele

Wie kann die Tastatureingabe im Programm verarbeitet


werden?
Wie werden die Funktionen getchar() und putchar()
eingesetzt?
Was sind globale und lokale Variablen?
ZIELE

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 2


Technische Informatik und Programmieren
Nützliche Funktionen
Inhalt
Nützliche Funktionen
Tastatureingaben
Syntax der Funktion scanf()
Beispiele zu scanf()
Rückgabewert der Funktion scanf()
Die Funktion getchar()
INHALT

Beispiele zu getchar()
Rückgabewert der Funktion getchar()
Die Funktion putchar()
Beispiele zu putchar()
Globale und lokale Variablen
Lokale Variablen
Globale Variablen
Zusammenfassung der Gültigkeitsbereiche
Beispiele
Übung

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 3


Technische Informatik und Programmieren
Nützliche Funktionen
Tastatureingaben
Tastatureingaben (ANSI-C)
• Abfrage von Tastatureingaben erfolgt in ANSI-C mit der Funktion scanf()
• scanf() (Einlesen von der Tastatur) ist damit das Gegenteil von printf()
(Bildschirmausgabe)
• Funktion scanf() ist eine Standardfunktion und ist im C-Standard-Header
stdio.h deklariert

Wie funktioniert scanf()?


• Tastatureingaben werden zeilenweise gepuffert -> Fehler bei der Eingabe
können mit der Backspace-Taste noch bis zum Betätigen der Return-
Taste korrigiert werden
• wie bei printf() ist das erste Argument ein Formatstring (Steuerung des
Einlesens und Konvertierungen), weitere Argumente sind
Adressen/Referenzen von Variablen, in denen die eingelesenen Werte
abgelegt werden sollen (z.B. &var == Adresse der Variablen var)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 4


Technische Informatik und Programmieren
Nützliche Funktionen
Tastatureingaben
Tastatureingaben (ANSI-C)
• Abfrage von Tastatureingaben erfolgt in ANSI-C mit der Funktion scanf()
• Funktion scanf() ist im C-Standard-Header stdio.h deklariert

Syntax der Funktion scanf()


int zahl;
scanf(“%d“, &zahl); Referenz (Adresse) auf die Variable, in der
die Eingabe gespeichert werden soll

• dem Funktionsnamen scanf() folgt zunächst ein String, der Information über
die Formatierung der Eingabe enthält
• danach werden (durch Komma getrennt) Referenzen (Adressen) auf die
Variablen übergeben, in denen die Werte der Tastatureingabe gespeichert
werden sollen

Welche Format-Zeichen sind möglich?

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 5


Technische Informatik und Programmieren
Nützliche Funktionen
Tastatureingaben
Format-Zeichen für scanf()

Datentyp Format-Zeichen Zweck


int %d oder %i Tastatureingabe wird als ganze Zahl (int) eingelesen

double %lf Tastatureingabe wird als Gleitkommazahl (doppelte


Genauigkeit, long float) übernommen.
Format ist sinnvoll i.V.m. Datentyp double.
float %f Tastatureingabe wird als Gleitkommazahl mit einfacher
Genauigkeit (float) übernommen.
char %c Tastatureingabe wird als Zeichen vom Typ char
eingelesen.
char[] %s Einlesen einer Zeichenkette z.B.
char s[100];
scanf(“%s“, s);

char-Array oder char-Feld -> Erklärung folgt später.. ☺

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 6


Technische Informatik und Programmieren
Nützliche Funktionen
Tastatureingaben
Ergänzung zu Format-Zeichen für scanf()
• fast alle von printf() bekannten Formatelemente können auch in scanf()
verwendet werden

Ausnahme/Sonderbehandlung für Gleitkommazahlen (float und double):


int a; float x; double y;
scanf(“%d %f %lf“, &a, &x, &y);

/* Eingabe folgender Werte:


123 45.67 890 */

890.0 -> double-Wert in y


45.67 -> float-Wert in x
123 -> dezimale Ganzzahl in a

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 7


Technische Informatik und Programmieren
Nützliche Funktionen
Tastatureingaben
Behandlung der Eingabefelder in scanf()
• generell wird für jedes Formatelement (%.. Platzhalter) das nächste
Eingabefeld gelesen, konvertiert und in der angegebenen Variablen
abgelegt

HINWEIS:
• führende Zwischenraumzeichen (whitespaces) werden „überlesen“
Whitespaces (Zwischenraumzeichen):
• Leerzeichen, Tabulatorzeichen ‘\t‘, Zeilenrücklauf ‘\r‘, Zeilensprung ‘\v‘,
Seitenvorschub ‘\f‘ und Zeilenendeerkennung ‘\n‘

• eine Eingabe (Eingabefeld) endet mit dem ersten (Zwischenraum)-Zeichen,


das nicht mehr verarbeitet wird (z.B. Buchstabe, wenn mit %d eine
Dezimalzahl eingelesen werden soll)
• dieses Zeichen ist dann das erste Zeichen des nächsten Eingabefeldes

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 8


Technische Informatik und Programmieren
Nützliche Funktionen
Tastatureingaben
Behandlung der Eingabefelder in scanf()
AUSNAHME bei Formatelement %c
• mit %c (char) wird einfach das nächste Zeichen (kann auch ein whitespace
sein) eingelesen

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 9


Technische Informatik und Programmieren
Nützliche Funktionen
Tastatureingaben
Code-Beispiel zu scanf()
• Generierung einer Glückszahl (Pseudo-Zufallszahl) abhängig vom
Geburtsdatum
#include <stdio.h> /* printf() und scanff() */
#include <stdlib.h> /* srand() und rand() */

int main()
{
int tag, monat, jahr;

printf("\nBitte geben Sie Ihr Geburtsdatum ein. \n");

printf("\nTag: ");
scanf("%d", &tag);

printf("\nMonat: ");
scanf("%d", &monat);

printf("\nJahr: ");
scanf("%d", &jahr);
...
Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 10
Technische Informatik und Programmieren
Nützliche Funktionen
Tastatureingaben
Code-Beispiel zu scanf()
...
/* Zufallsgenerator initialisieren */
srand(tag+monat+jahr);

printf("\nIhre Glueckszahl ist heute: %d\n", rand());

return 0;
}

Demo VC++ .NET:\K6_Nuetzliche-Funktionen\Glueckszahl\Glueckszahl.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 11


Technische Informatik und Programmieren
Nützliche Funktionen
Tastatureingaben
Code-Beispiel zu scanf()
• Artikelpreis wird über Tastatur eingegeben, MwSt-Satz und EURO-Satz
werden durch Variablen bereitgestellt, Ausgabe gibt den Artikelpreis mit /
ohne MwSt in DM und EURO auf Bildschirm aus
#include <stdio.h> /* wegen scanf() und printf() */
double mwst_satz=0.16; /* Konstante */
double euro_satz=1.98; /* Konstante */
double mwst(double p) /* globale Fkt. Berechnung Bruttopreis */
{ /* Parameter p: Nettopreis */
return (p*(mwst_satz+1)); /* Bruttopreis = Nettopreis * 1.16 */
}
double euro(double dm) /* globale Fkt. Berechnung EURO-Preis */
{
return dm/euro_satz; /* Gleitkomma-Division! */
}
int main(void) /* Hauptfunktion */
{
...

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 12


Technische Informatik und Programmieren
Nützliche Funktionen
Tastatureingaben
Code-Beispiel zu scanf()
...
int main(void)
{
double preis;
printf("Bitte geben Sie den Netto-Artikelpreis in DM ein: ");
scanf("%lf", &preis); Wert der Tastatureingabe in Variable preis speichern
printf("\nPreis ohne Mwst:\t%5.2f DM \n", preis); /* Netto-Preis */
printf("Preis mit Mwst:\t%5.2f DM\n", mwst(preis)); /*Brutto-Preis*/
printf("Preis ohne Mwst:\t%5.2f EURO \n", euro(preis));
printf("Preis mit Mwst:\t%5.2f EURO\n", euro(mwst(preis)));
fflush(stdin); /* Alle Zeichen aus dem Eingabepuffer löschen */
getchar();
Standardeingabekanal für Tastatureingabe
return 0;
-> sichergehen, daß keine „alten“ Zeichen
} mehr im Puffer stehen

HINWEIS: Wert kann auch in printf() berechnet werden (z.B. mwst(preis) )

Demo VC++ .NET:\K6_Nuetzliche-Funktionen\Tast\Tast.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 13


Technische Informatik und Programmieren
Nützliche Funktionen
Tastatureingaben
Konvertierung von Eingabefeldern in scanf()
A) Begrenzung von Eingabefeldern
• durch Angabe einer Feldbreite kann die Länge des Eingabefeldes
begrenzt werden (führende whitespaces werden nicht mitgezählt)
int i;
scanf(“%4d“, &i); /* Eingabefeld auf 4 Ziffern beschränkt */

/* Eingabe folgender Werte:


1234567 */
1234 -> als dezimale Ganzzahl in i speichern

567 -> verbleiben im Eingabepuffer (werden als Erstes gelesen,


wenn scanf() erneut aufgerufen wird)

HINWEIS: Genauigkeit bei Gleitkommazahlen kann nicht angegeben werden


-> (scanf() verarbeitet alle Ziffern im Eingabefeld)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 14


Technische Informatik und Programmieren
Nützliche Funktionen
Tastatureingaben
Code-Beispiel zu begrenzten Eingabefeldern in scanf()
#include <stdio.h>

int main()
{
int i_nummer;
double d_betrag;

printf("\nBitte die Kontonummer eingeben: ");


scanf("%8d", &i_nummer);/* Feldbreite 8 */

fflush(stdin); /* Eingabepuffer löschen */

printf("\nBitte den Geldbetrag eingeben: ");


scanf("%lf", &d_betrag);

/* bearbeiten.. */

return 0;
} Demo VC++ .NET:\K6_Nuetzliche-Funktionen\Feldbreite\Feldbreite.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 15


Technische Informatik und Programmieren
Nützliche Funktionen
Tastatureingaben
Code-Beispiel zu begrenzten Eingabefeldern in scanf()
Ausgabe mit fflush(stdin) -> Eingabepuffer löschen:

fflush() leert Puffer

Ausgabe ohne fflush(stdin) -> Eingabepuffer bleibt erhalten:

9 verbleibt im Eingabepuffer == erstes Zeichen der nächsten Eingabe (Geldbetrag)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 16


Technische Informatik und Programmieren
Nützliche Funktionen
Tastatureingaben
Konvertierung von Eingabefeldern in scanf()
B) Fehlersituation
• Was passiert, wenn die Eingabe nicht zum Formatelement paßt?
int i1, i2;
scanf(“%d %d“, &i1, &i2);

/* Eingabe folgender Werte:


1A5 */

Ziffer 1 wird an i1 zugewiesen


mit A beginnt das neue Eingabefeld, erwartet wird aber wieder eine
dezimale Ziffer -> A bleibt unverarbeitet!
da keine Konvertierung stattfindet, kehrt scanf() zurück

HINWEIS: scanf() liefert 1 als Rückgabewert (return-value), da ein Eingabefeld eingelesen wurde!
-> vgl. Rückgabewert von scanf() einige Folien weiter ...

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 17


Technische Informatik und Programmieren
Nützliche Funktionen
Tastatureingaben
Mehrere Tastaturwerte mit scanf() einlesen
• mit scanf() können mehrere Werte von der Tastatur eingelesen werden
int wert1, wert2, wert3;
scanf(“%d%d%d“, &wert1, &wert2, &wert3);

Eingabe eines Wertes wird durch return-


Taste abgeschlossen!

Spezialfall: Steuerung der Wertübernahme durch %*..


int wert1, wert2; dritte Eingabe -> wert2
scanf(“%d%*d%d“, &wert1, &wert2);

zweite Eingabe wird „überlesen“, d.h.


ignoriert und nicht gespeichert!

• Anwendung z.B. bei Einlesen von Daten aus einer Textdatei (Umleitung des
Standard-Eingabekanals Tastatur -> Datei)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 18


Technische Informatik und Programmieren
Nützliche Funktionen
Tastatureingaben
Steuerung der Tastaturübernahme mit scanf()
Code-Beispiel:
• Einlesen von 3 Tastatureingaben mit scanf(), nur die erste und dritte
Eingabe wird im Programm weiterverarbeitet (Variablen i und j)

#include <stdio.h>
int main(void)
{
int i,j;
printf("Bitte geben Sie nacheinander drei Zahlen ein: \n");
scanf("%d%*d%d",&i,&j); Eingabe getrennt durch Komma möglich
/* scanf("%d,%*d,%d",&i,&j); interessante Variation! */
/* Drei Eingaben werden erwartet, gespeichert werden nur 2 */
printf("\ni= %d",i);
printf("\nj= %d",j);
fflush(stdin); /* Löschen aller Zeichen im Eingabepuffer */
getchar();
return 0;
} Demo VC++ .NET:\K6_Nuetzliche-Funktionen\Zeijmp\Zeijmp.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 19


Technische Informatik und Programmieren
Nützliche Funktionen
Tastatureingaben
Steuerung der Tastaturübernahme mit scanf()
Gezieltes Überlesen von Zeichen:
• Whitespaces (Zwischenraumzeichen) können durch Einfügen in den
Format-String gezielt „überlesen“ werden

Whitespaces (Zwischenraumzeichen):
• Leerzeichen, Tabulatorzeichen ‘\t‘, Zeilenrücklauf ‘\r‘, Zeilensprung ‘\v‘,
Seitenvorschub ‘\f‘ und Zeilenendeerkennung ‘\n‘

Beispiel: Überlesen aller Leerzeichen in der Tastatureingabe


scanf(“ %d“, &i);

Beispiel: Überlesen der Zeilenendeerkennung „newline“ (Return-Taste)


scanf(“\n%d“, &i);

VORSICHT: Abschluß der Eingabe durch Return-Taste nicht mehr möglich!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 20


Technische Informatik und Programmieren
Nützliche Funktionen
Tastatureingaben
Steuerung der Tastaturübernahme mit scanf()
Einschränkung auf eine Zeichenmenge:
• scanf() erlaubt die Vorgabe von erlaubten Zeichen der Eingabe
• die Eingabe wird abgebrochen durch Eingabe eines Zeichens, das nicht
zur Zeichenmenge gehört

Beispiele: C-Array (Zeichenkette, Erklärung folgt später ☺)

scanf(“[+*/-]“, str); /* erlaubte Zeichen sind +, *, /, - */


scanf(“[a-zA-Z]“, str); /* erlaubt sind alle Buchstaben */
scanf(“[^0-9]“, str); /* außer Ziffern sind alle Zeichen erlaubt */

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 21


Technische Informatik und Programmieren
Nützliche Funktionen
Tastatureingaben
Rückgabewert der Funktion scanf()
• scanf() gibt die Anzahl der eingelesenen Zeichen/Eingabefelder zurück
• mit dem Rückgabewert kann also ausgewertet werden, ob die Eingabe
erfolgreich war (Länge > 0)
• beim ersten Fehler beendet die Funktion das Lesen der Standardeingabe
und gibt die Anzahl der bis dahin gelesenen Zeichen zurück

Zusatz:
• bei Umleitung der Standardeingabe auf eine Datei wird EOF (end of file)
geliefert, wenn das Dateiende erreicht ist!

EOF: Konstante in stdio.h als -1 definiert

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 22


Technische Informatik und Programmieren
Nützliche Funktionen
Funktion (Makro) getchar()
Die Funktion getchar()
Motivation:
• mit printf() und scanf() bietet ANSI-C universelle Funktionen zur Ein-
/Ausgabe von Zeichen(folgen)
• sollen nur einzelne Zeichen behandelt werden, die nicht umgewandelt oder
formatiert werden sollen -> ANSI-C bietet 2 effizientere Funktionen (genauer
Makros)

getchar() -> Eingabe eines Zeichens


putchar() -> Ausgabe eines Zeichens

HINWEIS:
• beide Makros sind im Standard-Header <stdio.h> definiert

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 23


Technische Informatik und Programmieren
Nützliche Funktionen
Funktion (Makro) getchar()
Zeichen einlesen mit getchar()
• Makro getchar() liest wie scanf() von der Standardeingabe stdin
• bei jedem Aufruf aber nur ein Zeichen
• Rückgabewert: getchar() liefert den Zeichen-Code (gem. ASCII-
Zeichentabelle) als int-Wert zurück

int zeichen;
zeichen = getchar();

HINWEIS:
• stdin ist zeilengepuffert -> getchar() wartet, bis eine Zeile mit der Return-
Taste abgeschlossen ist (zuvor kann die Eingabe noch mit Backspace-
Taste korrigiert werden)
Fehlerfall:
• tritt ein Fehler auf, liefert getchar() den Wert EOF (end-of-file) zurück (als
symbolische Konstante in stdio.h mit -1 definiert)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 24


Technische Informatik und Programmieren
Nützliche Funktionen
Funktion (Makro) getchar()
TRICK mit getchar()
• Programm kann mit getchar() auf die Bestätigung mit der Return-Taste
warten (Programm wird solange angehalten)
#include <stdio.h>
int main(void)
{
int antwort;
printf("Bitte lesen Sie diese Zeile!\n (Weiter mit der ENTER
Taste!)\n");
getchar(); wartet auf Return-Taste (Rückgabewert wird nicht ausgewertet)
printf("Das ist der weitere Text.... (Weiter mit 'J' und der ENTER-
Taste!)\n");
antwort=getchar(); antwort = 7410 (entspricht Buchstaben J gem. ASCII)
printf("Die Antwort war %c",antwort);
fflush(stdin); /* Löschen aller Zeichen im Eingabepuffer */
getchar();
return 0;
} Demo VC++ .NET:\K6_Nuetzliche-Funktionen\Pause\Pause.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 25


Technische Informatik und Programmieren
Nützliche Funktionen
Funktion (Makro) putchar()
Zeichen ausgeben mit putchar()
• Makro putchar() übergibt ein einzelnes Zeichen an die Standardausgabe
stdout (i.d.R. Bildschirm)
• dabei werden Zahlen vom Typ int übergeben, die gem. ASCII-Zeichensatz
interpretiert werden

int c = 65;
putchar(c); /* gibt Buchstaben ‘A‘ auf Bildschirm aus */

Fehlerfall:
• tritt ein Fehler auf, liefert putchar() EOF (end-of-file) zurück (also Wert -1)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 26


Technische Informatik und Programmieren
Nützliche Funktionen
Funktion (Makro) putchar()
Code-Beispiel zu putchar()
#include <stdio.h>
int main(void)
{
char z1;
z1='A'; /* Der Buchstabe A wird in z1 eingeschrieben. */
putchar(z1); /* Der Buchstabe A wird ausgegeben. */
putchar(' '); /* Ein Leerzeichen wird ausgegeben. */
putchar('b'); /* Der Buchstabe b wird ausgegeben. */
putchar(7); /* Das Steuerzeichen Bell (Ton ) wird ausgegeben */
putchar(124); /* Das Zeichen | wird ausgegeben. */
getchar(); Programm anhalten (warten auf Return-Taste)
return 0;
}

Demo VC++ .NET:\K6_Nuetzliche-Funktionen\Zeichen\Zeichen.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 27


Technische Informatik und Programmieren
Nützliche Funktionen
Funktion (Makro) putchar()
Weiteres Code-Beispiel zu putchar() (für Fortgeschrittene..)
/* Umlaute.c --> Wandelt in einem Text die Umlaute ä, ö, ü *
* in ae, oe, ue um, sowie ß in ss. *
* (Ä, Ö, Ü werden nicht beruecksichtigt.) *
* -------------------------------------------------------------- *
* Beim Lesen von der Tastatur (also ohne Eingabe-Umlenkung) die *
* Eingabe mit Strg+Z (DOS/Windows) bzw. Strg+D (Unix) beenden. */

#include <stdio.h> // Definitionen der Konstanten EOF


// und der Makros getchar(), putchar().
int main()
{
int c;
...

Hinweis: EOF kann durch Eingabe von Strg+Z über Tastatur simuliert werden (Windows-OS)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 28


Technische Informatik und Programmieren
Nützliche Funktionen
Funktion (Makro) putchar()
Weiteres Code-Beispiel zu putchar() (für Fortgeschrittene..)
while( (c = getchar()) != EOF) // Zeichen einzeln lesen
switch(c)
{
case 0x84: // 0x84 == 'ä'
putchar('a'); putchar('e');
break;
case 0x94: // 0x94 == 'ö'
putchar('o'); putchar('e');
break;
case 0x81: // 0x81 == 'ü'
putchar('u'); putchar('e');
break;
case 0xE1: // 0xE1 == 'ß'
putchar('s'); putchar('s');
break;
default:
putchar(c); // Jedes andere Zeichen
} // unveraendert ausgeben.
return 0;
}
Demo VC++ .NET:\K6_Nuetzliche-Funktionen\Umlaute\Umlaute.vcproj
Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 29
Technische Informatik und Programmieren
Nützliche Funktionen
Globale und lokale Variablen
Globale & lokale Variablen
• Sichtbarkeit und Gültigkeit von Variablen spielt bei größeren C-Programmen
eine entscheidende Rolle bei Verlassen des Gültigkeitsbereichs (z.B. Block)
wird die Variable gelöscht (d.h. Speicherplatz
wird automatisch freigegeben)
A) Lokale Variablen
• nur gültig innerhalb des Blocks { .. } (Verbundanweisung) in dem sie
deklariert/definiert wurden
• sowohl Variablenname (Bezeichner) als auch Wert existieren nur
innerhalb des Blocks
• außerhalb des Blocks sind Namen & Wert der Variablen unbekannt (z.B.
in anderen Funktionen)
• z.B. können in einem Programm gleiche Variablennamen verwendet
werden, wenn sie sich in unterschiedlichen Funktionen befinden!
void main() int func() a nur innerhalb der Funktion
{ { int a;
int a; .. Black-Box
a = func(); return a; }
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 30


Technische Informatik und Programmieren
Nützliche Funktionen
Globale und lokale Variablen
Globale & lokale Variablen
B) Globale Variablen
• gültig im gesamten Programm (von der Initialisierung bis zum
Programmende)
• sichtbar in allen Funktionen (können überall gelesen und verändert
werden)
Verdeckung globaler Variablen:
• wird in einer Funktion ein Bezeichner eingeführt, der bereits global
existiert, wird dieser verdeckt
• d.h. innerhalb der Funktion arbeitet man mit einer lokalen Variablen
• die globale Variable wird dann nicht verändert!

möglichst sparsamer Umgang mit globalen Variablen!


Einigung auf globale Bezeichner notwendig (Eindeutigkeit!)
erschwerte Fehlersuche, da von überall änderbar (Wer ist der „Schuldige“??)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 31


Technische Informatik und Programmieren
Nützliche Funktionen
Globale und lokale Variablen
Code-Beispiel zu globalen & lokalen Variablen
#include <stdio.h>
int x; /* globale Variable */
Deklaration/Definition außerhalb jeder Funktion!
int test(void)
{
char r; /* lokale Variable in Funktion test */
...
}
int main()
{
int y; /* lokale Variable in Funktion main */
int x; /* lokale Variable in Funktion main
verdeckt die globale Variable */
x = 15; /* ändert die lokale Variable x in main */
...
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 32


Technische Informatik und Programmieren
Nützliche Funktionen
Globale und lokale Variablen
Weiteres Code-Beispiel zu globalen & lokalen Variablen
#include <stdio.h>
int z; /* global */
int druck(void)
{
int z; /* lokal, verdeckt globales z */
z=19; /* Wertänderung lokal */
printf("%d",z); /* Ausgabe von lokal z */
printf("%d", ::z); /* Ausgabe von global z */
return 0;
} TRICK: Scope-Operator (Bereichsoperator)
int main()
{
z=17; /* Wertzuweisung global z */
printf("%d",z); /* Ausgabe global z */
druck(); /* Aufruf druck() -> lokal z */
printf("%d",z); /* wieder Ausgabe von global z
Wert unverändert z = 17; */
return 0;
}
Demo VC++ .NET:\K6_Nuetzliche-Funktionen\Global\Global.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 33


Technische Informatik und Programmieren
Nützliche Funktionen
Globale und lokale Variablen
Weiteres Code-Beispiel zu globalen & lokalen Variablen
Bildschirmausgabe:

Demo VC++ .NET:\K6_Nuetzliche-Funktionen\Global\Global.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 34


Technische Informatik und Programmieren
Nützliche Funktionen
Globale und lokale Variablen
Zusammenfassung – Gültigkeitsbereich von Variablen
Globale Variablen Variablen, die außerhalb von Funktionen deklariert werden
von allen Funktionen erreichbar
globale Gültigkeit bzgl. der Datei
Lokale Variablen Variablen, die innerhalb von Funktionen, Anweisungsblöcken vereinbart werden
nur innerhalb der Blöcke gültig
in anderen Funktionen unbekannt
Statische Statische Variablen behalten ihre Lebensdauer über das gesamte Programm
Variablen Werden bei Deklaration initialisiert (entweder per default = 0 oder mit anderem
Wert)
Existieren auch wenn Gültigkeitsbereich verlassen wird (quasi unsichtbar)
Syntax Beispiel
static Datentyp Name; static int Zaehler;
static Datentyp Name = Wert; static char Eingabe = ‘J‘;

Externe Variablen Extern heißt, daß eine Variable irgendwo (andere Datei oder Bibliothek) bereits
als globale Variable verfügbar ist
Um diese nutzen zu können, muß sie mit extern importiert werden

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 35


Technische Informatik und Programmieren
Nützliche Funktionen
Übung
Vorlesungsbegleitende Übung
(1) Schreiben Sie ein Taschenrechnerprogramm für die 4 Grund-
rechenarten. Dabei werden die Operanden über die Tastatur
eingegeben und in globalen Variablen gespeichert. Erstellen Sie für jede
Berechnung eine Unterfunktion, die auf diese globalen Variablen
zugreift. Geben Sie das Ergebnis für jede Grundrechenart auf dem
Bildschirm aus.
(2) Schreiben Sie ein Programm, das über die Funktion (Makro) putchar()
das Alphabet auf dem Bildschirm ausgibt (Hinweis: ‘A‘ = 65, ‘B‘ = 66 ..)
(3) Erklären Sie, wie die Verwendung von globalen Variablen mit Hilfe von
Referenzen (Zeigern) umgangen werden kann.
(4) Schreiben Sie ein Programm, das einen Text (z.B. Ihren Namen) aus
genau 9 Zeichen von der Tastatur annehmen kann und anschließend die
Buchstaben in umgekehrter Reihenfolge auf dem Bildschirm ausgibt
(z.B. nach der Eingabe von FERDINAND wird DNANIDREF auf dem
Bildschirm ausgegeben.

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 36


Technische Informatik und Programmieren
Steuerstrukturen
Orientierung
Einleitung
Das erste Programm in C
ORIENTIERUNG
Konstanten
Einfache Datentypen
Unterprogramm – Technik –
Nützliche Funktionen
Steuerstrukturen
Typvereinbarungen von Variablen
Zeiger
Der Präcompiler
Modulare Programmierung
Entwicklungsumgebungen
Standardbibliotheken
Anhang

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 1


Technische Informatik und Programmieren
Steuerstrukturen
Ziele

¾ Wie werden Schleifenanweisungen programmiert?


¾ Wie wird eine Programmverzweigung umgesetzt?
¾ Wie wird eine Fallauswahl realisiert?
ZIELE

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 2


Technische Informatik und Programmieren
Steuerstrukturen
Inhalt
Steuerstrukturen
Grundlagen
Sequenz
Anweisungsblock
Selektion (if – else)
Einfache Selektion
Zweifache Selektion
Der Bedingungsoperator ( ? )
INHALT

Mehrseitige Auswahl (switch – case)


Syntax und Verwendungsformen
Iteration (Schleifen)
Kopfgetestete Schleife (while)
Syntax und Beispiele
Endegetestete Schleife (do while)
Syntax und Beispiele
Die Zählschleife (for)
Syntax und Beispiele
Sprünge (continue, break, goto)
Rekursion
Einführendes Beispiel: Algorithmus zur Lösung des Schachbrett-Korn-Problems
Übung

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 3


Technische Informatik und Programmieren
Steuerstrukturen
Grundlagen
Steuerstrukturen / Kontrollstrukturen
• bislang können wir einzelne Programmteile auf Unterprogramme
(Funktionen) verteilen
• in diesem Abschnitt beschäftigen wir uns mit der Steuerung des
Programmablaufes durch Steuer-/Kontrollstrukturen

Übersicht der Steuerstrukturen in ANSI C/C++

Typ Schlüsselwörter Zweck


Verzweigung, if, if else, Programmzweig wird in Abhängigkeit von der
Selektion switch case und Auswertung eines Ausdrucks durchlaufen oder
? (Auswahloperator) ausgelassen
Schleife, Iteration while, do while, Mit Hilfe von Schleifen wird eine Gruppe von
for Anweisungen abhängig von einer Bedingung
mehrfach durchlaufen
Bedingungsfreie goto, continue, Abbrechen eines Schleifendurchgangs ohne
Sprünge break die gesamte Schleife zu verlassen.

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 4


Technische Informatik und Programmieren
Steuerstrukturen
Sequenz
Sequenz
• Sequenz ist ein Container für eine Anweisungsfolge (oder einen in { .. }
gesetzten Anweisungsblock) -> Anweisungen werden nacheinander
ausgeführt (sequentiell)
Struktogramm einer Sequenz
Block
Anweisung 1
Ausführungsreihenfolge
Anweisung 2
(von oben nach unten)
Anweisung 3

char c; Beispiel für eine Sequenz


int res;
c = getchar();
printf(“Hallo C-Gemeinde!\n“);
printf(“Summand 1: “);
scanf(“%d“, &res);
res = 17 + 4;

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 5


Technische Informatik und Programmieren
Steuerstrukturen
Anweisungsblock
Anweisungsblock
• Anweisungen können in Blöcke zusammengefaßt werden -> Blöcke werden
durch { .. } eingeschlossen
• einzelne Anweisungen innerhalb eines Blocks werden durch Semikolon ;
abgeschlossen (wie jede gültige Anweisung ...)
• Kontrollstrukturen bestehen häufig aus mehreren Blöcken

{ /* Beginn eines Anweisungsblocks */


Anweisung 1;
Anweisung 2;
...
} /* Ende eines Anweisungsblocks */

HINWEIS: Wir kennen dieses Prinzip bereits aus der Funktionsdefinition ..

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 6


Technische Informatik und Programmieren
Steuerstrukturen
Anweisungsblock
Beispiel für einen Anweisungsblock
• Funktionsdefinition mit einfacher Anweisungsfolge (ohne Kontrollstrukturen)
-> sequentielle Ausführung

int druck(char z)
{
printf(“Ausgabe: “);
printf(“1. Buchstabe: %c“, z);
return 0;
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 7


Technische Informatik und Programmieren
Steuerstrukturen
Selektion
Selektion
• Selektion == Programmverzweigung
• abhängig von der (logischen) Auswertung eine Bedingung (Ausdruck ergibt
entweder true oder false) wird der Zweig durchlaufen oder ausgelassen

Arten der Selektion:


A) Einfache Selektion (if)
• Programmzweig wird durchlaufen oder nicht (abhängig von
Bedingungsauswertung) -> 1 Zustand
B) Zweifache Selektion (if else)
• einer von 2 möglichen Programmzweigen wird durchlaufen (abhängig von
Bedingungsauswertung) -> 2 Zustände
C) Mehrfache Selektion (switch case)
• Programmverzweigung umfaßt viele Zustände; Auswahl erfolgt anhand
der Bedingungsauswertung -> n Zustände

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 8


Technische Informatik und Programmieren
Steuerstrukturen
Selektion
Einfache Selektion (if-Anweisung)
• Programmzweig wird abhängig von der Bedingungsauswertung durchlaufen

Bedingung der Verzweigung


Struktogramm einer einfachen Selektion

„tue nichts“

nächste Anweisung (einfacher Block)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 9


Technische Informatik und Programmieren
Steuerstrukturen
Selektion
Syntax der if-Anweisung
• beginnt mit Schlüsselwort if
• dahinter folgt ein Ausdruck (Bedingung) -> liefert einen Wert vom Datentyp
int -> wird „logisch“ interpretiert (false == 0, true ≠ 0)
• ergibt die Auswertung true (≠ 0) wird die folgende Anweisung bzw.
Anweisungsblock ausgeführt, sonst übersprungen

if (Ausdruck)
Anweisung;
Bedingung, ohne Semikolon!!!
if (Ausdruck)
{
Anweisung1;
Anweisungsblock
Anweisung2;
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 10


Technische Informatik und Programmieren
Steuerstrukturen
Selektion
Beispiel zur if-Anweisung
• Ausgabe des Textes “z ist positiv“ erfolgt nur, wenn der Ausdruck
(Bedingung) (z > 0) gültig d.h. true ergibt

if (z > 0)
printf(“z ist positiv“);

if (z > 0)
{
printf(“z ist positiv“); Anweisungsblock
...
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 11


Technische Informatik und Programmieren
Steuerstrukturen
Zweifache Selektion
Zweifache Selektion (if-else Anweisung)
• Programmcode verzweigt in 2 mögliche Wege abhängig von der
Bedingungsauswertung

Struktogramm einer zweifachen Selektion

Ausführung nur, wenn Bedingung true Ausführung nur, wenn Bedingung false

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 12


Technische Informatik und Programmieren
Steuerstrukturen
Zweifache Selektion
Syntax der if-else Anweisung (zweiseitige Auswahl)
• nach if Bedingung und Anweisungsteil folgt else-Zweig -> ergibt die
Bedingung false (== 0) wird der else Zweig ausgeführt
• WIEDER: bei mehreren Anweisungen -> Anweisungsblock { .. }
• NEU: Verschachtelungen sind möglich!
if (Ausdruck)
{
Anweisung1; Bedingung, ohne Semikolon!!!
Anweisung2;
}
else
Anweisung3; Alternative

/* Verschachtelung */
if (a)
if (b)
else-Zweig wird dem letzten if-Zweig zugeordnet,
c;
der noch keinen else-Zweig besitzt!
else
d;

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 13


Technische Informatik und Programmieren
Steuerstrukturen
Zweifache Selektion
(einfaches) Beispiel zur if-else Anweisung
• ergibt z < 0 == true -> if-Zweig wird ausgeführt
• ist z = 0 oder z > 0 -> Sprung in den else-Zweig und Ausführung

if (z < 0)
printf(“z ist eine negative Zahl!“);
else
printf(“z ist eine positive Zahl (oder =0)!“);

HINWEIS: da in jedem Zweig jeweils nur eine Anweisung ausgeführt werden soll,
kann der Anweisungsblock { .. } entfallen!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 14


Technische Informatik und Programmieren
Steuerstrukturen
Zweifache Selektion
noch ein (einfaches) Beispiel zur if-else Anweisung
// Berechnet den kleineren von 2 float-Werten
#include <stdio.h> /* printf() und scanff() */

int main()
{
float x, y, min;

printf("\nGeben Sie 2 verschiedene Zahlen ein: \n");


scanf("%f %f", &x, &y);

if (x < y)
min = x;
else
min = y;

printf("Die kleiner Zahl ist: %f\n", min);


return 0;
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 15


Technische Informatik und Programmieren
Steuerstrukturen
Selektion
else-if Ketten
• else-if Ketten ermöglichen eine Programmverzweigung in mehrere Pfade
(abhängig von der Bedingungsauswertung)
• -> Folge ineinander geschachtelter if-else Anweisungen
Struktogramm einer verschachtelten else-if Kette

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 16


Technische Informatik und Programmieren
Steuerstrukturen
Selektion
Syntax der else-if Kette
• Ausdruck1 .. Ausdruckn werden der Reihe nach ausgewertet; beim ersten
Ausdruck der true ergibt, wird die abhängige Anweisung ausgeführt
• danach ist die gesamte else-if Kette beendet

if (Ausdruck1)
Anweisung1;
else if (Ausdruck2)
Anweisung2;
...

else if (Ausdruckn)
Anweisungn;
else optional: Alternative, falls alle Teilbedingungen false ergaben
Anweisungn+1;

HINWEIS: fehlt der else-Zweig, wird das Programm mit der Anweisung fortgesetzt,
die der else-if Kette folgt

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 17


Technische Informatik und Programmieren
Steuerstrukturen
Selektion
Beispiel zur else-if Kette
// Bussgeld bei Geschwindigkeitsueberschreitung ausgeben
#include <stdio.h> /* printf() und scanff() */

int main()
{
float grenze, geschw, zuviel;

printf("\nGeschwindigkeitsgrenze: \n");
scanf("%f", &grenze);

printf("\nGeschwindigkeit: \n"); Berechnung von zuviel


scanf("%f", &geschw);
if ((zuviel = geschw – grenze) < 10)
printf("\nSie haben nochmal Glueck gehabt!\n");
else if (zuviel < 20)
printf("\nBussgeld faellig: 40,- EURO\n");
else if (zuviel < 30)
printf("\nBussgeld faellig: 100,- EURO\n");
else
printf("\nFuererscheinentzug!\n");
return
Frank Artinger0;
} Informatik - ANSI C 2.0 / ANSI C++ 18
Technische Informatik und Programmieren
Steuerstrukturen
Bedingungsoperator
Der Bedingungsoperator (?-Operator)
• ?-Operator (Bedingungs-/Auswahloperator) ermöglicht eine besonders kurze
Schreibweise der if-else Konstrukte (Verzweigung)

Syntax des Bedingungsoperators


Ergebnis = Ausdruck ? Anweisung1 : Anweisung2

• zunächst wird Ausdruck (logisch) ausgewertet


• ist das Ergebnis true (!=0) -> Anweisung1 wird ausgeführt
• ist das Ergebnis false (==0) -> Anweisung2 wird ausgeführt
• der Wert der ausgeführten Anweisungx wird dem Ergebnis (Variable)
zugewiesen

HINWEIS: ?-Operator ist der einzige ANSI-C Operator mit 3 Operanden!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 19


Technische Informatik und Programmieren
Steuerstrukturen
Bedingungsoperator
Beispiele zum ?-Operator
• Absolutwert (Betrag) von x bilden und in Variable z speichern

z = (x >= 0) ? x : -x;

• z.B. x = 24 -> (x >= 0) ergibt true (!=0) -> x wird z zugewiesen


• z.B. x = -1 -> (x >=0) ergibt false (==0) -> -x wird an z zugewiesen

Äquivalente if-else Struktur:


if (x >= 0)
z = x;
else
z = -x;

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 20


Technische Informatik und Programmieren
Steuerstrukturen
Bedingungsoperator
Beispiele zum ?-Operator
• Maximalwert von zwei Zahlen bilden

maximum = (a > b) ? a : b;

Äquivalente if-else Struktur:

if (a > b)
maximum = a;
else
maximum = b;

?-Operator ermöglicht eine kompaktere Schreibweise!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 21


Technische Informatik und Programmieren
Steuerstrukturen
Bedingungsoperator
Beispiele zum ?-Operator
// Berechnet den groesseren von 2 float-Werten
#include <stdio.h> /* printf() und scanff() */

int main()
{
float x, y;

printf("\nGeben Sie zwei verschiedene Zahlen ein: \n");

if ( scanf("%f %f", &x, &x) != 2) Ergebnis wird direkt an printf() übergeben


printf("Fehlerhafte Eingabe!\n");
else
printf("Die groessere Zahl: %f\n", x > y ? x : y);

return 0;
} Ergebnis der bedingten Auswertung kann auch
ohne Zuweisung weiterverarbeitet werden
NACHTEIL: schlechte Lesbarkeit!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 22


Technische Informatik und Programmieren
Steuerstrukturen
Mehrseitige Auswahl
Mehrseitige Auswahl (Verzweigung mit switch)
• switch-Anweisung (switch == Schalter) bietet wie else-if Kette die
Möglichkeit, eine von mehreren Alternativen auszuwählen

UNTERSCHIED zu else-if:
• der Wert eines Ausdrucks (z.B. Variablen) wird mit mehreren Konstanten
verglichen

Struktogramm der mehrfachen Auswahl


Selektor -> Datentyp int (oder char)
Konstante

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 23


Technische Informatik und Programmieren
Steuerstrukturen
Mehrseitige Auswahl
Syntax der mehrseitigen Auswahl (switch – case)
Schlüsselwort switch

switch (selektor) Ordinaltyp, d.h. ganzzahliger Typ (int oder char)


{ -> Variable, Konstante od. arithm. Ausdruck
case Konstante1: stimmt der selektor mit Konstante1 überein
Anweisung1; -> Anweisung1 wird ausgeführt
break; -> mit break wird switch-Anweisung verlassen
case Konstante2:
Anweisung2; alternativer Programmweg
break;
...
default: keine Übereinstimmung mit dem Wert von selektor
Anweisungn; -> Anweisungn wird ausgeführt
} -> default: ist optional!

• hinter case darf nur 1 Wert (einmal) abgefragt werden


• wird break (optional) weggelassen -> alle folgenden case-Zweige werden
(unabhängig vom Wert in case) ausgeführt, bis ein abschließendes break
gefunden wird!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 24


Technische Informatik und Programmieren
Steuerstrukturen
Mehrseitige Auswahl
Beispiele zu switch – case
• Ausgabe des Wochentages -> Kombination mit weglassen von breaks
#include <stdio.h>
int main(void)
{
int tag;
printf("Der wievielte Tag der Woche ist heute?\t");
scanf("%d", &tag);
switch(tag)
{
case 1:
Ausführung bis zum nächsten break
case 3:
case 5: printf("Heute ist Montag, Mittwoch oder Freitag! \n");
break;
case 2:
case 4: printf("Heute ist Dienstag oder Donnerstag! \n"); break;
case 6:
case 7: printf("Heute ist Wochenende! \n"); break;
default: printf("Diesen Tag haben Sie gerade erfunden!\n"); break;
}
fflush(stdin); kann entfallen, da default hier die letzte Alternative ist
Frank Artinger
getchar(); -> default darf auch „weiter oben“ stehen
Informatik - ANSI C 2.0 / ANSI C++ 25
Technische Informatik und Programmieren
} Demo VC++ .NET:\K7_Steuerstrukturen\Switch\Switch.vcproj
Steuerstrukturen
Mehrseitige Auswahl
Verwendungsformen der switch-Anweisung
• Auswahl über einzelne Auswahlwerte; wird keine Übereinstimmung des
Wertes im Selektor Zahl gefunden -> default-Zweig wird ausgeführt
switch (Zahl)
{
case 1: Anweisung1; break;
case 2: Anweisung2; break;
case 3: Anweisung3; break;
default: Anweisung4; break;
}

• Selektor besteht aus arithm. Ausdruck -> Wert des Selektors wird zuerst
berechnet
switch (Zahl1 – Zahl2)
{
case 1: Anweisung1; break;
case 2: Anweisung2; break;
case 3: Anweisung3; break;
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 26


Technische Informatik und Programmieren
Steuerstrukturen
Mehrseitige Auswahl
Verwendungsformen der switch-Anweisung
• Selektor ist eine Variable vom Typ char (über ASCII abbildbar auf int) ->
Auswahlwerte sind Buchstaben (Literale -> Apostrophe!)
switch (Buchstabe)
{
case ‘A‘: Anweisung1; break;
case ‘B‘: Anweisung2; break;
case ‘C‘: Anweisung3; break;
}

char-Konstanten (Literale)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 27


Technische Informatik und Programmieren
Steuerstrukturen
Mehrseitige Auswahl
Praktisches Beispiel..
// Ein in einem Menue eingegebenes Kommando abfragen
switch (Kommando)
{
case ‘a‘:
case ‘A‘:
action1(); // Aktion 1 ausführen
break;

case ‘b‘:
case ‘B‘:
action2(); // Aktion 2 ausführen
break;

default:
printf(“\007“); // Ton fuer falsches Kommando ausgeben
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 28


Technische Informatik und Programmieren
Steuerstrukturen
Iteration
Iteration (while, do – while, for)
• Iterationen == Schleifen d.h. Wiederholung von Anweisungen
• ANSI-C bietet verschiedene Typen von Iterationen
wie oft und unter welcher Bedingung
Prinzipieller Aufbau einer Iteration wird die Schleife ausgeführt

zu wiederholende
Anweisungen

Einteilung von Schleifen: a) Position, an der die Wiederholung durchgeführt wird


b) gewünschte Anzahl der Durchläufe

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 29


Technische Informatik und Programmieren
Steuerstrukturen
Kopfgetestete Schleife
Kopfgetestete Schleife (while-Schleife)
• kopfgetestet (anfangsgetestet) -> Prüfung, ob ein Durchlauf stattfindet
befindet sich am Anfang; nach jedem Durchlauf wird neu geprüft

Struktogramm der kopfgetesteten Schleife (while)


logische Bedingung (true oder false) -> sog. Laufbedingung

(1) -> Richtungsumkehr möglich


(Anweisungen werden wiederholt) ob (1) oder (2)
-> abhängig von Auswertung
(2) -> Anweisungen 1 – 4 werden übersprungen der Schleifenbedingung

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 30


Technische Informatik und Programmieren
Steuerstrukturen
Kopfgetestete Schleife
Syntax der while-Schleife (kopfgetestet)
Schlüsselwort while

while (Ausdruck) Bedingung: true (!=0) -> Eintritt in die Schleife


{ false (==0) -> Überspringen der Schleife
Anweisung1;
Anweisung2;
Anweisung3; Schleifenkörper
Anweisung4;
} Rücksprung zur Bedingungsauswertung in while
-> falls Bedingung erneut true -> Anweisung1 – 4 werden wiederholt

while (Ausdruck)
Anweisung1; Anweisungsblock { .. } kann entfallen, falls nur
eine Anweisung ausgeführt werden soll

HINWEIS: while-Schleife wird erst dann verlassen,


wenn die Bedingungsauswertung (irgendwann) false ergibt!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 31


Technische Informatik und Programmieren
Steuerstrukturen
Kopfgetestete Schleife
Beispiele zur while-Schleife
#include <stdio.h>
int main(void)
{
int i = 0;
int z = 65;

while(z != 69) Laufbedingung (69 == Buchstabe ‘E‘)


{
i++; Schleifenzähler (bei jedem Durchlauf wird i inkrementiert (um 1 erhöht)
printf("Durchlauf: i = %d\n", i);
printf("Beenden mit E \n"); Eingabe von E -> (z != 69) ergibt false!
printf(" Ihre Wahl: ");
z = getchar();
fflush(stdin); löscht Eingabepuffer (stdin)
} -> sonst würde Steuerzeichen der
return 0; RETURN-Taste im Puffer verbleiben!
}
Demo VC++ .NET:\K7_Steuerstrukturen\Menu\Menu.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 32


Technische Informatik und Programmieren
Steuerstrukturen
Kopfgetestete Schleife
Beispiele zur while-Schleife
Hinweis zum Menu-Beispiel:
• while-Schleife wird mehrfach durchlaufen, wenn mehrere Zeichen
hintereinander eingegeben und mit RETURN-Taste bestätigt werden
• durch Leeren des Eingabepuffers (stdin) mit fflush(stdin) kann dieser
Effekt verhindert werden

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 33


Technische Informatik und Programmieren
Steuerstrukturen
Kopfgetestete Schleife
noch ein Beispiel zur while-Schleife ..
// Schnitt.c -> Berechnet den Durchschnitt ganzer Zahlen.
#include <stdio.h>

int main()
{
int x, anzahl = 0; float summe = 0;

printf("\nBitte geben Sie ganze Zahlen ein\n"


"(Abbruch mit beliebigem Buchstaben):\n");

while( scanf("%d", &x) > 0) // Solange eine Zahl eingelesen


{ // werden kann.
summe += x;
++anzahl; Eingabe eines Buchstaben
} -> scanf() liefert 0 zurück
-> Laufbedingung false
printf("\nDer Durchschnitt der eingegebenen Zahlen ist: "
"%.2f\n", summe/anzahl);

return 0;
Demo VC++ .NET:\K7_Steuerstrukturen\Schnitt\Schnitt.vcproj
Frank
} Artinger Informatik - ANSI C 2.0 / ANSI C++ 34
Technische Informatik und Programmieren
Steuerstrukturen
Endegetestete Schleife
Endegetestete Schleife (do – while)
• Laufbedingung der do-while Schleife wird erst am Ende geprüft -> Schleife
(d.h. Anweisungen im Schleifenkörper) wird mind. 1 mal durchlaufen

Struktogramm der endegetesteten Schleife (do – while)

(2) -> Auswertung der Bedingung ergab 0 (false)

(1) -> Auswertung der Bedingung ergab != 0 (true)


-> Wiederholung (erneuter Schleifendurchlauf)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 35


Technische Informatik und Programmieren
Steuerstrukturen
Endegetestete Schleife
Syntax der endegetesteten Schleife (do – while)
Schlüsselwort do

do keine Bedingungsauswertung!
{
Anweisung1;
Anweisung2;
Schleifenkörper (mind. 1 Durchlauf)
Anweisung3;
Anweisung4;
}
while (Ausdruck); Bedingungsauswertung in while
-> falls Bedingung true (!=0) -> Anweisung1 – 4 werden wiederholt
-> falls Bedingung false (==0) -> nächste Anweisung..

HINWEIS: do-while Schleife wird mit einem Semikolon ; abgeschlossen!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 36


Technische Informatik und Programmieren
Steuerstrukturen
Endegetestete Schleife
Beispiel zur do – while Schleife
#include <stdio.h>
Ausgabe von Menuepunkten auf dem Bildschirm
/*Menuprogramm*/ Wahl über Tastatur wird ausgegeben
int menu (void)
{
int m;
printf("\n\tMenue\n");
printf("\t=====\n\n");
printf("Addition..........1\n");
printf("Subtraktion.......2\n");
printf("Multiplikation....3\n");
printf("Division..........4\n\n");
printf("ENDE..............0\n\n");
printf("Ihre Wahl: ");
scanf("%d",&m);
return m; Menueauswahl wird zurückgeliefert
}
int main (void)
...

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 37


Technische Informatik und Programmieren
Steuerstrukturen
Endegetestete Schleife
Beispiel zur do – while Schleife
..
int main (void)
{
int i;
do
{ wird mind. 1 x durchlaufen
i=menu();
printf("Das Hauptprogramm wuerde Menuepunkt %d abarbeiten\n",i);
}
while ((i > 0) && (i < 5));

return 0;
}
Laufbedingung i = [1, 4] -> Schleife wird erneut ausgeführt
andernfalls: Programmende

Demo VC++ .NET:\K7_Steuerstrukturen\Menuff\Menuff.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 38


Technische Informatik und Programmieren
Steuerstrukturen
Endegetestete Schleife
Flussdiagramm der do while Anweisung

Äquivalenz do while Ù while

do Anweisung
{ while(Bedingung)
Anweisung { Anweisung
} while(Bedingung) }

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 39


Technische Informatik und Programmieren
Steuerstrukturen
Zählschleife
Zählschleife (for-Schleife)
• Zählschleife == Schleife mit einer festen Anzahl von Schleifendurchläufen
• im Schleifenkopf wird eine Zähl-/Laufvariable mit Anfangs- und Endwert
vereinbart
• nach jedem Schleifendurchlauf wird die Laufvariable manipuliert
(typischerweise: inkrementiert oder dekrementiert)

Struktogramm der Zählschleife (for)


Zähl-/Laufvariable

Schleifenkörper

solange, bis vorgegebener Endwert der Zähl-/Laufvariable erreicht ist

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 40


Technische Informatik und Programmieren
Steuerstrukturen
Zählschleife
Syntax der Zählschleife (for-Schleife)
for (int count = 0; count < 10; count++) besser ein Beispiel..
{
printf(“\nIm %d. Schleifendurchlauf“, count);
}

Schlüsselwort for

for (Ausdruck1; Bedingung; Ausdruck2)


{
Anweisung1;
Anweisung2;
Schleifenkörper
Anweisung3;
Anweisung4;
}
Ausdruck1: Anfangswert -> wird nur 1x ausgeführt! (Initialisierung)
Bedingung: vor jedem Schleifendurchlauf wird die Laufbedingung ausgewertet
-> true (!=0) d.h. Schleifendurchlauf
-> false (==0) d.h. Schleife beenden
Ausdruck2: Reinitialisierung der Laufvariablen; anschließend wird die
Bedingung erneut geprüft (nächster Durchlauf.. oder Ende)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 41


Technische Informatik und Programmieren
Steuerstrukturen
Zählschleife
Spezielle Zählschleifen (for-Schleifen)
• jeder der 3 Ausdrücke in der for-Schleife kann weggelassen werden
• es müssen jedoch stets 2 Semikolons ; ; angegeben werden

for (; ;) Beispiel für Endlosschleife -> Verlassen nur mit break möglich
{
printf(“\nEndlosschleife ..“);
}

HINWEIS: bei fehlender Bedingung wird die Laufbedingung als true angenommen

Überführen for-Schleife -> while-Schleife

for (; i < 8 ;) Anweisung;

nur die Bedingung ist formuliert


// entspricht
while(i < 8) Anweisung;

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 42


Technische Informatik und Programmieren
Steuerstrukturen
Zählschleife
Spezielle Zählschleifen (for-Schleifen)

for(int i = 65; i < 70; i++)


{
// irgendwo im Programmcode..
i--; // erzeugt eine schöne Endlosschleife!
// und weiter geht‘s
}

Zur Vermeidung von Fehlern und zur besseren Verständlichkeit,


sollte die Laufvariable niemals innerhalb der Anweisung verändert werden

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 43


Technische Informatik und Programmieren
Steuerstrukturen
Zählschleife
Spezielle Zählschleifen (for-Schleifen)
• mit dem Kommaoperator können mehrere Teilausdrücke zu einem Ausdruck
zusammengefaßt werden
• die Teilausdrücke werden von links nach rechts sequentiell ausgeführt

int i, x, grenze;
for(i = 0, grenze = 8; i < grenze; i += 2)
{
x = i * i, printf(“%10d“, x); // auch 2 Teilausdrücke..

// und weiter geht‘s in 1 Anweisung: a) x berechnen, b) Ergebnis ausgeben


}

Vorrang des Kommaoperators: -> niedrigste Vorrangstufe


x = (a = 3, b = 5, a * b);
// zuerst werden die Zuweisungen an a und b ausgeführt
// dann erfolgt die Multiplikation a * b
// danach wird der Wert des Produkts a * b an x zugewiesen

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 44


Technische Informatik und Programmieren
Steuerstrukturen
Zählschleife
Beispiele zur Zählschleife (for-Schleife)

ASCII-Tabelle von 65..69 auf Bildschirm ausgeben

for(int i = 65; i < 70; i++)


{
cout << i << " " << (char)i << '\n';
}
Typumwandlung (static cast)
oder static_cast<char>(i)

HINWEIS: statt der for-Schleife kann auch eine while-Schleife verwendet werden
-> (vgl. Äquivalenz ff.)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 45


Technische Informatik und Programmieren
Steuerstrukturen
Zählschleife
Äquivalenz von for- und while-Schleife
• eine for Schleife entspricht direkt einer while Schleife, es liegt lediglich eine
Umformulierung vor

for(Initialisierung; Bedingung;
Änderung)
{ ASCII-Zeichen Bsp 65..69
Anweisung
} int i = 65;
<-> while(i < 70)
Initialisierung {
while(Bedingung) cout << i << " “
{ << (char)i << '\n';
Anweisung i++;
Änderung }
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 46


Technische Informatik und Programmieren
Steuerstrukturen
Zählschleife
weitere Beispiele zur Zählschleife (for-Schleife)
int main(void) Summe der Zahlen von 1 bis 100..
{
int i, k = 0;

for (i = 1; i < 101; i++)


{
k += i;
}

printf(“%d“, k);
return 0;
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 47


Technische Informatik und Programmieren
Steuerstrukturen
Zählschleife
Regeln für die Gültigkeit von Schleifenvariablen
for(int i = 0; i < 100; i++) gem. ANSI-C99
{
// hier ist i bekannt (liegt im scope)
}
// hier ist i nicht mehr bekannt (außerhalb des Blocks /)

// kompatible Schreibweise für ältere Compiler


{
int i;
for(i = 0; i < 100; i++)
//
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 48


Technische Informatik und Programmieren
Steuerstrukturen
Zählschleife
noch ein Beispiel zur for-Schleife..
// Umrechnungstabelle EURO -> US-Dollar
#include <stdio.h>

int main()
{
int euro;
double kurs = 1.2; // US-$ für einen €

printf("\tEuro \tDollar\n");

for(euro = 1; euro <= 5; euro++)


{
printf("\t %d\t %.2f\n, euro, euro*kurs);
}

return 0;
}

Demo VC++ .NET:\K7_Steuerstrukturen\TableEURO-DOLLAR\TableEURO-DOLLAR.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 49


Technische Informatik und Programmieren
Steuerstrukturen
Zählschleife
Bildschirmausgabe zum Beispiel..

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 50


Technische Informatik und Programmieren
Steuerstrukturen
Sprünge
Sprünge (Steuerung der Schleifenbearbeitung)
Übersicht der Spunganweisungen in ANSI C/C++

Anweisung Zweck
continue; Abbrechen eines Schleifendurchgangs ohne die Schleife insgesamt zu
verlassen -> Bedingung wird neu ausgewertet und abhängig vom Ergebnis
wird die Schleife neu durchlaufen
Anwendung in: for-/while-/do-while Schleifen
break; Vorzeitiges Beenden der gesamten Schleife -> Programm wird nach der
Schleife fortgesetzt!
Anwendung in: switch-/for-/while-/do-while Schleifen
goto; Unbedingter Sprungbefehl: es erfolgt der Sprung zu einer Markierung
(Label)
VORSICHT: sparsamer Umgang mit goto-Befehlen, Gefahr von
Unübersichtlichkeit!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 51


Technische Informatik und Programmieren
Steuerstrukturen
Sprünge
Continue-Anweisung
• Verwendung in Schleifen (for-/while-/do-while-Schleife)
• nach continue wird unmittelbar die nächste Wiederholung begonnen
(ohne die Schleife zu verlassen)

/* Ausgabe der ungeraden Zahlen */


#include <stdio.h>

int main(void)
{
int i;
for (i = 1 ; i < 20 ; i++)
{
if ((i % 2) == 0) // gerade Zahl
continue; // Rücksprung zum Schleifenkopf
printf("aktuelle Zahl ist: %d\n",i);
}
getchar();
return 0;
Demo VC++ .NET:\K7_Steuerstrukturen\continue\continue.vcproj
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 52


Technische Informatik und Programmieren
Steuerstrukturen
Sprünge
Break-Anweisung
• Verwendung in Schleifen (switch-/for-/while-/do-while-Schleife)
• nach break wird die komplette Schleife unmittelbar verlassen (Programm
wird mit der nächsten Anweisung nach der Schleife fortgesetzt)

/* Ausgabe der Zahl 1 */


#include <stdio.h>

int main(void)
{
int i;
for (i = 1 ; i < 20 ; i++)
{
if ((i % 2) == 0) // gerade Zahl (z.B. 2)
break; // Schleife verlassen (Programmende)
printf("aktuelle Zahl ist: %d\n",i);
}
getchar();
return 0;
Demo VC++ .NET:\K7_Steuerstrukturen\break\break.vcproj
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 53


Technische Informatik und Programmieren
Steuerstrukturen
Sprünge
weiteres Beispiel zur Break-Anweisung
/* Ascii.c --> Programm zur Ausgabe der ASCII-Code-Tabelle. */
#include <stdio.h>
int main()
{
char answer; int upper, ac = 32; // ab ASCII-Code 32
// ohne Steuerzeichen
while(1)
{
printf("\n\nZeichen Dezimal Hexadezimal\n\n");
immer 20 Zeilen ausgeben
for(upper = ac + 20 ; ac < upper && ac < 256 ; ++ac)
printf(" %c %10d %10X\n", ac, ac, ac);

if( upper >= 256) break; HEX-Code

printf("\nWeiter --> <Return>, Ende --> <q>+<Return> ");


scanf("%c", &answer);
if(answer == 'q' || answer == 'Q') break;
fflush(stdin); // Eingabepuffer loeschen
}
Frank Artinger
return 0;
Informatik - ANSI C 2.0 / ANSI C++ 54
Technische
} Demo VC++ .NET:\K7_Steuerstrukturen\ASCII\ASCII.vcproj
Informatik und Programmieren
Steuerstrukturen
Sprünge
weiteres Beispiel zur Break-Anweisung

Bildschirmausgabe
(1. Seite)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 55


Technische Informatik und Programmieren
Steuerstrukturen
Sprünge
Programmsprünge mit Goto
• goto erlaubt einen beliebigen Sprung innerhalb derselben Funktion (z.B.
main()-Funktion)
• Sprungziele müssen als Marken (Labels) vereinbart werden

... Markierung (Label) mit : gekennzeichnet


Sprungziel:
Anweisungen;
goto Sprungziel;
...

Sparsamer Umgang mit Goto‘s!!


Programm verliert schnell an Übersichtlichkeit (Spaghetti-Code)
-> Goto‘s können in den meisten Fällen umgangen werden

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 56


Technische Informatik und Programmieren
Steuerstrukturen
Sprünge
.. evtl. eine sinnvolle Anwendung von goto ..
• sofortiges Verlassen einer tiefgeschachtelten Schleifenkonstruktion
for( .. )
for( .. )
if(error)
goto errorcheck;

...
errorcheck:
// Fehlerbehandlung

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 57


Technische Informatik und Programmieren
Steuerstrukturen
Sprünge
Konkretes Beispiel zu Goto..
• Fehlerbehandlung für die Eingabe einer ungültigen Note
#include <stdio.h>
int main(void)
{
int i;
goto Eingabe;
Hinweis: printf("Es gibt nur die Noten von 1 - 6 !!\n\n");
Eingabe : printf("Bitte geben Sie Ihre Note ein ( 1-6 ): ");
scanf("%d",&i);
if ((i < 1) || (i > 6)) goto Hinweis;
fflush(stdin);
return 0;
}
Demo VC++ .NET:\K7_Steuerstrukturen\Goto\Goto.vcproj

HINWEIS: es geht auch ohne goto ..

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 58


Technische Informatik und Programmieren
Steuerstrukturen
Sprünge
umgeschriebenes Beispiel ohne goto ..
#include <stdio.h>
int main (void)
{
int i, a;
do
{
a=0;
printf("Bitte geben Sie Ihre Note ein (1-6): ");
scanf("%d",&i);
switch (i)
{
case 1: printf( "Sehr Gut!" ) ;a=1; break;
case 2: printf( "Gut!" ) ; a=1; break;
case 3: printf( "Befriedigend!" ) ; a=1; break;
case 4: printf( "Genügend!" ) ; a=1; break;
case 5: printf( "Ausreichend!" ) ; a=1; break;
case 6: printf( "Ungenügend!" ) ; a=1; break;
default:
printf("Fehlerhafte Eingabe!\n");
printf("Nur Noten von 1-6 sind gueltig!\n");
Frank Artinger }
Informatik - ANSI C 2.0 / ANSI C++ 59
Technische
} .. Informatik und Programmieren
Steuerstrukturen
Sprünge
umgeschriebenes Beispiel ohne goto ..
} ..
while (a==0);
fflush(stdin);
getchar();
return 0;
}

Demo VC++ .NET:\K7_Steuerstrukturen\SwitchStattGoto\SwitchStattGoto.vcproj

etwas länger zwar, aber leichter wartbar da übersichtlicher

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 60


Technische Informatik und Programmieren
Steuerstrukturen
Rekursion
Rekursion
• Rekursion == besondere Form der Wiederholung
• Realisierung mit einem Unterprogramm (Funktion), die 2 Randbedingungen
erfüllen muß:
1) Funktion muß eine Abbruchbedingung für die Rekursion enthalten
2) Funktion ruft sich selbst auf und übergibt ein Teilergebnis der
Abarbeitung

int fak(int z) Beispiel: Fakultätsberechnung


{
int r = 1;
if(z > 1) rekursive Bildungsvorschrift
r = fak(z – 1); { a1 = 1, an = n * an-1 und n > 0}

return(r * z); z.B. 5! = 5 * 4 * 3 * 2 * 1 = 120


} rekursiver Abstieg

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 61


Technische Informatik und Programmieren
Steuerstrukturen
Rekursion
Beispiel zur Rekursion (Fakultät)
#include "stdafx.h"
Beispiel: Fakultätsberechnung
using namespace std; -> Verfolgen des Programmablaufs im Debugger

int fak(int z)
{
int r = 1;
if(z > 1)
r = fak(z-1);
return(r * z);
}

int _tmain(int argc, _TCHAR* argv[])


{
int zahl = 0;
cout << "\nGeben Sie bitte eine Zahl ein: " << endl;
cin >> zahl;
cout << "Die Fakultaet von " << zahl << " lautet: " << fak(zahl) <<
endl;
getchar();
Demo VC++ .NET:\K7_Steuerstrukturen\Fakultaet\Fakultaet.vcproj
Frank Artinger
return 0;
Informatik - ANSI C 2.0 / ANSI C++ 62
Technische
} Informatik und Programmieren
Steuerstrukturen
Rekursion
Eigenschaften der Rekursion
• Rekursionen sind im Struktogramm nicht darstellbar
• Rekursion: besondere Art der Programmierung i.V.m. Unterprogrammen, die
eine Schleifenwirkung zeigt
• Besonderer Vorteil: Implementierung einer Schleifenanweisung mit vorher
nicht festgelegter Anzahl von Durchläufen möglich!
Einschränkung bei der Rekursion
• bei jedem Funktionseintritt wird ein Speicherabbild des verlassenen
Programmsegmentes (z.B. Variablennamen + -werte etc.) auf dem
Kellerspeicher (stack od. Stapelspeicher) abgelegt
• bei Erreichen/Überschreiten der Speichergröße des stacks: -> stack
overflow (Stacküberlauf) -> erneutes Aufrufen der Funktion ist dann nicht
mehr möglich
• kritische Parameter: Übergabe speicherintensiver Parameter,
Rekursionstiefe

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 63


Technische Informatik und Programmieren
Steuerstrukturen
Rekursion
Berühmtes (rekursiv lösbares) Rechenrätsel

rekursiver Lösungsansatz
Teil a) rekursiver Abstieg
Teil b) rekursiver Aufstieg

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 64


Technische Informatik und Programmieren
Steuerstrukturen
Rekursion
Rekursiver Lösungsansatz des Rechenrätsels
Teil a) rekursiver Abstieg (gesucht: Kornzahl erstes bekanntes Feld)
• Körnerzahl aktuelles Feld = Körnerzahl Vorgängerfeld * 2
• falls Körnerzahl Vorgängerfeld unbekannt -> Berechnung wiederum aus
Vorgängerfeld
• Abbruchkriterium: solange, bis ein Feld das 1. Feld als Vorgängerfeld hat
-> Körnerzahl des 1. Felds ist bekannt (1)

Teil b) rekursiver Aufstieg (gesucht: Kornzahl eines vorgegebenen Felds)


• Körnerzahl 2. Feld = Körnerzahl 1. Feld * 2
• Körnerzahl 3. Feld = Körnerzahl 2. Feld * 2
• Implementierung: nach jeder Return-Anweisung steigt die Rekursion eine
Stufe nach oben, abschließend Rückkehr zum Hauptprogramm und
Ausgabe des Ergebnisses auf Bildschirm

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 65


Technische Informatik und Programmieren
Steuerstrukturen
Rekursion
Schema der Rekursion (Teile der Unterfunktion rechne)
z: Nummer des Schachfeldes

ergebnis: Körnerzahl aktuelles Feld

Teil a) rekursiver Abstieg

Vereinfachter Ablauf für 4 Felder

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 66


Technische Informatik und Programmieren
Steuerstrukturen
Rekursion

Vereinfachter Ablauf für 4 Felder

Teil b) rekursiver Aufstieg

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 67


Technische Informatik und Programmieren
Steuerstrukturen
Rekursion
Code-Beispiel zur Rekursion (Kornbeispiel)
• Berechnung der Kornzahl auf einem Schachbrett (64 Felder)
• rekursive Funktion: rechne()
• Funktionen aufstieg() und abstieg() dienen zur Beobachtung der
Rekursion auf dem Bildschirm, für die eigentliche Berechnung werden sie
nicht benötigt

#include<stdio.h>
int nummer=1; // global: Zähler für Unterprogrammaufrufe
float gesamt=0; // global: Körnerzahl auf dem Schachbrett
int aufstieg(int i,float e) // Dokumentation rekursiver Aufstieg
{
printf("Der Aufstieg!\n");
printf("Aktuelle Schachfeldnummer ist: %d\naktuelles Ergebnis:
%5.0f\n",i,e) ;
getchar();
return 0;
}
...

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 68


Technische Informatik und Programmieren
Steuerstrukturen
Rekursion
Code-Beispiel zur Rekursion (Kornbeispiel)
...
int abstieg(int i) // Dokumentation rekursiver Abstieg
{
printf("Der Abstieg!\n");
printf("Schachfeldnummer %d\nUnterprogramm wurde %dx
aufgerufen.\n",i,nummer);
getchar();
nummer++;
return 0;
}
float rechne(int z) // rekursive Funktion, z: aktuelles Feld
{
float ergebnis; // Körnerzahl auf aktuellem Feld
abstieg(z); // Anzeige der Rekursionsschritte
if (z>1) // Rekursionsbedingung
ergebnis=2*rechne(z-1); // Rekursion (Selbstaufruf)
else
ergebnis = 1; // rekursiver Abstieg abgeschlossen -> Aufstieg
gesamt += ergebnis;
aufstieg(z,ergebnis); // Anzeige der Rekursionsschritte
Frank
returnArtinger
ergebnis; // Rücksprung (Körneranzahl
Informatik - ANSI C Vorgängerfeld)
2.0 / ANSI C++ 69
Technische
} ... Informatik und Programmieren
Steuerstrukturen
Rekursion
Code-Beispiel zur Rekursion (Kornbeispiel)
int main(void)
{
int n;
float u;
printf("Welches Feld wollen Sie bestimmen: ");
scanf("%d",&n); // Eingabe Feldnummer
u=rechne(n); // Übergabe des größten Felds: Start der Rekursion
printf("Es sind %5.0f Koerner auf dem %d ten Feld.\n\n",u,n);
printf("Insgesamt liegen %E Koerner auf dem Schachbrett.",gesamt);
getchar();
return 0;
}
Demo VC++ .NET:\K7_Steuerstrukturen\Rekursion\Rekursion.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 70


Technische Informatik und Programmieren
Steuerstrukturen
Rekursion
Rekursiver Algorithmus zur Zahlensuche (Zahlenraten)
Aufgabe:
• Erraten einer Zahl aus einem vorher festgelegten Zahlenbereich (z.B. 1 ..
100)
• Triviale Lösung: alle Zahlen erfragen -> max. 100 Fragen, technische
Lösung z.B. mit Zählschleife und 100 Durchläufen
• Ziel: Suche nach einer schnelleren Lösung

Rekursiver Lösungsansatz:
• sog. binäre Suche ermöglicht eine deutliche Einschränkung der
Fragestellungen (z.B. max. 10 Fragen, wenn zusätzlich die Information
verfügbar ist, ob die gezogene Zahl < oder > der gesuchten Zahl ist)
• Anwendung z.B. bei der Suche nach Telefonbucheinträgen

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 71


Technische Informatik und Programmieren
Steuerstrukturen
Rekursion
Struktogramm des Algorithmus SuchZahl
min, max: Bereichsgrenzen
test: Wert, der gerade
getestet wird

zahl: gesuchte Zahl

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 72


Technische Informatik und Programmieren
Steuerstrukturen
Rekursion
Funktionsweise des Algorithmus Suche Zahl (binäre Suche)
Verbale Beschreibung:

¾ Zahlenbereich (1 .. 100) in der Mitte teilen


¾ Vergleich der mittleren Zahl (Testzahl) mit der gesuchten Zahl
¾ falls Testzahl < gesuchte Zahl -> nochmaliger Funktionsaufruf mit
Zahlenbereich Testzahl .. Maximum (hier muß die gesuchte Zahl dann wohl
liegen)
¾ falls Testzahl > gesuchte Zahl -> nochmaliger Funktionsaufruf mit
Zahlenbereich Minimum .. Testzahl
¾ jetzt wieder der 1. Schritt, allerdings mit halbierten Zahlenintervall
¾ gesuchte Zahl ist spätestens dann gefunden, wenn das zu untersuchende
Intervall nur noch eine Zahl enthält (oder die gesuchte Zahl wurde zuvor
bereits zufällig erraten)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 73


Technische Informatik und Programmieren
Steuerstrukturen
Rekursion
Tabellendarstellung zur rekursiven Zahlensuche
Arbeitsweise für Zahlenbereich {min, max} = {0, 20}

gesuchte Zahl

Vergleich:
5 Aufrufe (rekursive Suche) vs. 20 Aufrufe bei sequentieller Suche

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 74


Technische Informatik und Programmieren
Steuerstrukturen
Rekursion
Code-Beispiel zur rekursiven Zahlensuche
• rekursive Funktion SucheZahl() ruft sich selbst auf
• in der Rekursionsbedingung wird entschieden, mit welchen Parametern die
Funktion sich selbst aufruft
• ist die Zahl gefunden, wird die Funktion mit der Übergabe der gesuchten
Zahl verlassen (Abbruchbedingung)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 75


Technische Informatik und Programmieren
Steuerstrukturen
Rekursion
Code-Beispiel zur rekursiven Zahlensuche
#include <stdio.h> min, max: Bereichsgrenzen
int zahl;
int nummer = 0;
int SuchZahl( int min, int max ) /*rekursive Funktion */
{
int test;
nummer++;
printf("\nDurchlauf Nr.: %d\n",nummer);
test=( min+max ) / 2; /* arithm. Mittel */
if ( test < zahl ) /* Rekursionsbedingung */
{
test = SuchZahl( test,max );
}
else Programmverzweigung in
{ der Rekursion
if ( test > zahl )
{
test = SuchZahl( min,test );
}
}
rekursiver Abstieg beendet,
Frank Artinger
return test;
Informatik
rekursiver - ANSI
Aufstieg C 2.0 / ANSI C++
beginnt 76
Technische
}...Informatik und Programmieren
Steuerstrukturen
Rekursion
Code-Beispiel zur rekursiven Zahlensuche
int main( void )
{
int min;
int max;
WHILE- Bedingung zur
int ergebnis;
Wiederholung fehlerhafter
do
Eingaben
{
printf( "Zufallszahl aus dem Intervall: " );
scanf( "%d", &zahl );
clrscr(); // oder printf( "\033[2J" ); für Linux
printf( "\nAnfangswert des Intervalls: \t " );
scanf( "%d", &min );
printf( "\nEndwert des Intervalls: \t" );
scanf( "%d", &max ); negative Zahlenbereichsgrenze?
}
while ((min-max) > 0 || (min*max) < 0 || (zahl < min) || (zahl>max ));
ergebnis = SuchZahl( min, max );
printf( "\n\aDie Zahl ist: %d\n", ergebnis );
fflush(stdin);
getchar(); Demo VC++ .NET:\K7_Steuerstrukturen\Ztest\Ztest.vcproj
Frankreturn
Artinger0; Informatik - ANSI C 2.0 / ANSI C++ 77
} Technische Informatik und Programmieren
Steuerstrukturen
Rekursion
Lessons learned ..
• rekursive Funktionsabläufe sind schwer aus dem Quelltext abzulesen
• der Programmablauf muß meist über das Verständnis des Prinzips
abgeleitet/erschlossen werden
• Hinweise (Kommentare) im Quelltext rekursiver Funktionen vereinfachen
vielfach das Verständnis für die komplexen Abläufe in rekursiven Schleifen

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 78


Technische Informatik und Programmieren
Steuerstrukturen
Übungen
Vorlesungsbegleitende Übung

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 79


Technische Informatik und Programmieren
Steuerstrukturen
Übungen
Vorlesungsbegleitende Übung

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 80


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Orientierung
Einleitung
Das erste Programm in C
ORIENTIERUNG
Konstanten
Einfache Datentypen
Unterprogramm – Technik –
Nützliche Funktionen
Steuerstrukturen
Typvereinbarungen von Variablen
Zeiger
Der Präcompiler
Modulare Programmierung
Entwicklungsumgebungen
Standardbibliotheken
Anhang

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 1


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Ziele

Wie werden eigene (benutzerdefinierte) Datentypen


vereinbart?
Wie werden Aufzählungsdatentypen deklariert und
definiert?
Was sind zusammengesetzte Datentypen?
ZIELE

Wie werden zusammengesetzte Datentypen verwendet?

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 2


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Inhalt
Typvereinbarungen von Variablen
Grundlagen
Typvereinbarung
Syntax der Typvereinbarung
Klassifikation der Datentypen
Aufzähldatentyp
Syntax der enumeration
Beispiele
Arrays (Felder)
INHALT

Syntax von Arrays


Beispiele zu Feldern
Mehrdimensionale Arrays (Felder)
Syntax mehrdimensionaler Felder
Beispiele zu mehrdimensionalen Feldern
Strukturen (struct)
Syntax von Strukturen
Zugriff auf einzelne Felder eines Datensatzes
Verschachtelte Strukturen
Union
Syntax einer Union
Beispiele zur Union
Bitfelder
Syntax von Bitfeldern
Beispiele zu Bitfeldern
Übung

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 3


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Grundlagen
Typvereinbarungen (strukturierte Datentypen)
• bislang haben wir sog. Grunddatentypen verwendet (z.B. int, float etc.) ->
werden durch ANSI-C/C++ bereitgestellt
• aus diesen Grund- oder Basisdatentypen können wir selbst komplexere
Datenstrukturen erzeugen und in unserem Programm verwenden

Beispiel: Programm zur Fahrzeugsimulation

Klassifikation realer Gegenstände führt zu Eigenschaften


-> Abbildung in Datentstruktur im Programm

Eigenschaften (Attribute):
- Farbe, Lack
- Anzahl Räder
- Leistung Motor
- cw-Wert
- etc.

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 4


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Grundlagen
Typvereinbarungen (strukturierte Datentypen)
• ANSI-C/C++ bietet die Möglichkeit, weitere (benutzerdefinierte) Datentypen
(-strukturen) einzuführen
• wie bei Variablen, Funktionen müssen neue Typen vereinbart (deklariert)
werden, bevor sie verwendet werden können
• sehr sinnvoll ist es, neuen Datentypen eigene (eindeutige) Namen zu geben

Syntax der Typvereinbarung (typedef)


• Schlüsselwort typedef dient zur Definition neuer Typnamen

typedef Datentyp NeuerTypName;

neuer Typname (Aliasname für Datentyp)


C-Grunddatentyp (int, float,..) oder eigener

HINWEIS: Auch ein bereits vorhandener Typname kann einen


neuen (evtl. intuitiveren) Namen erhalten.

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 5


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Typvereinbarung (typedef)
Beispiele zu typedef
leitet Typvereinbarung ein (Schlüsselwort!)
Datentyp des neuen Typs
neuer Typname
typedef float real;
typedef int temperatur;
typedef unsigned long ULONG;

// Anwendung im Programm
ULONG eineUnsignedLongVariable;
temperatur t_Raum1 = 20;
real stuetzpunkt = sqrt(3)/2.0;

neuer Datentyp wird verwendet wie Grunddatentypen

VORTEILE:
Lesbarkeit des Programms wird verbessert
maschinenabhängige Datentypen können zentral behandelt werden

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 6


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Typvereinbarung (typedef)
Wichtige Eigenschaften von typedef
• in einer neuen typedef-Definition nimmt der neue Typname immer die
Position eines Variablennamens ein (ohne das führende typedef würde
eine neue Variable und kein neuer Typname vereinbart)

• Typdefinitionen reservieren keinen Speicherplatz, es wird auch kein neuer


Datentyp konstruiert

• es wird lediglich ein neuer Name für einen bereits existierenden Datentyp
eingeführt

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 7


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Klassifikation der Datentypen

Grunddatentypen

Enumerationen

Grunddatentypen

benutzerdefinierter
Vorstufe der Klasse
Datentyp

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 8


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Aufzähltypen (enumeration)
Aufzähltypen (enum)
• Aufzählungstyp wird mit dem Schlüsselwort enum definiert
• der Wertebereich eines enums umfaßt bestimmte Ganzzahlen (nur Typ int)
• die möglichen Werte und deren Namen werden durch eine Aufzählung
festgelegt

Syntax der Enumeration (enum)


Variante 1) mit automatischer Numerierung

typedef enum {rot, gelb, gruen} t_Ampel;


typedef enum {Sa, So} t_Wochenende; Bezeichner für den Datentyp

Aufzählungsliste
• Aufzählungsliste enthält Konstanten vom Typ int
• Wert der Konstanten ergibt sich bei automatischer Numerierung aus der
Reihenfolge in der Liste (z.B. rot = 0, gelb = 1, gruen = 2 bzw. Sa = 0, So = 1)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 9


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Aufzähltypen (enumeration)
Syntax der Enumeration (enum)
Variante 1 mit expliziter Wertzuweisung:
typedef enum {blau, rot, gruen, gelb} t_farbe;
typedef enum {blau, rot = 10, gruen = 20, gelb} t_farbe1;
t_farbe wand = rot;
Variablen vom Typ t_farbe und t_farbe1
t_farbe1 wand1 = rot;

• automatische Numerierung: blau = 0, rot = 1, gruen = 2, gelb = 3


Var. wand besitzt den Wert 1
• explizite Numerierung: blau = 0, rot = 10, gruen = 20, gelb = 21
Var. wand1 besitzt den Wert 10

Vorteile der enumeration:


• nicht-ordinale Merkmale können intuitiv im Programm abgebildet werden
• Compiler prüft den Wertebereich vor einer Variablenzuweisung (Typsicherheit!)
• enums erleichtern häufig die Lesbarkeit des Codes

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 10


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Aufzähltypen (enumeration)
Beispiel zu enum (Variante 1 mit typedef)
#include <stdio.h> /* printf() und scanff() */

int main()
{
typedef enum {blau, rot, gruen, gelb} t_farbe;
t_farbe wand;

for (wand = blau; wand < gelb; wand = (t_farbe)(wand + 1)


printf(“Die Farbe der Wand ist: %d.\n“, wand);

getchar();
return 0;
}

enums können auch in switch – case Verzweigungen eingesetzt werden

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 11


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Aufzähltypen (enumeration)
Syntax der Enumeration (enum)
Variante 2) (ohne typedef)
• gem. ANSI C99 kann eine enumeration auch ohne typedef eingeführt
werden
// automatische Numerierung
enum BOOL {false, true}; // allg. Definition
enum BOOL {false, true} flag; // Definition + Var. flag erzeugen
enum BOOL flag; // Variable flag vom Typ BOOL erzeugen
BOOL flag; // dito, auch möglich

beliebige int-Konstanten (auch negativ!)


// explizite Numerierung
enum grundfarbe {blau = 1, gruen = 2, rot = 4} farbe;
enum schalter {aus,off = 0, ein,on = 1};

Konstanten aus und off


erhalten den Wert 0

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 12


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Aufzähltypen (enumeration)
Syntax der Enumeration (enum)
zu Variante 2) (ohne typedef)

// weitere Variante von enum


enum {rot_zeit = 23, gelb_zeit = 3, gruen_zeit = 20};

hier fehlt der Name des enum

enums können auch ohne Namen angegeben werden:


Aufzählungstyp später aber nicht mehr verwendbar (d.h. es
kann keine Variable vom Typ des enums erzeugt werden)
nur die int-Konstanten können genutzt werden
ergo: Alternative zu const int oder #define

// später..
Funktion(rot_zeit); // int-Konstante rot_zeit
int x = gelb_zeit; // int-Konstante gelb_zeit

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 13


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Aufzähltypen (enumeration)
Beispiel zu enum (Variante 2 ohne typedef)
/* Ampel.c --> Dieses Programm simuliert die Phasen einer Ampel. *
* Mit Unterbrechungstaste (Strg+C) beenden. */
#include <stdio.h>
#include <time.h> // wg. Timer
nur Konstanten definieren
enum farben { rot, gelb, gruen };
enum { rot_zeit = 23, gelb_zeit = 3, gruen_zeit = 20}; // Sekunden

void warte( int sekunden), schalte( int farbnr);

void main()
{
enum farben phase = rot; // oder: farben phase = rot;

printf("\n\n");
...

Demo VC++ .NET:\K8_Typvereinbarungen\Ampel\Ampel.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 14


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Aufzähltypen (enumeration)
Beispiel zu enum (Variante 2 ohne typedef)
...
while(1)
{
schalte( phase);
switch( phase) int-Konstante, Wert 23
{
case rot: warte( rot_zeit); phase = gelb;
break;
case gelb: warte( gelb_zeit); phase = gruen;
break;
case gruen: warte( gruen_zeit); phase = rot;
break;
default: phase = rot;
break;
}
}
}
...

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 15


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Aufzähltypen (enumeration)
Beispiel zu enum (Variante 2 ohne typedef)
...
void warte( int sek)
{
long start = time(NULL); Timer (OS-Funktion) nutzen
while( time(NULL) < start + sek)
;
}

void schalte( int farbnr)


{ „Gedächtnis“ der Funktion
static char *kontroll_str[] = { "ROT", "GELB", "GRUEN\n" };
printf("\t %s\n", kontroll_str[farbnr] );
}

Hinweis:
Standardfunktion time(NULL) gibt die aktuelle Systemzeit in UTC (coordinated
universal time) an d.h. Anzahl Sekunden seit Mitternacht 00:00:00, 1.Jan 1970
statt NULL kann auch ein Zeiger auf eine Variable angegeben werden

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 16


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
Array (Felder, Vektoren)
• Arrays können mehrere Elemente desselben Typs aufnehmen
• bei der Definition des Arrays wird die Anzahl der n Elemente bestimmt
• der Zugriff auf die Elemente erfolgt über einen
Index [0 .. n-1]; n:= Anzahl der Elemente

Beispiel zu Array
char puffer[100]; Anzahl der Elemente (100), Index von [0, 99]
puffer[0] = ‘A‘; Ansprechen eines Elements per Index

puffer[0] ‘A‘
puffer[1] Vektor (Array) puffer im Speicher
kann 100 Elemente vom Typ char aufnehmen
... jedes Element ist über Index [0, 99] erreichbar
belegt 100 * 1 Byte zusammenhängenden Speicher
puffer[99]

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 17


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
Syntax von Arrays
typ name[anzahl]; // allg. Syntax

int lottozahlen[6]; // Def. int-Array mit 6 Elementen


// Definition und Initialisierung int-Array mit 6 Elementen
int lottozahlen[] = {3, 27, 35, 6, 15, 21};
// nur Element [0], [1] initialisieren
int lottozahlen[] = {3, 27};
// schreibender Zugriff auf ein Element per Index
lottozahlen[2] = 23;
// lesender Zugriff auf ein Element per Index
printf(“%d“, lottozahlen[2]);

• anzahl muß eine Konstante sein (oder Ausdruck, der nur Konstanten enthält)

Es gibt keine Fehlermeldung, wenn zur Laufzeit des Programms


der Index den zulässigen Wertebereich verlässt!
-> Folge: Speicherüberschreiber (evtl. Absturz!!)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 18


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
Syntax von Arrays
• Arrays können mit jedem Datentyp gebildet werden
double zahl[20]; // double-Array (Vektor)
int i; // Index
// füllen der double-Elemente mit 1/1, 1/2, 1/3, .. 1/20
for(i = 0; i < 20; i++)
zahl[i] = 1.0 / (double)(i+1);

C- type cast: wandelt int-Ergebnis (i+1) in double

• Laufbedingung i < 20 stellt sicher, daß Index i im zulässigen Bereich [0, 19]
bleibt
• type cast (double) (i+1) wäre nicht unbedingt erforderlich, macht aber
deutlich, daß eine Gleitkommadivision (z.B. 1.0 / 12.0) erfolgen soll!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 19


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
Beispiel zu Arrays
/* Dreh.c --> Eine Zeile einlesen und umgekehrt ausgeben. */
#include <stdio.h>
#define MAXL 100 Konstante für Elementanzahl

int main()
{
int c, i; char puffer[MAXL];

printf("\nBitte geben Sie eine Zeile Text ein:\n\n");

for(i = 0; i < MAXL && (c = getchar()) != '\n'; ++i)


puffer[i] = c; // Zeile einlesen.

putchar('\n'); // Neue Zeile.

while( --i >= 0) // Zeile umgekehrt


putchar(puffer[i]); // ausgeben.

putchar('\n'); // Neue Zeile.


return 0;
}
Frank Artinger Demo VC++ .NET:\K8_Typvereinbarungen\Dreh\Dreh.vcproj
Informatik - ANSI C 2.0 / ANSI C++ 20
Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
weiteres Beispiel zu Arrays
• Ziel: alphabetische Sortierung von 5 eingegebenen Großbuchstaben (5
Ganzzahlen gem. ASCII-Zeichencodetabelle)
Angewandtes Sortierverfahren:
Zahlenpaar 1 (1,18)
• paarweiser Vergleich, links beginnend (1,18)
• Zahllinks < Zahlrechts -> o.k.
Zahlenpaar 2 (18,3)
• Zahllinks > Zahlrechts -> tausche Position
u.s.w.

am Ende des Arrays ist 1 Ziffer korrekt sortiert


d.h. bei n Elementen sind n Durchläufe erforderlich
falls in einem Durchlauf kein Tausch erfolgt -> Elemente sind sortiert
(Abbruchkriterium)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 21


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
weiteres Beispiel zu Arrays
Struktogramm zum Buchstabensortieren:

Durchlaufzähler
Zahllinks < Zahlrechts ?

tausche Zahllinks , Zahlrechts

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 22


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
weiteres Beispiel zu Arrays (Buchstabensortieren)
#include <stdio.h>
#define MAX 20 Anzahl der zu sortierenden Buchstaben
int main (void)
{
int index; Position eines Elementes in der Liste
int nummer; Anzahl der Durchläufe
int flag; 1 == Tausch im Durchlauf, 0 == kein Tausch im Durchlauf -> ABBRUCH!
char buchstabe; Zwischenspeicher beim Tausch der Buchstaben
char liste[MAX]; char-Array, Index [0, MAX-1]
printf("Bitte geben Sie die Liste der Buchstaben ein: \n");
for (index = 0; index < MAX; index++)
{
scanf("%c",&liste[index]);
if (liste[index] < 65 ) index--; /*Entfernen der Steuerzeichen */
}
...

Demo VC++ .NET:\K8_Typvereinbarungen\Sort\Sort.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 23


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
weiteres Beispiel zu Arrays (Buchstabensortieren)
Hinweis zu scanf():
scanf("%c",&liste[index]);

• entweder: alle Zeichen eingeben und mit RETURN abschließen (pro


Schleifendurchlauf liest scanf() dann 1 Zeichen aus dem Eingabepuffer)
• oder: Eingabe jedes einzelnen Buchstabens mit RETURN abschließen

Filtern von Steuerzeichen (ASCII-Code < 65):


if (liste[index] < 65 ) index--;

• wird ein ASCII-Zeichen < 65 eingegeben -> Listen-Index wird zurückgesetzt


(index--) d.h. das eingelesene Zeichen (< 65) wird im nächsten Schleifen-
durchlauf überschrieben

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 24


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
weiteres Beispiel zu Arrays (Buchstabensortieren)
...
nummer = 0; /* NUMMER DES DURCHLAUFS */
do Sortierschleife
{
flag = 0; vor jedem Durchlauf auf 0 setzen
nummer++;
for(index = 0 ; index < MAX-nummer ; index++)
{
if (liste[index] > liste[index + 1]) Zahllinks > Zahlrechts ?
{
flag = 1; jetzt 1, da getauscht wird
buchstabe = liste[index];
liste[index] = liste[index + 1]; tausche Zahllinks , Zahlrechts
liste[index + 1] = buchstabe;
};
}
}
while (flag==1); Abbruchkriterium, falls keine Sortierung mehr notwendig
...

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 25


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
weiteres Beispiel zu Arrays (Buchstabensortieren)
...
printf ("Sortierte Liste: \n");
for (index = 0; index < MAX; index++)
Ausgabe der sortierten Liste
{
printf("%c ",liste[index]);
}

printf("\nSortierung erfolgte nach %d Durchlaeufen.",nummer);

fflush(stdin); // Eingabepuffer leeren


getchar();
return 0;
} Demo VC++ .NET:\K8_Typvereinbarungen\Sort\Sort.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 26


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
Initialisierung von Arrays
• Initialisierung mit einer Liste von Elementen { .. }
// mit Längenangabe
int num[3] = {2, 4, 6}; // num[0] = 2, num[1] = 4, num[2] = 6
// ohne Längenangabe
int num[] = {2, 4, 6}; // num[0] = 2, num[1] = 4, num[2] = 6
Längenangabe kann entfallen

// unterbestimmte Liste
int num[3] = {2, 4}; // num[2] wird mit 0 belegt
// überbestimmte Liste
int num[3] = {2, 4, 6, 8, 10}; // Werte 8 und 10 werden ignoriert

Frage: Wann werden die Arrays (Vektoren) erzeugt?

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 27


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
Lokal und global definierte Arrays
Lokale Arrays (z.B. innerhalb einer Funktion)
• Erzeugung erst zur Laufzeit des Programms
• sog. dynamische Erzeugung

Globale Arrays (außerhalb jeder Funktion, auch main() )


• Erzeugung bereits zum Übersetzungszeitpunkt
• sog. statische Erzeugung

Arrays, die initialisiert werden (Liste) oder größeren Speicherplatz


(z.B. > 1 kByte) benötigen sollten global definiert werden!

Elemente eines nichtinitialsierten lokalen Arrays haben zunächst undefinierte Werte!


-> Wertzuweisung erfolgt meist durch ein nachfolgende Schleife

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 28


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
Ausflug: Fibonacci-Zahlen
Leonardo Fibonacci (L. von Pisa, L. Pisano) (1170 – 1240)
• Hauptwerk Liber abbaci (1202)
• popularisiert das in der arabischen Welt
• übliche Dezimalsystem
• (Ablösung des römischen Zahlensystems)
Fibonacci-Zahlen
• math. Folge von positiven ganzen Zahlen
• rekursive Definition: f0 = 0; f1 = 1; fn = fn-1 + fn-2
Folge: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, ..
• Beispiel zur Berechnung einer Kaninchenpopulation
• zu Beginn gibt es ein Paar neugeborene Kaninchen
• Jedes neugeborene Kaninchenpaar wirft nach 2 Monaten ein weiteres
Paar
• Anschließend wirft jedes Kaninchenpaar jeden Monat ein weiteres
• Kaninchen leben ewig und haben einen unbegrenzten Lebensraum

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 29


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
weiteres Beispiel zu Arrays (Initialisierung)
/* Fibo.c --> Dieses Programm berechnet die ersten 20 *
* Fibonacci-Zahlen und die zugehoerigen Fibonacci-Quotienten. *
* ------------------------------------------------------------ *
* Die ersten zwei Fibonacci-Zahlen sind 0 und 1. Jede folgende *
* Fibonacci-Zahl ist die Summe der beiden Vorgaenger. Das *
* ergibt die Zahlenfolge: 0, 1, 1, 2, 3, 5, 8, 13, ... . *
* *
* Die Quotienten der Fibonacci-Zahlen durch ihre Vorgaenger, *
* also 1/1, 2/1, 3/2 .... ,heissen Fibonacci-Quotienten. Sie *
* konvergieren gegen den Grenzwert (1 + sqrt(5)) / 2. */
fn+1/fn ≈ a = Ф ≈ 1,618... (Goldener Schnitt, irrationalste Zahl)
#include <stdio.h>
#include <math.h> // Prototyp von sqrt()
#define GRENZE 20

long fib[GRENZE+1] = { 0, 1 }; Element [0] und [1] initialisiert


...
Demo VC++ .NET:\K8_Typvereinbarungen\Fibo\Fibo.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 30


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
weiteres Beispiel zu Arrays (Initialisierung)
...
char header[] = "\n\n"
" Index Fibonacci-Zahl Fibonacci-Quotient Abweichung\n"
" Quotient - Grenzwert"
"\n\n";

int main()
{
int i; double q, lim;

for( i=1 ; i < GRENZE ; ++i) // Berechnung der


fib[i+1] = fib[i] + fib[i-1]; // Fibonacci-Zahlen.

lim = (1.0 + sqrt(5.0)) / 2.0; // Der Grenzwert.

printf(header);
printf("%5d %20ld\n", 0, fib[0]); // Ausgabe der ersten
printf("%5d %20ld\n", 1, fib[1]); // 2 Fibonacci-Zahlen.
...

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 31


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
weiteres Beispiel zu Arrays (Initialisierung)
...
for( i = 2 ; i <= GRENZE ; ++i) // Die weiteren Zeilen
{ // der Tabelle.
q = (double)fib[i] / (double)fib[i-1];
printf("%5d %20ld %20.14f %20.3E\n", i, fib[i], q, lim-q);
}

return 0;
}
Demo VC++ .NET:\K8_Typvereinbarungen\Fibo\Fibo.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 32


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
C-Zeichenketten (strings)
• String == Zeichenfolge, abschließend mit String-Endezeichen ‘\0‘
• jeder String wird in einem char-Array gespeichert
// ohne Längenangabe
char str1[] = “Hallo“; terminierende NULL
// äquivalent mit
char str1[] = {‘H‘, ‘a‘, ‘l‘, ‘l‘, ‘o‘, ‘\0‘};

5 Zeichen
+ 1 Byte = 6 Bytes
(5 Bytes)
// mit Längenangabe
char str2[100] = “Helau“; // belegt nur die ersten 6 Bytes

HINWEIS: Zeichenketten schließen mit dem Zeichen ‘\0‘ ab.


Bei Zuweisung eines Textes in “ .. “ wird automatisch
die terminierende NULL angehängt.

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 33


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
Vorgriff: Arrays und Adressen
• Name des Arrays == Speicheradresse des 1. Elementes
// Definition
char ort[] = “Muenchen“;

// Zeiger auf ort Zeichenkette


char* port = 0;
port = ort; // Zeiger auf ort oder
port = &ort[0]; // Zeiger auf ort

// Beispiel
printf(ort); // printf erhält Anfangsadresse von ort
// printf gibt Zeichen aus bis ‘\0‘ erreicht ist

HINWEIS: Die Äquivalenz zwischen Arrayname und Zeiger auf 1. Element


kann für die sog. Zeiger-/Adress-Arithmetik genutzt werden

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 34


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
Vorgriff: Adressarithmetik
• zur Anfangsadresse eines Arrays kann eine positive Ganzzahl addiert
werden
// Definition
char ort[] = “Muenchen“;

// Zeiger-Arithmetik
char* port = 0; // Zeiger auf char
port = ort; // Zeiger auf ort
int i = 2;
port = ort + i; // zeigt auf ort[2], also 3. Element, Wert ‘e‘
port = &ort[2]; // zeigt auf ort[2], also 3. Element , Wert ‘e‘

HINWEIS: Zeiger-Arithmetik ist ein sehr mächtiges Werkzeug!


Funktioniert bei allen Array-Typen (z.B. int-/float-Arrays..)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 35


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
Beispiel zur Verwendung von Adressen (Arrays)
#include <stdio.h>
char text[] = "Die Sonne ist warm!";
int i = 14;
printf(“20.9s, text)
int main() Feldbreite 20
{ Genauigkeit .9 d.h. höchstens 9 Zeichen ausgeben
// Lineal
printf("\n\n|012345678901234567890123456789|\n\n");
printf("|%30s| \n", text); // Feldbreite 30,
// rechtsbündig
printf("|%s| \n", text + 4); // ab dem 5. Zeichen
printf("|%-30s| \n", text + i); // ab dem 15. Zeichen
// linksbündig
printf("|%20.9s|\n", text); // rechtsbündig, 9 Zeichen

puts("\nUnd nun ohne Formatierung: "); kopiert string unformatiert an stdout


puts(text);
text + 4 = &text[4] d.h. 5. Element, Wert ‘S‘
return 0;
}
Demo VC++ .NET:\K8_Typvereinbarungen\Adressen\Adressen.vcproj
Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 36
Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
Mehrdimensionale Arrays
• C erlaubt Arrays mit mehreren Dimensionen (z.B. 2-dimensionale Matrizen)
• gem. ANSI-C mind. 63 Dimensionen möglich, in realitas ist die Anzahl der
Dimensionen nur durch den verfügbaren Speicherplatz beschränkt!

// Matrizen definieren
long zahlen[5][10]; // 5 Zeilen, 10 Spalten (50 Elemente)
int regal[5][3]; // 5 Zeilen, 3 Spalten (15 Elemente)

// Werte zuweisen
zahlen[0][9] = 7; // letztes Element in 0. Zeile erhält Wert 7
int regal[5][3] = {3, 17, 4, 6, 2, 1};
regal[0][0] = 3;
regal[0][1] = 17; Werte werden zeilenweise zugewiesen
regal[0][2] = 4;
regal[1][0] = 6; neue Zeile!
regal[1][1] = 2;
regal[1][2] = 1;

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 37


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
Mehrdimensionale Arrays
• n-dimensionale Arrays == 1-dimensionaler Vektor, dessen Elemente wieder
(n-1)-dimensionale Vektoren sind

Beispiel: 2-dimensionaler Vektor (Matrize)

5 Elemente

long zahlen[5][10];
0 1 2 3 4 5 6 7 8 9
1
2
3
4

1-dimensionaler Vektor mit 10 Elementen

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 38


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
Mehrdimensionale Arrays (Initialisierung)
• weitere mögliche Initialisierungen..
// Matrizen definieren und initialisieren
int a[2][3] = { {1, 0, 0}, {7, 0, 0} }; zeilenweise initialisieren

Zeile 1 Zeile 2
// Zeilenanzahl kann entfallen (nicht Spaltenanzahl!)
int a[][3] = { {1}, {7} };

Zeile 1 Zeile 2
1, 0, 0 7, 0, 0

HINWEIS:
• bei einer globalen Definition (außerhalb jeder Funktion) werden nicht-
initialisierte Elemente mit 0 belegt!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 39


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
Beispiel zur Verwendung 2-dimensionaler Arrays
// Vertreter.c -> Verwenden mehrdimensionaler Vektoren.

#include <stdio.h> Matrize vom Typ char

char vertreter[2][20] = { "Lauber, Otto", Zeile 1


"Forsch, Heidi" }; Zeile 2

// Jeder Vertreter hat vier verschiedene Artikel


// im Sortiment, davon wurden verkauft:
int artikel_anzahl[2][4] = { { 20, 5, 30, 17},
{150, 120, 90, 110} };
...
Matrize vom Typ int

Demo VC++ .NET:\K8_Typvereinbarungen\Vertreter\Vertreter.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 40


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
Beispiel zur Verwendung 2-dimensionaler Arrays
...
int main()
{
int i, j;

for( i = 0; i < 2; ++i) Zugriff auf i-te Zeile


{
printf("\n\nVertreter: %s", vertreter[i]);
printf("\nVerkaufte Stueckzahlen:");
Zugriff auf i,j-tes Element
for( j = 0; j < 4; ++j)
printf("%8d", artikel_anzahl[i][j]);
}
printf("\n");

return 0;
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 41


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
Beispiel: Brettspiel (2-dimensionale Arrays)
Spielregeln:
• Spielsteine werden im Wechsel von 2 Spielern aufgelegt
• Gewinner ist, wer zuerst 4 Spielsteine seiner Farbe zusammenhängend
diagonal, senkrecht oder waagrecht gelegt hat (vgl. „Vier-Gewinnt“)
• sind alle Felder ohne Gewinnsituation besetzt -> unentschieden!

Beispiel:

Spieler A hat gewonnen!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 42


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
Beispiel: Brettspiel (2-dimensionale Arrays)
Vorüberlegungen zum Programmentwurf (Design):
• Funktion zum ausgeben des aktuellen Spielstandes (== aktuelle Position der
Spielsteine) auf dem Bildschirm
• Funktion zur Kontrolle der Gewinnsituation
• Funktion zur Eingabe der Feld-Zeile durch den Spieler
• Funktion zur Eingabe der Feld-Spalte durch den Spieler
• Hauptprogramm zur Koordination und Ausgabe des Gewinners

HINWEIS: Es sind natürlich auch andere Entwürfe denkbar!


Bemerkenswert: Der Entwurf berücksichtigt nur die allgemeine Logik und ist
daher prinzipiell auch für eine fensterorientierte Realisierung geeignet!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 43


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
Beispiel: Brettspiel (2-dimensionale Arrays)
Funktionsprinzip:

Spieler A: Spielstein setzen Spieler B: Spielstein setzen


(Eingabe Zeilen-/Spaltennummer) (Eingabe Zeilen-/Spaltennummer)

Aktuelle Spielsituation Gewinnsituation!


ausgeben (Siegerermittlung ausgeben)

jetzt fehlt nur noch die Implementierung ..

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 44


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
Beispiel: Brettspiel (2-dimensionale Arrays)
#include <stdio.h>
char brett[8][8]; char-Matrize: 8 Zeilen, 8 Spalten (8 x 8 Spielfeld)

Funktion zum Aufbau des Spielbrettes

int init(void) Initialisierung der char-Matrize (Spielfeld)


{
int i;
Zeilen
int j;
for (j = 0; j < 8; j++)
for (i = 0; i < 8; i++) Doppelschleife um 8 x 8 Spielfeld
brett[j][i] = 'O'; mit ‘o‘ zu belegen
return 0;
} Spalten

Demo VC++ .NET:\K8_Typvereinbarungen\Brett\Brett.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 45


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
Beispiel: Brettspiel (2-dimensionale Arrays)
Funktion zur Eingabe der Zeilennummer durch den aktiven Spieler

int zeile()
{
int z;
printf("Zeile: ");
scanf("%d",&z); Tastaturabfrage
return z;
}

Funktion zur Eingabe der Spaltennummer durch den aktiven Spieler


int spalte()
{
int s;
printf("Spalte: ");
scanf("%d",&s); Tastaturabfrage
return s;
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 46


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
Beispiel: Brettspiel (2-dimensionale Arrays)
Funktion zur Kontrolle der Gewinnsituation
int erg(int sp) sp == 1 -> Spieler B, sp == -1 -> Spieler A
{
char zeichen; Spielstein (‘A‘ oder ‘B‘)
int r = 0; int i; int j; r == Anzahl gleicher Spielsteine (‘A‘ oder ‘B‘)
if (sp < 0) zeichen = 'A'; else zeichen = 'B';
for (j = 0; j < 8; j++)
{ Rücksetzen, falls weniger
if (r < 4) r = 0; senkrechte Felder prüfen.. als 4 gleiche Spielsteine
for (i = 0; i < 8; i++) hintereinander
if(brett[i][j] == zeichen) r++; else if(r < 4) r = 0;
}
for (j = 0; j < 8; j++)
{ waagrechte Felder prüfen..
if (r < 4) r = 0;
for (i = 0; i < 8; i++)
if(brett[j][i] == zeichen) r++; else if(r < 4) r = 0;
}
return r; r == 4 bei Gewinnsituation, sonst r == 0
}
Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 47
Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
Beispiel: Brettspiel (2-dimensionale Arrays)
Funktion zum Ausgeben des aktuellen Spielstandes
int ausgabe(int i, int j, int sp) sp == 1 -> Spieler B, sp == -1 -> Spieler A
{
int a; i, j == Zeilen-/Spaltenposition des Spielsteins (‘A‘ oder ‘B‘)
int b;
if (sp < 0) brett[i][j]='A'; setzen des aktuellen Spielsteins
if (sp > 0) brett[i][j]='B'; (entweder Spieler A oder B)
printf("\n");

for (a = 0; a < 8; a++)


{
printf("\n"); Doppelschleife zur Ausgabe des
for (b = 0; b < 8; b++) gesamten Spielfeldes (8 x 8 Brett)
printf(" %c",brett[a][b]);
}
return 0;
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 48


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
Beispiel: Brettspiel (2-dimensionale Arrays)
Hauptprogramm (Koordination der Funktionsaufrufe)
int main(void)
{
int runde = 64; max. 64 Runden bei 8 x 8 Brett
int i, j;
int spieler = 1; sp == 1 -> Spieler B, sp == -1 -> Spieler A
init();
while ((runde > 0) && (erg(spieler) < 4))
{
i = zeile();
j = spalte();
spieler *= -1; Spielerwechsel!
ausgabe(i,j,spieler);
printf("\n");
runde--; nach jeder Runde dekrementieren
}
if(runde > 0) d.h. erg(spieler) = 4 -> Gewinnsituation!
printf("Gewonnen!!!");
fflush(stdin);
getchar();
Frank Artinger
return 0; Informatik - ANSI C 2.0 / ANSI C++ 49
Technische Informatik und Programmieren
}
Typvereinbarungen von Variablen
Array (Felder, Vektoren)
Mehrdimensionale Arrays
• im vorigen Brett-Beispiel wurde ein 2-dimensionales Array verwendet
• 3- und mehrdimensionale Arrays sind ähnlich in der Handhabung

// 3-dimensionales Array
int a[2][4][3]; // Definition
a[0][0][0] = 15; // Wertzuweisung an das 1. Element

Beschränkung von Arrays:


• Elementgröße und Dimension von Arrays werden durch den Wertebereich
von unsigned int und den Speicherplatz beschränkt!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 50


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Strukturen
Strukturen (komplexer Datentyp)
Datensätze (records)
• Datensatz faßt logisch zusammengehörige Daten zu einer Einheit
zusammen (z.B. Personaldaten eines Mitarbeiters mit Tel.Nr, Anschrift etc.)
• jeder Datensatz unterteilt sich in mehrere Datenfelder
• C/C++ bildet Datensätze in Strukturen (struct) ab

Beispiel: mögliche Speicherbelegung

// Definition der Struktur adresse strasse


struct adresse Strukturvariable a ort
{
tel
char strasse[30];
char ort[30]; Komponenten
strasse
unsigned long tel;
}; Strukturvariable b ort
struct adresse a,b; tel
2 Strukturvariablen vom Typ adresse

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 51


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Strukturen
Definition von Strukturvariablen
• bei der reinen Defintion einer Struktur (Festlegung des Strukturtyps) wird
noch kein Speicherplatz reserviert
// Definition der Struktur adresse
struct adresse
{
keine Speicherplatzreservierung
char strasse[30]; für die Komponenten (Datenfelder)
char ort[30];
unsigned long tel;
};

• erst bei der Definition von Strukturvariablen (Variablen vom Typ der Struktur)
jetzt werden reserviert:
// Strukturvariablen definieren
2 * 30 * 1 Byte
struct adresse a, b; + 2 * 30 * 1 Byte
+ 2 * 4 Byte
-------------------------
128 Byte

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 52


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Strukturen
Syntax von Strukturen (struct)
Variante 1: Variante 2:
typedef struct spielkarte struct spielkarte
{ {
char farbe; char farbe;
int wert; Datenfelder
int wert;
} t_karte; } karte1;
t_karte karte1, karte2; struct spielkarte karte2, karte3;
struct spielkarte karte3;

• Schlüsselwort struct leitet Struktur ein (typedef ist optional)


• optional kann ein Name folgen (Name der Struktur, hier spielkarte)
• es folgen die Datenfelder im Block { .. }
• direkt im Anschluß an die Strukturvereinbarung können Strukturvariablen
erstellt werden (z.B. karte1 in Variante 2 oder ein Typ t_karte1 in
Variante 1)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 53


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Strukturen
Syntax von Strukturen (struct)
Variante 3: (Strukturdefinition ohne Strukturnamen)

struct sizeof(karte1);
{
char farbe; Speicherbedarf der Strukturvariablen ==
int wert; Datenfelder Speicherbedarf der Datenfelder
-> sizeof () liefert den Wert in Bytes
} karte1, karte2;

• werden nach der Strukturdefinition unmittelbar Strukturvariablen erzeugt


(hier karte1, karte2) kann der Strukturname entfallen

NACHTEIL:
• auf die Struktur kann später kein Bezug mehr genommen werden d.h. es
kann keine weitere Strukturvariable erstellt werden (z.B. karte3)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 54


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Strukturen
Verschachtelte Struktur
• ein Datenfeld darf wiederum vom Typ einer Struktur sein

typedef struct struct tkart


{ {
int x; float z;
int y; t_koord p; verschachtelte Struktur
} t_koord; // neuer Typ } Karte;

VORTEILE:
• komplexe Datenstrukturen lassen sich mit verschachtelten Strukturen
(relativ) einfach realisieren ☺
• werden Zeiger verwendet, können (neue) dynamische Datenstrukturen
(zur Laufzeit des Programms) erzeugt werden ☺

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 55


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Strukturen
Initialisierung von Strukturen
• jede Komponente (Datenfeld) einer Strukturvariablen kann durch eine
Initialisierungsliste mit einem Anfangswert vorbelegt werden

Beispiel:
/* Definition des Strukturtyps struct personal */

// Definition von struct adresse wie gehabt..

struct personal
{
unsigned long nummer; // Personalnummer
char name[50]; // Name
struct adresse adr; // Adresse
double income; // Gehalt
};
... Datenfeld darf wiederum eine Struktur oder
ein anderer benutzerdefinierter Datentyp sein

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 56


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Strukturen
Initialisierung von Strukturen
...
// Definition und Initialisierung einer Strukturvariablen
// vom Typ struct personal

struct personal chef = // personal chef ebenfalls möglich


{
1234567,
“Spenzer, Max“,
{
“Flowerweg 12“,
Initialisierungsliste
“81234 Muenchen“,
8325756
},
269000.0
};

enthält die Initialisierungsliste weniger Anfangswerte als Datenfelder in


der Struktur vorhanden sind
-> restliche Datenfelder werden mit 0 initialisiert!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 57


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Strukturen
Zugriff auf Komponenten/Datenfelder der Struktur
• mit dem . Operator sind Datenfelder zugreifbar (lesend / schreibend)

// Zugriff auf Datenfelder der Struktur


Beispiel:
chef.income = 90000.0;
char c_field[30] = {0}; Zugriff auf verschachteltes Datenfeld
char c = 0;
strcpy(c_field, chef.adr.strasse); // Standardbibliothek
//c_field = chef.adr.strasse; // leider nicht möglich
//c_field[0] = chef.adr.strasse[0]; // geht auch nicht
c = chef.adr.strasse[0];

Demo VC++ .NET:\K8_Typvereinbarungen\struct\struct.cpp

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 58


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Strukturen
Beispiel: Personendatenerfassung
#include <stdio.h>
int main(void)
{
int i;
struct person
{
char name[30];
int nummer;
} student; // Strukturvariable, uninitialisiert
printf ("Bitte geben Sie die Studiennummer ein: ");
scanf("%d",&student.nummer);
printf("Bitte geben Sie den Namen ein (Ende mit Leertaste):\n");
i = 0;
do
{
student.name[i]=getchar();
i++; ASCII-Code Leerzeichen (space)
}
while(student.name[i-1] != 32 ); /*Ende mit Leertaste*/
...
Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 59
Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Strukturen
Beispiel: Personendatenerfassung
...
printf("Kontrollausdruck:\n");
printf("Studentennummer: %d\n", student.nummer);
printf("Name: ");
i = 0;
do
{
printf("%c", student.name[i]);
i++; Leerzeichen wurde miteingelesen
}
while(student.name[i] != 32); /*Auslesen bis Leertaste*/
fflush(stdin);
getchar();
return 0;
} Demo VC++ .NET:\K8_Typvereinbarungen\Daten\Daten.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 60


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Union (Variante)
Union (Variante)
• Union ist ähnlich einer Struktur aufgebaut

Unterschiede Union vs. Struktur:


• nicht für jedes Datenfeld wird Speichplatz angelegt
• für alle Felder wird ein gemeinsamer Speicherbereich verwendet
• Größe des gemeinsamen Speicherbereichs == Speicherplatzbedarf des
größten Datenfeldes (oder: längste Komponente) der Union

Konsequenz:
• zum gleichen Zeitpunkt kann nur der Inhalt eines Datenfeldes gespeichert
werden!
• bei Speicherung eines weiteren Datenfeldes wird der bestehende Inhalt
überschrieben!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 61


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Union (Variante)
Syntax von Unions (union)
Variante 1: Variante 2:
typedef union name union t_karte
{ {
int nummer; char farbe;
char kette[10]; längstes Datenfeld int wert;
} t_variabel; } karte1;
t_variabel t1, t2; // oder union t_karte karte2, karte3;
union name t3; t_karte karte4; // auch möglich

Größe:
Startadresse 10 Byte == kette[10]

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 62


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Union (Variante)
Zugriff auf Datenfelder / Komponenten einer Union
Beispiel: Vektor nx im Speicher

union zahl
{
long n; nx[0].n 32 Bit
nx[0].x
double x; längstes Datenfeld 32 Bit
};
union zahl nx[10]; // Vektor
.
// Zugriff auf Elemente .
nx[5].n = 77; .
nx[0].x = 2.23;
// oder äquivalent (Zeiger) nx[9].n 32 Bit
(nx + 5) -> n = 77; nx[9].x
32 Bit
nx -> x = 2.23;

längstes Datenfeld bestimmt die Größe


(hier double, 64 Bits)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 63


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Union (Variante)
Initialisierung von Unions
• Union-Variable kann bei der Definition initialisiert werden

Unterschied zur Struktur:


• Initialisierungsliste enthält nur einen Anfangswert (== Typ des 1.
Datenfeldes!)

Erklärung:
• alle Datenfelder der Union werden im gleichen Speicherbereich gehalten
• dieser hat die Größe des „längsten“ Datenfeldes
• d.h. zu einem Zeitpunkt kann nur auf 1 Datenfeld zugegriffen werden

ein Beispiel bitte..

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 64


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Union (Variante)
Initialisierung von Unions
Beispiel:
union word_byte
{
unsigned short w;
unsigned char b[2]; Größe der Union: 2 Byte (16 Bit)
};
union word_byte wb = { 256 }; nur ein Anfangswert (Typ des 1. Datenfelds)

// gespeicherte Bit-Folge: 0000 0001 0000 0000 = 25610 = 0x100

b[1] b[0]

// Zugriff auf Wort (2 Byte)


printf(“WORD = %d“, wb.w); // liefert 256
// byte-weiser Zugriff
printf(“Low-Byte = %d, High-Byte = %d“, wb.b[0], wb.b[1]);
// liefert: Low-Byte = 0, High-Byte = 1

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 65


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Union (Variante)
Code-Beispiel zur Union
#include <stdio.h>
int main(void)
{
Demo VC++ .NET:\K8_Typvereinbarungen\Union\Union.vcproj
union vario
{
int ganze;
speichert Gleitkommazahl oder Ganzzahl
float gleit;
} zahl;

zahl.ganze = 15; // Ganzzahl


printf("Ganze Zahl: %d\n\n", zahl.ganze);
zahl.gleit = 8.25; // Gleitkommazahl
printf("Gleitkommazahl: %f\n\n", zahl.gleit);
printf("Ganze Zahl: %d\n\n", zahl.ganze);/*Fehler, da Gleitkommazahl
gespeichert ist*/
getchar();
return 0; Compiler meldet keinen Fehler!
} (nur im Programm verkehrt interpretiert!)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 66


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Union (Variante)
Code-Beispiel zur Union
Bildschirmausgabe:

Compiler meldet keinen Fehler!


(Gleitkommazahl 8.25 wird als Ganzzahl interpretiert!)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 67


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Bitfelder
Bitfelder (systemnahe Programmierung)
• Bitfeld == spezielle Struktur für den Zusammenschluß einzelner Bits oder
Bitgruppen
• ein Rechnerwort (16 Bit) wird in sog. Bit-Felder aufgeteilt

Vorteile:
• Erhöhung der Informationsdichte (z.B. bei begrenztem Speicherplatz)
• direktes Ansprechen einzelner Bits eines Rechnerwortes möglich (z.B. auf
Registerinhalte der Computerhardware)
• übersichtlicher (weniger fehleranfällig als Bit-Masken)

Anwendungsgebiete:
• Statusinformationen für Peripheriegeräte (z.B. Druckerstatus überprüfen)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 68


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Bitfelder
Syntax von Bitfeldern (systemnahe Programmierung)
struct Breite des Bitfelds bit0_4 (also 5 Bits) == 32 Zustände
{
unsigned bit0_4 : 5;
unsigned : 10; Lücke von 10 Bits (kein Zugriff möglich, da ohne Name)
unsigned bit15 : 1;
}
wort; Strukturvariable vom o.a. Strukturtyp

// Zugriff auf Bitfelder


wort.bit0_4 = 0x1F // Wert 31 wird in den unteren 5 Bits gespeichert

maximale Bitfeld-Breite == Rechnerwort (i.a. 16 Bit)

• Bitfelder == Datenfelder einer Struktur (struct)


• Typ des Bitfelds: unsigned int oder signed int (default)
• optional einen Namen (ohne Name: Ausrichtung nachfolgender Bitfelder)
• Breite des Bitfelds: nach dem Doppelpunkt

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 69


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Bitfelder
Code-Beispiel zu Bitfeldern
/* Checkprn.c --> Dieses Programm ueberprueft den Druckerstatus. *
* Hinweis: *
* Das Programm ist als DOS-Programm oder Konsolen-Anwendung *
* unter Windows 9x lauffähig. Dagegen erlaubt Windows NT einem *
* Anwenderprogramm nicht den direkten Zugriff auf die Hardware. */
#include <stdio.h>
#include <conio.h>
#define LPT1_PORT 0x378 // Portadresse der ersten prallelen
// Scnittstelle. (0x3BC bei PCs mit
// Adapter fuer Momochrom-Bildschirm.)

struct prn_status { unsigned bit012 : 3; // Nicht verwendet.


unsigned error : 1; // 0= I/O-Fehler.
unsigned select : 1; // 1= Drucker online.
unsigned paper : 1; // 1= kein Papier.
unsigned ack : 1; // Quittungssignal.
unsigned busy : 1; // 1= Drucker bereit.
} LPT1_status;

void get_status( char *status_ptr);


... Artinger
Frank Informatik - ANSI C 2.0 / ANSI C++ 70
Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Bitfelder
Code-Beispiel zu Bitfeldern
int main( ){
do
{
get_status( (char *)&LPT1_status);

printf("\nStatusbyte(HEX):%02X\n", *(unsigned char*)&LPT1_status);

if( LPT1_status.busy && LPT1_status.select )


{
printf("\nDrucker bereit!\n");
break;
}
else if( LPT1_status.paper )
printf("\nKein Papier im Drucker!\n");
else if( !LPT1_status.select )
printf("\nDrucker nicht online!\n");
else
printf("\nDrucker nicht bereit!\n");

printf("\nBitte Fehler am Drucker beseitigen.\n"


Frank Artinger "Esc -> Abbruch,Informatik
andere Taste -> Status pr fen.\n");
- ANSI C 2.0 / ANSI C++ 71
Technische Informatik und Programmieren
}while( getch() != 27);
Typvereinbarungen von Variablen
Bitfelder
Code-Beispiel zu Bitfeldern
return 0;
}

#ifdef __GNUC__
#define inp(portadr) inportb( portadr)
#endif

void get_status( char *status_ptr)


{
*status_ptr = inp(LPT1_PORT+1) & 0xF8; // Statusport lesen.
}

Demo VC++ .NET:\K8_Typvereinbarungen\Checkprn\Checkprn.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 72


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Übung
Vorlesungsbegleitende Übung
(1) Legen Sie einen benutzerdefinierten Datentyp über eine
Typvereinbarung an, der Daten eines Fahrzeugs speichern kann
(Modell, Farbe, Vmax, Hubraum, etc.).
(2) Schreiben Sie ein Programm, das nach Eingabe von 5 Wertepaaren aus
dem Nettopreis und der Mehrwertsteuer den Gesamtbruttopreis
berechnet. Speichern Sie dazu die Eingabewerte in einem 2-
dimensionalen Array.
(3) Schreiben Sie ein Programm, das in einem Array 5 Automarken
speichern kann. Die Eingaben werden über eine while-Schleife realisiert.
Lesen Sie die Automarken als unterschiedlich lange Zeichenketten (max.
20 Zeichen) über die Tastatur ein.

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 73


Technische Informatik und Programmieren
Typvereinbarungen von Variablen
Übung
Vorlesungsbegleitende Übung
(4) Schreiben Sie ein Programm zur Verwaltung einer CD-Sammlung.
Ermöglichen Sie über die Tastatur die Eingabe der CD-Nummer, der
Gesamtspiellänge in min, der Anzahl der Titel sowie eines
Kennbuchstaben für die Musikarten (R = Rock, K = Klassik etc.) und
nehmen Sie diese Werte in eine Struktur auf. Erstellen Sie zuvor einen
Datentyp dieser Struktur.
Speichern Sie 3 Angaben zu Ihnen bekannten CDs in einem Array
dieser Struktur ab.

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 74


Technische Informatik und Programmieren
Zeiger
Orientierung
Einleitung
Das erste Programm in C
ORIENTIERUNG
Konstanten
Einfache Datentypen
Unterprogramm – Technik –
Nützliche Funktionen
Steuerstrukturen
Typvereinbarungen von Variablen
Zeiger
Der Präcompiler
Modulare Programmierung
Entwicklungsumgebungen
Standardbibliotheken
Anhang

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 1


Technische Informatik und Programmieren
Zeiger
Ziele

¾ Was sind Zeiger?


¾ Wie greift man mit Zeigern auf Speicherinhalte zu?
¾ Wie wird Speicherplatz mit Zeigern reserviert und
freigegeben? (dynamische Speicherplatzverwaltung)
¾ Wie werden Zeiger auf benutzerdefinierte Datentypen
ZIELE

definiert?
¾ Was ist ein Zeiger auf Funktionen und wozu wird er
verwendet?

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 2


Technische Informatik und Programmieren
Zeiger
Inhalt
Zeiger
Grundlagen
Zeigertypen
Operatoren für Zeiger
Syntax von Zeigern
Wertzuweisung und Initialisierung von Zeigern
Speicherplatzanforderung
Funktionen malloc(), calloc() und realloc()
Speicherplatz freigeben
Dynamische Speicherverwaltung
INHALT

Speicheraufteilung in stack und heap


Zeigerarithmetik
Zeigerzuweisungen, Inkrementieren und Dekrementieren
Addieren und Subtrahieren, Differenz zweier Zeiger
Nullwert-Zuweisung, Vergleichsoperatoren
Zeiger auf Strukturen, Zeiger auf dynamisch verwaltete Strukturen
Zeiger in Strukturen
Einfach verkettete Listen
Listenelement anhängen, einfügen und löschen
Doppelt verkettete Listen
Binäre Bäume
Back-Tracking-Technik
Zeiger auf Arrays
Mehrdimensionale Arrays, Arrays dynamisch erzeugen
Zeiger auf Zeiger
Beispiele
Zeiger auf Funktionen
Funktionszuweisung, Funktionsaufruf über Zeiger, Anwendung Sprungtabelle
Zeiger auf Strings (Einlesen von Strings über Tastatur, Bildschirmausgabe von Strings)
Übung

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 3


Technische Informatik und Programmieren
Zeiger
Einführung
Warum beschäftigen wir uns mit Zeigern (Pointern)?
• effiziente Programmlogik -> nicht mit Daten selbst sondern mit Referenzen
auf Daten wird gearbeitet (z.B. Übergabe eines Arrays an eine Funktion:
nicht der gesamte Inhalt sondern nur die Anfangsadresse wird übergeben)
• Zeiger sind damit unverzichtbare Elemente in C/C++
• die Funktionsweise von C-Arrays und C-Strings basiert auf Zeigern
• dynamische Objekte (Objekte, die zur Laufzeit erzeugt werden) werden mit
Zeigern verwaltet

Zeiger bieten große Freiheit!

Zeiger beinhalten auch ihre Tücken!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 4


Technische Informatik und Programmieren
Zeiger
Zeiger und Adressen
Zeiger und Adressen
Was ist ein Zeiger?
• vergleichbar mit anderen Variablen: Name + Typ + Wert + Operationen möglich
• Unterschied:

Wert der Zeigervariablen == Speicheradresse eines Objekts

• Analogie-Beispiel:
Raum 03 04 01
Stockwerk

Raumnummer
Raum 02 06 04

Flur

== Pointer (Zeiger) auf einen Raum im Gebäude


Gebäude

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 5


Technische Informatik und Programmieren
Zeiger
Zeiger und Adressen
Zeiger und Adressen
Wie sieht ein Zeiger in C/C++ aus?
Beispiel:

int i = 99; // int-Variable definieren und initialisieren

Speicher (stack, Stapel-/Kellerspeicher)

(1) Compiler legt Speicherplatz


mit symbolischen Namen i an

(2) der Wert 99 wird eingetragen

(3) Compiler hat Speicher an der Adresse 10123 reserviert


(Adresse ist uns unbekannt!)
Wie kommen wir zur Adresse?

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 6


Technische Informatik und Programmieren
Zeiger
Zeiger und Adressen
Beispiel zu Zeigern
/* Adressen.c --> Wert und Adresse von Variablen ausgeben. */

#include <stdio.h>
Zeiger auf int (kurz: int-Zeiger)
int a, *p; // Definition der Variablen a und p

int main()
{
a = 5; p = &a; p speichert die Speicheradresse der int-Variablen a
printf("\nWert von a: %10d ", a);
printf(" Adresse von a: %10u", &a);

printf("\nWert von p: %10u ", p);


printf(" Adresse von p: %10u\n", &p);

return 0;
}
Demo VC++ .NET:\K9_Zeiger\Adressen\Adressen.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 7


Technische Informatik und Programmieren
Zeiger
Zeiger und Adressen
Beispiel zu Zeigern
Bildschirmausgabe:

Variable Wert Adresse


(Name) (Inhalt) (Inhalt)

... ZUFALL:
a 5 4359392 Compiler hat die Objekte
p 4359392 4359396 unmittelbar hintereinander
3 im Speicher angelegt
4

Zeiger haben wie gewöhnliche Variablen einen Namen + Typ + Wert

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 8


Technische Informatik und Programmieren
Zeiger
Zeiger und Adressen
Zeiger und Adressen
int* ip; // „Zeiger auf“ einen int-Wert (uninitialisiert)
ip = &i; // Adresse von i wird dem Zeiger ip zugewiesen

• mit dem *-Operator (Dereferenzierung) erstellen wir einen “Zeiger auf” int
an einer beliebigen (vom Compiler zugewiesenen Speicheradresse z.B.
10224), der Wert von ip ist rein zufällig, da er nicht initialisiert ist
• mit dem &-Operator (Adreßoperator) wird jetzt ip die Adresse von i
zugewiesen, d.h. ip hat jetzt den Wert 10123

int-Variable i Zeiger auf int i: ip

ip hat als Wert die Adresse von i

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 9


Technische Informatik und Programmieren
Zeiger
Zeiger und Adressen
Zeiger und Adressen
F: Können mehrere Zeiger auf i gerichtet sein?
int* ip2 = &i; // 2.er „Zeiger auf“ den int-Wert i

10123 jetzt 2 Zeiger auf int i: ip und ip2

10123

Adresse von i

F: Wie können wir von der Adresse auf den Wert kommen?

*ip oder *ip2 // Dereferenzierung d.h. Zugriff auf den Wert!

• der *-Operator ermöglicht es, auf den eigentlichen Wert zuzugreifen


• *ip -> (1) lese Wert von ip = 10123, (2) gehe zur Adresse 10123, (3) lese
den Wert aus Adresse 10123 (im Beispiel 99)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 10


Technische Informatik und Programmieren
Zeiger
Zeiger und Adressen
Zeiger und Adressen
F: Dann haben wir jetzt mehrere Möglichkeiten um auf den Wert von i
zuzugreifen?

i = 99; // entweder direkt..


*ip = 99; // oder über Dereferenzierung des Zeigers..
*ip2 = 99; // dito..

• *ip oder *ip2 werden als Aliasnamen bezeichnet


• alle 3 Anweisungen oben bewirken dasselbe

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 11


Technische Informatik und Programmieren
Zeiger
Zeiger und Adressen
Zeiger und Adressen
Hinweise zur Schreibweise
int* ip, x; // Schreibweise 1
int * ip, x; // Schreibweise 2
int *ip, x; // Schreibweise 3
nur ip ist ein Zeiger!
// oder besser: nur eine Variable pro Deklaration
int *ip; // Schreibweise 4
int x;

int* ip; // Schreibweise 5


int x;

• alle 5 Schreibweisen sind äquivalent!


• WICHTIG: der * bezieht sich nur auf den direkt im Anschluß folgenden
Namen!!
• TIPP: Besser jede Deklaration einzeln vornehmen (Schreibweise 4 oder 5)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 12


Technische Informatik und Programmieren
Zeiger
Zeiger und Adressen
Zeiger und Adressen
mögliche Fehlerfallen .. (nicht abschließend)
• Zeiger auf (C++) Referenzen sind nicht möglich!
int i = 99; nur C++!
int& ir = i; // Referenz auf int i
int* ip = &i; // möglich, ip zeigt auf Adresse von i
int* ip = &ir // Fehler: kein Zeiger auf Referenz

• nur initialisierte Zeiger dereferenzieren!

int* xp; // Zeiger auf xp (uninitialisiert)


*xp = -154; // Fehler!!
xp „zeigt“ an eine beliebige Adresse (Wert von xp ist zufällig
vom Compiler bestimmt..)

durch Dereferenzieren wird der Wert -154 an die beliebige Speicheradresse geschrieben
-> es kann „beliebiger“ Schaden entstehen, denn wir wissen nicht, wer die Speicheradresse
gerade verwendet -> Absturzgefahr, sog. „Speicherüberschreiber“

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 13


Technische Informatik und Programmieren
Zeiger
Zeiger und Adressen
Beispiel zur Verwendung des Dereferenzierungsoperators
float a, b, *pa;

pa = &a; // pa auf a zeigen lassen


*pa = 12; // an a den Wert 12 übergeben
*pa += 5.5; // a um 5.5 erhöhen
b = sqrt(*pa); // Wurzel von a in b ablegen

pa a

Adresse von pa Adresse von a Wert von a


== Wert von pa

&pa &a a
pa *pa

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 14


Technische Informatik und Programmieren
Zeiger
Zeigertypen
Zeigertypen
• Zeiger können für jeden Datentyp erstellt werden
// Variablen
int i; float f; char c; struct person testp;

// Zeiger auf ..
int* ip = &i; Zeiger auf float
float* fp = &f; auch für benutzerdefinierte Typen
char* cp = &c; (e.g struct, enum, etc.)
struct person* ptestp = &testp;

L-Wert / R-Wert
• L-Wert: Datenobjekt im Speicher des Rechners z.B. Variablenname oder
Zeigername (vgl. Zuweisung: linker Operand vor = muß eine Speichstelle
bezeichnen)
• R-Wert: kein L-Wert (z.B. Ausdruck x + 1)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 15


Technische Informatik und Programmieren
Zeiger
Zeigertypen
Größe eines Zeigers
• unabhängig vom Grundtyp (“Zeiger auf int”, “auf char”, “auf double” ..) belegt
jede Zeigervariable gleich viel Speicherplatz == Speicherplatzbedarf für die
Speicherung einer Adresse

• Typisch: 32 Bits (4 Byte) auf PC

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 16


Technische Informatik und Programmieren
Zeiger
Zeigertypen
Zeigertypen sog. leerer Zeiger
NULL-Zeiger zur Initialisierung von Zeigern
• ein mit NULL initialisierter Zeiger zeigt garantiert nicht auf ein (gültiges) Objekt
• NULL ist als logischer Wert abfragbar (NULL stammt aus der “C-Welt”)
• in C++: NULL wird durch eine 0 oder 0L (long) implementiert
int* iptr = 0; // Zeiger auf „nichts“
int* iptr = NULL; // Zeiger auf „nichts“
if(iptr) {..tue etwas} // Wert von ip logisch abfragbar

egal, wo iptr zuvor hingezeigt hat, nach der Anweisung zeigt er auf kein Objekt mehr!

TIPP: Zeiger auf NULL oder 0 setzen um sich zu merken,


daß der Zeiger noch nicht oder nicht mehr auf ein
gültiges Objekt zeigt

Bem.: NULL ist im Standard-Header <cstddef> oder <stddef.h> enthalten

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 17


Technische Informatik und Programmieren
Zeiger
Zeigertypen
Typprüfung von Zeigern (nur C++)
• im Gegensatz zu C wird der Typ eines Zeigers in C++ geprüft (Compiler)
char* cp; // Zeiger auf char
int* ip; // Zeiger auf int
void* vp; // Zeiger auf void (beliebiger Typ!)

vp kann auf jedes Objekt zeigen


• Typumwandlungen
vp = cp; // möglich, da vp alle Typen abdeckt
cp = vp; // Fehler! cp kann nur Typ char

// Alternative: bewußte Typumwandlung


cp = static_cast<char*>(vp); // nur in dringenden Fällen!

TIPP: Typumwandlung von Zeigern mit static_cast umgeht die Typkontrolle


des Compilers!
Bitte nur aus wichtigem Grund anwenden!!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 18


Technische Informatik und Programmieren
Zeiger
Zeigertypen
noch mehr Fehlerfallen..
Zeigerzugriff auf automatische Variablen
int i = 9;
int* ip = &i; // Zeiger ip zeigt auf i
*ip = 8; // weist i den Wert 8 zu
{
// neuer Block beginnt
int j = 7;
ip = &j; // Zeiger ip zeigt jetzt auf j
// weiterer Programmcode

} // Blockende, hier wird j ungültig!

*ip = 8; // gefährlich! (kann zum Absturz führen)

hier wird versucht über den Aliasnamen ip an j einen Wert zuzuweisen!


-> j existiert aber nicht mehr (Blockende)
-> an der Speicheradresse von früher j kann sich bereits ein anderes Objekt befinden!
-> sog. „Speicherüberschreiber“!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 19


Technische Informatik und Programmieren
Zeiger
Zeigertypen
noch mehr Fehlerfallen..
Zeigerzugriff auf automatische Variablen
• das vorhergehende Beispiel zeigt, daß die versehentliche Verwendung von
Zeigern zu Dateninkonsistenz und dadurch zum Systemabsturz führen kann

ERKENNTNIS:
• möglichst nicht mit Zeigern auf lokale Objekte zeigen, deren
Gültigkeitsbereich kleiner ist als der der Zeiger
¾ lieber Zeiger mit demselben Gültigkeitsbereich wie die Variable (Objekt),
auf den sie zeigen

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 20


Technische Informatik und Programmieren
Zeiger
Konstante Zeiger
Konstante Zeiger auf konstante Werte (Spezialität)

Variante 1: Zeiger auf konstantes Objekt (Variable)


const char* cp1; // Zeiger auf konstante Zeichen cp1

Variante 2: Konstanter Zeiger auf ein Objekt (Variable)


char* const cp2; // konstanter Zeiger auf Zeichen cp2

Variante 3: Konstanter Zeiger auf konstantes Objekt (Variable)

const char* const cp3; // konstanter Zeiger auf konstantes


// Zeichen

TIPP: Von rechts nach links lesen!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 21


Technische Informatik und Programmieren
Zeiger
Zeiger und Arrays
C-Arrays: Einführung
• primitives Äquivalent zu C++ Vektoren
• “roher” Speicherbereich
• Nutzung (eingeschränkt) wie C++ Vektoren
• Vektoren basieren auf C-Arrays

Definition:

• Anzahl_der_Elemente muß eine Konstante sein (oder Ausdruck mit


konstantem Ergebnis)
int i_table[5]; // enthält 5 Elemente von [0] – [4]
// Alternative
gutes Design: Array leicht erweiterbar!
const int n = 5;
int i_table2[n]; // o.k., weil n eine Konstante ist

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 22


Technische Informatik und Programmieren
Zeiger
Zeiger und Arrays
C-Arrays “behind the scenes”
F: Was macht der Compiler beim Anlegen von C-Arrays?
• reserviert für alle Elemente ausreichend Speicherplatz
• Anzahl der Elemente ist später nicht mehr änderbar
• tendenziell: Vorsichtshalber lieber einige Elemente mehr anlegen

int i_table[5]; // enthält 5 Elemente von [0] – [4]

ƒ Feldname == Zeiger (const) mit Startadresse des Feldes


i_table
ƒ Startadresse == Adresse des ersten Feldelementes

ƒ kann (fast) wie ein Zeiger verwendet werden

Unterschied: da der Wert des Zeigers i_table die Adresse


des ersten Elementes besitzt, bitte diesen Wert nicht ändern!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 23


Technische Informatik und Programmieren
Zeiger
Zeiger und Arrays
C-Arrays: Verwendung und Nutzung
Beispiele:
• Anlegen eines Feldes mit 10 char-Elementen (sog. Zeichenkette)

char c_array[10]; // Zeichenkette mit 10 Elementen


// Index von [0] – [9]

• Zugriff auf ein Zeichen mit Indexoperator [ ] oder Zeigerarithmetik


c_array[5] = '?'; // ? als 6. Zeichen einfügen
*(c_array + 5) = '?'; // gleichwertig: Array = roher Speicher
char c = c_array[9]; // 10. Zeichen (Element)

Vorsicht: Index beginnt bei 0!

c_array == Feldname == Startadresse 1. Element


c_array + 5 == Adresse 6. Element
*(c_array + 5) == Dereferenzierung d.h. Wert des 6. Elementes

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 24


Technische Informatik und Programmieren
Zeiger
Zeiger und Arrays
Beispiel für den Zusammenhang von C-Arrays und Zeigern
#include <stdio.h>

int a[4] = {0, 10, 20, 30}; int-Array mit 4 Elementen (Index 0 .. 3)

int main()
{
int i, *pa; Name des Arrays == Zeiger auf das 1. Array-Element

pa = a; // alternativ: pa = &a[0];

printf(“\nAdresse und Wert der Vektorelemente:\n\n“);


TRICK: liefert die Anzahl der Arrayelemente

for(i = 0; i < (sizeof(a) / sizeof(a[0])); i++)


{
printf(“Adresse: %p, Wert: %2d\n“, pa + i, *(pa + i));
}
return 0; Zeigerarithmetik
z.B. pa + 1 zeigt auf a[1]
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 25


Technische Informatik und Programmieren
Zeiger
Zeiger und Arrays
Beispiel für den Zusammenhang von C-Arrays und Zeigern
Graphische Darstellung:

Zeiger Werte Elementnamen

pa 0 a[0]
Addition von Ganzzahlen
Zeigerarithmetik:

pa + 1 10 a[1]

pa + 2 20 a[2]

pa + 3 30 a[3]

pa + 5 ungeschützter Zugriff auf nichtreservierten Speicher!!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 26


Technische Informatik und Programmieren
Zeiger
Zeiger und Arrays
Name und Adresse des C-Arrays
• sehr enger Zusammenhang zwischen Zeigern und Arrays in C/C++
• Name des Arrays == konstanter Zeiger auf das 1. Element
int a[4] = {0, 10, 20, 30};
// äquivalente Anweisungen
int* pa = a; // a entspricht der Anfangsadresse des Arrays
pa = &a[0]; // identisch mit Adresse des 1. Elements

Iterieren in Arrays (Zeigerarithmetik)


• Ganzzahlen können zu Zeigern addiert / subtrahiert werden
• Größe des Objekts auf das gezeigt wird, wird berücksichtigt!
pa -> zeigt auf a[0]
pa + 1 -> zeigt auf a[1]
pa + i -> zeigt auf a[i]
// gefährlich!
pa – 1 -> zeigt auf Adresse vor a[4]

pa + 1 d.h. Zeiger springt um sizeof(int) i.d.R. 4 Byte weiter

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 27


Technische Informatik und Programmieren
Zeiger
Zeiger und Arrays
Werte und Adressen in C-Arrays
Beispiele für äquivalente Ausdrücke:
// Adreßebene a == Zeiger auf 1. Array-Element!
&a[i] a + i pa + i

// Werteebene
a[i] *(a + i) *(pa + i) pa[i]

• Vektorschreibweise auch bei Zeigern möglich! ( pa[i] )

Interpretation durch den Compiler:


• a[i] interpretiert der Compiler als *(a + i) d.h. “Gehe von
Anfangsadresse a um i Datenobjekte weiter und nehme dort den Wert!”
• dasselbe gilt für pa[i]

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 28


Technische Informatik und Programmieren
Zeiger
Zeiger und Arrays
C-Arrays: Verwendung und Nutzung
Beispiele:
• Zeiger auf ein Feld (Array)
char c = c_array[9]; // 10. Zeichen (Element)

char* cp; // Zeiger auf char


cp = &c; // möglich
cp = c_array; // cp zeigt auf Feldbeginn d.h. *cp==c_array[0]

c_array == Feldname == Startadresse 1. Element == &c_array[0]


->*c_array == Dereferenzierung d.h. Wert des 1. Elementes

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 29


Technische Informatik und Programmieren
Zeiger
Zeiger und Arrays
C-Arrays: Verwendung und Nutzung
Beispiele:
• VORSICHT: Einschränkung bei Zeiger auf ein Feld (Array)

Ein Array ist kein Links-Wert (lvalue),


d.h. der Feldname (== Startadresse) darf nicht
auf der linken Seite einer Zuweisung stehen!

NEGATIV-Beispiel:
c_array = cp; // Fehler! c_array ist kein L-Wert (lvalue)
c_array = &c; // Fehler! c_array ist kein L-Wert (lvalue)

c_array == Feldname == Startadresse 1. Element == &c_array[0]


wenn c_array verändert wird -> wir verlieren die Startadresse des Feldes
-> das Feld ist nicht mehr „auffindbar“

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 30


Technische Informatik und Programmieren
Zeiger
Zeiger und Arrays
Zeiger vs. Arrays: Gegenüberstellung

Zeiger und Arrays sind im Gebrauch sehr ähnlich aber nicht identisch!

Zeiger:
• Zeiger hat einen Speicherplatz
• der Wert des Speicherplatzes ist ein Adresse

Array
• Array besitzt in diesem Sinne keinen Speicherplatz
• Array ist ein symbolischer Name für die Adresse (== Startadresse) eines
zusammenhängenden Speicherbereiches
• der Feldname wird syntaktisch wie ein konstanter Zeiger behandelt

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 31


Technische Informatik und Programmieren
Zeiger
Zeiger und Arrays
C-Arrays und sizeof
Problemstellung:
• C-Arrays sind als “roher” Speicher keine Objekte im bisherigen Sinn!
• es gibt keine Methoden, die verwendet werden könnten:
for(int i = 0; i < Kosten.size(); i++) // nicht bei C-Arrays!
cout << i << ": " << Kosten[i] << endl;

Wie bestimmt man die Größe eines C-Arrays?


• entweder die Größe ist vorher bekannt
• oder sie kann mit sizeof ermittelt werden
const int n = 5;
int i_table[n]; // C-Array
for(int i = 0; i < n; i++) {cout << i ": " << i_table[i] << endl;}

for(int i = 0; i < sizeof(i_table)/sizeof(i_table[0]); i++)


cout << i ": " << i_table[i] << endl;

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 32


Technische Informatik und Programmieren
Zeiger
Zeiger und Arrays
C-Arrays und sizeof
Was ist sizeof?
• sizeof( <Objekt> ) ist eine Funktion (Operator), die den Platzbedarf
des Objektes in Byte zurückliefert
sizeof(i_table) // liefert 5 * 4 Byte = 20 Byte
sizeof(i_table[0]) // liefert 1 * 4 Byte für 1. Element
sizeof(int) // liefert 1 * 4 Byte für int (32 bit)

// Trick: Größe des Feldes bestimmen durch Division


sizeof(i_table) / sizeof(i_table[0])
sizeof(i_table) / sizeof(int)

möglich, wenn klar ist, welcher Datentyp im Array verwendet wird

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 33


Technische Informatik und Programmieren
Zeiger
Zeiger und Arrays
C-Arrays und sizeof
Wann funktioniert sizeof nicht?
• C-Arrays können auch als Parameter an eine Funktion übergeben werden,
dann wird der Feldname nur noch als Zeiger interpretiert..
void Tabellenausgabe(int i_table[]) // C-Array Deklaration
{
int n = sizeof(i_table) / sizeof(int); // Fehler!
cout << „Anzahl der Elemente: „ << n << endl;
}
i_table liefert 1 * 4 Byte für die Größe des Zeigers!
int main() aber nicht 5 * 4 Byte für die Größe des Arrays
{
const int n = 5;
hier wird nur der Zeiger auf das 1. Element übergeben
int i_table[n];
-> das Array ist außerhalb des Sichtbarkeitsbereiches!

Tabellenausgabe(i_table); // leider falsch!


}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 34


Technische Informatik und Programmieren
Zeiger
Zeiger und Arrays
C-Arrays und sizeof
Wann funktioniert sizeof also?
• sizeof() funktioniert dort, wo das Array definiert wurde, d.h. wenn der
Speicher für das Array “beschafft” wird
• sobald der Sichtbarkeitsbereich der Array-Definition verlassen wird ist nur
noch der Zeiger auf das 1. Element erreichbar!

¾Innerhalb von Funktionen kann das Array nur noch als Zeiger interpretiert
werden!
void Tabellenausgabe(int i_table[5]) // C-Array Deklaration

auch die explizite Angabe der Elementanzahl nützt leider nichts!


-> trotzdem nur eine Deklaration!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 35


Technische Informatik und Programmieren
Zeiger
Zeiger und Arrays
Indexoperator [ ] bei C-Arrays
• keine Überprüfung der Grenzen d.h. keine Indexprüfung!

Was macht der Compiler?

i_table[i] == *(i_table + i)

jeder Zugriff auf ein Element über [ ] wird durch den Compiler
über Zeigerarithmetik realisiert!
i_table // zeigt auf das 1. Element i_table[0]
i_table + i // zeigt auf das Element [0] + i also i+1.Element
*(i_table + i) // enthält den Wert des i+1. Elementes

i_table[5]
0 i_table Index 4, Element 5
1 == Index i, Element (i+1)
2
3
4 i_table + 4

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 36


Technische Informatik und Programmieren
Zeiger
Zeiger und Arrays
Zeigerarithmetik bei C-Arrays
• C/C++ erlaubt arithmetische Operationen und Vergleiche mit Zeigern
Randbedingung:
• Zeiger sollen immer auf Array-Elemente zeigen!

int i = 3, anzahl;
float x, v[10], *pv;
pv = v;

Zeiger und die Operatoren ++ und -- (Inkrement/Dekrement)


• ++, -- und += bzw. -= bei Zeigervariablen erlaubt
• BEACHTE: *-Operator und ++ / -- Operatoren haben gleichen Vorrang!
*pv++ -> *(pv++) a) pv dereferenzieren d.h. *pv = v[0] (Wert!)
b) pv inkrementieren d.h. pv zeigt auf v[1] == &v[1]

++ rückt den Zeiger um 1 Element weiter! Wert des Elements, auf das der Zeiger
verweist, bleibt unverändert!
v++ od. v-- nicht erlaubt, da v eine Konstante!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 37


Technische Informatik und Programmieren
Zeiger
Zeiger und Arrays
Zeigerarithmetik bei C-Arrays
Differenz von Zeigern
• Addition von Zeigern unzulässig! (kein sinnvolles Ergebnis)
• Subtraktion zulässig!
pv = v + 3; // pv zeigt auf v[3] (4. Element)
anzahl = pv - v; // liefert Wert 3

Anzahl der Array-Elemente zwischen den beiden Zeigern!

Beispiel: Länge eines C-strings als Differenz von 2 Zeigern


int strlen(char* str) str == &str[0] (erstes Array-Element)
{ auch möglich: ( char str[ ] )
char* p;
p = str;
while(*p != ‘\0‘) String-Endezeichen suchen
++p;
return(p - str); p zeigt jetzt auf das letzte Zeichen ≠ ‘\0‘
} == vorletztes Array-Element

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 38


Technische Informatik und Programmieren
Zeiger
Zeiger und Arrays
Zeigerarithmetik bei C-Arrays
Vergleiche mit Zeigern
• Vergleiche von Zeigern gleichen Typs zulässig!
// Ausgabe der in v gespeicherten Elemente in umgekehrter
// Reihenfolge
for(pv = v + 9; pv >= v; pv--)
printf(“%10.3f“, *pv);

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 39


Technische Informatik und Programmieren
Zeiger
Zeiger und Arrays
Beispiel zur Zeigerarithmetik bei C-Arrays
float v[10], *pv, x;

pv = v + 3; // pv auf v[3] gesetzt (zeigt auf v[3] d.h. &v[3] )


pv -= 2; // pv auf v[1] zurückgesetzt
++pv; // pv auf v[2] setzen
x = *pv++; // a) v[2] an x zuweisen und
// b) dann pv ein Element weiter setzen auf v[3]
// (Postinkrement!)
x += *pv--; // a) x um v[3] erhöhen und
// b) dann pv wieder auf v[2] setzen
// (Postdekrement!)
--pv; // pv wieder auf v[1] zurücksetzen

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 40


Technische Informatik und Programmieren
Zeiger
Zeiger und Funktionen
Zeiger als Parameter von Funktionen
Motivation:
• Wertänderung an Funktionsparametern (übergebene Argumente)
• Vermeiden von Kopien der Datenobjekte (“Call by Reference”)
• Rückgabe mehrerer (Ergebnis-)Werte (ohne globale Variablen)

Beispiel: Funktion fswap() vertauscht die Werte von 2 float-Variablen


void fswap(float*, float*); // Prototyp

Zeiger als Parameter


void main()
{
float x = 5.5, y = 10.7; 2 float-Variablien (lokal in main() )
...
fswap(&x, &y);
...
Übergabe der Adressen von x und y
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 41


Technische Informatik und Programmieren
Zeiger
Zeiger und Funktionen
Zeiger als Parameter von Funktionen
void fswap(float *p1, float *p2) // Funktionsdefinition

{ Zeiger als Parameter (jetzt mit Namen)


float temp; // temporäre Hilfsvariable

temp = *p1; // *p1 enthält den Wert von x


*p1 = *p2; // *p2 enthält den Wert von y
*p2 = temp;
}

• Parameterübergabe als Zeiger (“Call by Reference”)


• fswap() ändert die Werte der übergebenen Parameter, d.h. der Orginale x
und y in der main() Funktion

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 42


Technische Informatik und Programmieren
Zeiger
Zeiger und Funktionen
Zeigerversion von Funktionen
Motivation:
• Übergabe von C-Arrays als Parameter (Argumente) an Funktionen

Beispiel: Anhängen von string 2 an string 1 (strcat)


Version 1: Indexversion Randbed.: s1-Array ist groß genug, um s2 anzuhängen!

// Hängt den string s2 an das Ende von string s1


void strcat(char s1[], char s2[])
{ s1 und s2 sind Zeiger auf die beiden Arrays
int i = 0, j = 0; alternativ: (char* s1, char* s2)

while(s1[i] != ‘\0‘) // String-Ende von s1 suchen


++i;

while( (s1[i++] = s2[j++]) != ‘\0‘) // s2 an das Ende von s1 kopieren


;
} Zuweisung der Vektorelemente
Demo VC++ .NET: \K9_Zeiger\strcat\strcat.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 43


Technische Informatik und Programmieren
Zeiger
Zeiger und Funktionen
Zeigerversion von Funktionen
Beispiel: Anhängen von string 2 an string 1 (strcat)
Version 2: Zeigerversion Randbed.: s1-Array ist groß genug, um s2 anzuhängen!
// Hängt den string s2 an das Ende von string s1
void strcat(char* s1, char* s2)
{ s1 und s2 sind Zeiger auf die beiden Arrays
int i = 0, j = 0;

while(*s1 != ‘\0‘) // String-Ende von s1 suchen


++s1;

while( (*s1++ = *s2++) != ‘\0‘) // s2 an das Ende von s1 kopieren


; Demo VC++ .NET:
} Zuweisung der Vektorelemente \K9_Zeiger\strcat\strcat.vcproj

beide Versionen führen zum gleichen Ergebnis!


ƒ Zeigerversion i.d.R. performanter (Arrayelemente werden durch „versetzte“
Zeiger angesprochen)
ƒ bei indiziertem Zugriff wandelt der Compiler zuerst in Zeiger s1[i] -> *(s1 + i)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 44


Technische Informatik und Programmieren
Zeiger
Zeiger und Funktionen
Zeiger als Returnwert von Funktionen
Motivation:
• bei größeren Datenobjekten ist es effizienter, durch die Funktion einen
Zeiger auf das Datenobjekt zurückgeben zu lassen
• z.B. C-Standardfunktionen strcat(), strcpy(), strstr()
Beispiel: Anhängen von string 2 an string 1 (strcat)
Version 3: Returnwert als Zeiger Randbed.: s1-Array ist groß genug, um s2 anzuhängen!

// Hängt den string s2 an das Ende von string s1


char* strcat(char* s1, char* s2)
{
Rückgabewert ist ein char-Zeiger

char* p;

p = s1 + strlen(s1); // p zeigt auf das Ende von s1


strcpy(p, s2); // s2 in p kopieren
return(s1); // Zeiger auf angehängten string zurückgeben
} Demo VC++ .NET: \K9_Zeiger\strcat\strcat.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 45


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
Dynamische Speicherverwaltung
Motivation:
• bei allen bislang vorgestellten Konzepten war der benötigte Speicherplatz
zum Übersetzungszeitpunkt bereits bekannt (z.B. Array mit konstanter
Anzahl von Datenelementen)
• Hintergund: verwendetes Speichermanagement (sog. automatisierte
Objektverwaltung)
Beispiel:
• (auto) Variablen werden beim Blockeintritt { .. } automatisch angelegt bzw.
beim Verlassen des Blocks automatisch gelöscht/zerstört
¾nur möglich, da Compiler Kenntnis über die Größe der Datenstruktur besitzt!
Nachteile:
• Größe einer Datenstruktur zur Laufzeit nicht änderbar (z.B. Array-Größe)
• zur Lösung vieler Programmieraufgaben ist zum Übersetzungszeitpunkt
nicht bekannt, wieviel Speicherplatz tatsächlich benötigt wird
(Suchalgorithmen, verkettete Listen, binäre Suchbäume etc.)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 46


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
Kurzübersicht: Speichermodelle
Stack-Speicherbereich (Stapel-/Kellerspeicher, kurz “stack”)
• durch das OS verwalteter Speicherbereich (LIFO-Prinzip: “last in, first out”)
• auto Variablen werden auf dem stack erzeugt/verwaltet
• Funktionen: vor Funktionseintritt werden alle lokalen Variablen im stack
gespeichert, nach Rücksprung (return) wiederhergestellt (restauriert)

Funktionsprinzip des Stapelspeichers (LIFO-Prinzip)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 47


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
Vorteile-/Nachteile des Stack-Speicherbereichs

+ Verwaltung durch OS (keine Verantwortung beim Programmierer)


+ Gültigkeits-/Sichtbarkeitsbereich und Lebensdauer durch die Definition
bestimmt (vgl. Speicherklassen, globale, lokale Variablen)
+ insgesamt unproblematischer Umgang

- Größe der Datenstrukturen “statisch”, d.h. zur Laufzeit des Programms


keine Änderung möglich
- eine dem Compiler vorgegebene Stack-Größe nicht änderbar
- HINWEIS: hoher Speicherbedarf bei rekursiven Funktionen, da alle
Parameter und lokalen Variablen auf dem Stack abgelegt werden!
- Stack-Überlauf: benötigt das Programm mehr Speicher als auf dem Stack
verfügbar -> Programm bleibt “stehen”

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 48


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
Kurzübersicht: Speichermodelle
Heap-Speicherbereich (Freispeicher oder kurz “heap”)
• zusammenhängender Speicherbereich im Arbeitsspeicher (RAM) oder
virtuellem Arbeitsspeicher (Auslagerungsspeicher sog. swapping)
• verwaltet dynamisch (zur Laufzeit) angelegte Datenstrukturen (z.B. Array-
Größe erst zur Laufzeit des Programms festlegen)
Vorteile-/Nachteile:
+ Programmierer kann Speicherinhalte (dynamisch) verwalten (Menge der
gespeicherten Daten nur abhängig von Größe des Arbeitsspeichers)
+ stark erhöhte Flexibilität!

- Verwaltung in der Verantwortung des Programmierers


- unsaubere Programmierung erzeugt z.B. “Speicherlöcher” (memory
leaks) d.h. reservierte Speicherbereiche ohne gültigen Zeiger -> häufig
nur durch Neustart des OS behebbar

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 49


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
ANSI-C
C-Programm HEAP (RAM-) Speicher

malloc()
calloc() Standard-Header <stdlib>
realloc() oder <cstdlib>
OS reserviert Speicher
free()

Startadresse

Win32 API

Funktionsprinzip:
• dynamisches Reservieren von Speicher benötigt Betriebssystemfunktionen
• ANSI-C: malloc(), calloc() und realloc() Speicherplatz reservieren,
mit free() nicht mehr benötigten Speicherplatz wieder freigeben!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 50


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
ANSI-C
Erläuterung zu den Funktionen:

// Zusammenhängenden Speicherbereich dynamisch anfordern


// (memory allocation)
void* malloc(unsigned size); benötigter Speicherbereich in Bytes

(typenloser) Zeiger/Startadresse des reservierten Speicherplatzes


(NULL falls kein Speicherplatz verfügbar)
// Speicher für mehrere Datenobjekte dynamisch reservieren
// (core allocation)
void* calloc(unsigned n, unsigned size); insgesamt n * size [Bytes] reservieren

Anzahl der Datenobjekte


// Größe des bereits reservierten Speicherplatzes verändern
void* realloc(void* ptr, unsigned size); neue Größe in Bytes
Zeiger auf bereits reservierten Speicher

// Speicherplatz freigeben
void free(void* ptr); Zeiger auf freizugebenden Speicher

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 51


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
ANSI-C
Was ist ein void* ?
• sog. typenloser Zeiger d.h. ein Zeiger auf eine Speicherstelle ohne den Typ
dafür festzulegen (ergo: kann auf alles == jedes Datenobjekt zeigen!)
• malloc(), calloc() und realloc() liefern void* zurück d.h. die Startadresse
eines zusammenhängenden Speicherbereiches, dessen Verwendung dem
Programmierer obliegt
• typisch: void* durch einen Cast in den gewünschten Typ umwandeln
// char-Array dynamisch anfordern
void* ptr; typenloser Zeiger
char* line; Zeiger auf char
ptr = malloc(20);
line = (char*)ptr;
Typumwandlung (Cast)
// oder kurz:
char* line = malloc(20);

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 52


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
Beispiel zu malloc()
Funktion getline()
• verwendet den mit malloc() reservierten Speicherbereich als char-Array
• Einlesen einer Textzeile in den statischen Puffer und anschließend in
dynamischen Speicher kopieren (Rückgabe: Zeiger auf char-Array)

/* Getline.c --> Die Funktion getline() liest eine Textzeile *


* von der Standardeingabe und kopiert sie in *
* einen zuvor reservierten Speicherbereich. *
* Das Zeilenende \n wird durch das Stringende \0 ersetzt. *
* Return-Wert: Zeiger auf die eingelesene Zeile. */

#include <stdio.h>
#include <string.h> // Fuer den Prototyp von strcpy().
#include <stdlib.h> // Fuer den Prototyp von malloc().

#define MAX 512 // Maximale Laenge einer Zeile

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 53


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
Beispiel zu malloc()
char* getline()
Textzeile zunächst in statischen Puffer einlesen
{
static char buffer[MAX], no_memory = 0;
char *line, *s, *end; Schalter: falls dynamische
int c; Speicheranforderung scheitert

if( no_memory) return NULL; // no_memory == 1 , falls im


// letzten Aufruf kein Platz.
s = buffer; Zeilenendezeichen ‘\n‘ abziehen
end = buffer + MAX - 1;
// Eine Zeile in buffer einlesen:
while(s < end && (c = getchar()) != '\n' && c != EOF)
*s++ = c;
*s = '\0'; // letztes Zeichen String-Ende

Demo VC++ .NET:\K9_Zeiger\Getline\Getline.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 54


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
Beispiel zu malloc()

if( c == EOF && s == buffer) // Falls sofort EOF,


line = NULL; // NULL zurückgeben.
else
{ // Platz reservieren:
line = malloc(s-buffer+1); // s - buffer = Anzahl
// eingegebener Zeichen.
if( line != NULL)
strcpy( line, buffer); // Zeile kopieren.
else
line = buffer, // Falls kein neuer
no_memory = 1; // Speicher verfügbar.
}
return line;
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 55


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
Freigabe von dynamisch reserviertem Speicher
Motivation:
• größere Programme müssen den verfügbaren Speicherplatz sparsam
verwalten
• daher: nicht mehr benötigter, dynamisch reservierter Speicherplatz soll
wieder freigegeben werden (d.h. wieder für andere Programme verfügbar)

Funktion free():
// char-Array dynamisch anfordern
void free(void* ptr); Zeiger auf zuvor reservierten Speicherbereich

leider kein Rückgabewert!

Was passiert, wenn Speicher nicht mit free() freigegeben wird?


• Speicherplatz bleibt reserviert bis zum Ende des Programms

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 56


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
ANSI-C++
Motivation:
• ANSI-C: Umgang mit malloc(), calloc() und realloc() ist recht umständlich
und fehlerträchtig
• ANSI-C++: einfache dynamische Speicherreservierung mit 2 zusätzlichen
Operatoren new und delete (Grundlage für Programmierung mit Klassen!)
C++ - Programm HEAP (RAM-) Speicher

Speicher anfordern
new Standard-Header
delete <cstdlib>
OS reserviert Speicher
Speicher freigeben

Startadresse

Win32 API

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 57


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
new für elementare Datentypen (int, float, double etc.)
Syntax:
// Objekt dynamisch erzeugen
ptr = new Typ; Objekt vom Typ Typ erzeugen

Zeiger auf das erzeugte Objekt vom Typ Typ

Beispiel: reserviert sizeof(long double) Bytes

// Objekt vom Typ long double dynamisch erzeugen


long double* pld = new long double; Objekt vom Typ long double erzeugen

Zeiger auf das erzeugte Objekt vom Typ long double

Beispiel: dynamische Erzeugung + Initialisierung


// Objekt vom Typ long double dynamisch erzeugen + initialisieren
long double* pld = new long double(10000.99);
cout << *pld << endl;
Inhalt der Speicherstelle ausgeben, also 10000.99

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 58


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
Beispielaufrufe von new
// Dynamische Objekte vom Typ long und double
long* ptr_long;
ptr_long = new long; // ohne Initialisierung
*ptr_long = 1234567; // Wert zuweisen

double* ptr_double;
double z = 1.9;
ptr_double = new double(z); // mit Initialisierung

++(*ptr_double); // Wert inkrementieren


*ptr_double += *ptr_long; // o.k., long-Wert hinzuaddieren

ptr_long = new double(2.7); // FEHLER: ptr_long ist kein double-Zeiger!

ptr_long 1234567 HEAP (RAM-)


ptr_double 1.9 Speicher

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 59


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
Fehlerbehandlung für new
Fehlerfall: zu wenig Speicherplatz (auf heap) verfügbar
• ein new-Handler wird aufgerufen (-> Funktion zur zentralen
Fehlerbehandlung)
• new-Handler ist standardmäßig aktiv und löst eine Exception (Ausnahme)
aus
• die Exception kann durch das Programm mit catch(..) gefangen und
behandelt werden (s.a. C++ Ausnahmebehandlung try-catch() )
• eine unbehandelte Ausnahme beendet das Programm

Hinweis: Manche ältere Compiler liefern NULL-Zeiger bei new-Aufruf zurück,


wenn zu wenig Speicherplatz verfügbar ist!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 60


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
delete für elementare Datentypen (int, float, double etc.)
Syntax:
// dynamisch erzeugtes Objekt freigeben
delete ptr; adressiert den freizugebenden Speicherplatz

Beispiel:
// Objekt vom Typ long dynamisch erzeugen + freigeben
long* pl = new long(2000000); Objekt vom Typ long erzeugen
... // mit *pl arbeiten
delete pl; Objekt vom Typ long freigeben (zerstören)

• ohne delete würde pl bis zum Programmende existieren


• delete darf NULL-Zeiger erhalten -> dann passiert nichts, vorherige Prüfung
auf NULL-Zeiger (d.h. ob das zu zerstörende Objekt noch existiert) kann
entfallen!
• delete hat keinen auswertbaren Rückgabewert (Typ void)
d.h. keine Aussage, ob Speicherplatz erfolgreich freigegeben wurde!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 61


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
Beispielprogramm für delete
// DynStd.cpp
// Die Operatoren new und delete für Standard-Typen.
// Das Programm enthält Fehler!
// ==> voher alle Daten sichern.
// ---------------------------------------------------

#include <iostream>
using namespace std;

int main()
{
cout << "\n Tests mit dynamischem Speicher!"
<< endl;

// Speicher reservieren:
double breite = 23.78; // stack-Variable
double* ptrBreite = &breite;
double* ptrLaenge = new double(32.54); // heap-Variable
double* ptrFlaeche = new double; // heap-Variable

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 62


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
Beispielprogramm für delete
// Mit ptrBreite, ptrLaenge und ptrFlaeche arbeiten

*ptrFlaeche = *ptrBreite * *ptrLaenge;

// delete ptrLaenge; // Fehler: Objekt wird noch


// benutzt!

cout << "\nBreite : " << *ptrBreite


<< "\nLänge : " << *ptrLaenge
<< "\nFläche : " << *ptrFlaeche << endl;

// Speicher freigeben:
// delete ptrBreite; // Fehler: Objekt wurde nicht
// dynamisch reserviert
delete ptrLaenge; // ok
delete ptrFlaeche; // ok

// delete ptrLaenge; // Fehler: Zeiger adressiert


// kein Objekt mehr.

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 63


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
Beispielprogramm für delete

ptrLaenge = new double(19.45); // ok

// Dynamischem Objekt einen Namen geben:


double& laenge = *ptrLaenge; // C++ Referenz

cout << "\nNeue Länge: " << laenge


<< "\nUmfang : " << 2 * breite * laenge
<< endl;

return 0; // Noch reservierter Speicher


} // wird hier freigegeben.

Demo VC++ .NET:\K9_Zeiger\DynStd\DynStd.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 64


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
Wichtige Hinweise zu delete
• falsche Verwendung von delete kann fatale Folgen haben

Regeln für delete:


• delete ptr; ptr muß einen Speicherplatz beschreiben, der zuvor mit
new (auf dem heap) angelegt wurde!
• delete darf nicht 2-mal für das gleiche Objekt aufgerufen werden
• delete darf nicht zur Freigabe von statisch reserviertem Speicherplatz
(stack-Variablen) verwendet werden

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 65


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
Dynamischer Speicher für Arrays (Vektoren)
Motivation:
• dynamisches Anlegen eines Arrays, wenn zum Übersetzungszeitpunkt die
Größe des Arrays nicht bekannt ist (sog. dynamisches Array)
• ANSI-C++: new[ ] und delete[ ] Operatoren für dynamische Arrays
Operator new[ ] HINWEIS: keine Initialisierungsliste möglich!
Syntax:
// dynamisch erzeugtes Array
vekPtr = new Typ[anzahl]; erzeugt Vektor vom Typ Typ mit anzahl Elementen
Zeiger auf das 1. Element des Vektors vom Typ Typ

Beispiel:
// dynamisch erzeugtes int-Array
int* pi = new int[256]; erzeugt int-Array mit 256 Elementen
// Speicher für pi[0] ... pi[255] reserviert Zeigerschreibweise
// Speicher für *pi, *(pi + 1), *(pi + 255) reserviert

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 66


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
Operator delete[ ]
Syntax:
// dynamisch erzeugtes Array freigeben (zerstören)
delete[] vekPtr;
Zeiger auf zuvor mit new[ ] angelegtes Array

• Klammern [ ] informiert Compiler, daß nicht nur ein einzelnes Objekt sondern
ein Array (Vektor) freizugeben ist!

Beispiel:
// dynamisch erzeugtes int-Array
int* pi = new int[256]; erzeugt int-Array mit 256 Elementen
// Speicher für pi[0] ... pi[255] reserviert
// Speicher für *pi, *(pi + 1), *(pi + 255) reserviert
delete[] pi; // korrekte Freigabe komplettes Array
delete pi; // VORSICHT: nur 1. Element wird freigegeben!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 67


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
Beispielprogramm zu new[ ] und delete[ ]
• Einlesen von Zahlen in einen dynamisch erzeugten Vektor
• nach Bedarf wird der Vektor vergößert d.h. ein neuer, größerer Vektor wird
erzeugt, die alten Daten in den neuen Vektor kopiert und der Speicherplatz für
den alten Vektor freigegeben
// DynArr.cpp
// Die Operatoren new[] und delete[] für dynamische Arrays.
// --------------------------------------------------------

#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
cout << "Einen dynamischen Array verwenden.\n" << endl;

int size = 0, anz = 0, step = 10, i;


float x, *pArr = NULL;

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 68


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
Beispielprogramm zu new[ ] und delete[ ]
cout << "Zur Berechnung Zahlen eingeben!\n"
"Ende: q oder anderer Buchstabe"
<< endl;

while(cin >> x)
{
if(anz >= size) // Vektor zu klein?
{ // => vergrößern.
float *p = new float[size + step];
// Zahlen kopieren
for(i = 0; i < size; ++i)
p[i] = pArr[i];
delete[] pArr; // Alten Vektor freigeben
pArr = p; size += step;
}
pArr[anz++] = x;
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 69


Technische Informatik und Programmieren
Zeiger
Dynamische Speicherplatzverwaltung
Beispielprogramm zu new[ ] und delete[ ]
// Mit den Zahlen arbeiten:
if(anz == 0)
cout << "Keine gültige Eingabe!" << endl;
else
{
float summe = 0.0;
cout << "Ihre Eingabe: " << endl;
for(i = 0; i < anz; i++)
{
cout << setw(10) << pArr[i];
summe += pArr[i];
}
cout << "\nMittelwert: " << summe/anz << endl;
}
delete[] pArr; // Speicher freigeben
return 0;
} Demo VC++ .NET:\K9_Zeiger\DynArr\DynArr.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 70


Technische Informatik und Programmieren
Zeiger
Zeiger und Strukturen
Zeiger und Strukturen
Motivation:
• Zeiger können auch auf benutzerdefinierte Datenobjekte z.B. Strukturen
gerichtet sein
Beispiel:
// Pointer auf struct
typedef struct Koordinate
{
int x;
int y;
} tkoord;
tkoord ko, *pko; Zeiger vom Typ der Struktur Koordinate (uninitialisiert!)
pko = &ko; pko zeigt auf Anfangsadresse der Struktur ko

// Alternative 1
(*pko).x = 17;
Zugriff auf Datenelemente der Struktur
(*pko).y = 2;

// Alternative 2
pko -> x = 17;
Zugriff auf Datenelemente der Struktur mit -> Operator
Frank
pko Artinger
-> y = 2; Informatik - ANSI C 2.0 / ANSI C++ 71
Technische Informatik und Programmieren
Zeiger
Zeiger und Strukturen
Zeiger und Strukturen
-> Operator

// Alternative 1
(*pko).x = 17;
(*pko).y = 2; unbedingt Klammern: . Operator hat sehr hohen Vorrang!

// Alternative 2
pko -> x = 17;
pko -> y = 2;

• wegen der Häufigkeit dieser Konstruktion in C/C++ wurde ein eigener


Operator -> eingeführt
• -> ermöglicht direkten Zugriff von der Adresse einer Struktur (Zeiger) auf die
Datenelemente der Struktur (in C++ Klasse!)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 72


Technische Informatik und Programmieren
Zeiger
Zeiger und Strukturen
komplexeres Beispiel zu Zeigern und Strukturen
Aufgabe:
• eine Funktion init() soll ein Array von Strukturen initialisieren
• zur Kontrolle werden in main() alle Namen ausgedruckt
• es soll die Pointer-Notation verwendet werden

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 73


Technische Informatik und Programmieren
Zeiger
Zeiger und Strukturen
komplexeres Beispiel zu Zeigern und Strukturen
// PSTRUCT.c: Zeiger und Strukturen
#include <iostream>
using namespace std;

// globale Struktur
struct Person
{
char name[30];
int jahrgang;
};

// Funktion init()
// Initialisierung des Struktur-Arrays
void init(Person *, char [], int); // Pointer : *

übernimmt einen Zeiger auf Struktur Person,


char-Array für einen Namen und int für einen Jahrgang

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 74


Technische Informatik und Programmieren
Zeiger
Zeiger und Strukturen
komplexeres Beispiel zu Zeigern und Strukturen
int main()
{
int a = 0;
Person liste[10]; // Array aus 10 Strukturen
init(&liste[a++], "Roland Meier", 1951 ); // Adresse : &liste[..]
init(&liste[a++], "Thomas Zimmer", 1956 );
init(&liste[a++], "Bea Beer", 1953 );

for(int i = 0; i < a ; ++i)


Kontrollausgabe
cout << liste[i].name << endl;

return 0;
}
void init(Person *p_liste, char name[], int jahr)
{
for(int i = 0; name[i] != '\0'; i++)
p_liste -> name[i] = name[i]; Namen in Struktur übernehmen
p_liste -> name[i] = '\0'; letztes Zeichen: String-Ende
p_liste -> jahrgang = jahr; Jahrgang in Struktur übernehmen
}
Frank Artinger Demo VC++ .NET:\K9_Zeiger\pstruct\pstruct.vcproj
Informatik - ANSI C 2.0 / ANSI C++ 75
Technische Informatik und Programmieren
Zeiger
Zeiger und Strukturen
komplexeres Beispiel zu Zeigern und Strukturen
Bildschirmausgabe:

Alternative:

void init(Person *p_liste, char name[], int jahr)


{
for(int i = 0; name[i] != '\0'; i++)
(*p_liste).name[i] = name[i];
(*p_liste).name[i] = '\0';
(*p_liste).jahrgang = jahr;
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 76


Technische Informatik und Programmieren
Zeiger
Zeiger und Strukturen
Vorrang (Präzedenz) von . und -> Operator
¾ die Operatoren . und -> haben eine sehr hohe Vorrangstufe (Stufe 1!)
¾ damit auf gleicher Stufe mit Klammern () oder [ ]
Beispiel:
struct Sam
{
int i;
int *pi;
};
int x, arr[] = { 3, 8, 4};
Sam st = { 121, &arr[0]}; // oder arr
Sam *pst; // Zeiger vom Typ der Struktur (uninitialisiert)
pst = &st;
++pst->i; // i wird inkrementiert, also auf 122

wird als ++(pst->i) interpretiert also nicht pst inkrementieren!


Alternative: ++(*pst).i

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 77


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Dynamische Datenstrukturen
Motivation: Größenänderung zur Programmlaufzeit möglich!
• dynamische Datenstruktur (z.B. einfach/doppelt verkettete Listen)
ermöglichen schnelles Einfügen und Löschen von Datenelementen

Definition Datenstruktur
• legt fest, wie Daten zu Einheiten zusammengefaßt werden, gespeichert
und bearbeitet werden
• z.B. als Vektoren, Listen, Datenringe oder (binäre) Bäume
• Wahl der Datenstruktur bestimmt: Speicherplatzbedarf, Zugriffszeit auf
Datenelemente, Komplexität der Algorithmen (== Operationen mit Daten)

Anwendungsbeispiele:
• Steuerung technischer / kaufmännischer Prozeßketten (z.B.
Automatisierung in der Fertigung oder Warenwirtschaftssysteme bzw.
Unternehmensinformationssysteme z.B. SAP R/3 etc.)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 78


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen C++
Listenelemente
Einfach verkettete Listen als Klassen!!
Definition & Eigenschaften:
• jedes Listenelement besitzt einen Informationsteil (zu speichernde Daten) und
einen Zeiger auf das nachfolgende Listenelement („verkettet“)
• jedes Listenelement besitzt genau einen Vorgänger und genau einen
Nachfolger (Ausnahme: erstes und letztes Element)
• für die verkettete Liste sind elementare Operationen definiert (z.B. Einfügen,
Löschen, Suchen und Hervorholen von Listenelementen)

Vorteile:
• Speicherbereich für die Liste muß nicht zusammenhängend sein
• Speicherplatz für Listenelement wird nach Bedarf reserviert (dynamisch)
• Einfügen, Löschen von Elementen erfolgt durch Versetzen von Zeigern

Hinweis: Einfügen/Löschen von Elementen bei Vektoren erfordert die Verschiebung einer
ganzen Gruppe von Vektorelementen, um „Platz zu schaffen“ bzw.
ein „Loch“ im Vektor zu schließen

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 79


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Funktionsprinzip einfach verketteter Listen

Element1 Element2 Element3 Element4


Inhalt A1 Inhalt A2 Inhalt A3 Inhalt A4
ANKER Inhalt B1 Inhalt B2 Inhalt B3 Inhalt B4
ptr_1 ptr_2 ptr_3 ptr_4 NULL

Einfach verkettete Liste mit 4 Elementen (+ Anker)

• Listenanfang: ANKER (Zeiger auf 1. Element)


• Element n enthält Informationsteil (Inhalt An, Bn) und Zeiger auf Element (n + 1)
• Daten eines Elements werden in einer Struktur abgelegt
• letztes Element enthält NULL-Zeiger (Listenende)

Operationen:
(1) neues Element an Liste anhängen (3) Element aus Liste löschen
(2) neues Element in Liste einfügen (4) Zugriff auf jedes Element

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 80


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Beispielprogramm zur einfach verketteten Liste
#include <iostream>
#include <cstdlib> // new und delete
using namespace std;

// Listenelement als Struktur


struct telement
{
int inhaltA; // Infoteil
int inhaltB; // Infoteil
struct telement *zeiger; // Zeiger auf struct
};

// Anker erstellen
struct telement *anker;

Demo VC++ .NET:\K9_Zeiger\Liste\Liste.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 81


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Beispielprogramm zur einfach verketteten Liste
// Operationen
// neues Listenelement an Listenende anhängen
void anhaengen(struct telement *anker, int a, int b)
{
struct telement *zgr, *hzgr;
zgr = anker;

while(zgr -> zeiger !=NULL) // letztes Element suchen


{
zgr = zgr -> zeiger;
}
hzgr = new telement; // neues Listenelement erzeugen
hzgr -> inhaltA = a; // Werte zuweisen
hzgr -> inhaltB = b; // Werte zuweisen
hzgr -> zeiger = NULL; // letztes Element
zgr -> zeiger = hzgr;
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 82


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Funktionsprinzip Operation „Listenelement anhängen“

Hilfszeiger
Element3 Element4 neues El.
ptr_neu
Inhalt A3 Inhalt A4 Inhalt A5
Inhalt B3 Inhalt B4 Inhalt B5
ptr_4 ptr_neu NULL

Adresse zuweisen

Algorithmus:
(1) letztes Element suchen (zgr)
(2) neues Element erzeugen (new) und Werte zuweisen (hzgr)
(3) Zeigervariable des neuen Elements (hzgr -> Zeiger) auf NULL setzen
(4) Zeiger des bislang letzten Elements (zgr -> Zeiger) auf hzgr setzen

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 83


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Beispielprogramm zur einfach verketteten Liste
// neues Element nach Element z einfügen
void einfuegen(struct telement *z, int a, int b )
{
struct telement *hzgr;
hzgr = new telement; // neues Element dynamisch erzeugen
hzgr -> inhaltA = a; hzgr -> inhaltB = b; // Werte zuweisen
hzgr -> zeiger = z -> zeiger; // Nachfolger des eingefügten Elements
z -> zeiger = hzgr; // Nachfolger des Vorgängerelements
// zeigt auf neu eingefügtes Element
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 84


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Funktionsprinzip Operation „Listenelement einfügen“

Element2
Aufgetrennte Verbindung Element3
Inhalt A2
Inhalt A3
Inhalt B2
Inhalt B3
ptr_neu
neues El. ptr_4
Inhalt A5
Hilfszeiger
Inhalt B5
ptr_neu
ptr_3

Algorithmus:
(1) neues Element erzeugen (new) und Werte zuweisen (hzgr)
(2) Zeigervariable des Vorgängerelementes (zgr -> Zeiger) als Zeigervariable
des neuen Elements (hzgr -> Zeiger) übernehmen: hzgr zeigt damit auf
bisherigen Nachfolger von zgr
(3) Zeigervariable von zgr aktualisieren (zgr -> Zeiger = hzgr -> Zeiger): zgr zeigt
jetzt auf neuen Nachfolger hzgr

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 85


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Beispielprogramm zur einfach verketteten Liste
// Element z löschen
void loeschen(struct telement *z)
{
struct telement *hzgr;
hzgr = anker;
while (hzgr -> zeiger != z) // Element z suchen
{
hzgr = hzgr -> zeiger;
}
hzgr -> zeiger = z -> zeiger; // Zeiger umsetzen
delete z; // Element z löschen
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 86


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Funktionsprinzip Operation „Listenelement löschen“

Element2 Neue Verbindung


Element4
Inhalt A2 überspringt Element3
Inhalt A4
Inhalt B2
Inhalt B4
ptr_4
Element3 ptr_5
Inhalt A3
Hilfszeiger
Inhalt B3
ptr_3
ptr_4

zu löschendes Element
Algorithmus:
(1) zu löschendes Element z suchen
(2) hzgr zeigt auf Vorgängerelement von z
(3) Zeigervariable des zu löschenden Elements z -> Zeiger (bisheriger
Nachfolger von z) retten und an Vorgänger (hzgr -> Zeiger) übergeben
(4) Listenelement z löschen (delete, da dynamisch erzeugt)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 87


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Beispielprogramm zur einfach verketteten Liste
// Element nach Inhalt suchen
struct telement* nav(int merkmal)
{
struct telement *hzgr;
hzgr = anker;
while((hzgr -> inhaltA != merkmal) && (hzgr -> zeiger !=NULL))
hzgr = hzgr -> zeiger;
return hzgr;
};

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 88


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Beispielprogramm zur einfach verketteten Liste
// Inhalt der Listenelemente ausgeben
void ausgabe(void)
{
struct telement *hzgr;
hzgr = anker;
do
{
cout << "Inhalt: " << hzgr -> inhaltA << "\t";
cout << hzgr ->inhaltB << endl;
hzgr = hzgr -> zeiger;
}
while (hzgr != NULL); // letztes Element (ohne Nachfolger!)
cout << "\n\n";
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 89


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Beispielprogramm zur einfach verketteten Liste
// Hauptprogramm
int main(void)
{
anker = new telement;
anker -> zeiger = NULL;
anker -> inhaltA = 11; anker -> inhaltB = 12;
ausgabe();
anhaengen(anker,3,2);
ausgabe();
einfuegen(anker,1,1);
einfuegen(anker,17,18);
ausgabe();
loeschen(nav(1));
ausgabe();
return 0;
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 90


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Beispielprogramm zur einfach verketteten Liste
Bildschirmausgabe:

Demo VC++ .NET:\K9_Zeiger\Liste\Liste.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 91


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Doppelt verkettete Listen
Erweiterung zur einfachen Verkettung:
• jedes Listenelement enthält 2 Zeiger (Vorgänger und Nachfolger)
Vorteil gegenüber einfacher Verkettung:
• Navigation durch die Liste in beide Richtungen möglich (da jedes Element
Vorgänger/Nachfolger kennt)

Funktionsprinzip doppelt verketteter Listen

Element1 Element2 Element3 Element4


Inhalt A1 Inhalt A2 Inhalt A3 Inhalt A4
ANKER Inhalt B1 Inhalt B2 Inhalt B3 Inhalt B4
ptr_1 ptr_2 ptr_3 ptr_4 NULL
NULL ptr_1 ptr_2 ptr_3
nextptr
prevptr Doppelt verkettete Liste mit 4 Elementen (+ Anker)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 92


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Funktionsprinzip doppelt verketteter Listen
• mind. 2 Zeigerfelder (nextptr, prevptr) im Listenelement
• Liste besitzt wieder einen „Anker“ (Startposition)
• 1. Listenelement: prevptr == NULL
• letztes Listenelement: nextptr == NULL

Beispiel: Struktur eines Listenelementes (doppelt verkettet)

// Listenelement als Struktur


struct telement
{
int inhaltA; // Infoteil
int inhaltB; // Infoteil
struct telement* nextptr; // Zeiger auf Nachfolger
struct telement* prevptr; // Zeiger auf Vorgänger
};

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 93


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Beispiel: Funktion einfuegen für doppelt verkettete Listen
// neues Element nach Element z einfügen
void einfuegen(struct telement *z, int a, int b )
{
struct telement *hzgr, *h1zgr;
hzgr = new telement; // neues Element dynamisch erzeugen
hzgr -> inhaltA = a; hzgr -> inhaltB = b; // Werte zuweisen
h1zgr = z -> nextptr; // Zeiger auf Nachfolger
hzgr -> nextptr = z -> nextptr; // Nachfolger in neues Element
// übernehmen
z -> nextptr = hzgr; // neues Element als Nachfolger eintragen
hzgr -> prevptr = z; // Vorgänger im neuen Element eintragen
h1zgr -> prevptr = hzgr; // neues Element im Nachfolger eintragen
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 94


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Datenringe
Erweiterung zur einfachen/doppelten Verkettung:
• Zeigervariable des letzten Listenelements enthält nicht NULL sondern zeigt auf
das 1. Listenelement (daher: geschlossener „Ring“)
Vorteil gegenüber einfacher/doppelter Verkettung:
• Datenring kann mit Schleifen (for, while, do-while durchlaufen werden)

Funktionsprinzip von Datenringen

Element1 Element2 Element3 Element4


Inhalt A1 Inhalt A2 Inhalt A3 Inhalt A4
ANKER Inhalt B1 Inhalt B2 Inhalt B3 Inhalt B4
ptr_1 ptr_2 ptr_3 ptr_4 ptr_1

Datenring (einfach verkettet) mit 4 Elementen (+ Anker)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 95


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Beispiel für einen (einfach verketteten) Datenring
#include <iostream>
#include <cstdlib> // new und delete

typedef struct telement


{ Listenelement mit 1 Zeigervariablen
char zeichen; (einfache Verkettung)
struct telement *zeiger;
};

// Anker erstellen
telement *anker;
Demo VC++ .NET:\K9_Zeiger\Ring\Ring.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 96


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Beispiel für einen (einfach verketteten) Datenring
// Operationen
// neues Element nach Element z einfügen
void einfuegen(struct telement *z, char zei)
{
telement *hzgr;
hzgr = new telement; // neues Element dynamisch erzeugen
hzgr -> zeichen = zei; // Wert zuweisen
hzgr -> zeiger = z -> zeiger; // Nachfolger des neuen Elements
z -> zeiger = hzgr; // Nachfolger des Vorgängerelements
// zeigt auf neu eingefügtes Element
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 97


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Beispiel für einen (einfach verketteten) Datenring
// Datenring ausgeben (Ring mehrfach durchlaufen)
void ausgabe(void)
{
int i;
telement *hzgr;
hzgr = anker;

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


{
cout << hzgr -> zeichen; DEMO: Ring mehrfach durchlaufen
hzgr = hzgr -> zeiger;
}
cout << "\n";
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 98


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Beispiel für einen (einfach verketteten) Datenring
int main(void)
{
char z;
int i;
anker = new telement;
anker -> zeiger =anker;
cout << "Geben Sie mindestens 9 Zeichen ein!\n";
cin >> z;
anker -> zeichen = z;
for (i = 1; i < 9; i++)
{
DEMO: 9 Zeichen eingeben
cin >> z;
einfuegen(anker,z);
};
ausgabe();
fflush(stdin);
getchar();
return 0; Demo VC++ .NET:\K9_Zeiger\Ring\Ring.vcproj
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 99


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Binäre Bäume
Motivation:
• Zugriff auf Informationen: Suche in verketteten Listen immer sequentiell
(worst case: jedes Element vergleichen -> / Laufzeit)
• wesentlich schnelleren Zugriff ermöglicht ein binärer Baum (Elemente sind
nicht linear geordnet wie bei verketteten Listen)
• vereinigt die Vorteile dynamischer Datenstrukturen mit denen sortierter
Vektoren, auf die das binäre Suchverfahren angewendet werden kann

Definition & Eigenschaften:


• binärer Baum besteht aus Knoten (nodes) -> enthalten die zu speichernde
Information
• jeder Knoten besitzt höchstens 2 direkte Nachfolger
• genau 1 Knoten ohne Vorgänger -> Wurzel (root)
• jeder Knoten ≠ Wurzel hat die Wurzel als Vorgänger

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 100


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Ein binärer Baum
Element1
Teilbaum

Element2 Element3

Element4 Element5 Element6 Element7

Element8 Element9 Element10 Element11 Element12

Nachfolgeknoten: Element10 ist Nachfolger von Element6


Blätter: Knoten ohne Nachfolgeknoten (z.B. Element5 und > Element8

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 101


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Darstellung von Knoten
• kann als verkettete Folge von Knoten implementiert werden (vgl. Listenelement)
• Knoten enthält die zu speichernde Information + 2 Zeigervariablen (linker und
rechter Nachfolger vgl. nächste Folie)
• AUSNAHME: Knoten am Baumende (Blätter) enthalten 2 NULL-Zeiger

Binärer Suchbaum
• sind die Daten im Baum nach bestimmten Regeln abgelegt, ist eine Suche sehr
effizient (Aufsteigen reduziert Ergebnismenge exponentiell)
• Sortierung (Ordnung) eines binären Suchbaums:
(1) 1. Element in Wurzel (root)
(2) jedes weitere Element mit 1. Element vergleichen: Fall „kleiner“: Vergleiche
fortführen im linken Teilbaum, Fall „größer“: Vergleiche fortführen im rechten
Teilbaum (so lange, bis es keinen Nachfolger mehr gibt)
(3) neuen Knoten als Nachfolger erstellen (== Blatt)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 102


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Binärer Baum mit 2 Ebenen (+ Anker)
WURZEL
ANKER
ptr_root Element1
Inhalt 1
ptr_2
ptr_3
Element2 Element3
Inhalt 2 Inhalt 3
ptr_4 EBENE 1 ptr_6
ptr_5 ptr_7

Element4 Element5 Element6 Element7


Inhalt 4 Inhalt 5 Inhalt 6 Inhalt 7
EBENE 2
NULL NULL NULL NULL
NULL NULL NULL NULL

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 103


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Beispiel zu binären Bäumen
Ziel des Programms:
• Textzeilen von der Standardeingabe (Tastatur) einlesen
• diese in einen binären Baum einsortieren
• lexikographisch sortiert ausgeben

Funktionen:
getline(): Textzeile einlesen, Speicherplatz dynamisch reservieren und
Zeiger auf eingelesene Zeile zurückgeben
insert(): Einsortieren der Textzeilen in binären Baum, erzeugt für jede
Zeile einen neuen Knoten und liefert Zeiger auf den Knoten
zurück
print_tree(): Inhalt des Baumes auf Bildschirm ausgeben

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 104


Technische Informatik und Programmieren
Zeiger
Dynamische Datenstrukturen
Beispiel für einen binären Suchbaum

Demo VC++ .NET:\K9_Zeiger\Sort1\Sort1.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 105


Technische Informatik und Programmieren
Zeiger
Arrays von Zeigern (Zeigervektoren)
Zeigervektoren
Motivation:
• Zeiger sind oft die einzige Möglichkeit für den einfachen/effizienten
Umgang mit großen Datenmengen (z.B. Sortieren von Strings: nicht die
Strings selbst sondern Zeiger auf Strings werden sortiert!)
• wird eine große Anzahl von Zeigern benötigt, kann ein Vektor (Array) von
Zeigern verwendet werden -> Vektor von Zeigern

Beispiele:
// Zeigervektoren
long* zahlenptr[20]; // enthält long-Zeiger
// Elemente: zahlenptr[0] .. zahlenptr[19]
char* strptr[500]; // Vektor mit 500 char-Zeigern
// Elemente: strptr[0] .. strptr[499]

Hinweis: Die Zeiger im Vektor sind uninitialisiert!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 106


Technische Informatik und Programmieren
Zeiger
Arrays von Zeigern (Zeigervektoren)
Initialisierung von Zeigervektoren
char-Zeigervektor:
char* strptr[500]; // Vektor mit 500 char-Zeigern
// Elemente: strptr[0] .. strptr[499]

// Initialisierung mit String-Konstanten


strptr[0] = “Hallo“;
strptr[1] = “Guten Tag“;

in C/C++: String-Konstante ist ein konstanter Zeiger auf das 1. Zeichen im String!

Alternative:
• Angabe einer Initialisierungsliste von String-Konstanten (s. Beispiel)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 107


Technische Informatik und Programmieren
Zeiger
Arrays von Zeigern (Zeigervektoren)
Beispiel zur Initialisierung von Zeigervektoren
/* Error_ex.c --> Die Funktion error_exit() erhaelt *
* eine Fehlernummer als Argument und *
* beendet das Programm mit einer *
* entsprechenden Fehlermeldung. */
#include <stdio.h>
#include <stdlib.h>

void error_exit(int error_nr) Speicherklasse static


{ -> nur beim 1. Aufruf initialisieren!
static char *error_msg[] = {
Initialisierungsliste
"Ungueltige Fehlernummer.\n" , (String-Konstante)
"Fehler 1: Zu viele Daten.\n" ,
"Fehler 2: Nicht genuegend Speicher.\n" ,
"Fehler 3: Keine Daten vorhanden.\n" insgesamt
}; 4 char-Zeiger
if(error_nr < 1 || error_nr > 3) error_nr = 0;
fputs(error_msg[error_nr], stderr);
exit(error_nr);
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 108


Technische Informatik und Programmieren
Zeiger
Zeiger auf Zeiger
Zeiger auf Zeiger
Motivation:
• Zeigervariablen sind selbst Datenobjekte, auf die wiederum über einen
Zeiger zugegriffen werden kann
• Anwendung: Zeigervektoren oder Übergabe von Arrays als Parameter an
Funktionen

Beispiel: Vektor von Zeigern (Zeigervektor)


char* tag[] = { “MONTAG“, “DIENSTAG“, “MITTWOCH“,
“DONNERSTAG“, “FREITAG“, “SAMSTAG“, “SONNTAG“};

// tag[i] zeigt auf i-ten String, i darf Werte von 0 .. 6 annehmen


*tag[0] // Buchstabe M aus MONTAG
*(tag[1] + 2) // Buchstabe E aus DIENSTAG

// tag ist konstanter Zeiger auf das 1. Vektorelement (also Zeiger


auf char-Zeiger)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 109


Technische Informatik und Programmieren
Zeiger
Zeiger auf Zeiger
Zeiger auf Zeiger
Beispiel: Vektor von Zeigern (Zeigervektor)

char* tag[] = { “MONTAG“, “DIENSTAG“, “MITTWOCH“,


“DONNERSTAG“, “FREITAG“, “SAMSTAG“, “SONNTAG“};

// äquivalente Ausdrücke:

*tag tag[0] // 0-ter Zeiger


*(tag + i) tag[i] // i-ter Zeiger
**(tag + i) *tag[i] // 0-tes Zeichen im i-ten String
*(*(tag+i)+j) *(tag[i]+j) // j-tes Zeichen im i-ten String

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 110


Technische Informatik und Programmieren
Zeiger
Zeiger auf Zeiger
Beispiel zu Zeiger auf Zeiger
Ziel:
• mehrere Wörter unterschiedlicher Länge speichern

Lösungsansatz:
• Array mit char-Zeigern
• jeder char-Zeiger zeigt auf ein char-Array, das ein Wort enthält

Vorteile:
• die char-Arrays müßen nur so lange sein, wie für das Wort notwendig
• werden alle Arrays dynamisch angelegt, kann die Datenstruktur beliebig
erweitert werden (Voraussetzung: genügend Hauptspeicher verfügbar)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 111


Technische Informatik und Programmieren
Zeiger
Zeiger auf Zeiger
Funktionsprinzip des Zeigervektors aus char-Arrays
char** aptr
Zeiger-Array T|O|K|I|O
wptr_1
A|N|K|A|R|A
wptr_2
wptr_3
S|O|F|I|A R|O|M
wptr_4
B|E|R|L|I|N wptr_5

Ausdruck Wert
*aptr wptr_1
*wptr_1 ‘A‘
*(*aptr) ‘A‘
*((*aptr)+1) ‘N‘
*((*aptr)+2) ‘K‘
*(*(aptr+1)) ‘T‘
*(*(aptr+3)) ‘R‘
*(*(aptr+3)+1) ‘O‘

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 112


Technische Informatik und Programmieren
Zeiger
Zeiger auf Zeiger
Code-Beispiel zu Zeiger auf Zeiger
#include <iostream>
#include <cstdlib> // new, delete
using namespace std;

int main (void)


{
char wptr1[] = "ANKARA" ;
char wptr2[] = "TOKIO" ;
char wptr3[] = "SOFIA" ;
char wptr4[] = "ROM" ;
char wptr5[] = "BONN" ;

char **aptr;
aptr = new char*[5];
*aptr = wptr1; /* Ablegen der Zeiger. */
*(aptr+1) = wptr2;
*(aptr+2) = wptr3;
*(aptr+3) = wptr4;
*(aptr+4) = wptr5;
Demo VC++ .NET:\K9_Zeiger\Scrable\Scrable.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 113


Technische Informatik und Programmieren
Zeiger
Zeiger auf Zeiger
Code-Beispiel zu Zeiger auf Zeiger
cout << "wptr1: \t\t" << *wptr1 << endl;
cout << "**aptr: \t" << **aptr << endl;
cout << "*(*aptr+1):\t" << *(*aptr+1) << endl;
cout << "*(*aptr+2):\t" << *(*aptr+2) << endl;
cout << "**(aptr+1):\t" << **(aptr+1) << endl;
cout << "**(aptr+3):\t" << **(aptr+3) << endl;
cout << "*(*(aptr+3)+1):\t" << *(*(aptr+3)+1) << endl;
delete[] aptr;
return 0;
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 114


Technische Informatik und Programmieren
Zeiger
Argumente aus der Kommandozeile
Argumente aus der Kommandozeile (Argumente für ein Programm)
Motivation:
• Verhalten eines Programmes soll beim Start gesteuert werden oder
• Beim Start sollen zu verarbeitende Dateien angegeben werde z.B.
// Start der Applikation copy durch
// Eingabe in der Kommandozeile (DOS-Box)
copy datei1 datei2

Kommandozeilenparameter (getrennt durch Zwischenraumzeichen, whitespaces)

Lösung:
• Neben dem Programmnamen können dem Programm weitere Parameter
(Argumente) in der Kommandozeile übergeben werden

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 115


Technische Informatik und Programmieren
Zeiger
Argumente aus der Kommandozeile
Argumente aus der Kommandozeile (Argumente für ein Programm)
Parameter der main()-Funktion
• um die Argumente in der Kommandozeile zu verarbeiten, muss main() mit
Parametern definiert werden
int main( int argc, char* argv[] )
{ // Funktionsblock }

Argument argc
• enthält die Anzahl der Argumente, die über die Kommandozeile an das
Programm übergeben werden
• mindestens wird der Programmname übergeben, d.h. argc hat immer
mind. den Wert 1

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 116


Technische Informatik und Programmieren
Zeiger
Argumente aus der Kommandozeile
Argumente aus der Kommandozeile (Argumente für ein Programm)
Parameter der main()-Funktion
int main( int argc, char* argv[] )
{ // Funktionsblock } Vektor mit char-Zeigern
== Array mit null-terminierten Strings

Argument argv
argv[0] zeigt auf den Programmnamen (inkl. Pfad)
argv[1] zeigt auf das erste eigentliche Argument (also das erste Wort
hinter dem Programmnamen)
argv[2] zeigt auf das zweite Argument
...
argv[argc-1] zeigt auf das letzte Argument
argv[argc] ist der NULL-Zeiger

HINWEIS: Üblicherweise werden die Parameternamen argc, argv verwendet,


prinzipiell können aber auch beliebige andere Namen gewählt werden.

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 117


Technische Informatik und Programmieren
Zeiger
Argumente aus der Kommandozeile
Beispiel für die Verarbeitung von Kommandozeilenargumenten
// gruss.cpp
// Demo-Programm für Argumente aus der Kommandozeile.
// Aufruf: gruss name1 name2
// ----------------------------------------------------
#include <iostream>
using namespace std;

int main( int argc, char *argv[])


{
if( argc != 3 ) Aufruf mit weniger als 2 Argumenten
{
cerr << "Benutzung: gruss name1 name2" << endl;
return 1;
1. übergebenes Argument
}
cout << "Hallo " << argv[1] << '!' << endl;

2. übergebenes Argument
cout << "Herzliche Grüsse\n"
"\tDeine " << argv[2] << endl;

return 0;
Frank
} Artinger Demo VC++ .NET:\K9_Zeiger\gruss\gruss.vcproj
Informatik - ANSI C 2.0 / ANSI C++ 118
Technische Informatik und Programmieren
Zeiger
Argumente aus der Kommandozeile
Beispiel für die Verarbeitung von Kommandozeilenargumenten
Beispielaufruf des Programmes gruss.exe:
gruss Andrea Peter
gruss.exe Andrea Peter

argv[1] argv[2]

Bildschirmausgabe:

Vektor argv im Speicher:

char** argv argv[0] ″f:\..\GRUSS.EXE″


argv[1] ″Andrea″
argv[2] ″Peter″
argv[3] NULL-Zeiger (terminiert)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 119


Technische Informatik und Programmieren
Zeiger
Argumente aus der Kommandozeile
Beispiel für die Verarbeitung von Kommandozeilenargumenten
Hinweis für Kommandozeilenparameter in VisualStudio .NET:

Definition und Übergabe von


Kommandozeilenparametern beim
Starten in der Debug-Umgebung

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 120


Technische Informatik und Programmieren
Zeiger
Zeiger auf Funktionen
Zeiger auf Funktionen
Motivation:
• Name einer Funktion == konstanter Zeiger auf die Funktion (vgl. Arrays,
Vektoren)
• Zeiger auf die Funktion adressiert den Maschinencode der Funktion

Anwendung:
• Sprungtabelle: Zeiger auf Funktionen in einem Array/Vektor speichern
• Funktionsaufruf kann dann per Index erfolgen
• -> wird vor allem in der OO-Programmierung (Vererbung) verwendet!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 121


Technische Informatik und Programmieren
Zeiger
Zeiger auf Funktionen
Zeiger auf Funktionen
Beispiel:

// Zeiger auf Funktion


int add(int z1, int z2)
{
Funktion
return(z1 + z2);
}

int main()
{
int erg; erzeugt eine Variable vom Typ Funktionszeiger
int (*ptradd)(int, int); // Funktionszeiger definieren
ptradd = add; // jetzt zeigt ptradd auf die Fkt. add()
erg = ptradd(45,55); // Funktionsaufruf über Zeiger

• ptradd speichert die Adresse der Funktion add()


• Datentyp von ptradd entspricht dem Rückgabewert von add() -> int
• in Klammern ( .. ) folgt die Parameterliste der Funktion add()

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 122


Technische Informatik und Programmieren
Zeiger
Zeiger auf Funktionen
Zeiger auf Funktionen
Syntax:
// Zeiger auf Funktion
Typ (*funcptr) (Parameterliste);

Parameterliste (Argumente) der Funktion


Name des Funktionszeigers (in Klammern einschließen!!)

Typ des Funktionszeigers


== Rückgabetyp der Funktion

Adresse der Funktion an Funktionszeiger zuweisen:


// entweder
funcptr = func;
Adresse der Funktion == Funktionsname
// oder
(Adreßoperator & ebenfalls möglich)
funcptr = &func;

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 123


Technische Informatik und Programmieren
Zeiger
Zeiger auf Funktionen
Zeiger auf Funktionen
Aufruf der Funktion über den Funktionszeiger:
// Funktion über Zeiger aufrufen
int FktZeichenCode(char c)
{
return (int) c;
}
int main()
{
int ergebnis;
int (*ptrzeichencode)(char);
ptrzeichencode = FktZeichenCode;
ergebnis = (*ptrzeichencode)(‘C‘); // Aufruf über Fkt.-Zeiger
ergebnis = ptrzeichencode(‘C‘); // Aufruf über Fkt.-Zeiger

return 0;
Aufruf über Funktionszeiger == normaler Funktionsaufruf
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 124


Technische Informatik und Programmieren
Zeiger
Zeiger auf Funktionen
Beispiel für Funktionszeiger: Sprungtabelle
• Sprungtabelle: Array von Funktionszeigern
• Funktionsaufruf erfolgt über den Array-Index
• per Zeigerarithmetik können weitere Funktionen aufgerufen werden

Vorteile:
• sehr performant, benötigt sehr wenig Speicherplatz (z.B. 4 Byte für den
Funktionszeiger)
• von anderen Programmodulen aus zugreifbar (Software-Schnittstelle)

Betrachten wir eine erläuternde Skizze..

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 125


Technische Informatik und Programmieren
Zeiger
Zeiger auf Funktionen
Funktionsprinzip einer Sprungtabelle

Funktionszeiger verweist
auf die Speicherstelle
der Funktion

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 126


Technische Informatik und Programmieren
Zeiger
Zeiger auf Funktionen
Beispiel für eine Sprungtabelle
#include <stdio.h>

int add(int z1, int z2)


{
return (z1+z2);
}

int sub(int z1, int z2)


{ Funktionen definieren
return (z1-z2);
}

int mul( int z1, int z2 )


{
return (z1*z2);
}
Demo VC++ .NET:\K9_Zeiger\Schnitt\Schnitt.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 127


Technische Informatik und Programmieren
Zeiger
Zeiger auf Funktionen
Beispiel für eine Sprungtabelle
int main (void)
{ Speicheradressen: ganzzahlig vom Typ int (32 bit = 4 Byte)
int i;
int a[3]; // Sprungtabelle als int-Array mit 3 Elementen
int (*zeiger)(int,int); // Funktionszeiger vom Typ der 3 Funktionen
int erg;
a[0] = add; // Element 1 erhält Zeiger auf Funktion add()
a[1] = sub; // Element 2 erhält Zeiger auf Funktion sub()
a[1] = mul; // TRICK: Umbiegen des Zeigers auf eine andere Funktion
// a[2] = mul;
for(i = 0 ; i < 3 ; i++)
{ per Index Funktionszeiger verschieben
zeiger = a[i]; // Array-Element dem Funktionszeiger zuweisen
erg = zeiger(5, 6); // Funktionsaufruf über Zeiger
printf( "Das Ergebnis ist: %d\n ", erg );
};
return 0;
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 128


Technische Informatik und Programmieren
Zeiger
Zeiger auf Strings
Zeiger auf Strings (ANSI-C)
Motivation:
• Zeichenketten werden in C-Strings (also char-Arrays) gespeichert -> ANSI-C
bietet keinen eigenen Datentyp (ANSI-C++: Datentyp/Klasse string)
• C-Strings besitzen einige erwähnenswerte Besonderheiten

Besonderheiten von C-Strings:


• C-Strings werden immer durch eine terminierende NULL \0 (Wert 0)
abgeschlossen (sog. String-Endezeichen) H | A | L | L | O | \0

• C-Strings können unmittelbar auf dem heap angelegt werden, eine


Zeichenkette wird bei der Definition sofort zugewiesen

// C-Strings erzeugen
char* Zeichenkette = “Guten Tag“; // Speicher für 10 Zeichen wird
// automatisch reserviert

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 129


Technische Informatik und Programmieren
Zeiger
Zeiger auf Strings
Zeiger auf Strings (ANSI-C)
Alternative: Erzeugung mit new[ ] (oder malloc() )
// C-Strings dynamisch erzeugen
char *zkette, *teil;
zkette = new char[80];
(*zkette + 79) = ‘\0‘; // letztes Zeichen String-Ende
(*zkette + 1) = ‘A‘; // auf 2.Element == 2. Zeichen zugreifen
teil = zkette + 68; // Zeichenkette teil enthält die letzten 11
// Zeichen von zkette

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 130


Technische Informatik und Programmieren
Zeiger
Zeiger auf Strings
Einlesen von Strings (ANSI-C)
Funktion gets():
• mit getchar() können nur einzelne Zeichen (unformatiert) eingelesen
werden
• mit gets() kann eine Zeichenkette übernommen werden
// C-Strings von Tastatur in dynamisch erzeugtes Array einlesen
#include <stdio.h> // für gets()
#include <cstdlib> // für new, delete
int main()
{
char* zeichenkette;
zeichenkette = new char[80];
gets(zeichenkette); liefert char-Zeiger zurück
delete[] zeichenkette; C-String wird mit \0 abgeschlossen

return 0;
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 131


Technische Informatik und Programmieren
Zeiger
Zeiger auf Strings
Einlesen von Strings (ANSI-C)
Funktion gets():
• mit getchar() können nur einzelne Zeichen (unformatiert) eingelesen
werden
• mit gets() kann eine Zeichenkette übernommen werden
// C-Strings von Tastatur in statisches Array einlesen
#include <stdio.h> // für gets()

int main()
{
char* zeichenkette;
char kette[80]; // statisches char-Array (stack)
zeichenkette = kette;
gets(zeichenkette); liefert char-Zeiger zurück
C-String wird mit \0 abgeschlossen
return 0;
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 132


Technische Informatik und Programmieren
Zeiger
Zeiger auf Strings
Ausgeben von Strings (ANSI-C)
Funktion puts():
• mit putchar() können nur einzelne Zeichen (unformatiert) ausgegeben
werden
• mit puts() kann eine Zeichenkette ausgegeben werden
// C-Strings auf dem Bildschirm ausgeben
#include <stdio.h> // für putchar() und puts()

int main()
{
int i = 0;
char zeichenkette[] = “Hallo!“; // statisches char-Array (stack)
while(zeichenkette[i])
putchar(zeichenkette[i++]); // entweder Zeichen für Zeichen

puts(zeichenkette); // oder kompletten C-String

return 0; liefert 0 falls fehlerfrei od. EOF im Fehlerfall


} \0 Zeichen wird nicht ausgegeben

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 133


Technische Informatik und Programmieren
Zeiger
Übung
Vorlesungsbegleitende Übung
(1) Das u.a. Programm enthält mehrere syntaktische Fehler. Korrigieren Sie
die Fehler und testen Sie die Lauffähigkeit des Programms!

#include <stdio.h>
void main(void)
{
char* satz = Das Zukünftige ist viel zu unbestimmt,
char* zeiger;
*zeiger = “um als präzise Handlungsmaxime zu dienen.“;
puts(*satz);
puts(zeiger);
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 134


Technische Informatik und Programmieren
Zeiger
Übung
Vorlesungsbegleitende Übung
(2) Erstellen Sie ein C-Programm, das nacheinander die folgenden
Zeichenkettenkonstanten auf dem Bildschirm ausgibt:
Eine Meinungsumfrage unter Löwen ergab:
Die Mehrheit lehnt den Käfig ab,
wünscht jedoch eine geregelte Verpflegung!
Geben Sie den Text über die Tastatur ein. Beachten Sie bei der
Ausgabe den Zeilenumbruch nach jeder Zeile. Die Speicherung der
Strings erfolgt in Zeigern und der benötigte Speicher wird dynamisch
verwaltet.
(3) Schreiben Sie eine Unterfunktion, die einen Zeiger auf einen Teilstring
eines Strings zurückgibt. Als Parameter werden ein Zeiger auf den
String, die Position des Buchstabens mit dem der Teilstring beginnt und
die Anzahl der Buchstaben übergeben.
char* SubString(char* s, int pos, int count) // Prototyp

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 135


Technische Informatik und Programmieren
Zeiger
Übung
Vorlesungsbegleitende Übung
(4) Erzeugen Sie dynamisch ein 2-dimensionales Feld über einen Zeiger.
Geben Sie dazu 2 Zahlen über die Tastatur ein und verwenden Sie diese
für die Dimension des Arrays. Speichern Sie in das Array beliebige
Zahlen vom Typ int und geben Sie diese auf dem Bildschirm
aus.
(5) Erzeugen Sie eine Sprungtabelle, die 3 Startadressen von Funktionen
zur Codierung von Buchstaben enthält. Schreiben Sie eine weitere
Funktion, der ein Zeichen und ein Index zur Funktionsauswahl
übergeben werden. Die Funktionsauswahl wird durch Addition des Index
zum Zeiger (der auf den Anfang der Sprungtabelle zeigt) realisiert. Sie
erhalten einen Zeiger auf die gewünschte Funktion, die jetzt aufgerufen
wird.

Testen Sie die Konstruktion in einem Programm, das den codierten


Buchstaben auf dem Bildschirm ausgibt.

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 136


Technische Informatik und Programmieren
Zeiger
Übung
Vorlesungsbegleitende Übung
Hinweis: Als Codierverfahren können Sie den aktuellen ASCII-Code des
Buchstabens um einen konstanten Wert verschieben. Bei einer Schrittweite
von 1 wird z.B. aus dem Buchstaben A der Buchstabe B (65 => 66).
Eine zweite Möglichkeit besteht in der Exclusiv-Oder-Verknüpfung des
ASCII-Codes des Buchstabens mit einem konstanten Zahlenwert (für alle
Codierungen der gleiche Zahlenwert). Der Vorteil dieses Verfahrens liegt in
der Zurückgewinnung des ursprünglichen Zeichens bei der zweimaligen
Ausführung der Codierung.
Die dritte Möglichkeit für die Codierung besteht darin, daß der Zahlenbereich
der Buchstaben im ASCII-Code in der Mitte geteilt wird und der ASCII-Code
den durch die Spiegelung zugeordneten Buchstaben darstellt. Aus dem
Buchstaben A wird so der Buchstabe Z, aus dem Buchstaben B wird der
Buchstabe Y und umgekehrt. Diese Codierverfahren stellen nur eine
Anregung dar und können durch andere sichere Verfahren ersetzt werden.

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 137


Technische Informatik und Programmieren
Zeiger
Übung
Vorlesungsbegleitende Übung
(6) Schreiben Sie eine Funktion, die einen String in eine Zahl vom Typ int
umwandelt. Der im Parameter übergebene String enthält Ziffern, die eine
vorzeichenlose (positive) Zahl darstellen. Der Funktion wird ein Zeiger
auf ein Array vom Typ char übergeben. Die Zahl ergibt sich aus den
Ziffern des Strings.

(7) Der Vektor v sei wie folgt definiert:

int v[] = { 10, 20, 30, 40 }, i, *pv;

Was geben die folgenden Anweisungen auf dem Bildschirm aus?

a) for( pv = v; pv <= v + 3; pv++ )


cout << ″ *pv = ″ << *pv;

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 138


Technische Informatik und Programmieren
Zeiger
Übung
Vorlesungsbegleitende Übung
zu (7)
b) for( pv = v, i = 1; i <= 3; i++ )
cout << ″ pv[i] = ″ << pv[i];

c) for( pv = v, i = 0; pv + i <= &v[3]; pv++,i++ )


cout << ″ *(pv + i) = ″ << *(pv + i);

d) for( pv = v + 3; pv >= v; --pv )


cout << ″ v[″ << (pv - v) << ″] = ″
<< v[pv - v];

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 139


Technische Informatik und Programmieren
Zeiger
Übung
Vorlesungsbegleitende Übung
(8) Schreiben Sie ein Programm, das eine Zeile zeichenweise mit der cin-
Methode get() in einen char-Vektor einliest. Anschließend wird die
Zeile in umgekehrter Reihenfolge ausgegeben. Verwenden Sie einen
Zeiger, keinen Index, um die Elemente des Vektors anzusprechen.

HINWEIS: Geben Sie für den char-Vektor eine feste Größe vor
(z.B. 80).

(9) Schreiben Sie ein Programm, das seinen Programmnamen und alle
Argumente auf der Kommandozeile untereinander ausgibt.

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 140


Technische Informatik und Programmieren
Zeiger
Übung
Vorlesungsbegleitende Übung
(10) Untenstehend finden Sie das Filterprogramm suche1, das alle Zeilen
mit Zeilennummer ausgibt, die das Suchmuster ″ei″ enthalten.

// suche1.cpp
// Ein Filter, der alle Zeilen mit einem bestimmmten
// Muster ausgibt. Verwendet die Funktion strstr().
//
// Aufruf: suche1 [ < text.dat ]
// Ohne Angabe einer Datei wird von der Tastatur gelesen.
// In diesem Fall die Eingabe mit <Strg> + <Z> beenden.
// ------------------------------------------------------
#include <iostream>
using namespace std;
#define MAXL 200 // Maximale Zeilenlänge

namespace MyScope
{ // Eigene Version der Funktion strstr():
char *strstr( const char *str, const char *muster);
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 141


Technische Informatik und Programmieren
Zeiger
Übung
Vorlesungsbegleitende Übung
zu (10)
char zeile[500], // Für eine Zeile Text
muster[] = "ei"; // Das Suchmuster

int main()
{
int zeilenNr = 0;
// Solange noch eine Zeile da ist:
while( cin.getline( zeile, MAXL))
{
++zeilenNr;
if( MyScope::strstr( zeile, muster) != NULL)
{ // Falls Muster gefunden:
cout.width(3);
cout << zeilenNr << ": " // Zeilennr. und
<< zeile << endl; // Zeile ausgeben
}
}
return 0; Demo VC++ .NET:\K9_Zeiger\suche1\suche1.vcproj
}
Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 142
Technische Informatik und Programmieren
Zeiger
Übung
Vorlesungsbegleitende Übung
zu (10) Machen Sie das Programm zu einem nützlichen Programm suche,
dem in der Kommandozeile ein beliebiges Suchmuster übergeben
werden kann. Wird in der Kommandozeile kein Suchmuster angegeben,
soll sich das Programm mit einer Fehlermeldung beenden. Verwenden
Sie die Standardfunktion strstr() (enthalten in der Header-Datei
<cstring> mit Standardfunktion für Strings).

Beispielaufruf:

suche Karlsruhe < nachrichten.txt

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 143


Technische Informatik und Programmieren
Programmstrukturierung
Orientierung
Einleitung
Das erste Programm in C
Konstanten
ORIENTIERUNG
Einfache Datentypen
Unterprogramm – Technik –
Nützliche Funktionen
Steuerstrukturen
Typvereinbarungen von Variablen
Zeiger
Der Präcompiler
Modulare Programmierung
Entwicklungsumgebungen
Standardbibliotheken
Anhang

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 1


Technische Informatik und Programmieren
Programmstrukturierung
Ziele

¾ Wie können große C++ Programme durch Funktionen in


übersichtliche Teile zerlegt werden?
¾ Was versteht man unter „Überladen einer Funktion“?
¾ Wie kann Quelltext auf mehrere Dateien verteilt werden?
¾ Was ist eine Übersetzungseinheit?
ZIELE

¾ Was passiert eigentlich bei der Übersetzung?


¾ Wie komme ich zum ausführbaren Programm?
¾ Was sind inline-Funktionen? Wann sollten man sie
verwenden?

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 2


Technische Informatik und Programmieren
Programmstrukturierung
Inhalt
Programmstrukturierung
Einleitung
Funktionen
Funktionsprototypen und Funktionsdefinition
Gültigkeit und Sichtbarkeit
Datenschnittstelle: Übergabe per Wert / per Referenz
INHALT

Vorgabewerte und variable Parameteranzahl


Überladen von Funktionen
Die main() Funktion
Grundsätze der modularen Gestaltung
3 Schritte zum Programm
Präprozessor (Dateien einbinden, Konstanten, bedingte Compilierung)
Aufteilung in Source- und Header Files
Dateiübergreifende Gültigkeit und Sichtbarkeit
Übersetzungseinheit, Deklaration und Definition
Template-Funktionen
inline-Funktionen

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 3


Technische Informatik und Programmieren
Programmstrukturierung
Einleitung
Einleitung
• C++-Programme können sehr umfangreich werden -> Zerlegung in
übersichtliche Teile ist sinnvoll (“divide et impera”, teile und herrsche)

¾Teilaufgaben an Funktionen delegieren


¾zusammengehörige Teilaufgaben in Module aufteilen

• nicht jede Lösung muß neu gefunden werden -> Wiederverwendung von
bereits existentem Code (z.B. Einbindung von Bibliotheken)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 4


Technische Informatik und Programmieren
Programmstrukturierung
Funktionen

Funktionen
• Zweck: Erledigung einer abgeschlossenen Teilaufgabe
• Funktionen sind das Zentrum der Prozeduralen Programmierung in C++
• In Form von Methoden auch der Objektorientierten Programmierung!
Aufbau und Prototypen
#include <iostream>
using namespace std;

unsigned long Fakultaet(int); // Funktionsprototyp (Deklaration)

int main() {
int n;
do {
cout << "Fakultaet berechnen. Zahl >=0:";
cin >> n;
} while(n < 0);

cout << "Ergebnis ist " << Fakultaet(n) << endl; // Aufruf

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 5


Technische Informatik und Programmieren
Programmstrukturierung
Funktionen
// alternativ mit Zwischenablage des Ergebnisses:
unsigned long Erg = Fakultaet(n); // Aufruf
cout << "Ergebnis ist " << Erg << endl;
}

// Funktionsimplementation (Definition)
unsigned long Fakultaet(int zahl)
{
unsigned long fak = 1;
for(int i = 2; i <= zahl; i++)
fak = fak * i;
return fak; // notwendig wegen Rückgabewert
}

Demo VC++ .NET:\K1011_Prog_struct\fakulta2\fakulta2.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 6


Technische Informatik und Programmieren
Programmstrukturierung
Funktionen
Deklaration:
Beschreibung/Hinweis für den Compiler, daß eine Funktion (oder
Variable, Objekt) irgendwo definiert ist. Er ist damit in der Lage, eine
Syntaxprüfung vorzunehmen.

Definition:
veranlaßt den Compiler, Speicherplatz zu reservieren und
Programmcode zu erzeugen

Funktionsprototyp:
Funktionsdeklaration ohne gleichzeitige Definition

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 7


Technische Informatik und Programmieren
Programmstrukturierung
Funktionen - Funktionsprototypen
Syntax eines Funktionsprototypen

Rückgabetyp: beliebig, aber kein Array, keine Funktion (aber Zeiger)

..in unserem Beispiel..


unsigned long Fakultaet ( int n );

Rückgabetyp Funktionsname ( Parameterliste )

Alternativen:
leere Liste int func(); Ù int func(void);
Liste Paramtertypen int func(int, char);
inkl.Parameternamen int func(int x, char y);

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 8


Technische Informatik und Programmieren
Programmstrukturierung
Funktionen - Funktionsdefinition
Syntax der Funktionsdefinition

..in unserem Beispiel..


unsigned long Fakultaet ( int zahl ){ .. }

Rückgabetyp Funktionsname (Formalparameterliste) Block

Syntax des Funktionsaufrufs Argument(e)

Compiler: prüft Syntax (z.B. stimmt der Datentyp des Argumentes?)


Linker: prüft, ob eine Definition vorhanden ist (paßt diese auch?)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 9


Technische Informatik und Programmieren
Programmstrukturierung
Funktionen - Funktionsdefinition
Hinweise:
• Formalparameter in der Fkt.-Definition sind Platzhalter, sie werden nur
innerhalb der Definition { Block } verwendet

• beim Fkt.-Aufruf wird der Platzhalter durch den Aktualparameter


(Argument) ersetzt

• Prinzip der Ersetzung ist eine wichtige Voraussetzung für die universelle
Verwendung der Funktionen (z.B. Fakultaet(zahl),
Fakultaet(xyz) etc., Hauptsache der Datentyp stimmt überein)

• mit return wird das Ergebnis der Funktion an den Aufrufer


zurückgegeben

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 10


Technische Informatik und Programmieren
Programmstrukturierung
Funktionen – Gültigkeit und Sichtbarkeit
Gültigkeitsbereiche und Sichtbarkeit in Funktionen

¾ Im Code-Block: Gültigkeit/Sichtbarkeit wie für Variablen


¾ Ausnahme: Parameterliste

Parameterliste
• wirkt nach innen wie eine lokale Deklaration von Variablen
• stellt nach außen die Datenschnittstelle dar

Fakultaet

Datenschnitt-
stelle zahl lokal

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 11


Technische Informatik und Programmieren
Programmstrukturierung
Funktionen – Gültigkeit und Sichtbarkeit
zum Beispiel ein Beispiel:
#include <iostream>
using namespace std;

int a = 1; // global, überall in Datei bekannt!

void f1() {
int c = 3; // lokal, nur in f1() bekannt!
cout << "f1: c=" << c << endl;
cout << "f1: globales a= " << a << endl;
}

int main() {
cout << "main: globales a= " << a << endl;
// f1: c ist in main nicht bekannt!
f1();
}
Demo VC++ .NET:\K1011_Prog_struct\scope\scope.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 12


Technische Informatik und Programmieren
Programmstrukturierung
Funktionen – Gültigkeit und Sichtbarkeit
Beispiel für static Variable (“Gedächtnis der Funktion”):
• static-Variablen erhalten einen festen Speicherplatz
• einmalige Initialisierung beim ersten Funktionsaufruf
#include <iostream>
using namespace std;

void func() {
// zählt die Anzahl der Aufrufe
static int anz = 0; // 0 bei static nicht notwendig
cout << "Anzahl = " << ++anz << endl;
}

int main() {
for(int i = 0; i < 3; i++)
func();
}

Ausgabe: Anzahl = 1 Anzahl = 2 Anzahl = 3

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 13


Technische Informatik und Programmieren
Programmstrukturierung
Funktionen – Schnittstellen zum Datentransfer
Schnittstellen zum Datentransfer

Schnittstelle:
Formale Vereinbarung zwischen Aufrufer und Funktion über:
¾ Art und Weise des Datentransports
¾ Leistung der Funktion

Eindeutige Beschreibung durch Funktionsprototyp:


• Rückgabetyp der Funktion
• Funktionsnamen
• Übergabeparameter
• Art der Parameterübergabe

Arten des Datentransports:


¾ Übergabe per Wert (by value)
¾ Übergabe per Referenz (by reference)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 14


Technische Informatik und Programmieren
Programmstrukturierung
Funktionen – Schnittstellen zum Datentransfer
Übergabe per Wert (by value)
Der Wert wird kopiert und an die Funktion übergeben (hineinkopiert)

#include <iostream>
using namespace std;

int addiere_5(int); // Funktionsprototyp

int main() {
int erg, i = 0;
cout << i << " Wert von i\n";
erg = addiere_5(i);
cout << erg << " Wert von addiere_5\n";
cout << i << " i unverändert!\n"; // quasi das Original
}

int addiere_5(int x) { // Funktionsdefinition


x += 5;
return x;
} Demo VC++ .NET:\K1011_Prog_struct\by_value\by_value.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 15


Technische Informatik und Programmieren
Programmstrukturierung
Funktionen – Schnittstellen zum Datentransfer
Übergabe per Wert (by value)
Vorstellung zur Parameterübergabe per Wert in unserem Beispiel:

¾by value sinnvoll, wenn das übergebene Objekt nicht geändert werden
soll; der Kopiervorgang kostet jedoch Zeit und Speicherplatz (ergo: bei
großen Objekten kann die Laufzeit negativ beeinflußt werden!)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 16


Technische Informatik und Programmieren
Programmstrukturierung
Funktionen – Schnittstellen zum Datentransfer
Übergabe per Referenz (by reference)
Die Funktion arbeitet mit dem Original!

Eigenschaften:
• Laufzeitvorteil bei großen Objekten (keine Kopie notwendig)
• ABER: das übergebene Original kann/wird verändert..

¾ Trick: Wenn das Original trotz Übergabe per Referenz vor Veränderung
geschützt werden soll:

Referenz auf const z.B.


const TYP& unveraenderliches_grosses_Objekt
-> auf const Objekte nur lesender Zugriff möglich

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 17


Technische Informatik und Programmieren
Programmstrukturierung
Funktionen – Schnittstellen zum Datentransfer
Beispiel zur Übergabe per Referenz (by reference)

#include <iostream>
using namespace std;

void addiere_7(int&); // int& = Referenz auf int

int main() {
int i = 0;
cout << i << " alter Wert von i\n";
addiere_7(i); // Syntax wie bei Übergabe per Wert
cout << i << " = neuer Wert von i nach addiere_7\n";
}

void addiere_7(int& x) {
x += 5; // Original des Aufrufers wird modifiziert!
}

Demo VC++ .NET:\K1011_Prog_struct\by_reference\by_reference.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 18


Technische Informatik und Programmieren
Programmstrukturierung
Funktionen – Schnittstellen zum Datentransfer
Übergabe per Referenz (by reference)
Vorstellung zur Parameterübergabe per Referenz in unserem Beispiel:

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 19


Technische Informatik und Programmieren
Programmstrukturierung
Funktionen – Schnittstellen zum Datentransfer
Gefahren bei der Rückgabe von Referenzen
Grundsätzlich dürfen Rückgabewerte auch Referenzen sein
Aber aufgepaßt:
(negatives) Beispiel:

#include <iostream>
using namespace std;

int& maxwert(int a, int b) { // Referenz als Rückgabewert


// a und b sind lokale Kopien der übergebenen Daten
if(a > b)
return a; // oh, je..
else return b; // auch nicht besser..

int main() {
int x = 17, y = 4;
int z = maxwert(x,y);
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 20


Technische Informatik und Programmieren
Programmstrukturierung
Funktionen – Vorgabewerte/variable Parameterzahl
Vorgabewerte und variable Parameterzahl
• Funktionen können mit variabler Parameterzahl aufgerufen werden
• im Funktionsprototyp werden nicht angegebene Parameter durch
vorgegebene Werte (default values) spezifiziert
Vorteil:
Erweiterbarkeit von Funktionen, ohne existierenden Code zu verletzen

// Aufruf im Programm1
AdressenSortieren(Adressdatei); // nach Nachnamen

// spätere Erweiterung im Programm2


enum Sortierkriterium {Nachname, PLZ, Telefon};
AdressenSortieren(Adressdatei, PLZ);

• altes Programm1 wie bisher übersetzbar


• Parameter mit Vorgabewerten erscheinen in der Deklaration nach den
anderen Parametern

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 21


Technische Informatik und Programmieren
Programmstrukturierung
Funktionen – Vorgabewerte/variable Parameterzahl
Beispiel: Funktion mit variabler Parameterzahl
// Funktionsprototyp (2 Parameter, 1 Vorgabewert)
void PreisAnzeige(double Preis, const string& Waehrung = "Euro");

// später im Hauptprogramm main Erweiterung im Programm2

// 1. Aufruf
PreisAnzeige(12.35); // Vorgabewert wird verwendet

// 2. Aufruf
PreisAnzeige(99.95, "US-Dollar");

// Funktionsdefinition (Implementation)
void PreisAnzeige(double Preis, const string& Waehrung)
{
cout << Preis << " " << Waehrung << endl;
}

Demo VC++ .NET:\K1011_Prog_struct\preis\preis.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 22


Technische Informatik und Programmieren
Programmstrukturierung
Funktionen – Überladen von Funktionen
Überladen von Funktionen

C++-Funktion wird eindeutig bestimmt durch:


• den Funktionsnamen
• die Parameterliste
Die Kombination wird als Signatur bezeichnet.

Folgerung:
• 2 Funktionen können gleichen Namen haben, wenn sie sich in ihren
Parametern unterscheiden (Anzahl und/oder Typen der Parameter)

Warum?
• Bessere Lesbarkeit (gleicher Funktionsname für ähnlichen Zweck)

-> wird in C++ als Überladen1 bezeichnet


1
: in der Literatur auch als Polymorphismus bezeichnet

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 23


Technische Informatik und Programmieren
Programmstrukturierung
Funktionen – Überladen von Funktionen
Beispiel für eine überladene Funktion
// Maximum von 2 Gleitkommazahlen
double max(double x, double y)
{
return x > y ? x : y;
}
// Maximum von 2 ganzen Zahlen
int max(int x, int y)
{
return x > y ? x : y;
}

// Aufruf in main
int main() {
double a = 100.2, b = 333.777;
int c = 1700, d = 1000;
cout << max(a,b) << endl; // max(double,double)
cout << max(c,d) << endl; // max(int,int)
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 24


Technische Informatik und Programmieren
Programmstrukturierung
Funktionen – main Funktion
Funktion main()
• main() ist eine spezielle Funktion
• jedes C++-Programm startet per Definition mit main()
• in einem Programm gibt es genau eine main() Funktion
• die main() Funktion ist implementationsabhängig (nicht vom Compiler
vorgegeben, Rückgabewert sollte int sein, kann 0 – 3 Parameter
besitzen)
• main() kann nicht überladen werden
• main() kann nicht von einer anderen Funktion aufgerufen werden
• i.A. gibt es in einer IDE (Integrated Development Environment) mehrere
Varianten von main()
• die nachfolgenden sind gefordert und müssen von jedem
Compilerhersteller unterstützt werden

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 25


Technische Informatik und Programmieren
Programmstrukturierung
Funktionen – main Funktion
Varianten der Funktion main()

// Variante 1
int main() {
...
return 0; // EXIT-Code
}

//Variante 2
int main(int argc, char* argv[]) {
...
// ohne return wird per default 0 zurückgegeben
}

Argumente:
• argc: Anzahl der Kommandozeilenparameter
• argv[ ]: C-Array mit Kommandozeilenparametern

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 26


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Grundsätze der modularen Gestaltung

Die Aufgabe des Softwareentwicklungs-Teams ist es,


die Illusion der Einfachheit zu erzeugen [Booch95]

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 27


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Grundsätze der modularen Gestaltung
Große C++ Programme (> 1.000 LOC) sollten in einzelne, getrennt
übersetzbare Einheiten (Dateien) aufgeteilt werden

Grundlegendes Prinzip der Aufteilung in


¾Deklaration (Schnittstellenbeschreibung) -> headerfiles
¾Definition (Implementierung, Realisierung) -> sourcefiles

Deklaration in Header-Dateien (Dateiendung *.h, *.hpp..)


• Konstanten
• Schnittstellenbeschreibungen
• Klassendeklarationen
• Deklaration globaler Daten
• Funktionsprototypen

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 28


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Grundsätze der modularen Gestaltung

Definition in Implementations-Dateien (Dateiendung *.cc, *.cpp..)


• Programmcode der Funktionen
• Klassendefinition

main()-Funktion (Dateiendung *.cc, *.cpp)


• Hauptprogramm main()

¾Diese Trennung wird in anderen OO-Programmiersprachen nicht


vorgenommen (z.B. Java oder C#). Ein Nachteil: Jede Änderung
erfordert einen kompletten Build- (Übersetzungs-)Vorgang!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 29


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Die 3 Schritte zum Programm
Umsetzung der Quelltexte (sourcecode, Textdatei) in Programmcode
(binäre, ausführbare Form) erfolgt in 3 Schritten:

1. Präprozessor
• sucht im Quelltext nach speziellen Befehlen
• führt im wesentlichen textuelle Ersetzungen durch
2. Compiler
• wandelt den geänderten Code in Objectcode um
• Objectcode enthält noch offene Aufrufe (d.h. noch keine Zuweisung
von Funktionsaufruf zu einer Funktion)
3. Linker
• verbindet die noch offenen Funktionsaufrufe mit den zugehörigen
Funktionen

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 30


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Praktischer Hinweis:

¾Moderne Programmieroberflächen (IDEs) machen die Kenntnis der


Dreiteilung fast überflüssig. Vor allem bei der Fehlersuche kann es
aber sehr wichtig sein, zu wissen, in welchem Schritt welcher Fehler
auftreten kann!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 31


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Der Präprozessor (Steuerung des Übersetzungsvorganges)
• Teil des Compilers, bearbeitet den Quelltext als Erster
• sucht nach speziellen Anweisungen (# Doppelkreuz, Gartenzaun)

Wesentliche Aufgaben:
• Dateien in andere einfügen (#include)
• Konstanten definieren und ersetzen (#define)
• Makros bereitstellen (#define)
• Selektion des Quelltextes, Bildung von Übersetzungseinheiten mit
(#ifdef / #ifndef)

• Präprozessor aus Kompatibilitätsgründen zu C


• Präprozessor i.d.R. in Compiler integriert
• Präprozessor verwendet eine eigene Syntax ≠ C++
• Präprozessorbefehle werden auch als Compilerdirektiven bezeichnet

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 32


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Der Compiler
• erhält den vom Präprozessor überarbeiteten Quelltext

• Umsetzung in Objectcode (Dateiendung *.o, *.obj)


• maschinennaher Code, aber nicht ausführbar, wegen unaufgelöster
Funktionsaufrufe (es ist nur bekannt, welche Funktion mit welchen
Parametern aufgerufen werden soll)
• eine Art “Zwischencode” (intermediate code)

• Prüfung auf syntaktische u. grammatische Fehler, tlw. auch Hinweis


auf logische Fehler

• Erzeugung einer Liste der verwendeten Variablen

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 33


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Der Linker
• setzt den vom Compiler generierten Objectcode zu einem vollständigen
Programm zusammen
• sucht nach Funktionsaufrufen und den dazugehörigen Funktionen
• prüft, ob alle deklarierten Variablen auch irgendwo definiert sind

Fehlerquelle Funktionsaufruf
• Aufruf mit korrektem Namen, aber falscher Parameteranzahl
• oder falscher Parameterreihenfolge
• oder fehlende Bibliotheken (s. später)

¾ Nach dem Linken liegt das fertige Programm vor und kann ausgeführt
werden!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 34


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Grundlegende Befehle des Präprozessors
Wichtige Befehle:
• Dateien einbinden (#include)
• Konstanten definieren (#define)
• Makros definieren (#define)
• Bedingte Compilierung (#ifdef, #ifndef)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 35


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Dateien einbinden (# include)
Zweck:
• Quellcode aus einer anderen Datei in das eigene Programm einbinden
(inkludieren)
• wichtige Voraussetzung, um Programmcode aufteilen zu können!

Zwei Varianten:

// Variante 1
#include <iostream.h> // Standard-Headerfile
#include <iostream> // Suche im Standard include Verzeichnis

//Variante 2
#include “..\Common/MyFunction.hpp“ // beliebige Datei mit Pfad

aus Kompatibilitätsgründen können \ und / verwendet werden!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 36


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Konstanten definieren (# define)
Zweck:
• Definition von Konstanten (Präprozessorsymbole) an zentraler Stelle
• definierte Symbole werden im Programm rein textuell ersetzt

Beispiele:

// Konstante definieren
#define MAXLOOP 1000 // Konvention: GROSSBUCHSTABEN verwenden
#define i 20 // gefährlich!! Fehler im Programm unten
// später im Programm
for(int i = 0; i <= MAXLOOP; i++)
// do something reasonable

// Allgemeine Form
#define NAME Ersetzungstext

¾ Definition kann mit #undef aufgehoben werden (eher selten)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 37


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Beispiele für vordefinierte Konstanten
Es gibt eine Reihe vordefinierter Konstanten (kleine Auswahl):

// Konstante definieren
__FILE__ // Dateiname, der gerade compiliert wird
__DATE__ // Datum des Compiliervorgangs
__TIME__ // Uhrzeit des Compiliervorgangs
__LINE__ // Zeile, in der sich der Compiler befindet
__STDC__ // 1, wenn Compiler im Standard-C Modus
__cplusplus // 1, wenn Compiler im C++-Modus

// später im Programm
cout << "Version vom " << __DATE__ << "um " << __TIME__ << "von"
<< __FILE__ << endl;

¾ Abhängig von der Plattform (z.B. Win32 oder UNIX) und der
Entwicklungsumgebung gibt es eine Vielzahl weiterer vordefinierter
Konstanten (s.a. MSDN, search for ‘predefined macros’)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 38


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Makros definieren
• mit #define können Makros erstellt werden
• Nachteile: keine Typprüfung, kein symbolisches Debuggen…
Beispiele:

// Makro definieren Hinweis: Präprozessor kennt keine Vorrangregeln


#define SCHREIBE cout (Ausnahme: Klammern)
#define QUAD(x) x * x // parametrisiertes Makro
// Chef, es gibt Problem (nix versteh‘n in Makros)
QUAD(5+3); // ergibt 5+3*5+3 = 23 (statt 64)
int i = 5;
QUAD(++i); // ergibt 7*7 = 49 QUAD(++i) == ++i * ++i
// (statt 6*6 = 36) d.h. 2-mal Präinkrement,
// korrekte Direktive danach multiplizieren
#define QUAD(x) ((x) * (x)) // parametrisiertes Makro

¾ Zitat von Bjarne Stroustrup: “Almost every macro demonstrates a flaw in


the programming language, in the program, or in the programmer.” ->
wann immer möglich, sollten Textersetzungen vermieden werden!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 39


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
#define versus const
• const ist in C++ relativ neu, früher gab es zu #define keine Alternative
Gegenüberstellung:
• Syntaxprüfung bei const (#define erst, wenn Makro im Programm
verwendet wird)
• const verwendet C++-Syntax, #define nicht
• const unterliegt den C++ Gültigkeitsregeln, #define immer gültig
• #define auf einfache Konstanten beschränkt, const kann auch
Strukturen
// beides Konstanten
#define MAX 10 // mit Präprozessor
const int MAX = 10; // sicherer

// etwas komplexer bitte..


struct box {
int breite, hoehe; }
const box myBox(10,20);

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 40


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Bedingte Compilierung mit #ifdef / #ifndef

Zweck:
1. Verhindern einer zweiten Compilierung
2. Selektion von Debugging-Code
3. Plattformübergreifende Programmierung

zu 1) Vermeidung von mehrfachen Einzügen bei headerfiles

zu 2) je nach Bedarf wird sourcecode mitcompiliert oder nicht (keine


Laufzeitnachteile!)

zu 3) in der Theorie ist C++ portabel.. ABER: in der Praxis gibt es kleine
Unterschiede zwischen Compilern für MS-Windows, UNIX etc.

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 41


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Verhindern einer zweiten Compilierung
• falls ein Quelltext in mehrere andere mit #include eingebunden wird,
könnte es passieren, daß er mehrfach übersetzt wird
• Folge: Compiler-Fehler wegen mehrfacher Definition (unzulässig)

Beispiel:
// const.h definiert sinnvolle Konstanten

// Dateien data.h und io.h nutzen beide die Konstanten


// in data.h
#include "const.h"
// in io.h
#include "const.h"

// später im Programm
#include "data.h" // const.h wird 1. mal eingezogen
#include "io.h" // const.h wird 2. mal eingezogen -> Fehler!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 42


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Selektieren von Debugging-Code
• systematische Fehlersuche basiert auf der Ausgabe von Diagnosewerten
• Fehlersuche ist im DEBUG Mode einfacher (keine Optimierungen durch
den Compiler, zusätzliche symbolische Information)
• und: evtl. zusätzlicher Code, speziell für die Fehlersuche

// Code am Anfang des Quelltextes (Textersetzungsmakro)


#ifdef __DEBUG__
#define DEBUG(code) code
#else
#define DEBUG(code) /* - */
#endif

// später im Programm
DEBUG( cout << „Initialisierung abgeschlossen.“ << endl; )
// wird nur ausgeführt, wenn __DEBUG__ definiert ist

¾ im Release Mode wird Debug Code nicht ausgeführt


¾ Testanweisungen können (für späteren Gebrauch) stehen bleiben

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 43


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Plattformübergreifende Programmierung
• Compilierung für mehrere Plattformen (Rechner, Betribessystem,
Oberflächen etc.) kann Spezifika erfordern

// bedingte Compilierung am Anfang des Quelltextes


#define __DEFAULT__
#ifdef __PF1__
#undef __DEFAULT__
#define EPSILON 0.0000000765
#endif
#ifdef __PF2__
#undef __DEFAULT__
#define EPSILON 0.0000000086
#endif
#ifdef __DEFAULT__
#define EPSILON 0.0005
#endif

Nachteil: Code kann schnell unübersichtlich werden

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 44


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Verifizieren logischer Annahmen mit assert (Makro)
• assert() ist ein sehr nützliches Makro zur Überprüfung logischer
Annahmen (assertion = Zusicherung)
• dabei können z.B. Vor- und Nachbedingungen von Funktionsaufrufen
überprüft werden
• bei Verwendung von assert() muß der Header <cassert>
eingebunden werden
// Beispiel zu assert()
#include <cassert> // enthält Makrodefinition
const int Grenze = 100;
int Index;

// Berechnung von Index

// Test auf Einhaltung der Grenzen:


assert(Index >= 0 && Index < Grenze);

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 45


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Verifizieren logischer Annahmen mit assert (Makro)
Wie funktioniert assert()?
• falls die Annahme assert(Index >= 0 && Index < Grenze); nicht
stimmen sollte (also Ergebnis false liefert) wird das Programm mit einer
Fehlermeldung abgebrochen!
• die Fehlermeldung enthält die zu verifizierende logische Annahme, die
Datei und die Zeilennummer, in der der Fehler aufgetreten ist

WICHTIGER ZUSATZ:
• assert() funktioniert nur im Debug-Stand, d.h. wenn vor der
#include <cassert> die Konstante DEBUG definiert wurde!
• d.h. es dient der schnelleren Fehlersuche im Debug-Stand

• assert() funktioniert nicht, wenn NDEBUG definiert wurde!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 46


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Verifizieren logischer Annahmen mit assert (Makro)
Ein Negativbeispiel zu assert()
• Seiteneffekte mit assert() (generell mit allen Makros!) sollten vermieden
werden
Beispiel:
assert(datei_oeffnen(filename) == erfolgreich); // Fehler!
assert(Grenze == max(x,y)); // Fehler

Problem:
• die Funktion in assert() wird bei gesetztem NDEBUG nicht ausgeführt!
• d.h. weder die Datei wird geöffnet noch der Wert für Grenze bestimmt

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 47


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Standardmakros zur Behandlung von Zeichen
Motivation:
• Header-Datei <ctype.h> bzw. <cctype> enthält Makros, um einzelnen
Zeichen zu klassifizieren oder umzuwandeln

Buchstaben umwandeln:
char c1 = ′a′, c2;
c2 = toupper(c1); // wandelt Kleinbuchstabe ′a′ nach ′A′

char c3 = ′B′, c4;


c4 = tolower(c3); // wandelt Großbuchstabe ′B′ nach ′b′

Randbedingung:
• toupper / tolower Makros behandeln nur Buchstaben des englischen
Alphabets, d.h. nationale Sonderzeichen (z.B. Umlaute, ß etc.) müssen
separat behandelt werden!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 48


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Standardmakros zur Behandlung von Zeichen
Beispiel:
// toupper.cpp
// Filter zur Umwandlung in Großbuchstaben
// Die Eingabe von der Tastatur mit
// Strg+Z (DOS/Windows) bzw. Strg+D (Unix) beenden.
// ------------------------------------------------------------
#include <iostream> Hinweis:
#include <cctype> cin.get(c) liefert das eingegebene Zeichen bis
using namespace std; zum Erreichen des Dateiendes (EOF) zurück
„Dateiende“ wird über Tastatur durch Strg+Z
int main() oder Strg+C simuliert!
{
sog. main-loop
char c;
while ( cin.get(c) ) // solange ein Zeichen
{ // gelesen werden kann
switch( c )
{
case 'ä' : c = 'Ä'; // deutsche Umlaute
break; // Zeichen ä

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 49


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Standardmakros zur Behandlung von Zeichen

case 'ö' : c = 'Ö'; // Zeichen ö


break;

case 'ü' : c = 'Ü'; // Zeichen ü


break;

case 'ß' : // Zeichen ß


cout.put('S'); c = 'S';
break;
Makro-Aufruf
default: c = toupper(c); // andere Zeichen
}
cout.put(c); // umgewandeltes Zeichen ausgeben
}
return 0;
}
Demo VC++ .NET:\K1011_Prog_struct\Toupper\Toupper.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 50


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Standardmakros zur Behandlung von Zeichen
Zeichen überprüfen:
• Zur Klassifizierung von Zeichen existieren ebenfalls zahlreiche Makros
• die Namen der Makros beginnen mit is...
char c; cin >> c; // Zeichen einlesen
if( !isdigit(c) ) // und überprüfen
cout << ″Das Zeichen ist keine Ziffer″ << endl;

Makros zur Klassifizierung von Zeichen Übersicht der wichtigsten Makros

Makro true als Rückgabewert bedeutet


isalpha(c) c ist ein Buchstabe
islower(c) c ist ein Kleinbuchstabe
isupper(c) c ist ein Großbuchstabe
isdigit(c) c ist eine dezimale Ziffer
isalnum(c) c ist ein Buchstabe oder eine Ziffer
isspace(c) c ist ein Zwischenraumzeichen (whitespace)
isprint(c) c ist ein druckbares Zeichen

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 51


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
für Fortgeschrittene..
Standardmakros zur Behandlung von Zeichen
Mögliche Makro-Definition von toupper():
#define toupper(c) /
( islower(c) ? ((c)-′a′+′A′) : (c) )

true, falls Wertdifferenz


Kleinbuchstabe im Code
von Klein- und Groß-
buchstaben

HINWEISE:
• ausgenutzt wird die Randbedingung aller gängigen Zeichencodes (ASCII,
EBCDIC etc.), dass sich Groß- und Kleinbuchstaben im Code durch einen
konstanten Wert unterscheiden
ASCII-Code:
Wertdifferenz beträgt 3210
z.B. ‘A‘ = 6510 ‚‘a‘ = 9710

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 52


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Einbinden von C-Funktionen
• möchte man C-Funktionen in C++ nutzen, muß man sie als solche
deklarieren!
• das Einbinden von C-Funktionen erfolgt ebenfalls mit #include
• C-Prototypen werden in der Header-Datei aber besonders gekennzeichnet:
extern "C" {
// hier folgen die C-Prototypen
}

Grund:
• der C++-Compiler behandelt Funktionsnamen anders als ein C-Compiler
(z.B. haben Funktionsdeklarationen ohne Parameter verschiedene
Bedeutung: in C++ ist die Anzahl dann immer 0)

Alle Standard-Headerfiles sind in C++ alle bereits mit den


enstprechenden Erweiterungen für den C++-Compiler ausgerüstet

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 53


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Einbinden von C-Funktionen
• die korrekte Einbindung in C++-Header-Dateien erfolgt über die Abfrage
des Makros __cplusplus

#ifdef __cplusplus
extern "C" {
#endif

// hier folgen die C-Prototypen

#ifdef __cplusplus
}
#endif

¾ die Technik, durch Makros gesteuert verschiedene Dinge ein- und


auszuschließen wird sehr gut in den *.h oder *.hpp Dateien im Standard-
Include Verzeichnis des Compilers sichtbar .. ein Blick lohnt sich..

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 54


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Das Linken des Codes
Wiederholung: Compiler erzeugt Objectcode, Funktionsaufrufe sind noch nicht
aufgelöst; Linker sorgt für passende Zuweisung

Wie kommt der Linker zu dieser Information?


Alternative 1: Übernahme vom Compiler
Alternative 2: Übernahme aus zusätzlichen Objektdateien
Alternative 3: Übernahme aus Bibliotheken

zu 1) einfachste Möglichkeit, aber immer alles compilieren (Build-all)


zu 2) jeden Quelltext individuell übersetzen und nur bei Änderung einzelne
Files neu compilieren (Delta-Build)
zu 3) vorübersetzte (binäre) Dateien (*.obj oder *.lib) mit dokumentierter
Funktionalität (Deklarationen in headerfiles liegt meist offen) für z.B.
spezielle mathematisch-numerische Verfahren, Ansteuerung graphischer
Oberflächen, etc.)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 55


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Der Standard: Aufteilung in Source- und Headerfiles
Wiederholung: Compiler benötigt nur Information, wie eine Funktion
aufgerufen werden soll -> Prüfung der Schnittstelle == Deklaration

sinnvolle Aufteilung:
• Fkt.-Deklaration befinden sich in getrennten files (headerfiles)

• Quelltexte, welche die Funktionen aufrufen binden diese headerfiles mit


#include "headerfile.h" ein

• Fkt.-Definition (Implementierung) befindet sich in Sourcefiles (*.cc, *.cpp)


kann getrennt compiliert werden (*.o, *.obj) und später vom Linker in das
fertige Programm (*.exe) eingebunden werden

• (bei Bedarf können mehrere *.obj files zu Bibliotheken *.lib


zusammengefaßt werden)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 56


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Beispiel für die Aufteilung von Source-/headerfiles
// Deklaration und Definition (Implementierung) Funktionen a

// a.h
#ifndef A_H
#define A_H

void func_a1();
void func_a2();
übersetzbare Einheit
#endif // A_H

// a.cpp
#include "a.h"

void func_a1() { /* hier implementieren */ }


void func_a2() { /* hier implementieren */ }

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 57


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
.. Beispiel fortsetzen ..
// Deklaration und Definition /Implementierung) der Funktionen b

// b.h
#ifndef B_H
#define B_H

void func_b();
übersetzbare Einheit
#endif // B_H

// b.cpp
#include "b.h"

void func_b() { /* hier implementieren */ }

Demo VC++ .NET:\K1011_Prog_struct\Source_Header\Source_Header.vcproj

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 58


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
.. Beispiel fortsetzen ..
// Verwendung im Hauptprogramm mainprog.cpp

// mainprog.cpp
#include "a.h"
#include "b.h"

int main() {
func_a1();
func_a2();
func_b();
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 59


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Compilations- und Linkverlauf am Beispiel

b.h
a.h

mainprog.cpp

COMPILER

mainprog.obj a.obj

(bereits übersetzt)
LINKER

Steuerung durch
b.obj
MAKE File oder
„Projekte“
(bereits übersetzt)
mainprog.exe

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 60


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Die 3 Grundregeln für den Umgang mit Source-/Header Files

1. Header Files immer vor zweiter Compilierung schützen (#ifndef ..)

2. Im Source File immer das zugehörige Header File einbinden (Definition


muß zur Deklaration passen!)

3. Im Header File nur Information aufnehmen, die von anderen


Programmteilen benötigt werden (z.B. Schnittstellenbeschreibung von
Funktionen, Konstanten etc.)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 61


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Die wesentlichen Konzepte zur modularen Gestaltung

1. Trennung von Schnittstellen und Implementierung

2. Gruppierung zusammengehöriger Funktionen und Klassen zu


Bibliotheksmodulen

¾ Grundvoraussetzung für größere Programmierprojekte mit


a) hoher Anzahl LOC (Lines of Code)
b) hoher Komplexität und
c) Entwicklung im Team

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 62


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Dateiübergreifende Gültigkeit und Sichtbarkeit
Globale Variablen sind:
• Variablen, die außerhalb von main() und jeglicher anderer Funktion
definiert sind
• sie sind in allen Teilen eines Programms gültig, (durch das Schlüsselwort
extern auch in anderen Dateien)
// datei_1.cpp
int global;
int main() {
global = 17;
extern: sagt dem Compiler,
} daß eine Variable irgendwo
anders definiert ist
//datei_2.cpp
extern int global; // Deklaration
int func1()
übersetzbare Einheit!!
{
(Referenz löst
global = 123;
der Linker auf)
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 63


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Dateiübergreifende Gültigkeit und Sichtbarkeit
Beschränkung des Gültigkeitsbereiches auf eine Datei:
• mit dem Schlüsselwort static wird die Gültigkeit auf eine Datei
beschränkt
• static Variablen werden automatisch mit 0 initialisiert

// datei_1.cpp (geändert)
static int global; // jetzt nur noch innerhalb datei_1 gültig!
int main() {
global = 17;
}

//datei_2.cpp
extern int global; // zwar übersetzbar, aber Linker-Fehler!
int func1()
{
global = 123;
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 64


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Dateiübergreifende Gültigkeit und Sichtbarkeit
Zusammenfassung:

Globale Variablen
• auf Dateiebene (außerhalb main() ) definierte Variable sind global und
sind in anderen Dateien benutzbar, wenn sie dort als extern deklariert
sind

AUSNAHME: Konstanten (const)


• bei Konstanten (const) ist es jedoch anders! Konstanten sind nur im
Definitionsfile sichtbar! Sollen Konstanten anderen Dateien zugänglich
gemacht werden, müssen sie als extern deklariert und initialisiert
werden

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 65


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Dateiübergreifende Gültigkeit und Sichtbarkeit
Spezialität Konstanten:
• Konstanten sind ohne Zusatz auf die Definitionsdatei beschränkt!
• mit extern werden Konstanten auch anderen Dateien zugänglich
gemacht (richtig global also)

// datei_1.cpp (geändert)
extern const float pi = 3.14159; // globale Konstante

//datei_2.cpp
extern const float pi; // keinen Wert zuweisen, nur Deklaration!

¾ ohne extern in datei1.cpp wäre der Geltungsbereich von pi auf


datei1.cpp beschränkt!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 66


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Dateiübergreifende Gültigkeit und Sichtbarkeit
Übersicht der Speicherklassen:
• die Speicherklasse einer Variablen wird mit den Schlüsselworten:
• auto
• static
• extern
• register
• mutable bestimmt
• mit auto, static und extern werden Sichtbarkeit und Lebensdauer
eingestellt
• auto-Variablen: alle nicht-globalen und nicht-const Variablen sind
automatisch automatisch (auto)
• auto Variablen werden beim Betreten eines Blocks (ohne Initialisierung)
angelegt und beim Verlassen wieder zerstört (Stack-Variablen)
• das Schlüsselwort auto ist optional

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 67


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Dateiübergreifende Gültigkeit und Sichtbarkeit
Ergänzung zu register und mutable:
register-Variablen:
• mit register gekennzeichnte Variablen sind auto-Variablen
• zusätzlich erhält der Compiler einen Hinweis, die Variable aus
Geschwindigkeitsgründen in ein Register der CPU zu packen
• das ist aber lediglich ein Hinweis, der Compiler ist daran nicht gebunden!

mutable-Variablen: (Ausblick auf OOP..)


• relevant für OOP: Daten (Attribute) eines als const deklarierten
Objektes dürfen i.a. nicht verändert werden
• wenn ein Attribut als mutable-Variable deklariert ist, ist eine Änderung
dennoch erlaubt
• eigentlich wird dadurch ein Grundkonzept der OOP (Kapselung)
unterlaufen, aber aus Performancegründen kann dies gelegentlich
sinnvoll sein

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 68


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Übersetzungseinheit, Deklaration und Definition
Übersetzungseinheit:
• alles, was der Compiler in einem Durchgang liest
• große Programme werden in viele Übersetzungseinheiten unterteilt

Deklaration:
• führt einen Namen in ein Programm ein und gibt ihm eine Bedeutung

Deklaration und Definition:


• wenn mehr als nur der Name eingeführt wird;
• wenn Speicherplatz für Daten oder Code angelegt wird
• der die innere Struktur eines Datentyps beschrieben wird (aus der sich
der Speicherplatzbedarf ableitet)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 69


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Übersetzungseinheit, Deklaration und Definition
Beispiele:

// Deklarationen und Definitionen


int a;
extern const float pi = 3.14159;
int f(int x) { return x*x };
struct myStruct {
int s,d;
}
myStruct x;
enum myEnum { li, re }; // implizit vom Typ int

// nur Deklarationen (ohne Definition)


extern int a;
extern const float pi;
int f(int);
struct myStruct;
enum myEnum;

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 70


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Übersetzungseinheit, Deklaration und Definition
one definition rule (ODR)

Jede Variable, Funktion,Struktur,Konstante etc.


in einem Programm hat genau eine Definition

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 71


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Funktionstemplates
Ziel:
• oftmals ist dieselbe Aufgabe für verschiedene Datentypen zu erledigen
• z.B. Sortieren eines int-Arrays, double-Arrays, String-Arrays
• Lösungsmöglichkeit “Kopieren” ist fehleranfällig: Änderungen,
Fehlerkorrekturen und Weiterentwicklungen des Algorithmus müssen in
jeder Kopie nachgezogen werden!

Lösung:
• Nutzen von Schablonen (templates): Funktionen können mit
parametrisierbaren Datentypen erstellt werden
• d.h. die Funktion wird für einen beliebigen (noch festzulegenden) Datentyp
geschrieben
• für den noch unbestimmten Datentyp wird ein Platzhalter eingefügt
• später wird dieser durch den tatsächlich benötigten Datentyp ersetzt!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 72


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Funktionstemplates
templates == parametrisierte Datentypen

Allgemeine Form für Templates (Synatx):

• anstatt class kann auch typename geschrieben werden


• Typbezeichner ist ein beliebiger Name, der in der Funktionsdefinition als
Datentyp verwendet wird

schauen wir uns hierzu am besten ein Beispiel an..

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 73


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Beispiel zu Funktionstemplates
• Sortierung eines int- und double-Feldes
• es wird nur eine Funktion quicksort() 1verwendet, die den
Datentypplatzhalter T verwendet
Vorteil: quicksort() kann leichter für Arrays von Objekten einer beliebigen
Klasse angewandt werden (class: template für beliebige Klassen möglich)

F: Wie erkennt der Compiler die Zuordnung zu einem bestimmten Datentyp?


Antwort:
• innerhalb von main() stellt der Compiler anhand des Funktionsaufrufes
fest, für welchen Datentyp die Funktion benötigt wird
• dann wird die Definition auf Basis des templates gebildet!
• für jeden Datentyp wird eine Funktion vom Compiler aus der Schablone
erzeugt
• Analogie: eine Kuchenform für Schoko- und Nußkuchen..
1: zu Demozwecken wird hier nicht die sort() Funktion der C++ - STL verwendet

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 74


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Beispiel zu Funktionstemplates
// Quicksort:
#include <iostream>
#include <vector>
using namespace std;

// Templates mit T als Parameter für den Datentyp (Platzhalter)


template<class T>
void tausche(T& a, T& b) {
// a und b vertauschen
const T temp = a;
a = b;
b = temp;
}

template<class T>
int kleiner(const T& a, const T& b) {
return (a < b);
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 75


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
.. Beispiel zu Funktionstemplates ..
template<class T>
void drucke(const vector<t>& V) {
for(size_t i = 0; i < V.size(); i++)
cout << V[i] << " ";
cout << endl;
}
template<class T>
void quicksort(vector<T>& a, int links, int rechts) {
int li = links; int re = rechts;
T el = a[(links+rechts)/2];
do {
while(kleiner(a[li],el)) ++li;
while(kleiner(el,a[re])) –re;
if(li < re) tausche(a[li], a[re]);
if(li <= re) {++li; --re;}
} while(li <= re);
if(links < re) quicksort(a, links, re);
if(li < rechts) quicksort(a, li, rechts);
}

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 76


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
.. Beispiel zu Funktionstemplates ..
// Verwendung in main()
int main() {
vector<int> iV(10);
iV[0]=100; iV[1]=22; iV[2]=-3; iV[3]=44; iV[4]=6;
iV[5]=-9; iV[6]=-2; iV[7]=1; iV[8]=8; iV[9]=9;

/* erst in der folgenden Anweisung werden vom Compiler


durch den Datentyp des Parameters iV aus den obigen
Templates die Funktionen quicksort(vector<int>&,int, int)
und drucke(const vector<int>&) erzeugt, ebenso wie die
implizit aufgerufenen Funktionen tausche(int&, int&) und
kleiner(int&, int&);
*/

quicksort(iV, 0 iV.size()-1);
drucke(iV);

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 77


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
.. Beispiel zu Funktionstemplates ..
// weiter in main() ...
vector<´double> dV(7);
dV[0]=1.09; dV[1]=2.2; dV[2]=79.6; dV[3]=-1.9; dV[4]=2.7;
dV[5]=100.9; dV[6]=18.8; dV[7]=99.9;

// Generierung der überladenen Funktionen für double:


quicksort(dV, 0 dV.size()-1);
drucke(dV);
} // Ende von main()

¾ damit liegt ein universelles Sortierprogramm vor, das für verschiedene


Datentypen geeignet ist
¾ (natürlich kann man auch die Sortierfunktion der Standardbibliothek
verwenden..)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 78


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
.. Beispiel zu Funktionstemplates ..
AUFFÄLLIG:
• der Vergleich, welches Element kleiner ist, wurde im quicksort()
ausgelagert in die Funktion kleiner() anstatt if(feld[i] <
feld[j]) zu verwenden
WARUM?
• es ist nicht selbstverständlich, daß der < - Operator für beliebige Klassen
und Datentypen definiert ist
• durch das Auslagern des Vergleichs erspart man sich Änderungen von
quicksort(), wenn der Vergleich anders definiert werden muß
LÖSUNG:
• durch die Spezialisierung von Templates kann ein Template für
festzulegende Datentypen angepaßt (spezialisiert) werden

schauen wir uns das an einem Beispiel einmal an

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 79


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Spezialisierung von Templates .. Beispiel ..
Annahme:
• double Zahlen sollen wie bisher, int Zahlen jetzt aber nach dem
Absolutbetrag sortiert werden
• der Vergleichsoperator < kann dann nicht mehr direkt auf Ganzzahlen
angewendet werden, wir brauchen eine Spezialisierung der Funktion
kleiner() für int
// (#include <cstdlib> für abs() nicht vergessen)
template<>
int kleiner<int>(const int& a, const int& b)
{
return abs(a) < abs(b); // Vergleich nach Absolutbetrag!
}

¾ Spezialfälle von überladenen Funktionen werden nach den Templates


eingefügt!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 80


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Kernaussage zu Templates

Ein Template ist keine Funktionsdefinition im bisherigen


Sinn! Die konkrete Definition wird erst bei Bedarf durch
den Compiler (auf Basis des Templates) erzeugt.

Beispiel-Template s. Demo VC++ 6.0: k4\qsort.dsp

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 81


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Einbinden von Templates
• normale Funktionen können vorübersetzt und dann eingebunden werden
• das gilt nicht für Funktionstemplates!!
• eine *.obj Datei nach Übersetzen einer Datei mit Templates enthält
keinen Programmcode und keine Daten

URSACHE:
• die Funktionsdefinition für einen bestimmten Datentyp wird eben erst bei
Bedarf erzeugt

LÖSUNG:
• Dateien mit Templates werden mit #include eingebunden
• daher könnten die Template-Definitionen ebensogut in der Header-Datei
stehen (das findet man gelegentlich auch so in der Standardbibliothek)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 82


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
INLINE-Funktionen
Warum wurde inline in C++ eingeführt?:
Problemstellung:
• ein Funktionsaufruf kostet Zeit und erfordert folgende Einzelschritte:
9 Sicherung des Zustand des Aufrufers
9 evtl. Kopie der Parameter (Übergabe per Wert an die Funktion)
9 Programmsprung an eine andere Stelle (Funktionsdefinition)
9 Ausführen der Funktion
9 Rücksprung zur Anweisung nach dem Aufruf
9 Wiederherstellen des Zustandes vor dem Aufruf
• dieser Verwaltungsaufwand fällt umso stärker ins Gewicht, je weniger
Zeit die Abarbeitung einer Funktion im Funktionskörper selbst benötigt
Lösung:
• zur Reduzierung dieses Aufwands können Funktionen als inline
deklariert werden d.h. bei der Übersetzung wird der Aufruf durch den
Funktionskörper ersetzt! (d.h. kein echter Funktionsaufruf)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 83


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
INLINE-Funktionen
Schlüsselwort inline:
• Empfehlung an den Compiler, einen Funktionsaufruf direkt durch den
Funktionskörper zu ersetzen (Vorteil: Zeitersparnis!)
• sinnvoll nur für sehr kurze Funktionen (mit kurzer Ausführungszeit!)
Beispiel:

// Funktion quadrat erzeugt ca. 10 Zeilen Assembler-Code


int quadrat(int wert) {
return (wert * wert);
}
// Alternative: inline, erzeugt ca. 4 Zeilen Assembler-Code
inline int quadrat(int wert) {
return (wert * wert);
}
// Der Aufruf:
int z = quadrat(100);
// wird durch den Compiler ersetzt zu:
int z = 100 * 100; // kein Einsprung in quadrat()!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 84


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
INLINE-Funktionen
Wo sollte inline verwendet werden?
¾ ausschließlich in Header-Dateien!
Gegen-Beispiel:
// X.h Deklarationsdatei
int f(int);
int g(int);
// Ende von X.h

// X.cpp
#include "X.h"
inline int f(int a) { // Fehler inline in Definitionsdatei!
return(a*a);
}
int g(int a) {
a += 1;
return f(a); // inline ist hier bekannt!
} // Ende von X.cpp

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 85


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
INLINE-Funktionen
.. Fortstetzung des Gegen-Beispiels …
// main.cpp Hauptprogramm
#include "X.h"
int main() {
int a = 1; b;
b = f(a) + g(a); // inline ist hier unbekannt!
// Ende von main.cpp

• bei getrennter Übersetzung von X.cpp und main.cpp gibt es 2 Fälle:


a) innerhalb von g() kann die inline-Ersetzung von f() vorgenommen
werden
b) in main.cpp weiß der Compiler nichts davon, daß f() inline sein soll und
nimmt einen Funktionsaufruf an
¾ Konsequenz: der Linker findet die Definition von f() nicht und liefert eine
Fehlermeldung zurück

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 86


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
INLINE-Funktionen
und hier die korrekte Version zum Beispiel …
// X.h Deklarationsdatei
inline int f(int a) { // inline in Deklarationsdatei
return(a*a);
}

int g(int);
// Ende von X.h

// X.cpp
#include "X.h"

int g(int a) {
a += 1;
return f(a); // inline ist hier bekannt!
}
// Ende von X.cpp

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 87


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
INLINE-Funktionen
und hier die korrekte Version zum Beispiel …

// main.cpp Hauptprogramm
#include "X.h"
int main() {
int a = 1; b;
b = f(a) + g(a); // inline ist jetzt bekannt!
// Ende von main.cpp

Hinweis:
• inline-Funktionen werden in jeder Übersetzungseinheit expandiert und
unterliegen damit dem internen Linken!

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 88


Technische Informatik und Programmieren
Programmstrukturierung
Grundsätze der modularen Gestaltung
Vergleich internes vs. externes Linken

internes Linken (internal linkage)


• alle nur innerhalb einer Übersetzungseinheit gültigen Variablen und
Funktionen unterliegen dem sog. internen Linken (sie werden intern
gebunden)

externes Linken (external linkage):


• alle globalen Variablen und Funktionen werden extern gebunden (extern
gelinkt)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 89


Technische Informatik und Programmieren
Standardbibliotheken
Orientierung
Einleitung
Das erste Programm in C
ORIENTIERUNG
Konstanten
Einfache Datentypen
Unterprogramm – Technik –
Nützliche Funktionen
Steuerstrukturen
Typvereinbarungen von Variablen
Zeiger
Der Präcompiler
Modulare Programmierung
Entwicklungsumgebungen
Standardbibliotheken
Anhang

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 1


Technische Informatik und Programmieren
Standardbibliotheken
Ziele

¾ Welche Standardbibliotheken sind in ANSI-C verfügbar?


¾ Welchen Funktionsprototypen haben sie?
¾ Wie können diese Funktionen im eigenen Programm
genutzt werden
ZIELE

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 2


Technische Informatik und Programmieren
Standardbibliotheken
Grundlagen
Standardbibliotheken in ANSI C
• Programmierung in C wird durch zahlreiche Bibliotheken (ANSI-C
Standardbibliothek) unterstützt
• ANSI-C89: nahezu alle heute gängigen Compiler unterstützen diese
Funktionen
• ANSI-C99: tlw. noch nicht verfügbar (z.B. Funktionen für komplexe Zahlen)

Handhabung:
• Funktionen der Standardbibliothek können im eigenen Programm
kostenfrei („for free“) genutzt werden
• die entsprechende Header-Datei mit den Funktionsprotoypen muß
inkludiert werden (z.B. #include <math.h> )
• die entsprechenden Bibliotheken (meist *.lib) werden durch den Linker
zum selbsterstellten Binärcode hinzugebunden

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 3


Technische Informatik und Programmieren
Standardbibliotheken
Übersicht
Ausgwählte Bibliotheken der Standardbibliothek

Header-Datei Zweck
ctype.h Konvertierung von Zeichen
locale.h Länderspezifische Einstellungen (z.B. Darstellung von Datum, Uhrzeit)
math.h Mathematische Funktionen
signal.h Signalbearbeitung
stdarg.h Variable Parameterlisten
stdio.h Ein- und Ausgabe
stdlib.h String-Umwandlung, Speicherverwaltung, Erzeugen von Zufallszahlen,
Beenden von Programmen
string.h String- und Speicherbehandlung
time.h Datum- und Uhrzeitfunktionen

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 4


Technische Informatik und Programmieren
Standardbibliotheken
ctype.h
ctype.h (Konvertierung von Zeichen)

Hinweise:
ƒ Funktionsparameter sind alle vom Typ int
ƒ wegen der automatischen Konvertierung von char -> int können
Parameter auch vom Typ char sein
ƒ Rückgabewerte: int als boolscher Datentyp (false == 0, true != 0)

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 5


Technische Informatik und Programmieren
Standardbibliotheken
ctype.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 6


Technische Informatik und Programmieren
Standardbibliotheken
ctype.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 7


Technische Informatik und Programmieren
Standardbibliotheken
ctype.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 8


Technische Informatik und Programmieren
Standardbibliotheken
ctype.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 9


Technische Informatik und Programmieren
Standardbibliotheken
ctype.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 10


Technische Informatik und Programmieren
Standardbibliotheken
ctype.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 11


Technische Informatik und Programmieren
Standardbibliotheken
ctype.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 12


Technische Informatik und Programmieren
Standardbibliotheken
string.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 13


Technische Informatik und Programmieren
Standardbibliotheken
string.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 14


Technische Informatik und Programmieren
Standardbibliotheken
string.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 15


Technische Informatik und Programmieren
Standardbibliotheken
string.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 16


Technische Informatik und Programmieren
Standardbibliotheken
string.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 17


Technische Informatik und Programmieren
Standardbibliotheken
string.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 18


Technische Informatik und Programmieren
Standardbibliotheken
string.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 19


Technische Informatik und Programmieren
Standardbibliotheken
string.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 20


Technische Informatik und Programmieren
Standardbibliotheken
string.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 21


Technische Informatik und Programmieren
Standardbibliotheken
string.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 22


Technische Informatik und Programmieren
Standardbibliotheken
string.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 23


Technische Informatik und Programmieren
Standardbibliotheken
string.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 24


Technische Informatik und Programmieren
Standardbibliotheken
string.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 25


Technische Informatik und Programmieren
Standardbibliotheken
string.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 26


Technische Informatik und Programmieren
Standardbibliotheken
string.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 27


Technische Informatik und Programmieren
Standardbibliotheken
string.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 28


Technische Informatik und Programmieren
Standardbibliotheken
string.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 29


Technische Informatik und Programmieren
Standardbibliotheken
stdio.h
stdio.h (Standard Ein-/Ausgabe)

Hinweise:
ƒ in stdio.h wird u.a. der neue Datentyp FILE deklariert
ƒ FILE vereinfacht den Zugriff auf Dateien

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 30


Technische Informatik und Programmieren
Standardbibliotheken
stdio.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 31


Technische Informatik und Programmieren
Standardbibliotheken
stdio.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 32


Technische Informatik und Programmieren
Standardbibliotheken
stdio.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 33


Technische Informatik und Programmieren
Standardbibliotheken
stdio.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 34


Technische Informatik und Programmieren
Standardbibliotheken
stdio.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 35


Technische Informatik und Programmieren
Standardbibliotheken
stdio.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 36


Technische Informatik und Programmieren
Standardbibliotheken
stdio.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 37


Technische Informatik und Programmieren
Standardbibliotheken
stdio.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 38


Technische Informatik und Programmieren
Standardbibliotheken
stdio.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 39


Technische Informatik und Programmieren
Standardbibliotheken
stdio.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 40


Technische Informatik und Programmieren
Standardbibliotheken
stdio.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 41


Technische Informatik und Programmieren
Standardbibliotheken
stdio.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 42


Technische Informatik und Programmieren
Standardbibliotheken
stdio.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 43


Technische Informatik und Programmieren
Standardbibliotheken
math.h
math.h (mathematische Funktionen)

Hinweise:
ƒ ist eines der Argumente der folgenden Funktionen außerhalb des
Definitionsbereiches der Funktion, wird in der Variablen errno ein
Fehlerwert EDOM abgelegt
ƒ ERANGE wird in errno abgespeichert, falls sich das Ergebnis im
zulässigen Wertebereich befindet
ƒ beim Überlauf von Wertebereichen wird das Funktionsergebnis
HUGE_VAL geliefert
ƒ einige Funktionen liefern den Fehlerwert NAN (not a number), wenn
das Ergebnis sich nicht als gültige Zahl darstellen läßt

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 44


Technische Informatik und Programmieren
Standardbibliotheken
math.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 45


Technische Informatik und Programmieren
Standardbibliotheken
math.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 46


Technische Informatik und Programmieren
Standardbibliotheken
math.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 47


Technische Informatik und Programmieren
Standardbibliotheken
math.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 48


Technische Informatik und Programmieren
Standardbibliotheken
math.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 49


Technische Informatik und Programmieren
Standardbibliotheken
math.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 50


Technische Informatik und Programmieren
Standardbibliotheken
math.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 51


Technische Informatik und Programmieren
Standardbibliotheken
math.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 52


Technische Informatik und Programmieren
Standardbibliotheken
math.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 53


Technische Informatik und Programmieren
Standardbibliotheken
math.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 54


Technische Informatik und Programmieren
Standardbibliotheken
math.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 55


Technische Informatik und Programmieren
Standardbibliotheken
stdlib.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 56


Technische Informatik und Programmieren
Standardbibliotheken
stdlib.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 57


Technische Informatik und Programmieren
Standardbibliotheken
stdlib.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 58


Technische Informatik und Programmieren
Standardbibliotheken
stdlib.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 59


Technische Informatik und Programmieren
Standardbibliotheken
stdlib.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 60


Technische Informatik und Programmieren
Standardbibliotheken
stdlib.h

z.B. x = 10000
9090 Rest 10
inkl. Grenzen!
x % 11
Wertebereich

min + 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 = [min, max]

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 61


Technische Informatik und Programmieren
Standardbibliotheken
stdlib.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 62


Technische Informatik und Programmieren
Standardbibliotheken
time.h
time.h (Verwaltung von Datums- und Uhrzeitangaben)

Hinweise:
ƒ die Bibliothek time.h verwendet 2 verschiedene Zeitangaben
ƒ Kalenderzeit: Anzahl der Sekunden seit dem Stichtag (01.01.1979)
ƒ Ortszeit: Struktur mit Datenelementen vom Typ int für die
Zeitangaben

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 63


Technische Informatik und Programmieren
Standardbibliotheken
time.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 64


Technische Informatik und Programmieren
Standardbibliotheken
time.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 65


Technische Informatik und Programmieren
Standardbibliotheken
time.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 66


Technische Informatik und Programmieren
Standardbibliotheken
time.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 67


Technische Informatik und Programmieren
Standardbibliotheken
time.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 68


Technische Informatik und Programmieren
Standardbibliotheken
time.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 69


Technische Informatik und Programmieren
Standardbibliotheken
time.h

Frank Artinger Informatik - ANSI C 2.0 / ANSI C++ 70


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

ORIENTIERUNG

Keine Programmiersprache, wie strukturiert sie auch sei, wird


Programmierer davon abhalten, schlechte Programme zu
schreiben
– (unbekannt, aber gut formuliert)

Es ist die Erhabenheit ihres Stils, die unsere Schriftsteller von


1840 vierzig Jahre später unlesbar machen wird.
– Standhal (Schriftsteller zur Zeit Goethes, um 1838)

Frank Artinger Informatik - C++ Programmiersprache 1


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

ORIENTIERUNG

Quality is designed in, not tested in


– David Packard
(Mitbegründer der Hewlett-Packard company, Stanford-Absolvent)

Frank Artinger Informatik - C++ Programmiersprache 2


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

Verstehen, warum guter Programmierstil wichtig ist


Einige Stilelemente gut strukturierter Programme
kennlernen
Worüber man streiten kann ..
ZIELE

Frank Artinger Informatik - C++ Programmiersprache 3


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil
Programmierstil
Kommentare
C++-Code
Benennungsstil
Code-Religionen
INHALT

Einrückungen und Code Formatierung


Klarheit
Einfachheit
weiterführende Hinweise..

Frank Artinger Informatik - C++ Programmiersprache 4


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil
Programmierstil

• Stil ist einer der wichtigsten Aspekte bei der Programmierung

• Stil trennt die Spreu vom Weizen (oder den Programmierkünstler vom
Schlächter)

• Der Unterschied zwischen der Mona Lisa und einem paint-by-numbers


picture ist...

Frank Artinger Informatik - C++ Programmiersprache 5


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil
Ein wenig Wartung gefällig??
Entwicklung der Systemgröße typischer Software-Systeme

Millions LOC (typical app)


10 10
9
8
7
6
5 5
4
3
2 1,2
1
0 0,023
1980 1990 2000 2010
(exp)

Frank Artinger Informatik - C++ Programmiersprache 6


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil
Ein wenig Wartung gefällig??
Entwicklung des Systemalters typischer Software-Systeme

average system age


14
12 11
10 9,4
8
6
6
4,75
4
2
0
1980 1990 2000 2010 (exp)

Frank Artinger Informatik - C++ Programmiersprache 7


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil
Ein wenig Wartung gefällig??

immer mehr SW-Entwickler sind mit der Wartung & Pflege (Maintenance)
eines SW-Systems beschäftigt (Einarbeitung in fremden Code, Fehlersuche,
Debuggen und BugFixes, Funktionserweiterungen an bestehenden
Systemen, etc.)

• noch 1990 konnte man sich folgende Aussage leisten:

74% of the managers surveyed at the 1990 Annual Meeting and Conference
of the Software Maintenenace Association reported that they „have systems
in their department that have to be maintained by specific individuals
because no one else understands them“

- Software Manitenance News, Februrary 1991

Frank Artinger Informatik - C++ Programmiersprache 8


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

Ein wenig Wartung gefällig??

Programm, deren ausschließliche Aufgabe es ist, kompakte Anweisungen


an den Computer zu geben besitzen 2 große Probleme:

• schwer korrigierbar, nach einer gewissen Zeit (abhängig von der


Komplexität der Lösung) hat selbst der Autor (so er denn noch zur
Verfügung steht) Probleme, das Programm zu verstehen

• Änderungen und Erweiterungen sind nur schwer möglich (und damit


kostenintensiv), da der dann für den Programmteil zuständige
Programmierer viel Zeit investieren muß, um die Funktionsweise zu
verstehen

Frank Artinger Informatik - C++ Programmiersprache 9


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

Kommentare
Ein Programm erfüllt 2 Aufgaben:

Code teilt dem Computer mit, was zu tun ist


Kommentare beschreiben, was das Programm tut (wichtig für den armen
Kollegen, der die Fehler finden und korrigieren muß)

Zwei Arten von Kommentaren:

C++-Variante

C-Variante
weiterhin gültig!

Frank Artinger Informatik - C++ Programmiersprache 10


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

Anfangskommentare
Beispiel für einen Kommentarkasten (sollte zu Beginn jeder Quellcodedatei
stehen)

* hello – Ein Programm zur Ausgabe von „Hello World“ *


* Kein furchtbar kompliziertes Programm *
* *
* Autor: Alter Haudegen, FH Karlsruhe *
* Zweck: Demo eines einfachen Programms *
* Verwendung: Programm starten,warten,bis Ausgabe erscheint *
* *
* erstellt am: 28.09.04 *
* zuletzt modifiziert: 01.10.04, erweitert um Kommentar *

Frank Artinger Informatik - C++ Programmiersprache 11


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

Welche Information sollten Anfangskommentare enthalten?


Überschrift
• Name des Programms, kurze Beschreibung, was das Programm tut)
Autor
• Programme schreiben kosten eine Menge Zeit, seien Sie stolz darauf
(und: jemand anderes kann Sie später fragen)
Zweck
• Warum haben Sie das Programm geschrieben? Was tut es?
Verwendung
• kurze Erklärung, wie das Programm ausgeführt wird (diese bitte auch
anpassen, wenn sich Änderungen ergeben haben ☺)
Referenzen
• copy & paste ist legitim, solange nicht gegen Urheberrecht verstoßen wird
• trotzdem: ursprüngliche Autoren bitte erwähnen!

Frank Artinger Informatik - C++ Programmiersprache 12


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

Welche Information sollten Anfangskommentare enthalten?


Dateiformate
• Beschreibung, welche Dateien gelesen / geschrieben werden und evtl.
kurze Beschreibung des Dateiformats
Einschränkungen und Randbedingungen
• z.B. Verzicht auf bestimmte Eingabeprüfungen, Aufrufmöglichkeit von
Diensten aus anderen Programmen heraus (Hinweis auf eine API
Application Programming Interface, falls vorhanden)
Versionierung
• Liste, wer, wann das Programm (evtl. aus welchem Grund) modifiziert hat

Ausblick professionelle SW-Entwicklung:


Source-Code-Verwaltungs-/Versionierungsprogramme sind heute
Standard (z.B. Visual SourceSafe von Microsoft (kostenfrei im
VisualStudio) oder ClearCase von Rational (a bisserle teurer..))

Frank Artinger Informatik - C++ Programmiersprache 13


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

Einschub: Was macht ein Source-Code Verwaltungsprogramm?

Explorer
Darstellung
Verwaltung der Differenzen
hinzufügen Versionsgeschichte anzeigen
neuer Projekte

durch Ein- bzw. Auschecken


werden Versionen aufgezeichnet

regelmäßige ermöglicht Roll-back


Datensicherung!! Database
auf ältere Versionen

Frank Artinger Informatik - C++ Programmiersprache 14


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

Welche Information sollten Anfangskommentare enthalten?


Fehlerbehandlung
• Wie verhält sich das Programm, wenn es auf einen Fehler stößt?
Copyright & Lizenzen
• Firmen verlangen häufig die Aufnahme eines Copyright Hinweises (z.B.
Copyright SIEMENS AG, A&D, 2004)
• Auch bei OpenSource: Hinweis auf GNU Public License (GPL), Info hierzu
unter: http://www.gnu.org)
Anmerkungen
• Alles, was Ihnen sonst noch als wichtig erscheint..

Frank Artinger Informatik - C++ Programmiersprache 15


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

Schriftsatz für Arme


leider nur ein (nichtproportionaler) Schriftsatz ohne fette oder kursive Stile
Aber hier einige Vorschläge, was man machen könnte:

*********** WARNUNG: Das ist ein Besipiel einer Warnung *****


********** zieht die Aufmerksamkeit des Programmieres an ****

* Eine Kommentarbox *
* *

* noch ein Kasten *

Frank Artinger Informatik - C++ Programmiersprache 16


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

Wann sollten Kommentare erstellt werden?

Grundsätzlich während der Code-Erzeugung (Programmierung)


die Erfahrung zeigt, daß hinterher keine Zeit mehr dafür ist
dann bleibt der Code in weiten Teilen undokumentiert und das Chaos ist
„vorprogrammiert“

Regel für unsere Übungen:


• immer einen Kommentarkasten zu Beginn jedes Quellcode files
verwenden (per copy & paste leicht zu übernehmen)

• mindestens Namen, Sinn und Zweck des Programms und


Erstellungsdatum eintragen

Frank Artinger Informatik - C++ Programmiersprache 17


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

Einschub:

Entwicklungsvorgaben bei der Software-Entwicklung der


SIEMENS AG, Bereich A&D (Automation and Drives)

F:\
hschule\FH_KA-Lehr

Entwicklungsvorgaben.chm

Anm.: confidential, daher leider keine öffentliche Weitergabe möglich

Ein wenig Prüfung muß sein..


Beispiel für statische Code-Review Tools (begleitend zum daily build):
PC-Lint (http://www.gimpel.com/html/pcl.htm) für MS Windows und OS/2

Frank Artinger Informatik - C++ Programmiersprache 18


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

Variablen
• Variable reserviert einen Platz im Speicher des Computers um einen Wert
abzulegen
• der Speicherplatz wird über den Variablennamen eindeutig zugeordnet
• C++ erlaubt Variablennamen fast beliebiger Läääääääänge...

Hier einige Hinweise und Tips:


• ausdrucksstarke Namen verwenden (aber nicht zu lang..)
// statt
int p,q;
// besser
int kontonummer;
int sollbetrag;
// noch besser
int kontonummer; // Index der Kontentabelle
int sollbetrag; // Gesamtschulden [Euro]

• vermeiden Sie Abkürzungen


Übtr. Abkzgn. sind sr. zu lsn. und zu vrstn.

Frank Artinger Informatik - C++ Programmiersprache 19


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

Variablen Hinweise und Tips..


• Vorteil: jeder gut gewählte Variablenname kann später durch
Programmierwerkzeuge (Editor, Cross-Reference-Tool wie grep (find-in-
files) schnell wieder gefunden werden!
• Achten Sie beim Umgang mit physikalischen Größen auf einheitliche
Einheiten!
/***************************************************
* Anm.: Ich habe keine Ahnung, welches Eingabe- *
* oder Ausgabeformat verwendet wird. Aber *
* die Plots sehen ungefaehr richtig aus, *
* wenn ich durch 3 teile. *
****************************************************/

• nicht den Code beschreiben, sondern das, was er tut (oder tun sollte..)
int obere_grenze; // obere_Grenze ist ein Integer

int obere_grenze; // Maximale Anzahl der Datenelemente vor Datenverlust

ergo: möglichst jede verwendete Variable inhaltlich beschreiben!

Frank Artinger Informatik - C++ Programmiersprache 20


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

Ein guter Grundsatz ist:

Keep it Simple, Stupid

• Jedes C++-Programm ist Natur aus ziemlich komplex


• C++ bietet viele sprachliche Idiome (Spezialitäten), die aber nicht alle in
jedem Programm genutzt werden müssen ☺
// ein schlauer Programmierer..
while('\n' != *p++ = *q++); // fast auf einen Blick erkennbar..

// ein kluger (besonnener) Programmierer..


while (true) {
*ziel_ptr = *quell_ptr;
++ziel_ptr; gute Compiler
++quell_ptr;
if(*(ziel_ptr-1) == '\n') optimieren den Code!
break; // Schleife beenden, wenn fertig
}

Frank Artinger Informatik - C++ Programmiersprache 21


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

zu KISS:
In der Software-Technik (Software-Engineering) gilt der Grundsatz:

Je früher ein Fehler in der Software gefunden wird,


desto günstiger ist der Fehler!

Begründung:
• im SW-Entwicklungsprozess sind nach Abschluß der reinen
Entwicklungsphase (M40 feature complete) immer mehr Leute beteiligt, die
auf den Fehler stoßen, bei der Integration und dem Systemtest mit
Seiteneffekten „kämpfen“ (worst case: Fehler tritt erst beim Kunden auf,
Auslieferung der Fehlerkorrektur per Hotfix.., Imageschaden etc.)
• tendenziell erhöht sich auch der Aufwand für die Fehlerkorrektur (Szenario
nicht mehr so bekannt, Entwickler muß sich erst wieder einarbeiten..)

Frank Artinger Informatik - C++ Programmiersprache 22


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

Benennungsstil
• Namen können in C++ sowohl GROSS als auch klein geschrieben werden
• i.A. werden GROSS Buchstaben für Konstanten (#define) oder Makros
(Präprozessoranweisungen) verwendet z.B. MAX_ANZAHL, PI, etc.)
• Viele neuere Programme verwenden gemischte Formen:
eintrageInDatei für lokale Variable
EintrageInDatei für gobal definierte Variable

• Mögliche Probleme:

Je komplizierter das Regelwerk zur Namensbildung, desto höher die


Wahrscheinlichkeit, daß es verletzt und damit inkonsistent wird!

und wieder: möglichst ganze Namen verwenden, keine unnötigen


Abkürzungen.. es gibt auch internationale Projekte..

Frank Artinger Informatik - C++ Programmiersprache 23


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

Code-Religionen
• Informatiker haben viele Programmierstile („Paradigmen“) gefunden
Beispiele:
• strukturierte Programmierung
• Top-Down-Entwurf
• goto-lose Programmierung (keine Sprunganweisungen verwenden)
• gelegentlich wird diesen Regeln „blind“ gefolgt, das muß aber nicht
sein!

Entscheiden Sie sich für eine Vorgehensweise und überlegen Sie


immer kritisch, ob diese Vorgehensweise Sie bestmöglich bei der
Lösung Ihrer Aufgabe unterstützt. Falls nicht, nur Mut, ändern Sie
das Regelwerk. It‘s software, you can go your own way!

Frank Artinger Informatik - C++ Programmiersprache 24


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

Einrückungen und Code-Formatierung


Die Lesbarkeit und damit das Verständnis von Programmcode wird durch
Einrückungen wesentlich erleichtert!

Allgemeine Regel für C++-Programme:

Bei jedem neuen Block oder bedingtem Ausdruck um eine Ebene einrücken!

Es gibt im wesentlichen 2 unterschiedliche Einrückungsstile:

a) Kurzform
b) Langform

schauen wir uns jeweils ein Beispiel an:

Frank Artinger Informatik - C++ Programmiersprache 25


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

Einrückungen und Code-Formatierung


zu a) Kurzform

while(!done) { gleiche Zeile


cout << "Verarbeitung .. " << endl;
naechsterEintrag();

if(total <= 0) {
cout << " Sie haben keine Schulden!" << endl;
total = 0;
} else {
cout << "Sie sind " << total << " Euro schuldig" << endl;
insgesamt = insgesamt + total;
}
}

die meisten geschweiften Klammern werden auf die gleiche Zeile wie die
Anweisung gestellt (s. rot markiert)

Frank Artinger Informatik - C++ Programmiersprache 26


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

Einrückungen und Code-Formatierung


zu b) Langform

while(!done)
{ separate Zeile
cout << "Verarbeitung .. " << endl;
naechsterEintrag();

if(total <= 0)
{
cout << " Sie haben keine Schulden!" << endl;
total = 0;
}
else
{
cout << "Sie sind " << total << " Euro schuldig" << endl;
insgesamt = insgesamt + total;
}
}

die geschweiften Klammern werden auf eine eigene Zeile gestellt (s. rot
markiert) -> benötigt etwas mehr Platz!

Frank Artinger Informatik - C++ Programmiersprache 27


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

Einrückungen und Code-Formatierung


Welche Form sollte man verwenden?

Auch hier gilt: Benutzen Sie das Format, mit dem Sie sich am wohlsten fühlen.
In Büchern wird häufig aus Platzgründen die Kurzform gewählt..

Einrückungsbreite:
• bleibt auch dem Programmierer überlassen
• typisch sind: 2..4..8 Leerzeichen
• Untersuchungen haben gezeigt, daß die Lesbarkeit mit 4 Leerzeichen am
besten ist

bitte konsistent anwenden (also nicht zwischen den Formen und


Einrückungsbreiten wechseln)
bei vielen Editoren kann die Einrückungstiefe /t parametriert werden

Frank Artinger Informatik - C++ Programmiersprache 28


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

Klarheit
Ein Programm sollte sich wie ein technischer Bericht lesen lassen
Aufteilung in Abschnitte und Absätze
Funktionen (Prozeduren) bilden eine natürliche Abschnittsgrenze
Beispiele

// schlechter Programmierstil // eine bessere Version


temp = box_x1; /*
box_x1 = box_x2; * Die beiden Ecken vertauschen
box_x2 = temp; */
temp = box_y1;
box_y1 = box_y2; // Die x-Koordinate tauschen
box_y2 = temp; temp = box_x1;
box_x1 = box_x2;
box_x2 = temp;
Leerzeile
// Die y-Koordinate tauschen
temp = box_y1;
box_y1 = box_y2;
box_y2 = temp;

Frank Artinger Informatik - C++ Programmiersprache 29


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

Einfachheit
Faustregeln:
• Funktionen sollten nicht länger als 1 – 2 Seiten sein, sonst lieber aufteilen in
2 einfachere Funktionen -> Kurzzeitgedächtnis des Menschen ist beschränkt
• keine komplexe Logik in tief verschachtelten if-Anweisungen, lieber
Komplexität durch mehrere Funktionen reduzieren
• wie in der natürlichen Sprache auch: C++-Anweisungen möglichst kurz
halten, Anweisungen über das Zeilenende hinaus sind schwerer lesbar
• divide et impera: Teilen Sie große Codedateien in kleinere Dateien auf, ein
Daumenwert: <= 1.500 Code-Zeilen / Datei
• Klassen: Jede Klasse in ein separates Modul (kommt alles später..)

DAS WICHTIGSTE:
Die Regeln hier sind keine Dogmen, Abweichungen können in der Praxis
durchaus sinnvoll sein!

Frank Artinger Informatik - C++ Programmiersprache 30


Technische Informatik und Programmieren
C++-Programmiersprache
Programmierstil

Qestions & Answers

Weiterführende Literatur:
„C Elements of Style“, Online-Buch unter
http://www.oualline.com/style/index.html

Frank Artinger Informatik - C++ Programmiersprache 31


Technische Informatik und Programmieren