Vorlesung Informatik I

Größe: px
Ab Seite anzeigen:

Download "Vorlesung Informatik I"

Transkript

1 Inhalt Vorlesung Informatik I Universität Augsburg Wintersemester 2010/2011 Prof. Dr. Robert Lorenz Lehrprofessur für Informatik Programmieren in C: Variablen, Teil 2 Wir vervollständigen nun unser Wissen über Variablen und Konstanten: Datentypen und Modifizierer (Überblick) Sichtbarkeit von Variablen Speicherklassen Casts Konstanten Operatoren 1 2 Datentypen Grund-Datentypen: Datentypen Grund-Datentypen können Modifizierer vorangestellt werden: Typ Größe (in Byte) signed mit Vorzeichen char 1 int 4 (2) float 4 double 8 void 0 unsigned long short ohne Vorzeichen lange Version kurze Version 3 4

2 Datentypen - Zusammenfassung Typ Größe Min Max char (char ) unsigned char signed char int unsigned int signed int short int unsigned short int signed short int long int unsigned long int signed long int float E E+38 long double E E+308 double E E+308 Datentypen - Zusammenfassung Abfrage der Speichergrössen und grenzen auf ihrem Rechner: In limits.h und float.h definierte symbolische Konstanten: CHAR_MIN, CHAR_MAX, UCHAR_MAX, INT_MIN, INT_MAX, UINT_MAX SHRT_MIN, SHRT_MAX, USHRT_MAX LONG_MIN, LONG_MAX, ULONG_MAX FLT_MIN, FLT_MAX, DBL_MIN, LDBL_MIN, Verwendung der symbolischen Namen anstatt von Konstanten im Quellcode macht Programme Maschinen-unabhängig 5 6 Datentypen - Zusammenfassung Abfrage der Speichergrössen und grenzen auf ihrem Rechner: Aufruf des sizeof()-operators gibt Grösse eines Datentyps / einer Variable (auch Feldvariable) in Byte aus: sizeof(<datentyp>) sizeof(<variable>) Ergebnis ist vom Typ size_t (ist Compiler-abhängig definiert; laut Standard immer ganzzahlig und unsigned) Verwendung von sizeof anstatt von Konstanten im Quellcode macht Programme Maschinen-unabhängig Sichtbarkeit von Variablen Jeder { Block erzeugt Gültigkeitsbereich für Variablen In einem Gültigkeitsbereich deklarierte Variablen können nur dort benutzt werden ( sind nur dort sichtbar ) Beispiel: main() { { int x = 1; printf( %i,x);//fehler, da x unbekannt In einem Gültigkeitsbereich deklarierte Variablen heißen lokal 7 8

3 Sichtbarkeit von Variablen Jeder { Block erzeugt Gültigkeitsbereich für Variablen Lokale Variablen existieren nur während der Ausführung der Anweisungen in einem Gültigkeitsbereich, also: - Reservieren von Speicherplatz durch Deklaration - Freigeben von Speicherplatz nach - Klammer Sichtbarkeit von Variablen Jeder { Block erzeugt Gültigkeitsbereich für Variablen Speicherung auf dem sog. Stack (Arbeitsspeicherbereich) Speicherplatz des Stacks ist sehr begrenzt (typisch sind 2 MB) Bei zuvielen lokalen Daten: Programm-Abbruch durch stack-overflow Der Stack kann beim Compilieren vergrößert werden Vor der ersten Wertzuweisung hat eine lokale Variable einen zufälligen Wert ( alte Bits am zugewiesenen Speicherplatz) 9 10 Sichtbarkeit von Variablen Jeder { Block erzeugt Gültigkeitsbereich für Variablen Gültigkeitsbereiche können verschachtelt werden Namensgleiche innere Variablen überdecken dann äußere Variablen Beispiel: main() { int x = 2; { int x = 1; printf( %i,x); //Ausgabe: 1 printf( %i,x);//ausgabe: 2 Sichtbarkeit von Variablen Jeder { Block erzeugt Gültigkeitsbereich für Variablen Wir kennen bereits Gültigkeitsbereiche: Schleifenrümpfe while(...){... Rümpfe bedingter Anweisungen if(...){...else{... main-rumpf main(){

4 Sichtbarkeit von Variablen Jeder { Block erzeugt Gültigkeitsbereich für Variablen Richtlinien für lokale Variablen: Deklarieren Sie Variablen so lokal wie möglich Überdecken Sie keine Variablen Erhöht Übersichtlichkeit, Erweiterbarkeit, Wartbarkeit Hilft bei der Vermeidung von Fehlern und bei der Fehlersuche Sichtbarkeit von Variablen Ausserhalb von Gültigkeitsbereichen deklarierte Variablen heißen global Beispiel: int zaehler = 0; main() { int i; for(i=0;i<2;i++){zaehler++;; printf( %i,zaehler); //Ausgabe: Sichtbarkeit von Variablen Ausserhalb von Gültigkeitsbereichen deklarierte Variablen heißen global Können in allen lokalen Gültigkeitsbereichen verwendet und manipuliert werden (sind in der ganzen Datei gültig) Behalten ihren Wert Können lokal überdeckt werden (durch namensgleiche lokale Variable) Vor der ersten Wertzuweisung hat eine globale Variable den Wert 0 (im entsprechenden Datentyp) Sichtbarkeit von Variablen Ausserhalb von Gültigkeitsbereichen deklarierte Variablen heißen global Richtlinien für globale Variablen: Sparsam verwenden Nicht lokal überdecken In der Deklaration initialisieren Erhöht Übersichtlichkeit, Erweiterbarkeit, Wartbarkeit Hilft bei der Vermeidung von Fehlern und bei der Fehlersuche 15 16

5 Speicherklassen Speicherklassen legen fest, wo und wie Variablen-Werte gespeichert werden: Angabe am Anfang der Variablendeklaration: <Speicherklasse> <bekannte Deklaration>; Speicherklassen Speicherklasse auto Speicherplatz nur bis zum Verlassen des Gültigkeitsbereiches reserviert Standardeinstellung für lokale Variablen Speicherung im Arbeitsspeicher Speicherklassen Speicherklasse register Speicherplatz nur bis zum Verlassen des Gültigkeitsbereiches reserviert Variante für lokale Variablen mit häufigem Zugriff, z.b. Zählvariablen Speicherung in einem Register des Prozessors schnellerer Zugriff nur begrenzte Anzahl von Registern verfügbar (~2) nur für int- und char- Werte keine Speicheradresse verfügbar Speicherklassen Speicherklasse static zur Deklaration global gültiger Variablen static-variablen behalten ihren jeweils letzten Wert bei und sollten in der Deklaration initialisiert werden (Übersichtlichkeit) Vergleich static-variable vs. globale Variable: Semantik ist gleich Funktionen mit static-variablen sind leichter portabel Beispiel: Zufallszahlen-Generatoren (später, Übung) 19 20

6 Speicherklassen Speicherklasse extern zur Deklaration global gültiger Variablen für Programme, die aus mehreren Dateien bestehen Globale Variable wird in einer der Dateien normal deklariert und in allen anderen als extern deklariert Compiler reserviert nur einmal Speicherplatz (weitere Syntax-Einschränkungen) (auch auf Funktionen anwendbar) Casts Bekannt: Compiler vollzieht automatische Datentyp-Umwandlungen in Ausdrücken und Wertzuweisungen Jetzt: Der Compiler kann durch sog. Casts zu Datentyp-Umwandlungen gezwungen werden Beispiel: später Casts Syntax für Umwandlung in einen Datentyp: (<Datentyp>) Ausdruck Casts Syntax für Umwandlung in einen Datentyp: (<Datentyp>) Ausdruck Beispiel: double x = (double) 5 / 2;//Wert von x ist (double) wandelt 5 wird in 5.0 um 2. Automatische Typumwandlung passt Datentyp von 2 an 3. Es wird 5.0 / 2.0 gerechnet Beispiel: double x = (double) (5 / 2);//Wert von x ist Es wird 5 / 2 gerechnet 2. (double) wandelt das Ergebnis 2 in 2.0 um Beachte hierbei: Der Cast-Operator bindet als unärer Operator stärker als binäre Operatoren 23 24

7 Konstanten Ganzzahl-Konstanten Ziffernfolge ohne 0 am Anfang, optional mit /+ als erstes Zeichen Dezimaldarstellung Datentyp: int Beispiel: 100 Ziffernfolge mit einer 0 am Anfang und keiner 0 als zweites Zeichen Oktaldarstellung Datentyp: unsigned int Beispiel: 0144 Konstanten Ganzzahl-Konstanten Folge aus Zeichen 0,,9,A,,F mit 0X am Anfang und keiner 0 als drittes Zeichen Hexadezimaldarstellung Datentyp: unsigned int Beispiel: 0X64 Ziffernfolge ohne 0 am Anfang, mit L abgeschlossen, optional mit als erstes Zeichen Datentyp: long int Beispiel: 100L Konstanten Ganzzahl-Konstanten: Ziffernfolge ohne 0 am Anfang, mit U abgeschlossen, optional mit als erstes Zeichen Datentyp: unsigned int Beispiel: 100U Verwendung in spezifischen Anwendungen, deren mathematische Struktur dies nahelegt Konstanten Fließkommakonstanten: Festkommadarstellung Datentyp: double Beispiel: 3.67 Gleitkommadarstellung Datentyp: double Beispiel: -4.1e+2 Bsp.: Hexadezimaldarstellung bei Verschlüsselungsprogrammen 27 28

8 Konstanten Zeichenkonstanten: In Hochkommas eingeschlossenes Zeichen Datentyp: char Zwischenraumzeichen: \n, \r, \t, \v, \b, \f Sonderzeichen:\,\,\\,\a,\? Beispiele: A, ], \n Konstanten Zeichenkettenkonstanten: In Anführungszeichen eingeschlossene Zeichenfolge Können Zwischenraum- und Sonderzeichen enthalten Werden im Speicher durch die binäre 0 abgeschlossen Länge einer Zeichenkette mit n Zeichen ist n+1 \w mit w = ASCII-Code in Oktalschreibweise Datentyp: char Beispiel: \101 (entspricht A ) \xw mit w = ASCII-Code in Hexadezimalschreibweise Datentyp: char Beispiel: \x41 (entspricht A ) Konstanten Variablenkonstanten: Variablen können als konstant deklariert werden, wenn ihr Wert nicht mehr verändert werden soll Syntax: const <Datentyp> <Name> = <Wert> <Datentyp> const <Name> = <Wert> Beispiel: const double PI = 3.14; Auf solche Variablen kann nur lesend zugegriffen werden Konstante Variablen sind also symbolische Namen für Konstanten Müssen in der Deklaration initialisiert werden Formatangaben %d,%i int %ld long int %u unsigned int %lu unsigned long int %o unsigned int (Oktalzahl) %x unsigned int (Hexadezimalzahl) %f float %lf double %Lf long double %e double (Fließkommazahl) %c char %s char* (Zeichenkette) %% '%' (Prozentzeichen) Konvention: Verwende nur Großbuchstaben für symbolische Namen 31 32

9 Operatoren Unäre Operatoren:! (Negation) Alle Datentypen -,+ (Vorzeichen) Alle Datentypen (type) (Cast) Alle Datentypen ++,-- (Inkrement,Dekrement) Alle Datentypen i++ liefert den Wert von i und erhöht dann i um 1 ++i erhöht i um 1 und liefert dann den Wert von i i-- liefert den Wert von i und verringert dann i um 1 --i verringert i um 1 und liefert dann den Wert von i ~ (1-Komplement=Negation) Alle Ganzzahltypen Operatoren Arithmetische Operatoren +,-,*,/ Alle Datentypen % Alle Ganzzahltypen Binäre bitweise Operatoren (sehr schnelle Ausführung!) (Bitweises oder) Alle Ganzzahltypen Operiert stellenweise auf Bits, wie für Wahrheitswerte & (Bitweises und) Alle Ganzzahltypen Operiert stellenweise auf Bits, wie && für Wahrheitswerte ^ (Bitweises exklusives oder) Alle Ganzzahltypen Operiert stellenweise auf Bits, x^y entspricht (x y)&~(x&y) <<,>> (Verschiebeoperatoren) Alle Ganzzahltypen x<<n entspricht Multiplikation von x mit 2 n x>>n entspricht Division von x durch 2 n Operatoren Vergleichsoperatoren <,>,<=,>=,==,!= Alle Datentypen Logische Operatoren,%%,! Alle Datentypen Zuweisungsoperatoren = (Wertzuweisung) Alle Datentypen +=,*=,/=,-=, =,&=,^=,%=,<<=,>>= x op= y entspricht x = y op x (op binärer Operator) für zu op passende Datentypen Vorlesung Informatik I Universität Augsburg Wintersemester 2010/2011 Prof. Dr. Robert Lorenz Lehrprofessur für Informatik Programmieren in C - Funktionen 35 1

10 Inhalt Motivation: Bisher: Braucht man in einem Programm eine Berechnung mehrmals, so muss der Code dafür immer wieder neu geschrieben werden Das Programm wird unnötig lang und unübersichtlich Jetzt: Häufiger (oder in mehreren Programmen) vorkommende Berechnungen werden als Funktion gekapselt. Die Funktion muss nur einmal geschrieben werden und kann dann immer wieder benutzt werden Inhalt Motivation (Code ohne Funktionen): /*bsp14a.c*/ #include <stdio.h> main() { double ergebnis,fak49=1.0,fak43=1.0,fak6=1.0; int i; for(i=1; i <= 49; i++) { fak49*=i; for(i=1; i <= 43; i++) { fak43*=i; for(i=1; i <= 6; i++) { fak6*=i; ergebnis=fak49/(fak43*fak6); printf("\ndie Anzahl der moeglichen Kombinationen "); printf("im Lotto 6 aus 49 ist %.0f \n",ergebnis); 2 3 Inhalt Motivation (Code mit Funktionen): /*bsp14b.c*/ #include <stdio.h> double fakultaet(int zahl){ int i; double ergebnis=1.0; for(i=1; i <= zahl; i++) { ergebnis*=i; return(ergebnis); main() { double erg=fakultaet(49)/(fakultaet(43)*fakultaet(6)); printf("\ndie Anzahl der moeglichen Kombinationen "); printf("im Lotto 6 aus 49 ist %.0f \n",erg); Inhalt Motivation: Beispiele: Vorgegebene Bibliotheksfunktionen aus stdio.h: printf, scanf, getchar Sinnvolle eigene Funktionen: fak Berechung der Fakultät einer natürlichen Zahl leeren Leeren des Standard-Eingabestroms ggt Berechung des größten gemeinsamen Teilers maximum Berechnet das Maximum zweier Zahlen vspace Ausgabe eines vertikalen Abstands 4 5

11 Inhalt Syntax Aufruf Deklaration Call by Value Deklaration und Definition <Rückgabetyp> <Name> (<Parameter>) {<Rumpf> Beispiele double fakultaet(int zahl){... Rückgabetyp: double Name: fakultaet Ein Parameter: Typ: int, Name: zahl void leeren(){... kein Rückgabetyp (void) Name: leeren kein Parameter 6 7 Deklaration und Definition <Rückgabetyp> <Name> (<Parameter>) {<Rumpf> Beispiele double maximum(double a, double b){... Rückgabetyp: double Name: maximum Zwei Parameter: beide vom Typ: double, Namen: a,b void vspace(int n){... kein Rückgabetyp (void) Name: vspace Ein Parameter: Typ: int, Name: n Deklaration und Definition Rückgabetyp: Datentyp des Rückgabewerts, falls es einen gibt Es kann höchstens ein Wert zurückgegeben werden Es muss kein Wert zurückgegeben werden Für Funktionen ohne Rückgabewert wird void verwendet Ist kein Rückgabetyp angegeben, so nimmt der Compiler automatisch int an 8 9

12 Deklaration und Definition Funktionsname: Im Prinzip frei gewählter Name Konventionen: klein geschrieben, sprechend Deklaration und Definition Parameter: Variablen zur Verwendung im Rumpf Festlegung von Datentyp und Name in der Form: <Datentyp> <Name> Bei Aufruf müssen konkrete Werte eingesetzt werden Mehrere Parameter durch Komma getrennt Parameternamen nur lokal im Rumpf gültig Deklaration und Definition Rumpf: Deklaration und Definition Die return-anweisung: Dient der Definition der Funktion return; Beendet Funktion ohne Rückgabewert Dazu können weitere Variablen deklariert werden (lokal gültig) return E; Gleichbedeutend zu return(e); Rückgabetyp void: Letzte ausgeführte Anweisung von der Form return(e) E Ausdruck mit zum Rückgabetyp passenden Wert Wert von E = Rückgabewert der Funktion 12 13

13 main-funktion main hat Rückgabewert int Rückgabewert gibt an, ob main korrekt beendet wurde: Rückgabewert = 0: korrekt beendet Rückgabewert 0: Rückgabewert = Fehlercode Ab jetzt main also wie folgt benutzen: int main(){... main-funktion Über Fehlercodes können verschiedene Programme Informationen austauschen (weiterführendes Thema) Es gibt systemabhängige Fehlercodes Man kann selbst Fehlercodes ausgeben mit return(code) oder exit(code) (exit gibt zusätzlich Systemressourcen frei) Aufruf <Name> (<Parameterwerte>) Beispiele int n = fakultaet(10); Aufruf Parameterwerte Für jeden Parameter einen Ausdruck mit Wert passenden Typs: in der richtigen Reihenfolge zum Zeitpunkt des Aufrufs auswertbar leeren(); double a; scanf( %lf,&a); double max = maximum(a+1,2*a); vspace(2); 16 17

14 Aufruf Auswertung: 1. Auswertung der Parameterwerte 2. Einsetzen der Werte für die Parameternamen im Rumpf 3. Ausführung des Rumpfs 4. Rückgabetyp void: Ersetzung des Aufrufs durch Rückgabewert Folgerung: Funktionsaufrufe sind Ausdrücke Prototypen <Rückgabetyp> <Name> (<Parameter>); Wird am Programmanfang angegeben (noch ohne Rumpf) Legt die korrekte Benutzung einer Funktion fest : Wieviel Eingabeparameter gibt es? Welchen Typs sind diese Parameter? Gibt einen Rückgabewert? Ggf.: welchen Typs ist der Rückgabewert? Hintergrund: Vor Aufruf sollte Compiler die Funktion kennen, damit er deren korrekte Benutzung überprüfen kann Prototypen Beispiele aus stdio.h: int getchar(); Rückgabewert ist ASCII-Code eines Zeichens oder EOF EOF = Konstante für Dateiende (End Of File) vom Typ int Prototypen Beispiele aus stdio.h: int printf(const char * format,...); Rückgabewert ist Anzahl der geschriebenen Zeichen const char * = Typ für konstante Zeichenketten (später) int scanf(const char * format,...); Rückgabewert ist Anzahl der gelungenen Wertzuweisungen const char * = Typ für konstante Zeichenketten (später) 20 21

15 Prototypen Bibliotheksfunktionen in Online-Dokumentation recherchieren: Dokumentation enthält die Prototypen der Bibliotheksfunktionen und Beschreibungen der Bedeutung der Parameter Lernziel: sich die korrekte Benutzung und den sinnvollen Einsatz von Bibliotheksfunktionen selbst durch die Dokumentation aneignen Beispiele: int rand(), double sqrt(double x), int isdigit(int c), int strcmp(const char * cs, const char * ct),... Prototypen Formatfunktionen /*bsp15.c*/ #include <stdio.h> void vspace(int n); main() { int eingabe; printf("wieviel Abstand?"); scanf("%i",&eingabe); vspace(eingabe); void vspace(int n) { int i; for(i=1; i<=n; i++) { printf("\n"); Beispiele Standardeingabestrom leeren /*bsp16a.c*/ #include <stdio.h> void leeren(); main() {... void leeren(){ while (getchar()!='\n') { Beispiele Eingabefunktion /*bsp16b.c*/ #include <stdio.h> double eingabe(); main() {... double eingabe(){ double zahl; while(scanf("%lf",&zahl)==0){ leeren(); printf("bitte Zahl eingeben!"); leeren(); return zahl; 24 25

16 Beispiele Standardeingabestrom leeren + Eingabefunktion /*bsp16b.c*/ #include <stdio.h> void leeren(); double eingabe(); main() {... double zahl; printf("beenden der Eingabe mit '0' "); while(1) { printf("bitte Zahl eingeben : "); zahl = eingabe(); if (zahl==0){break;... Call by Value An Funktionen werden Werte übergeben, keine Variablen! Für an Funktionen übergebene Variablen werden lokale Kopien angelegt Im Rumpf wird mit den lokalen Kopien gerechnet Wert der Variablen kann im Rumpf nicht geändert werden (nur der Wert der lokalen Kopie) Call by Value An Funktionen werden Werte übergeben, keine Variablen! Beispiel: /*bsp17.c*/ #include <stdio.h> void meinefunktion(int x); main(){ int x = 1; meinefunktion(x); printf( %i,x);//ausgabe ist 1! void meinefunktion(int test){ test++; Vorlesung Informatik I Universität Augsburg Wintersemester 2010/2011 Prof. Dr. Robert Lorenz Lehrprofessur für Informatik Programmieren in C Der Compilierungsprozess 28 1

17 Aufbau eines C-Programms 1. Direktiven für den Präprozessor 2. Globale Vereinbarunen a. Globale Variablen b. Funktions-Prototypen 3. main-funktion a. lokale Vereinbarungen b. Anweisungen Aufbau eines C-Programms C-Programme sind Sammlungen von Funktionen Funktionen zerlegen Programme in kleinere, selbständige Einheiten erhöht Übersichtlichkeit und Wartbarkeit Alle benutzten Funktionen müssen zu Beginn deklariert werden 4. Funktions-Definitionen a. lokale Vereinbarungen b. Anweisungen 2 3 Aufteilung großer C-Programme Compilierungsprozess - Überblick Zur Modularisierung werden die Funktionen auf mehrere Quelldateien verteilt und getrennt übersetzt (genau einer der Dateien enthält die main-funktion) Jede solche Datei sollte eine sinnvoll zusammenhängende Gruppe von Vereinbarungen enthalten. Die Deklarationen der Funktionen, die in mehreren Quelldateien benötigt werden, werden in Header-Dateien zusammengefasst (werden mit #include eingebunden) Mehrfach benötigten Vereinbarungen werden nur in wenigen Dateien verwaltet Bibliotheken Quellcode Präprozessor (erweiterter Quellcode) Compiler Assemblercode Assembler Objektcode Linker ausführbarer Code 4 5

18 Inhalt Präprozessor Compiler Assembler Linker Bibliotheksfunktionen Das Programm gcc Große Programme Präprozessor Konstanten deklarieren Die Präprozessor-Direktive #define <Name> <Zeichenkette> veranlasst den Präprozessor, jedes Vorkommen von <Name> im folgenden Quellcode durch <Zeichenkette> zu ersetzen Ausnahme: Keine Ersetzung in Namen und Zeichenketten <Name> kann im Programm als Konstante benutzt werden, deren Wert durch <Zeichenkette> gegeben ist 6 7 Präprozessor Konstanten deklarieren Beispiele für sinnvolle eigene Deklarationen: #define PI 3.14 #define TRUE 1 #define FALSE 0 #define MAX_BUFFER 1000 Konvention: Der Name der Konstante besteht aus Großbuchstaben und wird an keiner anderen Stelle benutzt Präprozessor Konstanten deklarieren Vordefinierte Beispiele aus Header-Dateien: Wertebereichgrenzen von Datentypen (in limits.h, float.h) LINE aktuelle Zeilennummer im Programmcode (num.) FILE Dateiname (Zeichenkette) DATE aktuelles Datum (Zeichenkette) TIME aktuelle Zeit (Zeichenkette) (u.v.m.) 8 9

19 Präprozessor Konstanten deklarieren Vorteile: Konstanten muss man bei Bedarf nur einmal ändern Programm ist besser lesbar Vergleich zu globalen konstanten Variablen: Keine zusätzliche Variable nötig Konfiguration mehrerer Programme durch Deklaration in Header- Datei möglich Präprozessor Makros deklarieren Die Präprozessor-Direktive #define <Name>(<Parameternamen>) <Zeichenkette> veranlasst den Präprozessor zu folgendem: Ersetzt jedes Vorkommen von <Name>(<Argumente>) im Quellcode durch <Zeichenkette> Ersetzt jeden in <Zeichenkette> vorkommenden Namen aus <Parameternamen> durch zugehöriges Argument aus <Argumente> <Parameternamen>: Durch Komma getrennte Parameternamen <Argumente>: Durch Komma getrennte Ausdrücke <Name>(<Argumente>) kann im Programm als Aufruf einer Funktion, die durch <Zeichenkette> definiert ist, benutzt werden Präprozessor Makros deklarieren Selbst definierte Beispiele: #define inhalt(r) PI*(r)*(r); Aufruf im Code: double inhalt = inhalt(10); #define max(a,b) ( ((a) > (b))? (a) : (b)) ); Aufruf im Code: scanf( %i,&x);int m=max(5*x,x*x); Vordefinierte Beispiele aus Headerdateien: Oft ist getchar ein Makro Präprozessor Makros deklarieren Achtung: In <Zeichenkette> benutzte Operationszeichen können stärker binden als die Operatoren in einem für einen Parameternamen eingesetzten Ausdruck! Man muss dafür sorgen, dass der Ausdruck nach dem Einsetzen unbedingt zuerst ausgewertet wird Dazu unbedingt die in <Zeichenkette> vorkommenden Parameternamen klammern (Beispiel vorige Folie) 12 13

20 Präprozessor Makros deklarieren Vergleich zu Funktionen Parameter sind Datentyp-unabhängig: #define max(a,b) ( ((a) > (b))? (a) : (b)) ); Präprozessor Makros deklarieren Vergleich zu Funktionen Es entsteht mehr Programmcode, da der Funktionsrumpf für alle Vorkommen des Funktionsnamens eingesetzt wird Mögliche Aufrufe : int m = max(5,7); double m = max(5.0,7.5); Präprozessor Header-Dateien in den Code einfügen Die Anweisung #include <Header-Datei> veranlasst den Präprozessor, die angegebene Header-Datei in den Quellcode zu kopieren Es entsteht ein erweiterter Quellcode Präprozessor Header-Dateien in den Code einfügen Eine Header-Datei ist eine Textdatei um Funktions-Prototypen zu deklarieren (kennen wir schon) Konstanten zu deklarieren (wie eben) Makros zu definieren (wie eben) Man kann (sollte) sich seine eigenen Header-Dateien schreiben Da die Header-Datei nur in den Quellcode kopiert wird, kann man doch alles auch gleich direkt in den Quellcode schreiben!? 16 17

21 Präprozessor Header-Dateien in den Code einfügen In einer Header-Dateien sammelt man Vereinbarungen und Funktionalitäten, die man immer wieder für einen bestimmten Anwendungsbereich braucht Ist beliebig oft in wiederverwendbar, ohne dass man alles in jedem Programm nochmal extra aufschreiben muss Präprozessor Header-Dateien in den Code einfügen Beispiele: stdio.h (Standard Input Output): Unterstützung von Eingabe und Ausgabe math.h: Unterstützung mathematischer Funktionen und Konstanten string.h: Unterstützung bei der Verarbeitung von Zeichenketten Präprozessor Header-Dateien selbst schreiben Textdatei mit Präprozessor-Direktiven schreiben Unter beliebigem Namen mit Endung.h abspeichern in: Programmverzeichnis include-verzeichnis des Compilers In Quellcode einbinden durch Anweisung: include-verzeichnis: #include <Headerdatei.h> (relative Pfadangaben erlaubt) Programmverzeichnis: #include Headerdatei.h (relative und absolute Pfadangaben erlaubt) Präprozessor Header-Dateien selbst schreiben Achtung: Es sind verschachtelte include-anweisungen möglich Datei Header1.h enthält Direktive #include Header2.h Dadurch kann es durch mehrfaches Einbinden von Direktiven zu Syntaxfehlern kommen Programm enthält Direktiven #include Header1.h und #include Header2.h Lösung: Bedingte Aktivierung von Direktiven 20 21

22 Präprozessor Header-Dateien selbst schreiben Bedingte Aktivierung von Direktiven Headerdateien sollten immer die folgende Form haben: #ifndef DATEINAME_H_INCLUDED #define DATEINAME_H_INCLUDED <Deklarationen> #endif Präprozessor Header-Dateien selbst schreiben Bedingte Aktivierung von Direktiven #define Fasst Deklarationen unter einem Namen zusammen Name = Dateiname in Großbuchstaben + _ #ifndef Text einbinden, falls Name noch nicht exisitiert #ifdef Text einbinden, falls Name schon exisitiert...#endif Präprozessor Erstellen mehrteilger Programme 1. Zerlegung des Programms in funktionale allgemein wiederverwendbare Module 2. Für jedes Modul: Headerdatei erstellen Code-Datei erstellen mit eingebundenem Header Präprozessor Erstellen mehrteilger Programme - Beispiel Datei format.h: #ifndef FORMAT_H_INCLUDED #define FORMAT_H_INCLUDED void vspace(int n); void hspace(int n); #endif 3. Programmdatei mit main-funktion erstellen 4. Übersetzungsprozess (später) Analog für Sammlungen mathematischer Funktionen (Fakultät) oder Eingabefunktionalitäten (Eingabestrom leeren, Eingaben vom Benutzer verarbeiten,...) 24 25

23 Präprozessor Erstellen mehrteilger Programme - Beispiel Datei format.c: #include format.h #include <stdio.h> void vspace(int n){ int i; for(i=1;i<=n;i++){printf("\n"); void hspace(int n){... Präprozessor Erstellen mehrteilger Programme - Beispiel Datei programm.c: #include format.h #include eingabe.h #include computations.h #include <stdio.h> int main(){ Compiler Zusammenfassung Überprüft den (erweiterten) Quellcode auf Syntaxfehler (lässt sich das Programm in Maschinensprache übersetzen?) Weist Variablen und Konstanten Speicherbereiche zu Übersetzt den Quellcode in Assemblercode (Assemblercode ist symbolischer=menschenlesbarer Maschinencode) Assembler Überblick Übersetzt Assemblercode in Maschinencode Was jetzt noch fehlt? Zusammenführung von mehreren Quellcode-Dateien Integration von Bibliotheksfunktionen 28 29

24 Linker Überblick Bindet andere Dateien mit dem Hauptprogramm: Führt mehreren Quellcode-Dateien in einer Datei zusammen (man sagt, Quellcode-Dateien werden statisch (ein)gebunden) Fügt Informationen für den Zugriff auf Bibliotheksfunktionen ein (man sagt, Bibliotheksfunktionen werden dynamisch gebunden) Linker Bibliotheksfunktionen werden in Header-Dateien also nur deklariert (aber nicht definiert) sind entweder vorübersetzte C-Programme oder direkt ausführbare Assembler-Programme werden mit dem Compiler installiert Das Programm gcc Das Programm gcc umfasst die Ausführung von Preprozessor, Compiler, Assembler und Linker Mittels verschiedener Optionen (Kommandozeilenparameter) lassen sich diese Programme auch einzeln ausführen Mittels verschiedener Optionen lässt sich die Syntax-Kontrolle unterschiedlich detailliert ausführen Das Programm gcc gcc Optionenen: Syntaxkontrolle -ansi weist den Compiler an, den C89-Standard zu verwenden. -pedantic bringt ihn weiterhin dazu, nichts außer dem C89-Standard z zuzulassen -W schaltet zusätzliche Warnungen an. -Wall schaltet alle zusätzlichen Warnungen an. -Wextra schaltet zusätzliche zusätzliche Warnungen an. -Wmain schaltet zusätzlich Warnungen über eine falsch definierte main()-funktion an. Man sollte ALLE Warnungen zum verstummen bringen, selbst wenn das Programm schon übersetzbar ist und läuft 32 33

25 Das Programm gcc gcc Optionenen: Teile ausführen Das Programm gcc gcc Optionenen: weitere (Auswahl) -E Preprozessor wird ausgeführt (nicht Compiler, Assembler, Linker) Ausgabe in Datei <Programmname>.i -S Compiler wird ausgeführt (nicht Assembler, Linker) Ausgabe in Datei <Programmname>.S -c Compiler und Assembler werden ausgeführt (nicht Linker) Ausgabe in Datei <Programmname>.o -save-temps Zwischenergebnisse werden gespeichert --help Übersicht über Benutzung des Programms -o <name> Festlegung des Namens der Ausgabedatei -WI -stack <Bytes> Stackgröße erhöhen Das Programm gcc Übersetzung mehrteilger Programme 1. Dateien ohne main-funktion übersetzen in Objektcode gcc -ansi -pedantic -W -Wall -Wextra -c modul1.c 2. Datei mit main-funktion übersetzen + mit Objetdateien linken gcc -ansi -pedantic -W -Wall -Wextra -Wmain modul1.o modul2.o programm.c -o Programm Vorlesung Informatik I Universität Augsburg Wintersemester 2010/2011 Prof. Dr. Robert Lorenz Lehrprofessur für Informatik Algorithmen und ihre Darstellung 36 1

26 Inhalt Motivation In der Regel schreibt man nicht direkt ein Programm zur Lösung eines Problems, sondern entwirft erstmal ein abstrakteres Modell der Lösung Zerlegung der Problemlösung in mehrere Schritte Abstraktion von Spezifika von Programmiersprachen Inhalt Zerlegung der Problemlösung in mehrere Schritte Problem Analyse und Präzisierung des Problems Problemspezifikation Herausfinden eines Lösungsweges Algorithmus (programmiersprachenunabhängig, formal) Übersetzung in computerverständliche Form Programm (in geeigneter Programmiersprache) 2 3 Inhalt Der Algorithmusbegriff Algorithmusdarstellungen: Programmablaufplan Struktogramm Pseudocode Algorithmusbegriff Ein Algorithmus ist ein exaktes Verfahren zur Lösung eines Problems Bestandteile eines Algorithmus Daten, auf die eine Wirkung ausgeübt werden soll Anweisungen, die mittels Elementaroperationen auf gewünschte Weise auf Daten wirken Kontrollstrukturen, die die Anweisungen in die richtige Reihenfolge bringen 4 5

27 Algorithmusbegriff Beispiel: Auswechseln eines Reifens am Auto (1) Löse die Radmuttern. (2) Hebe den Wagen an. (3) Schraube die Radmuttern ab. (4) Tausche das Rad gegen ein anderes Rad aus. (5) Schraube die Radmuttern an. (6) Setze den Wagen ab. (7) Ziehe die Radmuttern fest. Algorithmusbegriff Beispiel: Auswechseln eines Reifens am Auto (1) Wiederhole für jede Radmutter: Löse die Radmutter (Ende der Wiederholung) (2) Hebe den Wagen an. (3) Schraube die Radmuttern ab. 6 7 Algorithmusbegriff Beispiel: Auswechseln eines Reifens am Auto (1) Wiederhole für jede Radmutter: Wiederhole: Setze Schraubenschlüssel an Drehe Schraubenschlüssel um 90 Grad nach links bis Radmutter gelöst. (Ende der Wiederholung) (2) Hebe den Wagen an. (3) Schraube die Radmuttern ab. Algorithmusbegriff Beispiel: Auswechseln eines Reifens am Auto (1) Wiederhole für jede Radmutter: Falls Radmutter angerostet: Behandele Radmutter mit Spray Warte 5 Minuten (Ende der Fallunterscheidung) Wiederhole: Setze Schraubenschlüssel an Drehe Schraubenschlüssel um 90 Grad nach links bis Radmutter gelöst. (Ende der Wiederholung) 8 9

28 Algorithmusbegriff Beispiel: Auswechseln eines Reifens am Auto Beobachtungen: Anwender des Algorithmus muss jeden einzelnen Schritt verstehen und ausführen können Algorithmusbegriff Algorithmen in der Informatik Daten sind computerverständlich dargestellt Daten werden mittels Variablen (bestimmter Datentypen) beschrieben Verfahren enthält Sequenzen und Wiederholungen von Handlungen (Anweisungen). Über Reihenfolge der Anweisungen wird erst während der Ausführung des Algorithmus mittels Fallunterscheidungen entschieden Algorithmusbegriff Algorithmen in der Informatik Anweisungen sind computerverständlich formuliert Anweisungen werden durch Elementaroperationen ausgedrückt Algorithmusbegriff Algorithmen in der Informatik Ablaufstrukturen werden formal dargestellt Darstellungen bei uns: Programmablaufplan, Struktogramm, Pseudocode Unterschiedliche Abstraktionsebenen möglich: benutzernah maschinennah Auch noch umgangssprachliche Formulierungen erlaubt! Unterste Ebene bei uns: Sprachkonstrukte höherer Programmiersprachen 12 13

29 Darstellungen Programmablaufplan, Struktogramm, Pseudocode Grundelemente Bedingungen und Anweisungen dürfen auch umgangssprachlich formuliert werden Daten werden durch Variablen dargestellt Abstraktion von Datentypen, Eingabe und Ausgabe Kontrollstrukturen: Sequenzen, Wiederholungen, Fallunterscheidungen Darstellungen Programmablaufplan, Struktogramm, Pseudocode Kontrollstrukturen Sequenz Führe eine Anweisung nach der anderen einer Anweisungs- Sequenz aus Fallunterscheidung Führe Anweisungen nur aus, falls eine Bedingung zutrifft (und falls nicht, so führe andere Anweisungen aus) Wiederholung Führe Anweisungen wiederholt aus, solange eine Bedingung zutrifft Darstellungen Problemablaufpläne Programmablaufplan, Struktogramm, Pseudocode Syntaktische Unterschiede zu Anweisungen zu C Wertzuweisung in C: = hier: := Vergleich auf Gleichheit in C: == hier: = 16 17

30 Problemablaufpläne Problemablaufpläne Sequenz: Anweisung 1 Anweisung 2 Als C-Code: Anweisungen sind C-Elementaroperationen oder müssen durch solche ausgedrückt (implementiert) werden Anweisung 1; Anweisung 2; Problemablaufpläne Fallunterscheidung: Bedingung nein Anweisung 1b Problemablaufpläne Wiederholungen: Bedingung ja nein Anweisung 1a Übersetzung in C-Code: if (Bedingung) { Anweisung 1a; else { Anweisung 1b; Anweisung x; ja Anweisung x Übersetzung in C-Code: while(bedingung){ Anweisung 1; Anweisung n; Anweisung 1 Anweisung n 20 21

31 Problemablaufpläne Wiederholungen: Anweisung 1 Problemablaufpläne Anweisung n Übersetzung in C-Code: do { Anweisung 1; Anweisung n; while(bedingung) ja Bedingung nein Problemablaufpläne Vorteile graphische Darstellung verschiedene Abstraktionsebenen möglich alle wesentlichen Kontrollstrukturen darstellbar (teilweise umständlich) Problemablaufpläne Nachteile bei größeren Diagrammen zu unübersichtlich Verzweigungen und Zusammenführungen können beliebig miteinander kombiniert werden 24 25

32 Problemablaufpläne Struktogramme Nachteile: Beispiel unübersichtliches Modell Anweisung ja Bedingung nein Anweisung nein Bedingung ja Anweisung Anweisung Struktogramme Struktogramme Übersetzung in C-Code: F1 F2 Fn Übersetzung in C-Code: while(b){ do{ F F while(!b) 28 29

33 Struktogramme Struktogramme Übersetzung in C-Code: if(b){ F1 else { F Struktogramme Struktogramme Oberster Block: Sequenz Oberster Block: Sequenz Innere Blöcke: Rechte Seite Anweisung Anweisung Schleife Verzweigung 32 33

34 Struktogramme Struktogramme Schleife: Innerer Block: Sequenz Verzweigung: Innere Blöcke: Sequenzen Struktogramme Vorteile gegenüber Programmablaufplänen: Struktogramme beinhalten Symbole für alle wichtigen Ablaufstrukturen höherer Programmiersprachen (Verzweigungen, while-/ repeat-anweisungen) Top-Down-Entwurf und die schrittweise Verfeinerung von Algorithmen möglich (Prinzip der strukturierten Programmierung) Beliebige Sprünge können nicht dargestellt werden Zwang zu übersichtlicher Darstellung Struktogramme Achtung! (Gültige) Struktogramme können nur durch obige Regeln konstruiert werden. Ist ein Diagramm nicht durch ein wie eben beschriebenes hierarchisches Top-Down-Vorgehen (ein Strukturblock komplett enthalten in einem anderen Strukturblock) konstruierbar, so handelt es sich nicht um ein Struktogramm 36 37

35 Pseudocode Verbale Beschreibung von Algorithmen unter Benutzung von Ablaufstrukturen der strukturierten Programmierung (z.b. mit Sprachkonstrukten höherer Programmiersprachen). Pseudocode Es bezeichne F, F1, F2,..., Fn elementare oder zusammengesetzte Anweisungen und B einen logischen Ausdruck. Dann sind die folgenden Ausdrücke ebenfalls zusammengesetzte Anweisungen: Pseudocode Übersetzung in C-Code: F1 F2 Fn Pseudocode Übersetzung in C-Code: while(b){ do{ F F while(!b) 40 41

36 Pseudocode Pseudocode Übersetzung in C-Code: if(b){ F1 else { F Pseudocode Pseudocode Elementare Anweisung Elementare Anweisung Schleife Oberste zusammengesetzte Anweisung: Sequenz Verzweigung Oberste zusammengesetzte Anweisung: Sequenz 44 45

37 Pseudocode Pseudocode Elementare Anweisung Elementare Anweisung Schleife Elementare Anweisung Elementare Anweisung Verzweigung Pseudocode Bewertung: ähnlich wie Struktogramme weniger anschaulich, da nicht graphisch kompakter als Struktogramme unabhängig von konkreter Programmiersprache im Vergleich zu konkreten Programmiersprachen: keine Implementierungsdetails keine Typ- und Variablendeklarationen natürlichsprachliche Details sind erlaubt Pseudocode Achtung! (Gültiger) Pseudocode kann nur durch obige Regeln konstruiert werden. Ist ein Programmcode nicht durch ein wie eben beschriebenes hierarchisches Top-Down-Vorgehen (eine elementare oder zusammengesetzte Anweisung komplett enthalten in einer anderen zusammengesetzten Anweisung) konstruierbar, so handelt es sich nicht um Pseudocode 48 49

38 Ein in Pseudocode, als Struktogramm oder Programmablaufplan gegebener Algorithmus läßt sich wie folgt als Funktion in C implementieren: (1) Lege Datentypen der Variablen fest; (2) Eingabe-Variablen = Eingabeparameter der Funktion (3) Alle anderen Variablen = lokale Variablen (so lokal wie möglich, keine globalen Variablen!)... Übersetzung in C-Code Übersetzung in C-Code Ein in Pseudocode, als Struktogramm oder Programmablaufplan gegebener Algorithmus läßt sich wie folgt als Funktion in C implementieren: (4) Fall 1: Es gibt genau eine Ausgabevariable Ausgabe über return-anweisung als Rückgabewert (5) Fall 2: Es gibt mehrere Ausgabevariablen Werden Eingabeparameter vom Datentyp Zeiger (dazu später mehr) keine return-anweisung (6) Fall 3: Es gibt keine Ausgabevariablen keine return-anweisung Übersetzung in C-Code Ein in Pseudocode, als Struktogramm oder Programmablaufplan gegebener Algorithmus läßt sich wie folgt als Funktion in C implementieren: (7) Implementiere umgangssprachlich formulierte Bedingungen und Anweisungen durch C-Operationen (8) Übersetze Wertzuweisungen und Ausdrücke wie angegeben (9) Übersetze Kontrollstrukturen wie angegeben Vorlesung Informatik I Universität Augsburg Wintersemester 2010/2011 Prof. Dr. Robert Lorenz Lehrprofessur für Informatik Eigenschaften von Algorithmen 52 1

39 Inhalt Motivation Was sind sinnvolle definierende Eigenschaften von Algorithmen? Sind wir zufrieden, wenn ein Algorithmus die Zahlenfolge 1,7,3,19,2 sortieren kann, aber keine andere Zahlenfolgen? (Universalität) Genügt es, wenn Algorithmen endlich beschreibbar sind, oder sollte man noch Forderungen an deren Verhalten stellen? (Endlichkeitseigenschaften) Natürlich sollte die Ausgabe eindeutig von der Eingabe abhängen, aber sollte z.b. jede Anweisung eindeutig die Folgeanweisung festlegen? (Determiniertheit, Determinismus) Inhalt Motivation Was sind wichtige beschreibende Eigenschaften von Algorithmen? Benutzte Lösungsstrategie (Rekursive/Iterative Algorithmen) Verhalten bei ungültigen Eingaben (Robuste Algorithmen) Macht der Algorithmus das was er soll? (anderes Kapitel) (Korrektheit) Ist ein Algorithmus praktisch einsetzbar? (anderes Kapitel) (Effizienz) 2 3 Inhalt Universalität Endlichkeit Determiniertheit / Determinismus Robustheit Rekursivität Einführendes Beispiel Sequentielles Suchen in sortierter Folge Die Folge wird soweit von links nach rechts durchlaufen, bis der Vergleichsschlüsselwert k erstmalig kleiner oder gleich dem aktuellen Element k i ist. Dann ist k entweder an der betreffenden Stelle einzufügen, oder der gesuchte Schlüsselwert wurde gefunden. Beispiel: Folge: Vergleichswert k: 6 Neue Folge: Ausgabe: 3 4 5

40 Einführendes Beispiel Sequentielles Suchen in sortierter Folge Einführendes Beispiel Verbesserung: Binäres Suchen Die Variablen Li und Re stellen jeweils den linken bzw. rechten Begrenzer einer aktuell betrachteten Teilfolge dar. Mit jedem Durchlauf wird die mittlere Position zwischen diesen Begrenzern berechnet (Variable M) entweder Li oder Re wird auf M gesetzt, abhängig vom Vergleich von k mit k M (Weitersuchen in unterer oder oberer Teilfolge) Beispiel: Folge: , Begrenzer: 0,6,M=3 Vergleichswert k: 6 Teilfolge: 1 4 7, Begrenzer: 0,3,M=1 Teilfolge: 1 4 7, Begrenzer: 1,3,M= Einführendes Beispiel Verbesserung: Binäres Suchen Universalität Unter Universalität versteht man die Forderung, dass ein Algorithmus nicht nur eine konkrete Ausprägung eines Problems, sondern eine möglichst allgemeine Problemklasse löst. Beispiel: Suchen soll nicht nur in konkrete Zahlenfolge, z. B. 5, 7, 12, 45, 67, sondern in beliebigen Zahlenfolgen endlicher Länge gesucht werden können (oder sogar nicht nur in Zahlenfolgen, sondern in beliebigen endlichen Folgen von Zeichen oder Wörtern) 8 9

41 Endlichkeit Erste Endlichkeitsbedingung (E1) Ein Algorithmus muss endlich beschreibbar sein, d.h. durch einen endlichen Text formulierbar Ob ein Problem durch einen Algorithmus lösbar ist, hängt damit von der zur Verfügung stehenden Sprache (Ablaufstrukturen, Elementaroperationen) ab. Endlichkeit Erste Endlichkeitsbedingung (E1) Ein Algorithmus muss endlich beschreibbar sein, d.h. durch einen endlichen Text formulierbar Beispiel 1: Eine rationale Zahl a soll mit einer ganzen nichtnegativen Zahl n multipliziert werden Spezifikation 1 (Scheifen dürfen verwendet werden): Eingabe: a rational, n ganz, nicht-negativ Ausgabe: x = n * a Rahmenbedingungen: Elementaroperationen: :=, +, -, = Ablaufstrukturen: Sequenz, Schleife Endlichkeit Erste Endlichkeitsbedingung (E1) Ein Algorithmus muss endlich beschreibbar sein, d.h. durch einen endlichen Text formulierbar Beispiel 1: Eine rationale Zahl a soll mit einer ganzen nichtnegativen Zahl n multipliziert werden Lösung: (mit Schleifen) Endlichkeit Erste Endlichkeitsbedingung (E1) Ein Algorithmus muss endlich beschreibbar sein, d.h. durch einen endlichen Text formulierbar Beispiel 1: Eine rationale Zahl a soll mit einer ganzen nichtnegativen Zahl n multipliziert werden Spezifikation 2 (Schleifen dürfen nicht verwendet werden): Eingabe: a rational, n ganz, nicht-negativ Ausgabe: x = n * a Rahmenbedingungen: Elementaroperationen: :=, +, -, = Ablaufstrukturen: Sequenz, Verzweigung 12 13

42 Endlichkeit Erste Endlichkeitsbedingung (E1) Ein Algorithmus muss endlich beschreibbar sein, d.h. durch einen endlichen Text formulierbar Beispiel 1: Eine rationale Zahl a soll mit einer ganzen nichtnegativen Zahl n multipliziert werden Lösung??? (ohne Schleifen) Nicht endlich beschreibbar Endlichkeit Erste Endlichkeitsbedingung (E1) Ein Algorithmus muss endlich beschreibbar sein, d.h. durch einen endlichen Text formulierbar bezieht sich auf die Beschreibung, nicht auf die Ausführung: Beschreibung besteht aus endlich vielen elementaren Operationen zur Ausführungszeit können diese jedoch beliebig oft durchlaufen werden eventuell terminiert der Algorithmus nicht Für Praxis ist Forderung (E1) nicht ausreichend Endlichkeit Erste Endlichkeitsbedingung (E1) Ein Algorithmus muss endlich beschreibbar sein, d.h. durch einen endlichen Text formulierbar Endlichkeit Zweite Endlichkeitsbedingung (E2) Ein Algorithmus soll in endlicher Zeit ausführbar sein, d. h. für jede erlaubte Eingabe terminiert der Algorithmus nach endlicher Ausführungszeit Jede Elementaroperation muss in endlicher Zeit ausführbar sein Beispiel für nicht zulässige Operation: "Berechne Grenzwert der Folge (1 + 1/n)n Beteiligte Größen müssen endlich beschreibbar sein Beispiel: Rationale Zahlen, z. B. 1/3= entweder: hinreichend genaue Näherung, oder Zahlenpaar (1, 3) wird benutzt (Interpretation als Bruch) 16 17

43 Determiniertheit/Determinismus Determiniertheit (Globale Eindeutigkeit): Ein Algorithmus heißt determiniert, falls er eine eindeutige Abhängigkeit der Ausgabedaten von den Eingabedaten garantiert. Determiniertheit/Determinismus Determinismus (Lokale Eindeutigkeit): Ein Algorithmus heißt deterministisch, falls die Wirkung bzw. das Ergebnis jeder einzelnen Anweisung eindeutig ist und an jeder einzelnen Stelle des Ablaufs festliegt, welcher Schritt als nächster auszuführen ist. Folgerung: Jeder deterministische Algorithmus ist determiniert Determiniertheit/Determinismus Determinismus (Lokale Eindeutigkeit): Ein Algorithmus heißt deterministisch, falls die Wirkung bzw. das Ergebnis jeder einzelnen Anweisung eindeutig ist und an jeder einzelnen Stelle des Ablaufs festliegt, welcher Schritt als nächster auszuführen ist. Nichtdeterminismus: In den Elementaroperationen, d.h. die Wirkung bzw. das Ergebnis einer Operation ist nicht eindeutig festgelegt. Determiniertheit/Determinismus Determinismus (Lokale Eindeutigkeit): Ein Algorithmus heißt deterministisch, falls die Wirkung bzw. das Ergebnis jeder einzelnen Anweisung eindeutig ist und an jeder einzelnen Stelle des Ablaufs festliegt, welcher Schritt als nächster auszuführen ist. Beispiel: Nicht-deterministisches binäres Suchen in einer sortierten Folge In den Ablaufstrukturen, d.h. die Ausführungsreihenfolge von Anweisungen ist nicht eindeutig festgelegt

44 Determiniertheit/Determinismus Beispiel: Nicht-deterministisches binäres Suchen in einer sortierten Folge: Nicht-deterministisch (Elementaroperation Auswahl ) Determiniert Rekursivität Ein Algorithmus heißt rekursiv, wenn er sich selbst wieder benutzt direkte Rekursion: Algorithmus ruft sich selbst wieder auf indirekte Rekursion: man hat mehrere Algorithmen A1,...,An (n > 1): A1 ruft A2 auf, A2 ruft A3 auf,... An-1 ruft An auf, An ruft A1 auf (Algorithmen rufen sich im Zyklus auf) Rekursivität Rekursivität Beispiele für Rekursion: Rückkopplung bei Schallübertragung/-verstärkung Spiegelbild zwischen zwei Spiegeln Bild vom Bild (Kamera, die Monitor mit eigenem Bild aufnimmt) Fakultätsfunktion: 0! = 1, n! = n * (n-1)! Fibonacci-Folge (fib(0), fib(1), fib(2),...): fib(0) = 0 fib(1) = 1 fib(n) = fib(n-1) + fib(n-2) 24 25

45 Rekursivität Rekursivität Rekursivität Rekursivität 28 29

46 Rekursivität Rekursiver Algorithmus ist oft kürzer als nicht-rekursiver Rekursiver Algorithmus ist nicht zwangsläufig effizienter Robustheit Vereinbarungen: A: Algorithmus DA: Menge gültiger Eingabewerte WA: Menge möglicher Ausgabewerte Definition: A heißt robust, wenn für jede Eingabe e DA gilt: Entweder A terminiert nicht, oder A liefert eine Ausgabe, die (offensichtlich) nicht zu WA gehört zum Beispiel eine Fehlermeldung Robustheit Dieser Algorithmus ist im folgenden Sinne robust: Falls statt einer natürlichen Zahl eine negative, ganze Zahl eingegeben wird, terminiert der Algorithmus nicht (Unzulässigkeit der Eingabe ist für Benutzer erkennbar!?) Robustheit Bemerkungen: Obiger Robustheitsbegriff ist nur für theoretische Überlegungen sinnvoll Für praktische Erstellung von Software engere Definition: Ausnahmesituationen wie etwa falsche Eingaben, Störungen etc., sollten durch geeignete Vorkehrungen, z.b. Fehlermeldungen, abgefangen werden

47 Inhalt Vorlesung Informatik I Universität Augsburg Wintersemester 2010/2011 Prof. Dr. Robert Lorenz Lehrprofessur für Informatik Programmieren in C: Felder Motivation: Bisher: Für eine große Anzahl von gleichartigen Werten braucht man viele verschiedene Variablen(namen) Zugriff auf jede Variable nur gesondert möglich Jetzt: Speichern von Werten in einer Variable mit mehreren gleichartigen Komponenten (Felder) Einheitlicher Zugriff auf alle Komponenten (eines Feldes) 1 2 Inhalt Motivation: Felder sind indizierte (nummerierte) Variablen Inhalt Motivation: Felder sind indizierte (nummerierte) Variablen Beispiel: int feld[]={31,3,55,1,0,103,45,1,83; Alternative Initialisierung: int feld[9];feld[0] = 31;feld[1] = 3;... Veranschaulichung: Veranschaulichung: Nummerierung der Elemente Nummerierung der Elemente Werte Werte feld[3] feld[3] 3 4

48 Inhalt Motivation: Felder sind indizierte (nummerierte) Variablen Darstellung im Speicher: int feld[]={31,3,55,1,0,103,45,1, Inhalt /*bsp18.c*/ #include <stdio.h> main() { int i,folge[10],suchzahl,found=0,ausgabe; for(i=1; i<=10; i++) { printf("geben Sie die %i. Zahl der Folge ein: ", i); scanf("%i",&folge[i-1]); printf("welche Zahl wollen Sie suchen: "); scanf("%i",&suchzahl); for(i=1; i<=10; i++) { if (!found) { found = (folge[i-1] == suchzahl); if (found) { ausgabe = i; printf("ausgabe: %i",(found)? ausgabe : 11); 5 6 Inhalt Motivation Felder Zeichenketten Zeichenkettenfunktionen Umwandlungsfunktionen Felder Ein Feld ist eine Kombination einer festen Anzahl von Variablen gleichen Typs Neben den Grund-Datentypen int, double, char, usw., gibt es zusammengesetzte Datentypen, die aus Grund-Datentypen aufgebaut sind Der erste zusammengesetzte Datentyp, den wir nun kennenlernen, sind Felder Mehrdimensionale Felder 7 8

49 Felder Ein Feld ist eine Kombination einer festen Anzahl von Variablen gleichen Typs Felder Ein Feld ist eine Kombination einer festen Anzahl von Variablen gleichen Typs Deklaration: <Datentyp> <Name>[<groesse>] Datentyp: Ist der Datentyp der Komponenten des Feldes Ein Feld kann nicht Komponenten verschiedenen Typs haben Name: Regeln und Konventionen wie bei einfachen Variablen Deklaration: <Datentyp> <Name>[<groesse>] Groesse: Anzahl der Komponenten = ganze Zahl (auswertbarer ganzzahliger Ausdruck) Compiler reserviert (<groesse> * Platz für Datentyp) viel Speicherplatz für das Feld 9 10 Felder Ein Feld ist eine Kombination einer festen Anzahl von Variablen gleichen Typs Felder Ein Feld ist eine Kombination einer festen Anzahl von Variablen gleichen Typs Deklaration: <Datentyp> <Name>[<groesse>] Initialisierung: 1. In einer Schleife der Reihe nach für alle Komponenten for(i=0,i<<groesse>,i++){<name>[i]=...;... for(i=0,i<<groesse>,i++) {scanf(".",&<name>[i]);... Deklaration: <Datentyp> <Name>[<groesse>] Initialisierung: 2. In der Deklaration durch Angabe aller Werte: <Datentyp> <Name>[]={wert1,wert2,...,wertN (in diesem Fall muss <groesse> nicht angegeben werden die Anzahl der Komponenten ist ja bekannt) 11 12

50 Felder Ein Feld ist eine Kombination einer festen Anzahl von Variablen gleichen Typs Felder Ein Feld ist eine Kombination einer festen Anzahl von Variablen gleichen Typs Deklaration: <Datentyp> <Name>[<groesse>] Zugriff: Mit <Name>[i] greift man auf die i-te Komponente zu Mit <Name>[i] geht man wie mit einer einfachen Variable um: Wertzuweisung: <Name>[i] = <Ausdruck>; Benutzereingaben: scanf("...",&<name>[i]); Deklaration: <Datentyp> <Name>[<groesse>] Wertzuweisung: Seien v und w Felder gleichen Typs und gleicher Länge n Die Anweisung v = w; erzeugt einen Compilerfehler! (Begründung später) Man muss Werte komponentenweise zuweisen: for(i=0,i<n,i++){v[i]=w[i]; Felder Ein Feld ist eine Kombination einer festen Anzahl von Variablen gleichen Typs Zeichenketten Es gibt keinen eigenen Grund-Datentyp für Zeichenketten Zeichenketten sind Felder von Zeichen Deklaration: <Datentyp> <Name>[<groesse>] Für Wertzuweisungen und Vergleiche stehen vordefinierte Funktionen zur Verfügung (deklariert in string.h) Vergleich: Seien v und w Felder gleichen Typs und gleicher Länge n Der Vergleich (v==w) hat genau dann den Wert 1, wenn v und w Namen für denselben Speicherbereich sind (Begründung später) Gleichheit aller Werte muss man komponentenweise prüfen 15 16

51 Zeichenketten Es gibt keinen eigenen Grund-Datentyp für Zeichenketten Zeichenketten sind Felder von Zeichen Zeichenketten Es gibt keinen eigenen Grund-Datentyp für Zeichenketten Zeichenketten sind Felder von Zeichen Beispiel: char wort[]={'h','a','l','l','o'; Beispiel: char wort[]="hallo"; //So nur in der Deklaration möglich! Nummerierung der Elemente Nummerierung der Elemente H a l l o \0 Werte H a l l o \0 Werte wort[3] binäre 0, beendet jede Zeichenkette wort[3] binäre 0, beendet jede Zeichenkette Zeichenketten Beispielprogramm: Zeichenkette zeichenweise ausgeben /*bsp19a.c*/ #include <stdio.h> main() { int i=0; char wort[80]; printf("\nbitte einen Satz eingeben\n>"); gets(wort); while(wort[i]!= '\0') { printf("%c",wort[i]); i++; Zeichenketten Beispielprogramm: Zeichenkette zeichenweise ausgeben (Kurzform) /*bsp19b.c*/ #include <stdio.h> main() { int i=0; char wort[80]; printf("\nbitte einen Satz eingeben\n>"); gets(wort); while(wort[i] ) { printf("%c",wort[i++]); 19 20

52 Zeichenketten Funktion gets(char w[]) Weist Zeichenkette w Benutzereingabe als Wert zu Beendet Eingabe im Speicher automatisch mit dem \0-Zeichen Zeichenketten Funktion gets(char w[]) Weist Zeichenkette w Benutzereingabe als Wert zu Beendet Eingabe im Speicher automatisch mit dem \0-Zeichen Achtung: Es findet keine Überprüfung der Länge der Benutzereingabe statt Man kann über reservierten Speicherbereich hinaus schreiben \0-Zeichen Binäre 0 als Zeichen (Bitmuster 00), entspricht ASCII-Code 0 Ist immer letztes Zeichen einer Zeichenkette: Dadurch wird das Ende markiert Nur (<Feldgroesse> 1) Elemente durch Zeichen belegbar Zeichenketten Beispielprogramm: Passwortüberprüfung /*bsp20.c*/ #include <stdio.h> #include <string.h> main() { char geheim[]={65,66,67,68,69,70,passwort[80]; int versuch=3; printf("\nsie haben 3 Versuche.\n"); do { printf("\nbitte Passwort eingeben.\n>"); gets(passwort); if(strcmp(geheim,passwort) == 0) { printf("\npasswort ok!\n"); break; else { printf("\nfehlerhaftes Passwort! \n\a"); versuch--; while(versuch > 0); Zeichenketten Datei string.h Header-Datei für Zeichenkettenfunktionen: Wertzuweisungen Vergleiche 23 24

53 Zeichenketten Funktion int strcmp(char v[],char w[]) Vergleicht die zwei Zeichenketten v und w bzgl. der Standardlexikographischen Sortierung (siehe Codierungstheorie) (die Zeichen sind gemäß ASCII-Tabelle geordnet): w1<w2 Rückgabewert -1 w1=w2 Rückgabewert 0 w1>w2 Rückgabewert 1 Zeichenketten Funktion char[] strcpy(char v[],char w[]) Weist der Zeichenketten-Variablen v den Wert der Zeichenketten-Variablen oder Konstanten w zu (inklusive abschließender \0) Gibt v zurück Achtung: Man kann weniger Komponenten von v mit Zeichen belegen, als Speicherplatz reserviert wurde; binäre Null markiert das Ende Man kann aber auch über den reservierten Bereich von v hinaus schreiben (und dahinter liegende Daten überschreiben) Zeichenketten Funktion char[] strcpy(char v[],char w[]) Zeichenketten Funktion char[] strcat(char v[],char w[]) char text[9] w x y z Hängt den Wert der Zeichenketten-Variablen oder Konstanten w an den Wert der Zeichenketten-Variablen v an strcpy(text, Zahl ) strcpy(text, ) Z a h l \0 w x y z \0 a h l \0 w x y z Gibt v zurück Auch hier kann man über den reservierten Bereich von v hinaus schreiben (und dahinter liegende Daten überschreiben) strcpy(text, Zahlensystem ) Z a h l e n s y s t e m \

54 Zeichenketten Funktion int atoi(char v[]) (ascii to int) Header-Datei stdlib.h Wandelt als Ziffer interpretierbaren Anfang von v in eine Zahl vom Typ int um, dabei wird Zwischenraum am Anfang ignoriert Wenn das Resultat zu groß werden würde, wird (je nach Vorzeichen) der größte bzw. kleinste darstellbare Wert geliefert Beispiel: int x = atoi( 137a ); //x hat Wert 137 Zeichenketten Funktion int sprintf(char w[], char format[],...) Funktioniert wie printf... druckt aber in die Zeichenkette w (mit abschließender \0) (statt in die Kommandozeile) w muß groß genug für das Resultat sein Im Resultatwert wird \0 nicht mitgezählt Beispiel: char w[3]; sprintf(w, %i,137);\\ w hat Wert Mehrdimensionale Felder Beispielproblem: Speichere für jeden Tag eines Jahres die Mittagstemperatur Mehrdimensionale Felder Beispielproblem: Speichere für jeden Tag eines Jahres die Mittagstemperatur Lösung mit bisherigen Mitteln: Deklariere ein Feld mit 365 Elementen double temperatur[365]; Datenhaltung unstrukturiert (Zugriff auf bestimmtes Datum?) Bessere Lösung: Deklariere ein Feld mit 12 Elementen (eines für jeden Monat), wobei jedes dieser Elemente ein Feld mit 31 Elementen ist: double temperatur[12][31]; Datenhaltung besser strukturiert Zugriff auf Temperatur am 6. März durch temperatur[2][5] 31 32

55 Mehrdimensionale Felder Noch ein Beispielproblem: Betrachte ein lineares Gleichungssystem: a 11 * x 1 + a 12 * x 2 = b 1 a 21 * x 1 + a 22 * x 2 = b 2 1. Es müssen die Koeffizienten a 11, a 12, a 21, a 22, b 1, b 2 eingegeben und gespeichert werden 2. Nach der Berechnung müssen die Lösungswerte x 1, x 2 gespeichert werden Lösung: double a[2][2];//zugriff auf a ij mit a[i-1][j-1] double b[2],x[2]; Mehrdimensionale Felder Ein 2-dimensionales Feld ist ein Feld von Feldern gleichen Typs Deklaration: <Datentyp> <Name>[n][m] Lesart von innen nach aussen! <Datentyp> (<Name>[n])[m] Das Feld hat n Komponenten (innen) Jede der n Komponenten ist Feld mit m Komponenten (aussen) Compiler reserviert (n * m * Platz für Datentyp) viel Speicherplatz für das Feld Mehrdimensionale Felder Ein 2-dimensionales Feld ist ein Feld von Feldern gleichen Typs Mehrdimensionale Felder Ein 2-dimensionales Feld ist ein Feld von Feldern gleichen Typs Deklaration: <Datentyp> <Name>[n][m] Deklaration: <Datentyp> <Name>[n][m] Initialisierung: 1. In einer verschachtelten Schleife der Reihe nach für alle Komponenten for (i=0,i<n,i++){ for (j=0,j<m,j++){<name>[i][j]=...;... Initialisierung: 2. In der Deklaration durch Angabe aller Werte: <Datentyp> <Name>[][m]={{w11,...,w1M,...,{wN1,...,wNM (in diesem Fall muss Feldlänge auf der obersten Ebene nicht angegeben werden; für andere Ebenen aber schon!) 35 36

56 Mehrdimensionale Felder Ein 2-dimensionales Feld ist ein Feld von Feldern gleichen Typs Deklaration: <Datentyp> <Name>[n][m] Zugriff: Mit <Name>[i][j] greift man auf die j-te Komponente der i-ten Komponente des Feldes zu Mehrdimensionale Felder Man kann auch Felder mit mehr als 2 Dimensionen definieren: <Datentyp> <Name>[n1]...[nK] Alle Überlegungen für 2-dimensionale Felder lassen sich auf diesen Fall übertragen Mit <Name>[i][j] geht man wie mit einfacher Variable um: Wertzuweisung: <Name>[i][j] = <Ausdruck>; Benutzereingaben: scanf("...",&<name>[i][j]); Inhalt Vorlesung Informatik I Motivation: Vertauschung von Werten in einer Funktion Universität Augsburg Wintersemester 2010/2011 Prof. Dr. Robert Lorenz Lehrprofessur für Informatik Programmieren in C: Pointer 1 2

57 Inhalt Motivation: Vertauschung von Werten in einer Funktion Vertausche Variablenwerte von x und y: hilf=x; x=y; y=hilf; Inhalt Motivation: Vertauschung von Werten in einer Funktion Vertausche Variablenwerte von x und y in einer Funktion: /*bsp21a.c*/ void tausche(int x,int y){ int z; z=x; x=y; y=z; int main(){ int v[2]; v[0]=3; v[1]=5; tausche(v[0],v[1]); return 0; 3 4 Inhalt Motivation: Vertauschung von Werten in einer Funktion Inhalt Motivation: Vertauschung von Werten in einer Funktion Vorgang im Speicher: Vorgang im Speicher: /*bsp21a.c*/ void tausche(int x,int y){ int z; z=x; x=y; y=z; /*bsp21a.c*/ void tausche(int x,int y){ int z; z=x; x=y; y=z; v[0] v[1] int main(){ int v[2]; v[0]=3; v[1]=5; tausche(v[0],v[1]); return 0; int main(){ int v[2]; v[0]=3; v[1]=5; tausche(v[0],v[1]); return 0; 5 6

58 Inhalt Motivation: Vertauschung von Werten in einer Funktion Inhalt Motivation: Vertauschung von Werten in einer Funktion Vorgang im Speicher: /*bsp21a.c*/ void tausche(int x,int y){ int z; z=x; x=y; y=z; int main(){ int v[2]; v[0]=3; v[1]=5; tausche(v[0],v[1]); return 0; v[0] v[1] 3 5 Vorgang im Speicher: /*bsp21a.c*/ void tausche(int x,int y){ int z; z=x; x=y; y=z; int main(){ int v[2]; v[0]=3; v[1]=5; tausche(v[0],v[1]); return 0; cv v[0] Temporäre Kopien: int cv0=v[0]; int cv1=v[1]; v[1] cv Inhalt Motivation: Vertauschung von Werten in einer Funktion Vorgang im Speicher: /*bsp21a.c*/ void tausche(int x,int y){ int z; z=x; x=y; y=z; int main(){ int v[2]; v[0]=3; v[1]=5; tausche(v[0],v[1]); return 0; cv v[0] v[1] cv1 5 z Inhalt Motivation: Vertauschung von Werten in einer Funktion Vorgang im Speicher: /*bsp21a.c*/ void tausche(int x,int y){ int z; z=x; x=y; y=z; int main(){ int v[2]; v[0]=3; v[1]=5; tausche(v[0],v[1]); return 0; cv v[0] v[1] 3 5 Rechnung mit temporären Kopien:... 3 cv1 5 z

59 Inhalt Motivation: Vertauschung von Werten in einer Funktion Vorgang im Speicher: /*bsp21a.c*/ void tausche(int x,int y){ int z; z=x; x=y; y=z; int main(){ int v[2]; v[0]=3; v[1]=5; tausche(v[0],v[1]); return 0; cv v[0] v[1] 3 5 Rechnung mit temporären Kopien:... 5 cv1 5 z 3 Inhalt Motivation: Vertauschung von Werten in einer Funktion Vorgang im Speicher: /*bsp21a.c*/ void tausche(int x,int y){ int z; z=x; x=y; y=z; int main(){ int v[2]; v[0]=3; v[1]=5; tausche(v[0],v[1]); return 0; cv v[0] v[1] 3 5 Rechnung mit temporären Kopien:... 5 cv1 3 z Inhalt Motivation: Vertauschung von Werten in einer Funktion Inhalt Motivation: Vertauschung von Werten in einer Funktion Vorgang im Speicher: /*bsp21a.c*/ void tausche(int x,int y){ int z; z=x; x=y; y=z; int main(){ int v[2]; v[0]=3; v[1]=5; tausche(v[0],v[1]); return 0; v[0] v[1] 3 5 Speicherplatz freigegeben:... Fazit: Wegen dem Call-by-Value-Prinzip kann man die Werte zweier Variablen eines Grund-Datentyps in einer Funktion nicht vertauschen Lösung: Einführung von neuen Datentypen, sog. Zeigern, in denen Adressen von Werten gespeichert werden 13 14

60 Inhalt Call by Value und Call by reference Der Zeiger-Datentyp Deklaration Wertzuweisung / Adressoperator & Dereferenzierung / Dereferenzierungsoperator * Adressverschiebung Konstante Zeiger Zeiger als Eingabeparameter und Rückgabetyp von Funktionen Kombinierte Variablen-Deklarationen Zeiger auf Funktionen Call by Value und Call by Reference Call by value An Funktionen werden Werte übergeben (es wird mit Variablen- Kopien gerechnet) In Funktionen können die Werte ihrer Parameter nicht verändert werden Call by Value und Call by Reference Call by reference An Funktionen werden Variablen-Adressen übergeben Über die Adressen können die Werte der Variablen verändert werden Call by Value und Call by Reference Call by reference An Funktionen werden Variablen-Adressen übergeben Über die Adressen können die Werte der Variablen verändert werden Beispiel px 320 &x liefert die Adresse von x &x 77 x 17 18

61 Call by Value und Call by Reference Call by reference An Funktionen werden Variablen-Adressen übergeben Über die Adressen können die Werte der Variablen verändert werden Call by Value und Call by Reference Call by reference An Funktionen werden Variablen-Adressen übergeben Über die Adressen können die Werte der Variablen verändert werden Beispiel px &x liefert die Adresse von x px=&x; weist px Adresse von x zu Beispiel px &x liefert die Adresse von x px=&x; weist px Adresse von x zu x 77 x px ist ein sog. Zeiger (Pointer) auf x Call by Value und Call by Reference Call by reference An Funktionen werden Variablen-Adressen übergeben Über die Adressen können die Werte der Variablen verändert werden Beispiel px x &x liefert die Adresse von x px=&x; weist px Adresse von x zu px ist ein sog. Zeiger (Pointer) auf x *px=5; weist x den Wert 5 zu Pointer-Datentyp Pointer sind Variablen, die als Werte Adressen annehmen Es wird dabei immer der Datentyp der Werte, die an einer solchen Adresse gespeichert werden dürfen, festgelegt Deklaration (eines Zeigers auf <Datentyp>) <Datentyp> *<Zeigername>; <Zeigername> <Datentyp> <Datentyp>* Name der Zeigervariablen Datentyp, der an der im Zeiger gespeicherten Adresse gespeichert werden darf Datentyp des Zeigers 21 22

62 Pointer-Datentyp Pointer sind Variablen, die als Werte Adressen annehmen Pointer-Datentyp Pointer sind Variablen, die als Werte Adressen annehmen Es wird dabei immer der Datentyp der Werte, die an einer solchen Adresse gespeichert werden dürfen, festgelegt Beispiel Zeiger-Deklaration int x; Deklaration (eines Zeigers auf <Datentyp>) <Datentyp> *<Zeigername>; Nach der Deklaration hat ein Pointer folgenden Wert: double y,*py; //double-variable y, //Pointer py auf double py Lokaler Pointer: Globaler Pointer: Zufälliger Wert ( zeigt irgendwohin ) Wert NULL ( zeigt nirgendwohin ) y x Pointer-Datentyp Pointer-Datentyp Pointer sind Variablen, die als Werte Adressen annehmen Pointer sind Variablen, die als Werte Adressen annehmen Zeiger können beliebig verschachtelt werden Beispiel Zeiger auf Zeiger <Datentyp> **<Zeigername>; <Zeigername> Name der Zeigervariablen <Datentyp>* Datentyp, der an der im Zeiger gespeicherten Adresse gespeichert werden darf <Datentyp>** Datentyp des Zeigers int **px; //px Zeiger auf int* //Werte sind Adressen //von Zeigern auf int px 25 26

63 Pointer-Datentyp Pointer sind Variablen, die als Werte Adressen annehmen Adressoperator & Unärer Operator Hat eine Variable als Argument Gibt die Speicheradresse der Variable zurück (= Adresse des ersten Bytes des Speicherbereichs der Variablen) Pointer-Datentyp Pointer sind Variablen, die als Werte Adressen annehmen Wertzuweisung <Zeigername> = <Adresse>; <Adresse> Adresse einer Speicherzelle NULL (Konstante für keine Adresse gespeichert ) Man sagt: Der Zeiger referenziert (zeigt auf) die Adresse Adressen sind keine Integer! Pointer-Datentyp Pointer sind Variablen, die als Werte Adressen annehmen Pointer-Datentyp Pointer sind Variablen, die als Werte Adressen annehmen Wertzuweisung einfach: Variablenadressen Beispiel: Wertzuweisung von Variablenadressen <Zeigername> = &<Variablenname>; int x; double y,*py; Im einfachsten Fall zeigen Zeiger auf Adressen, die zu anderen Variablen gehören. Man sagt: Der Zeiger referenziert (zeigt auf) die Variable py = &y; //py wird die Adresse //von y zugewiesen py? Achtung: Typ der Variable muss zum Typ des Zeigers passen py = &x; //Compilerfehler!! y x 29 30

64 Pointer-Datentyp Pointer sind Variablen, die als Werte Adressen annehmen Pointer-Datentyp Pointer sind Variablen, die als Werte Adressen annehmen Wertzuweisung an Zeiger auf Zeiger Beispiel: Wertzuweisung an Zeiger auf Zeiger <Datentyp> **<Zeigername1>; <Datentyp> *<Zeigername2>; <Datentyp> <Variablenname>; <Zeigername1>=&<Zeigername2>; <Zeigername2>=&<Variablenname>; <Zeigername1>=&<Variablenname>;//Compilerfehler!! Adressen können auch Adressen anderer Zeiger-Variablen sein, der Zeiger-Typ muss halt passen double **ppy,*py,y; ppy = &py; //ppy wird die Adresse von py zugewiesen py = &y; //py wird die Adresse von y zugewiesen ppy = &y; //Compilerfehler! ppy py y? Pointer-Datentyp Pointer sind Variablen, die als Werte Adressen annehmen Dereferenzierungs-Operator *: Unärer Operator Hat einen Adressen-wertigen Ausdruck als Argument Gibt den an referenzierter Adresse gespeicherten Wert zurück Pointer-Datentyp Pointer sind Variablen, die als Werte Adressen annehmen Dereferenzierung von Adress-wertigen Ausdrücken *<Adressausdruck> Ist ein Name für den referenzierten Speicherbereich Kann als solcher in Ausdrücken verwendet werden Kann als solcher für Wertzuweisungen verwendet werden Die Anwendung von * nennt man Dereferenzierung Einfachste Verwendung: *<Zeigername> 33 34

65 Pointer-Datentyp Pointer sind Variablen, die als Werte Adressen annehmen Pointer-Datentyp Beispiel: Ausgabe von Adressen als positive ganze Zahlen Beispiel: Dereferenzierung double y,*py; py = &y; y = 5; double z = *py + 1; //z wird Wert 5+1=6 zugewiesen *py = 7.5; //y wird Wert 7.5 zugewiesen if (*py == z){ py *py 5 /*bsp22a.c*/ #include <stdio.h> int main() { int a[]={2,3,4; char b[]="du"; printf("\nadresse von a[0] = %u ",&a[0]); printf("wert von a[0] = %i ",a[0]); printf("\nadresse von a[1] = %u ",&a[1]); printf("wert von a[1] = %i ",a[1]); printf("\nadresse von a[2] = %u ",&a[2]); printf("wert von a[2] = %i ",a[2]); printf("\nadresse von b[0] = %u ",&b[0]); printf("wert von b[0] = %c ",b[0]); printf("\nadresse von b[1] = %u ",&b[1]); return 0; printf("wert von b[1] = %c ",b[1]); Pointer-Datentyp Beispiel: Ausgabe von Adressen als positive ganze Zahlen /*bsp22b.c*/ #include <stdio.h> int main() { int a[]={2,3,4,*pa=&a[0]; char b[]="du", *pb=&b[0]; printf("\nadresse von a[0] = %u ",pa); printf("wert von a[0] = %i ",*pa); printf("\nadresse von a[1] = %u ",pa+1); printf("wert von a[1] = %i ",*(pa+1)); printf("\nadresse von a[2] = %u ",pa+2); printf("wert von a[2] = %i ",*(pa+2)); printf("\nadresse von b[0] = %u ",pb); printf("wert von b[0] = %c ",*pb); printf("\nadresse von b[1] = %u ",pb+1); return 0; printf("wert von b[1] = %c ",*(pb+1)); Pointer-Datentyp Eingangsbeispiel mit Zeigern: Vertausche zwei Werte /*bsp21b.c*/ void tausche(int *pv0,int *pv1){ int z; z=*pv0; *pv0=*pv1; *pv1=z; int main(){ int v[2]; v[0]=3;v[1]=5; tausche(&v[0],&v[1]); return 0; 37 38

66 Pointer-Datentyp Eingangsbeispiel mit Zeigern: Vertausche zwei Werte /*bsp21b.c*/ void tausche(int *pv0,int *pv1){ int z; z=*pv0; *pv0=*pv1; *pv1=z; int main(){ Parameter pv1 vom Typ Zeiger auf int int v[2]; v[0]=3;v[1]=5; tausche(&v[0],&v[1]); return 0; Pointer-Datentyp Eingangsbeispiel mit Zeigern: Vertausche zwei Werte /*bsp21b.c*/ void tausche(int *pv0,int *pv1){ int z; z=*pv0; *pv0=*pv1; *pv1=z; int main(){ Übergabe der Adresse von v[1] int v[2]; v[0]=3;v[1]=5; tausche(&v[0],&v[1]); return 0; Pointer-Datentyp Eingangsbeispiel mit Zeigern: Vertausche zwei Werte /*bsp21b.c*/ void tausche(int *pv0,int *pv1){ int z; z=*pv0; *pv0=*pv1; *pv1=z; int main(){ Zugriff auf den Wert von v[1] int v[2]; v[0]=3;v[1]=5; tausche(&v[0],&v[1]); return 0; Pointer-Datentyp Eingangsbeispiel mit Zeigern: Vertausche zwei Werte /*bsp21b.c*/ void tausche(int *pv0,int *pv1){ int z; z=*pv0; *pv0=*pv1; *pv1=z; int main(){ int v[2]; v[0]=3;v[1]=5; tausche(&v[0],&v[1]); return 0; v[0] v[1] 41 42

67 Pointer-Datentyp Eingangsbeispiel mit Zeigern: Vertausche zwei Werte Pointer-Datentyp Eingangsbeispiel mit Zeigern: Vertausche zwei Werte /*bsp21b.c*/ void tausche(int *pv0,int *pv1){ int z; z=*pv0; *pv0=*pv1; *pv1=z; v[0] v[1] 3 5 /*bsp21b.c*/ void tausche(int *pv0,int *pv1){ int z; z=*pv0; *pv0=*pv1; *pv1=z; v[0] v[1] 3 5 int main(){ int v[2]; v[0]=3;v[1]=5; tausche(&v[0],&v[1]); return 0; int main(){ int v[2]; v[0]=3;v[1]=5; tausche(&v[0],&v[1]); return 0;... Temporäre Zeiger: int *pv0=&v[0]; int *pv1=&v[1]; pv0 pv Pointer-Datentyp Pointer-Datentyp Eingangsbeispiel mit Zeigern: Vertausche zwei Werte Eingangsbeispiel mit Zeigern: Vertausche zwei Werte /*bsp21b.c*/ void tausche(int *pv0,int *pv1){ int z; z=*pv0; *pv0=*pv1; *pv1=z; v[0] v[1] 3 5 /*bsp21b.c*/ void tausche(int *pv0,int *pv1){ int z; z=*pv0; *pv0=*pv1; *pv1=z; *pv0 v[1] 3 5 int main(){ int v[2]; v[0]=3;v[1]=5; tausche(&v[0],&v[1]); return 0;... int main(){ int v[2]; v[0]=3;v[1]=5; tausche(&v[0],&v[1]); return 0;... pv0 pv1 pv0 pv1 Derefernzierung mit temporären Zeigern: z 45 z 3 46

68 Pointer-Datentyp Eingangsbeispiel mit Zeigern: Vertausche zwei Werte Pointer-Datentyp Eingangsbeispiel mit Zeigern: Vertausche zwei Werte /*bsp21b.c*/ void tausche(int *pv0,int *pv1){ int z; z=*pv0; *pv0=*pv1; *pv1=z; *pv0 *pv1 5 5 /*bsp21b.c*/ void tausche(int *pv0,int *pv1){ int z; z=*pv0; *pv0=*pv1; *pv1=z; *pv0 *pv1 5 3 int main(){ int v[2]; v[0]=3;v[1]=5; tausche(&v[0],&v[1]); return 0;... int main(){ int v[2]; v[0]=3;v[1]=5; tausche(&v[0],&v[1]); return 0;... pv0 pv1 pv0 pv1 Derefernzierung mit temporären Zeigern: Derefernzierung mit temporären Zeigern: z 3 47 z 3 48 Pointer-Datentyp Pointer-Datentyp Eingangsbeispiel mit Zeigern: Vertausche zwei Werte /*bsp21b.c*/ void tausche(int *pv0,int *pv1){ int z; z=*pv0; *pv0=*pv1; *pv1=z; int main(){ int v[2]; v[0]=3;v[1]=5; tausche(&v[0],&v[1]); return 0; v[0] v[1] Rechnen mit Zeigern und Adressen Man kann Zeiger mit int-werten addieren / subtrahieren: Adresse wird um (int-wert)*(speicherbedarf des referenzierten Datentyps) verschoben 49 50

69 Pointer-Datentyp Rechnen mit Zeigern und Adressen Man kann Zeiger mit int-werten addieren / subtrahieren: Adresse wird um (int-wert)*(speicherbedarf des referenzierten Datentyps) verschoben Anwendung 1: Zugriff auf Wert an verschobener Adresse über Dereferenzierung (ohne Wert des Zeigers zu ändern) *(<Zeigername>+n) Pointer-Datentyp Rechnen mit Zeigern und Adressen Man kann Zeiger mit int-werten addieren / subtrahieren: Adresse wird um (int-wert)*(speicherbedarf des referenzierten Datentyps) verschoben Beispiel 1: char c[]= Du,*pc; pc = &c[0]; *(pc+1) = a ; pc D a \0 c[0] c[1] Pointer-Datentyp Pointer-Datentyp Rechnen mit Zeigern und Adressen Man kann Zeiger mit int-werten addieren / subtrahieren: Adresse wird um (int-wert)*(speicherbedarf des referenzierten Datentyps) verschoben Anwendung 2: Wert des Zeigers ändern ( Zeiger umbiegen ) <ZeigerName>=<ZeigernName>+n; Rechnen mit Zeigern und Adressen Man kann Zeiger mit int-werten addieren / subtrahieren: Adresse wird um (int-wert)*(speicherbedarf des referenzierten Datentyps) verschoben px Beispiel 2: int x, *px; px = &x; px++; *px = 3; //Speicherbereich nicht reserviert! x 53 54

70 Pointer-Datentyp Rechnen mit Zeigern und Adressen: Eingangsbeispiel Pointer-Datentyp Rechnen mit Zeigern und Adressen: Eingangsbeispiel /*bsp21c.c*/ void tausche(int *p){ int z; z=*p; *p=*(p+1); *(p+1)=z; v[0] v[1] /*bsp21c.c*/ void tausche(int *p){ int z; z=*p; *p=*(p+1); *(p+1)=z; v[0] v[1] 3 5 int main(){ int v[2]; v[0]=3;v[1]=5; tausche(&v[0]); return 0; int main(){ int v[2]; v[0]=3;v[1]=5; tausche(&v[0]); return 0; Pointer-Datentyp Pointer-Datentyp Rechnen mit Zeigern und Adressen: Eingangsbeispiel Rechnen mit Zeigern und Adressen: Eingangsbeispiel /*bsp21c.c*/ void tausche(int *p){ int z; z=*p; *p=*(p+1); *(p+1)=z; v[0] v[1] 3 5 /*bsp21c.c*/ void tausche(int *p){ int z; z=*p; *p=*(p+1); *(p+1)=z; v[0] v[1] 3 5 int main(){ int v[2]; v[0]=3;v[1]=5; tausche(&v[0]); return 0;... int main(){ int v[2]; v[0]=3;v[1]=5; tausche(&v[0]); return 0;... Temporärer Zeiger: int *p=&v[0]; p p z 57 58

71 Pointer-Datentyp Rechnen mit Zeigern und Adressen: Eingangsbeispiel Pointer-Datentyp Rechnen mit Zeigern und Adressen: Eingangsbeispiel /*bsp21c.c*/ void tausche(int *p){ int z; z=*p; *p=*(p+1); *(p+1)=z; *p v[1] 3 5 /*bsp21c.c*/ void tausche(int *p){ int z; z=*p; *p=*(p+1); *(p+1)=z; *p *(p+1) 5 5 int main(){ int v[2]; v[0]=3;v[1]=5; tausche(&v[0]); return 0;... int main(){ int v[2]; v[0]=3;v[1]=5; tausche(&v[0]); return 0;... Dereferenzierung mit temporärem Zeiger: p z 3 Dereferenzierung mit temporärem Zeiger: p z Pointer-Datentyp Rechnen mit Zeigern und Adressen: Eingangsbeispiel Pointer-Datentyp Rechnen mit Zeigern und Adressen: Eingangsbeispiel /*bsp21c.c*/ void tausche(int *p){ int z; z=*p; *p=*(p+1); *(p+1)=z; *p *(p+1) 5 3 /*bsp21c.c*/ void tausche(int *p){ int z; z=*p; *p=*(p+1); *(p+1)=z; v[0] v[1] 5 3 int main(){ int v[2]; v[0]=3;v[1]=5; tausche(&v[0]); return 0;... int main(){ int v[2]; v[0]=3;v[1]=5; tausche(&v[0]); return 0;... Dereferenzierung mit temporärem Zeiger: p z

72 Pointer-Datentyp Rechnen mit Zeigern und Adressen: Zeichenkettenfunktionen Zeichenkette umkehren, Variante 1: Speichere neue Zeichenkette im selben Speicherbereich wie die alte. Greife dann auf neue Zeichenkette mit originaler Feldvariable zu. Funktion hat keinen Rückgabewert. Pointer-Datentyp Rechnen mit Zeigern und Adressen: Zeichenkettenfunktionen Zeichenkette umkehren, Variante 1: Speichere neue Zeichenkette im selben Speicherbereich wie die alte. Greife dann auf neue Zeichenkette mit originaler Feldvariable zu. Funktion hat keinen Rückgabewert. /*bsp23a*/ #include <stdio.h> void rev1(char *p); int main() { char wort[] = "Hallo"; rev1(&wort[0]); printf("%s",wort); return 0; void rev1(char *p){ int max = 0; while (*(p+max)!= '\0'){ max++; int i; for(i=0;i < max/2;i++){ char hilf; hilf = *(p+i); *(p+i)=*(p+(max-1-i)); *(p+(max-1-i))=hilf; Pointer-Datentyp Rechnen mit Zeigern und Adressen: Zeichenkettenfunktionen Zeichenkette umkehren, Variante 2: Verwende zwei Eingabeparameter: einen für die Eingabe, einen für das Ergebnis. Kein Rückgabewert. Man behält alte Werte Pointer-Datentyp Rechnen mit Zeigern und Adressen: Zeichenkettenfunktionen Zeichenkette umkehren, Variante 2: Verwende zwei Eingabeparameter: einen für die Eingabe, einen für das Ergebnis. Kein Rückgabetyp. Man behält alte Werte /*bsp23b*/ #include <stdio.h> void rev2(char *e,char *a); int main() { char wort[] = "..."; char erg[100]; rev2(&wort[0],&erg[0]); printf("%s",erg); return 0; void rev2(char *e,char *a){ int max = 0; while (*(e+max)!= '\0'){ max++; int i; for(i=0;i < max;i++){ *(a+i)=*(e+(max-1-i)); *(a+max)='\0'; 65 66

73 Pointer-Datentyp Rechnen mit Zeigern und Adressen: Zeichenkettenfunktionen Zeichenkette umkehren, Variante 3: Verwende zwei Eingabeparameter: einen für die Eingabe, einen für das Ergebnis. Rückgabe eines Zeigers auf das Ergebnis Verwendung: nächstes Kapitel /*bsp23c.c*/ #include <stdio.h> char *rev3(char *e,char *a); int main() { char wort[] = "..."; char erg[100]; rev3(&wort[0],&erg[0]); printf("%s",erg); return 0; char *rev3(char *e,char *a){ int max = 0; while (*(e+max)!= '\0'){ max++; int i; for(i=0;i < max;i++){ *(a+i)=*(e+(max-1-i)); *(a+max)='\0'; return a; Pointer-Datentyp Rechnen mit Zeigern und Adressen: Zusammenfassung Man kann Zeiger mit int-werten addieren / subtrahieren: Adresse wird um (int-wert)*(speicherbedarf des referenzierten Datentyps) verschoben Anwendungen: Adressen verschieben, Pointer umbiegen Achtung: Nicht reservierten Speicherbereich überschreiten! Pointer-Datentyp Pointer-Datentyp Rechnen mit Zeigern und Adressen: Zusammenfassung Pointer eignen sich zum Manipulieren von Feldern, auch in Funktionen Ausblick: Realisieren von dynamischen Feldern durch Pointer (dynamisches Feld = Feld mit variabler Länge) (notwendig: dynamische Speicherallokation für Pointer) Konstanter Zeiger <Datentyp> * const <Zeigername> Zeiger kann nicht umgebogen werden Wert kann über Dereferenzierung geändert werden Zeiger auf konstanten Wert const <Datentyp> * <Zeigername> Zeiger kann umgebogen werden Wert kann nicht über Dereferenzierung geändert werden Konstanter Zeiger auf konstanten Wert const <Datentyp> * const <Zeigername> 69 70

74 Pointer-Datentyp Zeiger können Rückgabetyp von Funktionen sein (klar) Dabei beachten: Geben Sie keine Adressen auf lokale Speicherbereiche zurück! Beispiel: int * murks(){ int n=5; return(&n); //Speicherbereich von n wird freigegeben int main() { int * p; p = murks(); printf("%d\n",*p);//zugriff auf undefinierten Bereich Pointer-Datentyp Zeiger können Rückgabetyp von Funktionen sein (klar) Dabei beachten: Geben Sie keine Adressen auf lokale Speicherbereiche zurück! Rückgabewert sollte auf vorher reservierten Speicherbereich zeigen Vorgehensweise: 1. Deklariere Feld für Aufnahme des Ergebnisses 2. Übergebe Adresse dieses Feldes an Funktion 3. Durchlaufe Feld für Berechnungen mit einem Zeiger 4. Gib Zeiger auf das Feld zurück Pointer-Datentyp Deklarationen von Datentypen verstehen Merke: [] bindet stärker als * Lies Deklarationen von innen nach aussen Pointer-Datentyp Zeiger und Felder: Nächstes Kapitel im Detail <Datentyp> **<Name> <Datentyp> *<Name>[n] Zeiger auf Zeiger auf <Datentyp> Feld aus n Zeigern auf <Datentyp> <Datentyp> (*<Name>)[n] Zeiger auf Feld aus n <Datentyp>- Elementen <Datentyp> <Name>[n][m] Feld aus n Feldern aus m <Datentyp>- Elementen 73 74

75 Pointer-Datentyp Deklarationen von Funktionen verstehen Merke: () bindet stärker als * Lies Deklarationen von innen nach aussen <Datentyp> *<Name>() <Datentyp> (*<Name>)() Funktion, die einen Zeiger auf <Datentyp> zurückgibt Zeiger auf eine Funktion, die einen <Datentyp>-Wert zurückgibt Pointer-Datentyp Zeiger auf Funktionen <Datentyp> (*<Name>)(<Eingabeparameter>) Merke: Idee: Auch Funktionen sind im Speicher abgelegt Die zugehörige Speicherzelle hat eine Adresse Auf diese Adresse kann man zeigen Eingabeparameter und Rückgabetyp stehen fest, aber man kann auf verschiedene Funktionen zeigen Man kann über einen einheitlichen Zugriff (den Funktionszeiger *<Name>) verschiedene Funktionen aufrufen Pointer-Datentyp Zeiger auf Funktionen <Datentyp> (*<Name>)(<Eingabeparameter>) Beispiel: int max(int a, int b){... int min(int a, int b){... int comp(int a, int b, int (*f)(int x,int y)){ if ((*f)(a,b)==-1){return(b); else return(a); int main(){ int a=3, int b=5; printf("\nmin: %i",comp(a,b,&min)); printf("\nmax: %i",comp(a,b,&max)); Vorlesung Informatik I Universität Augsburg Wintersemester 2010/2011 Prof. Dr. Robert Lorenz Lehrprofessur für Informatik Programmieren in C: Pointer und Felder 77 1

76 Inhalt Zeiger und Felder Zeichenketten sind Zeiger auf char Felder als Eingabeparameter von Funktionen Verschachtelte Zeiger Felder von Feldern Felder von Zeigern Zeiger auf Felder Zeiger auf Zeiger Pointer und Felder <Datentyp> <Feldname>[<groesse>] Feldnamen werden als konstante Zeiger auf <Datentyp> interpretiert; Wert dieses Zeigers ist die Feldadresse Die Feldadresse ist die Adresse des ersten Bytes des für das Feld reservierten Speicherbereichs Beispiel: int v[4]; v Pointer und Felder <Datentyp> <Feldname>[<groesse>] Feldnamen werden als konstante Zeiger auf <Datentyp> interpretiert; Wert dieses Zeigers ist die Feldadresse Die Adresse der n-ten Komponente ist die Feldadresse um n Schritte verschoben: &<Feldname>[n]==<Feldname>+n Beispiel: int v[4]; v 1045 &v[0] 1049 &v[1] 1053 &v[2] 1057 &v[3] Pointer und Felder <Datentyp> <Feldname>[<groesse>] Feldnamen werden als konstante Zeiger auf <Datentyp> interpretiert; Wert dieses Zeigers ist die Feldadresse Es gilt insbesondere: <Feldname> == &<Feldname>[0] Beachte: Für den Feldnamen ist kein Speicherplatz reserviert wie für einen Zeigernamen, er wird nur als Adresse ausgewertet Es gilt per Konvention: <Feldname> == &<Feldname>

77 Pointer und Felder <Datentyp> <Feldname>[<groesse>] Feldnamen werden als konstante Zeiger auf <Datentyp> interpretiert; Wert dieses Zeigers ist die Feldadresse Den Wert der n-ten Komponente erhält man auch mit Dereferenzierung: <Feldname>[n]==*(<Feldname>+n) Beispiel: int v[4]; v 1045 *v 1049 *(v+1) 1053 *(v+2) 1057 *(v+3) Pointer und Felder <Datentyp> <Feldname>[<groesse>] Feldnamen werden als konstante Zeiger auf <Datentyp> interpretiert; Wert dieses Zeigers ist die Feldadresse Tatsächlich ist <Feldname>[n] nur eine andere Schreibweise für *(<Feldname>+n) Im Hintergrund wird also immer eine Adressverschiebung mit anschließender Dereferenzierung ausgeführt! Beispiel: Zeichenweise Ausgabe eine Zeichenkette char satz[]= Hallo ; int i = 0; while (*(satz+i)){ printf( %c,*(satz+(i++)); //while (satz[i]){ printf( %c,satz[i++]); Pointer und Felder <Datentyp> <Feldname>[<groesse>] Feldnamen werden als konstante Zeiger auf <Datentyp> interpretiert; Wert dieses Zeigers ist die Feldadresse Tatsächlich ist <Feldname>[n] nur eine andere Schreibweise für *(<Feldname>+n) Im Hintergrund wird also immer eine Adressverschiebung mit anschließender Dereferenzierung ausgeführt! Umgekehrt gibt es die Feld-Schreibweise auch für Zeiger: Schreibe <Zeigername>[n] statt *(<Zeigername>+n) Pointer und Felder <Datentyp> <Feldname>[<groesse>] Feldnamen werden als konstante Zeiger auf <Datentyp> interpretiert; Wert dieses Zeigers ist die Feldadresse Man kann einem Feldnamen keinen neuen Speicherbereich zuweisen, d.h. man kann Felder nicht umbiegen Beispiele: int v[4],w[]={1,2,3,4,*p=w,x; v=v+1;//compilerfehler!! v=w;//compilerfehler!! v=p;//compilerfehler!! v=&x;//compilerfehler!!

78 Pointer und Felder <Datentyp> <Feldname>[<groesse>] Feldnamen werden als konstante Zeiger auf <Datentyp> interpretiert; Wert dieses Zeigers ist die Feldadresse Folgerung 1: Diese Interpretation gilt in Ausdrücken Ist v ein Feldname und ist w ein Ausdruck, der als Adresse ausgewertet wird, so überprüft (v==w), ob w der Adresse von v entspricht v w Pointer und Felder <Datentyp> <Feldname>[<groesse>] Feldnamen werden als konstante Zeiger auf <Datentyp> interpretiert; Wert dieses Zeigers ist die Feldadresse Folgerung 2: Diese Interpretation gilt für Wertzuweisungen Man kann Zeigern Feldnamen als Wert zuweisen; Zugewiesen wird dann die Feldadresse <Typ> *<Zeiger>, <Feld>[n]; <Zeiger> = <Feld>; <Feld> <Zeiger> Pointer und Felder <Datentyp> <Feldname>[<groesse>] Feldnamen werden als konstante Zeiger auf <Datentyp> interpretiert; Wert dieses Zeigers ist die Feldadresse Folgerung 3: Diese Interpretation gilt bei Parameterübergabe an Funktionen Man kann Feldnamen an Funktionen übergeben, die einen Zeiger erwarten; übergeben wird dann die Feldadresse. <Rückgabetyp> <meinefunktion>(<typ> *p){... int main(){ <Typ> <Feld>[<Groesse>]; <meinefunktion>(<feld>);... Pointer und Felder <Datentyp> <Feldname>[<groesse>] Feldnamen werden als konstante Zeiger auf <Datentyp> interpretiert; Wert dieses Zeigers ist die Feldadresse /*bsp21d.c*/ void tausche(int *p){ int z; z=*p; *p=*(p+1); *(p+1)=z; int main(){ int v[2]; v[0]=3;v[1]=5; tausche(v); return 0; /*bsp23d.c*/ #include <stdio.h> void rev1(char *p); int main() { char wort[] = Hallo"; rev1(wort); printf("%s",wort); return 0; void rev1(char *p){...

79 Pointer und Felder Pointer und Felder Zusammenfassung 1 Zusammenfassung 2 Zeiger <Typ>*<Name> Feld <Typ> <Name>[] Zeiger <Typ>*<Name> Feld <Typ> <Name>[] hat Adresse als Wert Reserviert Speicherplatz für Speicherung dieser Adresse Reserviert keinen Speicherplatz an der referenzierten Adresse <Name> <Adresse> wird als Adresse ausgewertet Die Adresse wird nirgends extra gespeichert Reserviert Speicherplatz für alle Komponenten <Name> ==<Adresse> Kann man umbiegen: <Name> = <neueadresse> Kann man verschieben: <Name>+n Kann man deferenzieren: *<Name> == <Name>[0] Zugriff auf verschobene Adresse: *(<Name>+n)==<Name>[n] Kann man nicht umbiegen, ist also konstant Kann man verschieben: <Name>+n Kann man deferenzieren: *<Name> == <Name>[0] Zugriff auf verschobene Adresse: *(<Name>+n)==<Name>[n] Felder als Eingabeparameter, Teil 2 Felder als Eingabeparameter, Teil 2 Als Feld deklarierte Eingabeparameter werden als Zeiger interpretiert Keine Angabe der Dimension des Feldes notwendig (da Funktion keinen Speicherplatz für das Feld bereitstellen muss): <Rückgabetyp> <meinefunktion>(<typ> <Name>[]); entspricht <Rückgabetyp> <meinefunktion>(<typ> *<Name>); Als Feld deklarierte Eingabeparameter werden als Zeiger interpretiert /*bsp21e.c*/ void tausche(int w[]){ int z; z=w[0]; w[0]=w[1]; w[1]=z; int main(){ int v[2]; v[0]=3;v[1]=5; tausche(v); return 0;

80 Felder als Eingabeparameter, Teil 2 Zusammenfassung 3: Vertauschungsbeispiel Felder als Eingabeparameter, Teil 2 Zusammenfassung 4: Funktionen void tausche(int *p,int *q){ int z; z=*p; *p=*q; *q=z; int main(){ int v[2]; v[0]=3;v[1]=5; tausche(&v[0],&v[1]); return 0; void tausche(int w[]){ int z; z=w[0]; w[0]=w[1]; w[1]=z; int main(){ int v[2]; v[0]=3;v[1]=5; tausche(v); return 0; void tausche(int *p){ int z; z=*p; *p=*(p+1); *(p+1)=z; int main(){ int v[2]; v[0]=3;v[1]=5; tausche(&v[0]); return 0; void tausche(int *p){ int z; z=*p; *p=*(p+1); *(p+1)=z; int main(){ int v[2]; v[0]=3;v[1]=5; tausche(v); return 0; Wenn man in einer Funktion mit Feldwerten rechnen will: (1) Deklariere ein Feld und reserviere so Speicherplatz (2) Definiere Funktion mit einem Zeiger als Eingabeparameter (3) Übergebe bei Aufruf den Feldnamen an die Funktion Zeichenketten, Teil 2 Zeichenketten sind Zeiger auf char Konstante Zeichenkette wird als Adresse der Speicherstelle des ersten Buchstabens ausgewertet Zeichenketten, Teil 2 Zeichenketten sind Zeiger auf char Konstante Zeichenkette wird als Adresse der Speicherstelle des ersten Buchstabens ausgewertet Hallo H a l l o \0 Hallo H a l l o t \0 char *t = Hallo ist ein Zeiger auf diese Adresse

81 Zeichenketten, Teil 2 Zeichenketten sind Zeiger auf char: Besonderheit Zeichenketten, Teil 2 Zeichenketten sind Zeiger auf char: Besonderheit char s[] = Hallo ; Zeichenkette mit Wert Hallo Einzelne Zeichen können geändert werden s steht für eine konstante Adresse char *t = Hallo ; Pointer auf konstante Zeichenkette mit Wert Hallo Man kann den Inhalt der Zeichenkette nicht ändern Pointer kann umgebogen werden char s[] = Hallo ; s[1]= e ; *(s+4)= a ; char *t = Hallo ; *(t+1)= e ;//Fehler!!! t[4]= a ;//Fehler!!! s H a l l o \0 t H a l l o \0 s H e l l a \0 t H a l l o \0 Zeichenketten, Teil 2 Zeichenketten, Teil 2 Zeichenketten sind Zeiger auf char: Besonderheit char s[] = Hallo ; s[1]= e ; *(s+4)= a ; s=t;//fehler!!! s= Mexiko ;//Fehler!!! char *t = Hallo ; *(t+1)= e ;//Fehler!!! t[4]= a ;//Fehler!!! t=s+2; Zeichenketten sind Zeiger auf char Der Name einer Zeichenkette char <Name>[n] wird als Adresse der Speicherstelle des ersten Buchstabens ausgewertet <Name> s H e l l a \0 t H a l l o \0

82 Zeichenketten, Teil 2 Zeichenketten, Teil 2 Zeichenketten sind Zeiger auf char Der Name einer Zeichenkette char <Name>[n] wird als Adresse der Speicherstelle des ersten Buchstabens ausgewertet <Name> Zeichenketten sind Zeiger auf char Zeichenkettenfunktionen arbeiten mit Zeigern auf char char *strcpy(char * v, const char * w); entspricht char[] strcpy(char v[], const char w[]); int scanf(const char * format,...); t char *t = <Name> ist ein Zeiger auf diese Adresse format Zeiger auf konstante Zeichenkette weitere Eingabeparameter von der Form &<Variablenname> in scanf wird mit Zeigern gerechnet, um Werte zu setzen (call by reference) Vergleiche printf: Hier werden nur Werte gelesen, also keine Zeiger nötig Zeichenketten, Teil 2 Zeichenketten, Teil 2 Zeichenketten sind Zeiger auf char Zeichenkettenfunktionen arbeiten mit Zeigern auf char Dadurch können in der Funktion Werte von Zeichenketten verändert/gesetzt werden! (call by reference vs. call by value) Zeichenketten sind Zeiger auf char Zeichenkettenfunktionen arbeiten mit Zeigern auf char Dadurch können in der Funktion Werte von Zeichenketten verändert/gesetzt werden! (call by reference vs. call by value) Woher ist ist in der Funktion das Ende der Zeichenkette bekannt? Letztes Zeichen einer Zeichenkette im Speicher ist immer \0 Ein Zeiger auf char repräsentiert also genau die Zeichenkette im Speicher von der Speicherzelle, auf die der Zeiger zeigt, bis zur ersten Speicherzelle mit dem \0-Zeichen Bibliotheksfunktionen beenden Zeichenketten mit \0 Achten Sie darauf bei selbst geschriebenen Zeichenketten-Funktionen

83 Verschachtelte Referenzen Werden immer von innen nach aussen gelesen! Felder von Feldern (Teil 2) <Typ> <Name>[n][m]; ist ein Feld mit n Komponenten jede Komponente ist ein Feld mit m Komponenten <Name> <Name>[0][0] ==<Name>[0]... <Name>[0][m-1] <Name>[1] <Name>[1][0]... <Name>[1][m-1]... Verschachtelte Referenzen Werden immer von innen nach aussen gelesen! Felder von Feldern (Teil 2) <Typ> <Name>[n][m]; ist ein Feld mit n Komponenten <Name>[j] ist ein Feldname Die j-te Komponente von <Name> ist das Feld <Name>[j] <Name>[j] ist ein Synonym für *(<Name>+j) jede Komponente ist ein Feld mit m Komponenten <Name>+j verschiebt die Adresse von <Name> um die Größe von j Komponenten, also um(j*m*sizeof(<typ>)) <Name>[j][i] ist die i-te Komponente des Feldes <Name>[j] Verschachtelte Referenzen Werden immer von innen nach aussen gelesen! Felder von Feldern (Teil 2) <Typ> <Name>[n][m]; Beispiel: Komponenten können mit einem einfachen Zeiger auf <Typ> durchlaufen werden: <Name> <Name>[0][0] <Zeiger> ==<Name>[0]... <Name>[0][m-1] <Name>[1] <Name>[1][0]... <Name>[1][m-1]... Verschachtelte Referenzen Werden immer von innen nach aussen gelesen! Felder von Feldern (Teil 2) <Typ> <Name>[n][m]; Übergabe an Funktionen: Deklariere die Funktion in der Form <Rückgabetyp> <meinf>(<typ> <Name>[][m]); Alle Dimensionen bis auf die Oberste müssen angegeben werden (wichtig für Adressverschiebung) Wenn man die aber nicht kennt (Funktion zum Einlesen von Matrixwerten)?

84 Verschachtelte Referenzen Werden immer von innen nach aussen gelesen! Felder von Feldern (Teil 2) <Typ> <Name>[n][m]; Verwaltung: Komponenten können mit einem einfachen Zeiger auf <Typ> durchlaufen werden: <Typ> *<Zeiger> = <Name>[0];//oder =&<Name>[0][0] <Zeiger>[m*j+i] entspricht <Name>[j][i] Ermöglicht die Verwaltung von Matrizen in 1-dimensionalen Feldern Verschachtelte Referenzen Werden immer von innen nach aussen gelesen! Felder von Zeigern <Typ> *<Name>[n]; ist ein Feld mit n Komponenten jede Komponente ist ein Zeiger auf <Typ> <Name> <Name>[0]... <Name>[m-1] Speicherbereiche der Größe sizeof(<typ>) (noch nicht reserviert!) Verschachtelte Referenzen Werden immer von innen nach aussen gelesen! Felder von Zeigern <Typ> *<Name>[n]; ist ein Feld mit n Komponenten jede Komponente ist ein Zeiger auf <Typ> <Name> <Name>[0] *(<Name>[0])... <Name>[m-1] <Typ> <Variable>; <Name>[0]=&<Variable>; Verschachtelte Referenzen Werden immer von innen nach aussen gelesen! Felder von Zeigern <Typ> *<Name>[n]; ist ein Feld mit n Komponenten <Name>[j] ist ein Zeigername Die j-te Komponente von <Name> ist der Zeiger <Name>[j] <Name>[j] ist ein Synonym für *(<Name>+j) jede Komponente ist ein Zeiger auf <Typ> <Name>+j verschiebt die Adresse von <Name> um die Größe von j Komponenten, also um(j*sizeof(*<typ>)) Zeiger-Komponente Wert zuweisen: <Name>[j] = &<Variable>

85 Verschachtelte Referenzen Werden immer von innen nach aussen gelesen! Felder von Zeigern <Typ> *<Name>[n]; Beispiel: Kommandozeilen-Parameter an main übergeben Deklaration von main argc argv argv[i] Übergabe der Parameter Konvention int main(int argc, char* argv[]) Argument Count: Anzahl übergebene Parameter Argument Vektor Zeigt auf i-te übergebene Zeichenkette Bei Programmaufruf getrennt durch Leerzeichen Programmname selbst ist erster Parameter Verschachtelte Referenzen Werden immer von innen nach aussen gelesen! Felder von Zeigern <Typ> *<Name>[n]; Beispiel: Kommandozeilen-Parameter an main übergeben: Übergebene Parameter wieder ausgeben /*bsp24.c*/ int main(int argc, char* argv[]) { int i=0; for (i=0 ; i<argc ; i++) { printf( Comand line argument %i = %s\n,i,argv[i]); return 0; Verschachtelte Referenzen Werden immer von innen nach aussen gelesen! Felder von Zeigern <Typ> *<Name>[n]; Übergabe an Funktionen: Deklariere die Funktion in der Form <Rückgabetyp> <meinf>(<typ> *<Name>[]); Verschachtelte Referenzen Werden immer von innen nach aussen gelesen! Zeiger auf Felder <Typ> (*<Name>)[m]; ist ein Zeiger auf Felder mit m Komponenten vom Typ <Typ> <Name>... Speicherbereich der Größe m*sizeof(<typ>) (noch nicht reserviert!)

86 Verschachtelte Referenzen Werden immer von innen nach aussen gelesen! Zeiger auf Felder <Typ> (*<Name>)[m]; ist ein Zeiger auf Felder mit m Komponenten vom Typ <Typ> <Name> <Name>[0][0] oder (*<Name>)[0]... <Name>[0][m-1] oder (*<Name>)[m-1] <Typ> <Feld>[m]; <Name> = &<Feld>; //oder: <Name> = <Feld>; Verschachtelte Referenzen Werden immer von innen nach aussen gelesen! Zeiger auf Felder <Typ> (*<Name>)[m]; ist ein Zeiger auf Felder mit m Komponenten vom Typ <Typ> *(<Name>+j) ist ein Feldname Die i-te Komponente von *<Name> ist (*<Name>)[i] <Name>+j verschiebt die Adresse um j mal die Größe des Datentyps, auf den <Name> zeigt, also um(j*m*sizeof(<typ>)) Zeiger einen Wert zuweisen: <Name> = &<Feld> Verschachtelte Referenzen Werden immer von innen nach aussen gelesen! Zeiger auf Felder <Typ> (*<Name>)[m]; Übergabe an Funktionen: Deklariere die Funktion wie in der Form <Rückgabetyp> <meinf>(<typ> (*<Name>)[m]); Dimension des Feldes muss bekannt sein, da wichtig für Adressverschiebung Verschachtelte Referenzen Werden immer von innen nach aussen gelesen! Zeiger auf Zeiger (Teil 2) <Typ> **<Name>; ist ein Zeiger auf einen Zeiger vom Typ <Typ> <Name> Speicherbereich der Größe sizeof(*<typ>) (noch nicht reserviert!) Speicherbereich der Größe sizeof(<typ>) (noch nicht reserviert!)

87 Verschachtelte Referenzen Werden immer von innen nach aussen gelesen! Zeiger auf Zeiger (Teil 2) <Typ> **<Name>; ist ein Zeiger auf einen Zeiger vom Typ <Typ> Verschachtelte Referenzen Werden immer von innen nach aussen gelesen! Zeiger auf Zeiger (Teil 2) <Typ> **<Name>; ist ein Zeiger auf einen Zeiger vom Typ <Typ> <Name> *<Name> <Name> *<Name> **<Name> <Typ> *<Zeiger>; <Name> = &<Zeiger>; Speicherbereich der Größe sizeof(<typ>) (noch nicht reserviert!) <Typ> *<Zeiger>; <Name> = &<Zeiger>; <Typ> <Variable>; <Zeiger> = &>Variable>; Verschachtelte Referenzen Werden immer von innen nach aussen gelesen! Zeiger auf Zeiger (Teil 2) <Typ> **<Name>; ist ein Zeiger auf einen Zeiger vom Typ <Typ> *<Name> ist ein Zeiger auf <Typ> <Name>+j verschiebt die Adresse um (j*sizeof(*<typ>)) Zeiger einen Wert zuweisen: <Name> = &<Zeiger> Verschachtelte Referenzen Werden immer von innen nach aussen gelesen! Zeiger auf Zeiger (Teil 2) <Typ> **<Name>; Übergabe an Funktionen: Deklariere die Funktion wie in der Form <Rückgabetyp> <meinf>(<typ> **<Name>);

88 Verschachtelte Referenzen Kompatible Datentypen Verschachtelte Referenzen Kompatible Datentypen <Typ> **<Name1>; <Typ> *<Name2>[n]; Zeiger auf Zeiger Feld von Zeigern wird als Zeiger auf Zeiger aufgefasst <Typ> (*<Name1>)[m]; <Typ> <Name2>[n][m]; Zeiger auf Feld Feld von Feldern wird als Zeiger auf Feld aufgefasst Erlaubt: Einseitige Wertzuweisungen und Parameterübergabe <Name1> = <Name2>; (auch <Name2> = <Name1>;?) <Rückgabetyp> <meinf>(<typ> **<Name1>){ <meinf>(<name2>); Erlaubt: Einseitige Wertzuweisungen und Parameterübergabe <Name1> = <Name2>; (auch <Name2> = <Name1>;?) <Rückgabetyp> <meinf>((*<name1>)[m]){ <meinf>(<name2>); Verschachtelte Referenzen Inkompatible Datentypen alle anderen, da alle Ebenen kompatibel sein müssen und die Umwandlung von Feldnamen in Zeiger nur auf oberster Ebene erfolgt: Beispiele: <Typ> **<Name1>; Zeiger auf Zeiger <Typ> (*<Name2>)[n]; Zeiger auf Feld <Typ> *<Name1>[n]; Feld von Zeigern Zeiger auf Zeiger <Typ> <Name2>[n][m]; Feld von Feldern Zeiger auf Feld

Vorlesung Informatik I

Vorlesung Informatik I Vorlesung Informatik I Universität Augsburg Wintersemester 2010/2011 Prof. Dr. Robert Lorenz Lehrprofessur für Informatik Programmieren in C Der Compilierungsprozess 1 Aufbau eines C-Programms 1. Direktiven

Mehr

Die Programmiersprache C

Die Programmiersprache C Die Programmiersprache C höhere Programmiersprache (mit einigen Assembler-ähnlichen Konstrukten) gut verständliche Kommandos muss von Compiler in maschinenlesbaren Code (Binärdatei) übersetzt werden universell,

Mehr

Deklarationen in C. Prof. Dr. Margarita Esponda

Deklarationen in C. Prof. Dr. Margarita Esponda Deklarationen in C 1 Deklarationen Deklarationen spielen eine zentrale Rolle in der C-Programmiersprache. Deklarationen Variablen Funktionen Die Deklarationen von Variablen und Funktionen haben viele Gemeinsamkeiten.

Mehr

Einführung in den Einsatz von Objekt-Orientierung mit C++ I

Einführung in den Einsatz von Objekt-Orientierung mit C++ I Einführung in den Einsatz von Objekt-Orientierung mit C++ I ADV-Seminar Leiter: Mag. Michael Hahsler Syntax von C++ Grundlagen Übersetzung Formale Syntaxüberprüfung Ausgabe/Eingabe Funktion main() Variablen

Mehr

Einführung in die C-Programmierung

Einführung in die C-Programmierung Einführung in die C-Programmierung Warum C? Sehr stark verbreitet (Praxisnähe) Höhere Programmiersprache Objektorientierte Erweiterung: C++ Aber auch hardwarenahe Programmierung möglich (z.b. Mikrokontroller).

Mehr

GI Vektoren

GI Vektoren Vektoren Problem: Beispiel: viele Variablen vom gleichen Typ abspeichern Text ( = viele char-variablen), Ergebnisse einer Meßreihe ( = viele int-variablen) hierfür: Vektoren ( = Arrays = Feld ) = Ansammlung

Mehr

Modul Entscheidungsunterstützung in der Logistik. Einführung in die Programmierung mit C++ Übung 2

Modul Entscheidungsunterstützung in der Logistik. Einführung in die Programmierung mit C++ Übung 2 Fakultät Verkehrswissenschaften Friedrich List, Professur für Verkehrsbetriebslehre und Logistik Modul Entscheidungsunterstützung in der Logistik Einführung in die Programmierung mit C++ Übung 2 SS 2016

Mehr

Schachtelung der 2. Variante (Bedingungs-Kaskade): if (B1) A1 else if (B2) A2 else if (B3) A3 else if (B4) A4 else A

Schachtelung der 2. Variante (Bedingungs-Kaskade): if (B1) A1 else if (B2) A2 else if (B3) A3 else if (B4) A4 else A 2.4.6. Kontrollstrukturen if-anweisung: Bedingte Ausführung (Verzweigung) 2 Varianten: if (Bedingung) Anweisung (Anweisung = einzelne Anweisung oder Block) Bedeutung: die Anweisung wird nur ausgeführt,

Mehr

Annehmende Schleife do while

Annehmende Schleife do while Annehmende Schleife do while Schleife mit nachfolgender Bedingungsprüfung: annehmende Schleife B S Mit B wird eine Bedingung (logischer Ausdruck) bezeichnet, S ist ein Strukturblock. Zuerst wird S ausgeführt,

Mehr

Programmieren in C / C++ Grundlagen C 2

Programmieren in C / C++ Grundlagen C 2 Programmieren in C / C++ Grundlagen C 2 Hochschule Fulda FB AI Wintersemester 2016/17 http://c.rz.hs-fulda.de Peter Klingebiel, HS Fulda, FB AI Anweisung / Ausdruck 1 Programm setzt sich aus vielen Anweisungen

Mehr

Programmierung mit C Zeiger

Programmierung mit C Zeiger Programmierung mit C Zeiger Zeiger (Pointer)... ist eine Variable, die die Adresse eines Speicherbereichs enthält. Der Speicherbereich kann... kann den Wert einer Variablen enthalten oder... dynamisch

Mehr

Modul Entscheidungsunterstützung in der Logistik. Einführung in die Programmierung mit C++ Übung 4

Modul Entscheidungsunterstützung in der Logistik. Einführung in die Programmierung mit C++ Übung 4 Fakultät Verkehrswissenschaften Friedrich List, Professur für Verkehrsbetriebslehre und Logistik Modul Entscheidungsunterstützung in der Logistik Einführung in die Programmierung mit C++ Übung 4 SS 2016

Mehr

Zeichendarstellung. Zeichen sind Zahlen (in C) Zeichen und switch

Zeichendarstellung. Zeichen sind Zahlen (in C) Zeichen und switch darstellung Arbeiten mit darstellung werden im Computer durch (kleine) Zahlen dargestellt in C können im Datentyp char gespeichert werden, dieser umfasst ein Byte und gilt als Ganzzahltyp darstellung Arbeiten

Mehr

Programmieren in C. Macros, Funktionen und modulare Programmstruktur. Prof. Dr. Nikolaus Wulff

Programmieren in C. Macros, Funktionen und modulare Programmstruktur. Prof. Dr. Nikolaus Wulff Programmieren in C Macros, Funktionen und modulare Programmstruktur Prof. Dr. Nikolaus Wulff Der C Präprozessor Vor einem Compile Lauf werden alle Präprozessor Kommandos/Makros ausgewertet. Diese sind

Mehr

Fakultät Angewandte Informatik Lehrprofessur für Informatik 23.01.2012

Fakultät Angewandte Informatik Lehrprofessur für Informatik 23.01.2012 WS 2011/2012 Fakultät Angewandte Informatik Lehrprofessur für Informatik 23.01.2012 Prof. Dr. Robert Lorenz Musterlösung zur Vorlesung Informatik I, Extrablatt zu komplexen Datenstrukturen Aufgabe 45 **

Mehr

4. Einfache Programmstrukturen in C Einfache Programmstrukturen in C

4. Einfache Programmstrukturen in C Einfache Programmstrukturen in C Einfache Programmstrukturen in C 4-1 Welche einfache Programmstrukturen sind zu unterscheiden? Arithmetische und logische Ausdrücke und Zuweisungen Verzweigungen Unvollständige bedingte Anweisungen Vollständige

Mehr

Elementare Datentypen in C++

Elementare Datentypen in C++ Elementare Datentypen in C++ bool signed/unsigned char signed/unsigned short int signed/unsigned int signed/unsigned long int (signed/unsigned long long int) float double long double void enum char Der

Mehr

Kapitel 3: Variablen

Kapitel 3: Variablen Kapitel 3: Variablen Thema: Programmieren Seite: 1 Kapitel 3: Variablen Im letzten Kapitel haben wir gelernt, bestimmte Ereignisse zu wiederholen solange eine Bedingung erfüllt ist. Nun möchten wir aber

Mehr

Einführung in die Informatik I (autip)

Einführung in die Informatik I (autip) Einführung in die Informatik I (autip) Dr. Stefan Lewandowski Fakultät 5: Informatik, Elektrotechnik und Informationstechnik Abteilung Formale Konzepte Universität Stuttgart 24. Oktober 2007 Was Sie bis

Mehr

Präzedenz von Operatoren

Präzedenz von Operatoren Präzedenz von Operatoren SWE-30 Die Präzedenz von Operatoren bestimmt die Struktur von Ausdrücken. Ein Operator höherer Präzedenz bindet die Operanden stärker als ein Operator geringerer Präzedenz. Mit

Mehr

Erste Schritte der Programmierung in C

Erste Schritte der Programmierung in C Erste Schritte der Programmierung in C C versus C++ Anatomie von C-Programmen für AVR- Mikrocontroller Unterschiede zwischen C++ und C 1 Grundlegende Unterschiede File-Extensions (Header und Quellcode)

Mehr

5. Unterprogrammtechnik/Module

5. Unterprogrammtechnik/Module 5. Unterprogrammtechnik/Module Unterprogramm/Modul: separate Programmeinheit, mit Anweisungen, die eine bestimmte Aufgabe erfüllen bekommt i.a. Argumente (Werte, Informationen) vom aufrufenden Programm

Mehr

FH München, FB 03 FA WS 06/07. Ingenieurinformatik. Name Vorname Matrikelnummer Sem.Gr.: Hörsaal Platz

FH München, FB 03 FA WS 06/07. Ingenieurinformatik. Name Vorname Matrikelnummer Sem.Gr.: Hörsaal Platz FH München, FB 03 FA WS 06/07 Ingenieurinformatik Name Vorname Matrikelnummer Sem.Gr.: Hörsaal Platz Zulassung geprüft vom Aufgabensteller: Teil I Aufg. 2 Aufg. 3 Aufg. 4 Aufg. 5 Summe Note Aufgabensteller:

Mehr

Einführung in die Programmiersprache C

Einführung in die Programmiersprache C Einführung in die Programmiersprache C Marcel Arndt [email protected] Institut für Numerische Simulation Universität Bonn Der Anfang Ein einfaches Programm, das Hello World! ausgibt: #include

Mehr

CEN1112 Labor Software-Entwicklung

CEN1112 Labor Software-Entwicklung Dipl.-Ing. (FH) Peter Bitterlich M.Sc. Joachim Storz Fakultät für Technik STUDIENGANG MEDIZINTECHNIK CEN1112 Labor Software-Entwicklung Vorbereitungsaufgaben zu Versuch 3 C-Programmierung Vertiefung Wintersemester

Mehr

Propädeutikum. Dipl.-Inf. Frank Güttler

Propädeutikum. Dipl.-Inf. Frank Güttler Propädeutikum 2015 Vorbereitungskurs Informatikstudium Erfolgreich Studieren Programmieren (C-Kurs) [email protected] Universität Leipzig Institut für Informatik Technische Informatik

Mehr

Grundlagen der Programmierung

Grundlagen der Programmierung Grundlagen der Programmierung 7. Vorlesung 18.05.2016 1 Konstanten Ganzzahlkonstante Dezimal: 42, 23, -2 Oktal (0 vorangestellt): 052 Hexadezimal (0x vorangestellt): 0x2A Gleitkommazahlen: 3.1415, 2.71,

Mehr

Java 8. Elmar Fuchs Grundlagen Programmierung. 1. Ausgabe, Oktober 2014 JAV8

Java 8. Elmar Fuchs Grundlagen Programmierung. 1. Ausgabe, Oktober 2014 JAV8 Java 8 Elmar Fuchs Grundlagen Programmierung 1. Ausgabe, Oktober 2014 JAV8 5 Java 8 - Grundlagen Programmierung 5 Kontrollstrukturen In diesem Kapitel erfahren Sie wie Sie die Ausführung von von Bedingungen

Mehr

JavaScript. Dies ist normales HTML. Hallo Welt! Dies ist JavaScript. Wieder normales HTML.

JavaScript. Dies ist normales HTML. Hallo Welt! Dies ist JavaScript. Wieder normales HTML. JavaScript JavaScript wird direkt in HTML-Dokumente eingebunden. Gib folgende Zeilen mit einem Texteditor (Notepad) ein: (Falls der Editor nicht gefunden wird, öffne im Browser eine Datei mit der Endung

Mehr

zu große Programme (Bildschirmseite!) zerlegen in (weitgehend) unabhängige Einheiten: Unterprogramme

zu große Programme (Bildschirmseite!) zerlegen in (weitgehend) unabhängige Einheiten: Unterprogramme Bisher Datentypen: einfach Zahlen, Wahrheitswerte, Zeichenketten zusammengesetzt Arrays (Felder) zur Verwaltung mehrerer zusammengehörender Daten desselben Datentypes eindimensional, mehrdimensional, Array-Grenzen

Mehr

Inhaltsverzeichnis. Grundbegriffe der C-Programmierung Für den HI-TECH C-Compiler

Inhaltsverzeichnis. Grundbegriffe der C-Programmierung Für den HI-TECH C-Compiler Inhaltsverzeichnis Grundbegriffe der C-Programmierung 1. Grundsätzliches... 2 1.1 Darstellung von Werten... 2 1.1.1 Dezimale Zahlendarstellung... 2 1.1.2 Binäre Zahlendarstellung... 3 1.1.3 Hexadezimale

Mehr

Werkzeuge zur Programmentwicklung

Werkzeuge zur Programmentwicklung Werkzeuge zur Programmentwicklung B-15 Bibliothek Modulschnittstellen vorübersetzte Module Eingabe Editor Übersetzer (Compiler) Binder (Linker) Rechner mit Systemsoftware Quellmodul (Source) Zielmodul

Mehr

Grundlagen. Die Komponenten eines C Programms. Das erste Programm

Grundlagen. Die Komponenten eines C Programms. Das erste Programm Grundlagen 1. Die Komponenten eines C Programms 2. Ein Programm erzeugen und übersetzen 3. Variablen Deklarieren und Werte zuweisen 4. Zahlen eingeben mit der Tastatur 5. Arithmetische Ausdrücke und Berechnungen

Mehr

2. Programmierung in C

2. Programmierung in C 2. Programmierung in C Inhalt: Überblick über Programmiersprachen, Allgemeines zur Sprache C C: Basisdatentypen, Variablen, Konstanten Operatoren, Ausdrücke und Anweisungen Kontrollstrukturen (Steuerfluss)

Mehr

Java Einführung VARIABLEN und DATENTYPEN Kapitel 2

Java Einführung VARIABLEN und DATENTYPEN Kapitel 2 Java Einführung VARIABLEN und DATENTYPEN Kapitel 2 Inhalt dieser Einheit Variablen (Sinn und Aufgabe) Bezeichner Datentypen, Deklaration und Operationen Typenumwandlung (implizit/explizit) 2 Variablen

Mehr

C für Java-Programmierer

C für Java-Programmierer Carsten Vogt C für Java-Programmierer ISBN-10: 3-446-40797-9 ISBN-13: 978-3-446-40797-8 Inhaltsverzeichnis Weitere Informationen oder Bestellungen unter http://www.hanser.de/978-3-446-40797-8 sowie im

Mehr

Repetitorium Informatik (Java)

Repetitorium Informatik (Java) Repetitorium Informatik (Java) Tag 6 Lehrstuhl für Informatik 2 (Programmiersysteme) Übersicht 1 Klassen und Objekte Objektorientierung Begrifflichkeiten Deklaration von Klassen Instanzmethoden/-variablen

Mehr

Modul Entscheidungsunterstützung in der Logistik. Einführung in die Programmierung mit C++ Übung 1

Modul Entscheidungsunterstützung in der Logistik. Einführung in die Programmierung mit C++ Übung 1 Fakultät Verkehrswissenschaften Friedrich List, Professur für Verkehrsbetriebslehre und Logistik Modul Entscheidungsunterstützung in der Logistik Einführung in die Programmierung mit C++ Übung 1 SS 2016

Mehr

Einführung in die C++ Programmierung für Ingenieure

Einführung in die C++ Programmierung für Ingenieure Einführung in die C++ Programmierung für Ingenieure MATTHIAS WALTER / JENS KLUNKER Universität Rostock, Lehrstuhl für Modellierung und Simulation 14. November 2012 c 2012 UNIVERSITÄT ROSTOCK FACULTY OF

Mehr

Einleitung Entwicklung in C Hello-World! Konstrukte in C Zusammenfassung Literatur. Grundlagen von C. Jonas Gresens

Einleitung Entwicklung in C Hello-World! Konstrukte in C Zusammenfassung Literatur. Grundlagen von C. Jonas Gresens Grundlagen von C Jonas Gresens Proseminar C Grundlagen und Konzepte Arbeitsbereich Wissenschaftliches Rechnen Fachbereich Informatik Fakultät für Mathematik, Informatik und Naturwissenschaften Universität

Mehr

Javaprogrammierung mit NetBeans. Variablen, Datentypen, Methoden

Javaprogrammierung mit NetBeans. Variablen, Datentypen, Methoden Javaprogrammierung mit NetBeans Variablen, Datentypen, Methoden Programmieren 2 Java Bezeichner Bezeichner: Buchstabe _ $ Buchstabe _ $ Ziffer Groß- und Kleinbuchstaben werden strikt unterschieden. Schlüsselwörter

Mehr

RO-Tutorien 3 / 6 / 12

RO-Tutorien 3 / 6 / 12 RO-Tutorien 3 / 6 / 12 Tutorien zur Vorlesung Rechnerorganisation Christian A. Mandery WOCHE 2 AM 06./07.05.2013 KIT Universität des Landes Baden-Württemberg und nationales Forschungszentrum in der Helmholtz-Gemeinschaft

Mehr

Einführung in die Programmierung Wintersemester 2011/12

Einführung in die Programmierung Wintersemester 2011/12 Einführung in die Programmierung Wintersemester 2011/12 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund : Kontrollstrukturen Inhalt Wiederholungen - while

Mehr

Inhalt. 4.7 Funktionen

Inhalt. 4.7 Funktionen Inhalt Inhalt: 4. Programmiersprache C 4.1 Programmaufbau in C 4.2 Basisdatentypen und einfache Anweisungen 4.3 Steuerfluss-Konstrukte 4.4 Arbeit mit indizierten Größen (Felder) 4.5 Arbeit mit Pointern

Mehr

Programmieren lernen mit C

Programmieren lernen mit C Programmieren lernen mit C Bearbeitet von Karlheinz Zeiner 4., aktualisierte Auflage 2000. Buch. XIV, 361 S. Hardcover ISBN 978 3 446 21596 2 Format (B x L): 16,9 x 24,1 cm Gewicht: 730 g Weitere Fachgebiete

Mehr

JAVA-Datentypen und deren Wertebereich

JAVA-Datentypen und deren Wertebereich Folge 8 Variablen & Operatoren JAVA 8.1 Variablen JAVA nutzt zum Ablegen (Zwischenspeichern) von Daten Variablen. (Dies funktioniert wie beim Taschenrechner. Dort können Sie mit der Taste eine Zahl zwischenspeichern).

Mehr

S. d. I.: Programieren in C Folie 4-1. im Gegensatz zu Pascal gibt es in C kein Schlüsselwort "then"

S. d. I.: Programieren in C Folie 4-1. im Gegensatz zu Pascal gibt es in C kein Schlüsselwort then S. d. I.: Programieren in C Folie 4-1 4 Anweisungen 4.1 if-anweisung 1) if (Ausdruck) 2) if (Ausdruck) } else im Gegensatz zu Pascal gibt es in C kein Schlüsselwort "then" es wird nur der numerische Wert

Mehr

Grundlagen der Informatik I (Studiengang Medieninformatik)

Grundlagen der Informatik I (Studiengang Medieninformatik) Grundlagen der Informatik I (Studiengang Medieninformatik) Thema: 3. Datentypen, Datenstrukturen und imperative Programme Prof. Dr. S. Kühn Fachbereich Informatik/Mathematik Email: [email protected]

Mehr

C- Kurs 04 Anweisungen

C- Kurs 04 Anweisungen C- Kurs 04 Anweisungen Dipl.- Inf. Jörn Hoffmann jhoffmann@[email protected] leipzig.de Universität Leipzig Ins@tut für Informa@k Technische Informa@k Ausdrücke Institut für Informatik Anweisungen C-Programm

Mehr

Programmieren I. Kapitel 5. Kontrollfluss

Programmieren I. Kapitel 5. Kontrollfluss Programmieren I Kapitel 5. Kontrollfluss Kapitel 5: Kontrollfluss Ziel: Komplexere Berechnungen im Methodenrumpf Ausdrücke und Anweisungen Fallunterscheidungen (if, switch) Wiederholte Ausführung (for,

Mehr

Wiederholung Wozu Methoden? Methoden Schreiben Methoden Benutzen Rekursion?! Methoden. Javakurs 2012, 3. Vorlesung

Wiederholung Wozu Methoden? Methoden Schreiben Methoden Benutzen Rekursion?! Methoden. Javakurs 2012, 3. Vorlesung Wiederholung Wozu? Schreiben Benutzen Rekursion?! Javakurs 2012, 3. Vorlesung [email protected] 5. März 2013 Wiederholung Wozu? Schreiben Benutzen Rekursion?! 1 Wiederholung 2 Wozu? 3 Schreiben

Mehr

Gliederung. Tutorium zur Vorlesung. Gliederung. Gliederung. 1. Gliederung der Informatik. 1. Gliederung der Informatik. 1. Gliederung der Informatik

Gliederung. Tutorium zur Vorlesung. Gliederung. Gliederung. 1. Gliederung der Informatik. 1. Gliederung der Informatik. 1. Gliederung der Informatik Informatik I WS 2012/13 Tutorium zur Vorlesung 1. Alexander Zietlow [email protected] Wilhelm-Schickard-Institut für Informatik Eberhard Karls Universität Tübingen 11.02.2013 1. 2. 1.

Mehr

4.Grundsätzliche Programmentwicklungsmethoden

4.Grundsätzliche Programmentwicklungsmethoden 4.Grundsätzliche Programmentwicklungsmethoden 1.1 Grundlage strukturierter und objektorientierter Programmierung Begriff Software Engineering - umfaßt den gezielten Einsatz von Beschreibungsmitteln, Methoden

Mehr

C programmieren. Jürgen Wolf

C programmieren. Jürgen Wolf C programmieren Jürgen Wolf Vorwort 11 Kapitel 1: Schnelleinstieg 13 Was sollten Sie bereits können? 14 Was lernen Sie mit diesem Buch? 14 Was benötigen Sie noch? 14 Überblick zu den einzelnen Kapiteln

Mehr

5. Elementare Befehle und Struktogramme

5. Elementare Befehle und Struktogramme 5. Elementare Befehle und Struktogramme Programmablauf Beschreibung des Programmablaufs mittel grafischer Symbole Beispiel : Flussdiagramme ja nein Besser : Struktogramme Dr. Norbert Spangler / Grundlagen

Mehr

Microcontroller Praktikum SS2010 Dipl. Ing. R. Reisch

Microcontroller Praktikum SS2010 Dipl. Ing. R. Reisch Microcontroller Praktikum SS2010 Dipl. Ing. R. Reisch Die wichtigsten Unterlagen/Tools Für das Praktikum Unterlagen/Kenntnisse/Tools wichtig: Datenblatt des AT80USB1287 µc Schaltplan des im Praktikum verwendeten

Mehr

Algorithmen & Programmierung. Ausdrücke & Operatoren (1)

Algorithmen & Programmierung. Ausdrücke & Operatoren (1) Algorithmen & Programmierung Ausdrücke & Operatoren (1) Ausdrücke Was ist ein Ausdruck? Literal Variable Funktionsaufruf Ausdruck, der durch Anwendung eines einstelligen (unären) Operators auf einen Ausdruck

Mehr

BKTM - Programmieren leicht gemacht.

BKTM - Programmieren leicht gemacht. BKTM Programmieren leicht gemacht. + Struktogramm Das Struktogramme ist eine Entwurfsmethode für die strukturierte Programmierung. Es ist nach der DIN 66261 genormt. Es ist 1972/73 von Dr. Isaac Nassi

Mehr

Programmiersprache 1 (C++) Prof. Dr. Stefan Enderle NTA Isny

Programmiersprache 1 (C++) Prof. Dr. Stefan Enderle NTA Isny Programmiersprache 1 (C++) Prof. Dr. Stefan Enderle NTA Isny 7. Funktionen Einleitung Nach dem Prinzip Divide and Conquer bietet es sich an, größere Aufgaben in kleinere Teile zu unterteilen. Anweisungsblöcke,

Mehr

zu große Programme (Bildschirmseite!) zerlegen in (weitgehend) unabhängige Einheiten: Unterprogramme

zu große Programme (Bildschirmseite!) zerlegen in (weitgehend) unabhängige Einheiten: Unterprogramme Bisher Datentypen: einfach Zahlen, Wahrheitswerte, Zeichenketten zusammengesetzt Arrays (Felder) zur Verwaltung mehrerer zusammengehörender Daten desselben Datentypes eindimensional, mehrdimensional, Array-Grenzen

Mehr

Elementare Konzepte von

Elementare Konzepte von Elementare Konzepte von Programmiersprachen Teil 1: Bezeichner, Elementare Datentypen, Variablen, Referenzen, Zuweisungen, Ausdrücke Kapitel 6.3 bis 6.7 in Küchlin/Weber: Einführung in die Informatik Bezeichner

Mehr

Algorithmen & Programmierung. Rekursive Funktionen (1)

Algorithmen & Programmierung. Rekursive Funktionen (1) Algorithmen & Programmierung Rekursive Funktionen (1) Berechnung der Fakultät Fakultät Die Fakultät N! einer nichtnegativen ganzen Zahl N kann folgendermaßen definiert werden: d.h. zur Berechnung werden

Mehr

Einführung in die Programmierung 1

Einführung in die Programmierung 1 Einführung in die Programmierung 1 Einführung (S.2) Einrichten von Eclipse (S.4) Mein Erstes Programm (S.5) Hallo Welt!? Programm Der Mensch (S.11) Klassen (S.12) Einführung Wie Funktioniert Code? Geschriebener

Mehr

Programmieren in C. Operatoren, Variablen und deren Sichtbarkeit. Prof. Dr. Nikolaus Wulff

Programmieren in C. Operatoren, Variablen und deren Sichtbarkeit. Prof. Dr. Nikolaus Wulff Programmieren in C Operatoren, Variablen und deren Sichtbarkeit Prof. Dr. Nikolaus Wulff Auswertung von Ausdrücken Was passiert wenn ein Ausdruck wie z. B. int y,x=2; y = ++x * x++; im Computer abgearbeitet

Mehr

Informatik I. Übung 2 : Programmieren in Eclipse. 5. März Daniel Hentzen

Informatik I. Übung 2 : Programmieren in Eclipse. 5. März Daniel Hentzen Informatik I Übung 2 : Programmieren in Eclipse 5. März 2014 Daniel Hentzen [email protected] Downloads : http://n.ethz.ch/~dhentzen/download/ Heute 1. Nachbesprechung Übung 1 2. Theorie 3. Vorbesprechung

Mehr

Compiler und Präprozessor (1) Erstellen eines Projektes

Compiler und Präprozessor (1) Erstellen eines Projektes Compiler und Präprozessor (1) Erstellen eines Projektes Projekte bestehen meist aus mehreren Dateien, z.b. Quelldateien, Funktionssammlungen in Bibliotheken Zur Definition eines Projektes sind folgende

Mehr

Flussdiagramm / Programmablaufplan (PAP)

Flussdiagramm / Programmablaufplan (PAP) Flussdiagramm / Programmablaufplan (PAP) Basissysmbole Grenzstelle (Anfang, Zwischenhalt oder Ende des Programms/Algorithmus) Verbindung Zur Verdeutlichung der Ablaufrichtung werden Linien mit einer Pfeilspitze

Mehr

Vorlesung Programmieren

Vorlesung Programmieren Vorlesung Programmieren 3. Kontrollstrukturen 04.11.2015 Prof. Dr. Ralf H. Reussner Version 1.1 LEHRSTUHL FÜR SOFTWARE-DESIGN UND QUALITÄT (SDQ) INSTITUT FÜR PROGRAMMSTRUKTUREN UND DATENORGANISATION (IPD),

Mehr

Hochschule Niederrhein Einführung in die Programmierung Prof. Dr. Nitsche. Bachelor Informatik WS 2015/16 Blatt 3 Beispiellösung.

Hochschule Niederrhein Einführung in die Programmierung Prof. Dr. Nitsche. Bachelor Informatik WS 2015/16 Blatt 3 Beispiellösung. Zahldarstellung Lernziele: Vertiefen der Kenntnisse über Zahldarstellungen. Aufgabe 1: Werte/Konstanten Ergänzen Sie die Tabelle ganzzahliger Konstanten auf einem 16- Bit- System. Die Konstanten in einer

Mehr

DAP2-Programmierpraktikum Einführung in C++ (Teil 1)

DAP2-Programmierpraktikum Einführung in C++ (Teil 1) DAP2-Programmierpraktikum Einführung in C++ (Teil 1) Carsten Gutwenger 11. April 2008 Lehrstuhl 11 Algorithm Engineering Fakultät für Informatik, TU Dortmund Überblick Mein erstes C++-Programm Namensräume

Mehr

AuD-Tafelübung T-B5b

AuD-Tafelübung T-B5b 6. Übung Sichtbarkeiten, Rekursion, Javadoc Di, 29.11.2011 1 Blatt 5 2 OOP Klassen Static vs. Instanzen Sichtbarkeit 3 Stack und Heap Stack Heap 4 Blatt 6 1 Blatt 5 2 OOP Klassen Static vs. Instanzen Sichtbarkeit

Mehr

Pass by Value Pass by Reference Defaults, Overloading, variable Parameteranzahl

Pass by Value Pass by Reference Defaults, Overloading, variable Parameteranzahl Funktionen Zusammenfassung von Befehlssequenzen als aufrufbare/wiederverwendbare Funktionen in einem Programmblock mit festgelegter Schnittstelle (Signatur) Derartige prozedurale Programmierung erlaubt

Mehr

Es ist für die Lösung der Programmieraufgabe nicht nötig, den mathematischen Hintergrund zu verstehen, es kann aber beim Verständnis helfen.

Es ist für die Lösung der Programmieraufgabe nicht nötig, den mathematischen Hintergrund zu verstehen, es kann aber beim Verständnis helfen. Ziele sind das Arbeiten mit Funktionen und dem Aufzählungstyp (enum), sowie - einfache Verzweigung (if else) - Alternativen switch case - einfache Schleifen (while oder do while) Aufgabe 3: Diese Aufgabe

Mehr

Grundlagen der Informatik - 6. Praktikum

Grundlagen der Informatik - 6. Praktikum Grundlagen der Informatik - 6. Praktikum In diesem Praktikum soll es neben der Anwendung von Funktionsdefinitionen auch um einfache Prinzipien der verteilten Quelltext-Strukturierung gehen. Diese spielt

Mehr

Algorithmus: Kochrezept

Algorithmus: Kochrezept Algorithmus: Kochrezept Ziel: Menü mit drei Gängen für 4 Personen Grundlegende Spezifikation: 1. Vorspeise: Badische Flädlesuppe 2. Hauptgericht: Überbackene Schinkenröllchen mit Spargel 3. Dessert: Vanilleeis

Mehr

Advanced Programming in C

Advanced Programming in C Advanced Programming in C Pointer und Listen Institut für Numerische Simulation Rheinische Friedrich-Wilhelms-Universität Bonn Oktober 2013 Überblick 1 Variablen vs. Pointer - Statischer und dynamischer

Mehr

Operatoren für elementare Datentypen Bedingte Anweisungen Schleifen. Programmieren I. Martin Schultheiß. Hochschule Darmstadt Wintersemester 2010/2011

Operatoren für elementare Datentypen Bedingte Anweisungen Schleifen. Programmieren I. Martin Schultheiß. Hochschule Darmstadt Wintersemester 2010/2011 Programmieren I Martin Schultheiß Hochschule Darmstadt Wintersemester 2010/2011 1 Operatoren für elementare Datentypen 2 Bedingte Anweisungen 3 Schleifen Zuweisungsoperator Die Zuweisung von Werten an

Mehr

II. Grundlagen der Programmierung. 9. Datenstrukturen. Daten zusammenfassen. In Java (Forts.): In Java:

II. Grundlagen der Programmierung. 9. Datenstrukturen. Daten zusammenfassen. In Java (Forts.): In Java: Technische Informatik für Ingenieure (TIfI) WS 2005/2006, Vorlesung 9 II. Grundlagen der Programmierung Ekkart Kindler Funktionen und Prozeduren Datenstrukturen 9. Datenstrukturen Daten zusammenfassen

Mehr

Die Programmiersprache C Eine Einführung

Die Programmiersprache C Eine Einführung Die Programmiersprache C Eine Einführung Christian Gentsch Fakutltät IV Technische Universität Berlin Projektlabor 2. Mai 2014 Inhaltsverzeichnis 1 Einführung Entstehungsgeschichte Verwendung 2 Objektorientiert

Mehr

3. Anweisungen und Kontrollstrukturen

3. Anweisungen und Kontrollstrukturen 3. Kontrollstrukturen Anweisungen und Blöcke 3. Anweisungen und Kontrollstrukturen Mit Kontrollstrukturen können wir den Ablauf eines Programmes beeinflussen, z.b. ob oder in welcher Reihenfolge Anweisungen

Mehr

Einführung in die Programmierung mit VBA

Einführung in die Programmierung mit VBA Einführung in die Programmierung mit VBA Vorlesung vom 07. November 2016 Birger Krägelin Inhalt Vom Algorithmus zum Programm Programmiersprachen Programmieren mit VBA in Excel Datentypen und Variablen

Mehr

6. Bearbeitung von Strings in C Bearbeitung von Strings in C

6. Bearbeitung von Strings in C Bearbeitung von Strings in C Bearbeitung von Strings in C 6-1 Definition des String: 6. Bearbeitung von Strings in C Zeichenstrings werden als Felder von Zeichen abgespeichert: char [ ] ; Wie die Daten (Zeichenfolge)

Mehr

Kontrollstrukturen, Pseudocode und Modulo-Rechnung

Kontrollstrukturen, Pseudocode und Modulo-Rechnung Kontrollstrukturen, Pseudocode und Modulo-Rechnung CoMa-Übung III TU Berlin 29.10.2012 CoMa-Übung III (TU Berlin) Kontrollstrukturen, Pseudocode und Modulo-Rechnung 29.10.2012 1 / 1 Themen der Übung 1

Mehr

Kapitel 5. Datentypen und Operatoren

Kapitel 5. Datentypen und Operatoren Kapitel 5 Datentypen und Operatoren 1 Gliederung Kapitel 5 Datentypen und Operatoren 5.1 Elementare Datentypen 5.2 Symbolische Konstanten 5.3 Typumwandlungen 5.4 Operatoren 2 5.1. Elementare Datentypen

Mehr

Klausur C-Programmierung / 15.02.2014 / Klingebiel / 60 Minuten / 60 Punkte

Klausur C-Programmierung / 15.02.2014 / Klingebiel / 60 Minuten / 60 Punkte Klausur C-Programmierung / 15.02.2014 / Klingebiel / 60 Minuten / 60 Punkte Musterlösung 1. Aufgabe (5 Punkte) Im folgenden Programmcode sind einige Fehler enthalten. Finden und markieren Sie mindestens

Mehr

M. Graefenhan 2000-12-07. Übungen zu C. Blatt 3. Musterlösung

M. Graefenhan 2000-12-07. Übungen zu C. Blatt 3. Musterlösung M. Graefenhan 2000-12-07 Aufgabe Lösungsweg Übungen zu C Blatt 3 Musterlösung Schreiben Sie ein Programm, das die Häufigkeit von Zeichen in einem eingelesenen String feststellt. Benutzen Sie dazu ein zweidimensionales

Mehr

Modulare Programmierung und Bibliotheken

Modulare Programmierung und Bibliotheken Modulare Programmierung und Bibliotheken Proseminar-Vortrag am 24.06.2011 von Ludwig Eisenblätter Ludwig Eisenblätter 1 von 25 Modulare Programmierung und Bibliotheken Inhaltsübersicht Motivation / Einleitung

Mehr

Grundlagen der Programmierung

Grundlagen der Programmierung Grundlagen der Programmierung 8. Vorlesung 25.05.2016 1 Ausdrücke "Befehle", die ein Ergebnis liefern 3 + 4 sin(x) x < 10 getchar() Ausdrücke können Teil eines anderen Ausdrucks sein x = sin( x + y ) Auswertung:

Mehr

Schleifenanweisungen

Schleifenanweisungen Schleifenanweisungen Bisher: sequentielle Abarbeitung von Befehlen (von oben nach unten) Nun: Befehle mehrfach ausführen (= Programmschleife): for-anweisung - wenn feststeht, wie oft z.b.: eine Berechnung

Mehr

Einführung Datentypen Verzweigung Schleifen. Java Crashkurs. Kim-Manuel Klein May 4, 2015

Einführung Datentypen Verzweigung Schleifen. Java Crashkurs. Kim-Manuel Klein May 4, 2015 Java Crashkurs Kim-Manuel Klein ([email protected]) May 4, 2015 Quellen und Editoren Internet Tutorial: z.b. http://www.java-tutorial.org Editoren Normaler Texteditor (Gedit, Scite oder ähnliche)

Mehr

Algorithmen & Programmierung. Steuerstrukturen im Detail Selektion und Iteration

Algorithmen & Programmierung. Steuerstrukturen im Detail Selektion und Iteration Algorithmen & Programmierung Steuerstrukturen im Detail Selektion und Iteration Selektion Selektion Vollständige einfache Selektion Wir kennen schon eine Möglichkeit, Selektionen in C zu formulieren: if

Mehr

VBA-Programmierung: Zusammenfassung

VBA-Programmierung: Zusammenfassung VBA-Programmierung: Zusammenfassung Programmiersprachen (Definition, Einordnung VBA) Softwareentwicklung-Phasen: 1. Spezifikation 2. Entwurf 3. Implementierung Datentypen (einfach, zusammengesetzt) Programmablaufsteuerung

Mehr

C/C++ Programmierung

C/C++ Programmierung 1 C/C++ Programmierung Grundlagen: Der Präprozessor Sebastian Hack Christoph Mallon (hack mallon)@cs.uni-sb.de Fachbereich Informatik Universität des Saarlandes Wintersemester 2009/2010 2 Der Präprozessor

Mehr

Einstieg in die Informatik mit Java

Einstieg in die Informatik mit Java Vorlesung vom 18.4.07, Vordefinierte Datentypen Übersicht 1 Ganzzahlige Typen 2 Boolscher Typ 3 Gleitkommatypen 4 Referenztypen 5 void Typ 6 Implizite und explizite Typumwandlungen Ganzzahlige Typen Die

Mehr

1 Vom Problem zum Programm

1 Vom Problem zum Programm Hintergrundinformationen zur Vorlesung GRUNDLAGEN DER INFORMATIK I Studiengang Elektrotechnik WS 02/03 AG Betriebssysteme FB3 Kirsten Berkenkötter 1 Vom Problem zum Programm Aufgabenstellung analysieren

Mehr

2 Einfache Rechnungen

2 Einfache Rechnungen 2 Einfache Rechnungen 2.1 Zahlen Computer, auch bekannt als Rechner, sind sinnvoller eingesetzt, wenn sie nicht nur feste Texte ausgeben, sondern eben auch rechnen. Um das Rechnen mit Zahlen zu verstehen,

Mehr