6. Unterprogramme 6-1

Ähnliche Dokumente
C++ - Einführung in die Programmiersprache Funktionen. Leibniz Universität IT Services Anja Aue

Inhalt. 4.7 Funktionen

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

C.3 Funktionen und Prozeduren

Java Einführung Methoden. Kapitel 6

Deklarationen in C. Prof. Dr. Margarita Esponda

Prozeduren und Funktionen

Programmiertechnik Klassenmethoden

Funktionen Häufig müssen bestimmte Operationen in einem Programm mehrmals ausgeführt werden. Schlechte Lösung: Gute Lösung:

Programmierung mit C Zeiger

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

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

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

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

Präzedenz von Operatoren

1. Grundzüge der Objektorientierung 2. Methoden, Unterprogramme und Parameter 3. Datenabstraktion 4. Konstruktoren 5. Vordefinierte Klassen

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

Programmieren in C / C++ Grundlagen C 4

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

Praktikum Ingenieurinformatik. Termin 4. Funktionen, numerische Integration

Programmsteuerung. Mittel zur Programmverzweigung:

Eine Einführung in C-Funktionen

Grundlagen der Programmierung Prof. H. Mössenböck. 6. Methoden

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

2. Programmierung in C

Einführung in die Programmiersprache C

Programmierkurs. Manfred Jackel

Einführung in Java. Arne Hüffmeier. Angelehnt an Java-Vorkurs der Freitagsrunde. Methoden implementieren. Michelle Liebers, Dennis Hoffmann

Übersicht. Einführung in die Programmierung. main. main. main. main. Speicherverwaltung. Definition nach ANSI C:

5. Unterprogrammtechnik/Module

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

Speicher und Adressraum

3. Anweisungen und Kontrollstrukturen

Einführung in die C-Programmierung

Einfache Rechenstrukturen und Kontrollfluss II

1 Vom Problem zum Programm

Unterprogramme, Pointer und die Übergabe von Arrays

AuD-Tafelübung T-B5b

Grundlagen. Die Komponenten eines C Programms. Das erste Programm

Algorithmen & Programmierung. Rekursive Funktionen (1)

Methoden. von Objekten definiert werden, Methoden,, Zugriffsmethoden und Read-Only

C- Kurs 04 Anweisungen

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

Kapitel 8. Programmierkurs. Methoden. 8.1 Methoden

Grundlagen der Programmierung in C Funktionen

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

Programmierkurs Python I

Grundlagen der Informatik I (Studiengang Medieninformatik)

Repetitorium Informatik (Java)

Die Programmiersprache C

JAVA - Methoden

Welche Informatik-Kenntnisse bringen Sie mit?

4. Ablaufsteuerung (Kontrollstrukturen)

Einstieg in die Informatik mit Java

Grundstruktur eines C-Programms

Werkzeuge zur Programmentwicklung

6 Speicherorganisation

Advanced Programming in C

Unterprogramme. Funktionen. Bedeutung von Funktionen in C++ Definition einer Funktion. Definition einer Prozedur

Kapitel 8: Funktionen / Prozeduren

Fallunterscheidung: if-statement

BKTM - Programmieren leicht gemacht.

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

Programmiersprachen Einführung in C. Unser erstes C-Programm. Unser erstes C-Programm. Unser erstes C-Programm. Unser erstes C-Programm

Prof. W. Henrich Seite 1

Informationsverarbeitung im Bauwesen

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

Unterprogramme. Unterprogramme

ANSI C. Grundlagen der Programmierung. Ricardo Hernández García. 3. Ausgabe, September 2011 CANSI2

Grundlagen der Programmierung

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

Anweisungsblöcke (dazu zählen auch Programme) werden in geschweifte Klammern eingeschlossen.

Programmieren I. Kapitel 5. Kontrollfluss

Objektorientierte Programmierung

Aufbau von Klassen. class punkt {...

Grundlagen der Programmiersprache C++

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

Einführung in VisualBasic for Applications. Stefan Mahlitz

Erste Schritte der Programmierung in C

Java Kurs für Anfänger Einheit 5 Methoden

C-Propädeutikum Funktionen

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

Modellierung und Programmierung 1

Übersicht Programmablaufsteuerung

Grundlagen der Programmiersprache C für Studierende der Naturwissenschaften

4 Kontrollfluss-Diagramme

Algorithmische Kernsprache. Zuweisung, einfache und bedingte Anweisung, Blöcke, Schleifen, return, debugging.

RO-Tutorien 3 / 6 / 12

4. Einfache Programmstrukturen in C Einfache Programmstrukturen in C

Es gibt zwei verschiedene Arten, wie Programme auf dem Rechner ausgeführt werden:

Die Programmiersprache C Eine Einführung

Übungspaket 29 Dynamische Speicherverwaltung: malloc() und free()

Einführung in die Programmierung mit VBA

Objektorientiertes Programmieren für Ingenieure

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

Einstieg in die Informatik mit Java

5.4 Klassen und Objekte

Transkript:

6. Unterprogramme 6.1 Prozeduren und Funktionen 6.2 Deklaration und Aufruf 6.3 Call-by-Value / Call-by-Reference 6.4 Standardfunktionen in C 6.5 Gültigkeitsbereich von Namen 6.6 Rekursion 6. Unterprogramme 6-1

6.1 Prozeduren und Funktionen Unterprogramme dienen zur Modularisierung von Programmen. Sie werden deklariert und aufgerufen. Generell unterscheidet man in prozeduralen Programmiersprachen zwei Arten von Unterprogrammen: a) Prozeduren führen einen Teil der Arbeit des aufrufenden Programms durch Ergebnisse können in Form von Parametern an das aufrufende Programm zurück gegeben werden. b) Funktionen führen die Berechnung von Funktionswerten (meist im mathematischen Sinn) durch Das Ergebnis wird an der Stelle des Funktionsnamens als Wert zurück geliefert. Es können zusätzlich auch Parameterwerte zurück gegeben werden. In C gibt es nur einen Typ von Unterprogrammen: Funktionen. Die Ergebniswerte von Funktionen können in C jedoch auch ignoriert werden, so dass eine C-Funktion sich dann wie eine Prozedur verhält. 6. Unterprogramme 6-2

6.2 Deklaration und Aufruf In der Deklaration eines Unterprogramms wird festgelegt, wie das Unterprogramm heißt, welche Parameter es hat, welche lokalen Variablen im Unterprogramm benutzt werden werden und was es macht (ausführbare Anweisungen). Der Kopf der Deklaration enthält den Namen und die Parameter des Unterprogramms, der Rumpf ( body ) enthält den auszuführenden C-Code. Beim Aufruf eines Unterprogramms wird zur Laufzeit auf das Unterprogramm verzweigt. Dabei werden die aktuellen Parameter an das Unterprogramm übergeben. Nach Ausführung des Unterprogramms kehrt der Rechner an die auf den Aufruf folgende nächste Anweisung im Hauptprogramm zurück bzw. fährt mit der Berechnung das Ausdruck im Hauptprogramm fort, in dem der Unterprogrammaufruf steht. Der Aufruf erfolgt in C stets synchron, das heißt, dass die Ausführung des Hauptprogramms ruht, solange das Unterprogramm ausgeführt wird. 6. Unterprogramme 6-3

Deklaration von Unterprogrammen (1) Unterprogrammvereinbarung Unterprogrammkopf Unterprogrammrumpf Unterprogrammkopf Typname Routinenname ( Parameterliste ) Unterprogrammrumpf { Anweisungsfolge Vereinbarungsfolge Anweisungsfolge } ; 6. Unterprogramme 6-4

Deklaration von Unterprogrammen (2) Unterprogramme sollten im Deklarationsteil eines C-Programms, im Anschluss an die Variablen-Deklarationen, deklariert werden. Es sollte immer ein Typ für das Ergebnis angegeben werden, auch wenn der Compiler dies nicht verlangt. Wird keiner angegeben, geht der Compiler vom Typ int aus. 6. Unterprogramme 6-5

Die return-anweisung Die Rückgabe von Ergebnissen einer Funktion erfolgt in der Funktion durch die Anweisung return: return-anweisung return Ausdruck ; Nach dem Schlüsselwort kann ein beliebiger Ausdruck stehen. Das Ergebnis der Funktion ist das Ergebnis der Berechnung dieses Ausdrucks. Merke: Eine Funktion muss keinen Resultatwert liefern. Ein leeres return bzw. die abschließende geschweifte Klammer beenden die Funktion und geben 0 zurück (normales Ende). Eine Funktion sollte jedoch immer eine Return-Anweisung haben, um ein definiertes Ende explizit anzuzeigen. 6. Unterprogramme 6-6

Aufruf von Unterprogrammen (1) Routinenaufruf Variable = Routinenname ( aktueller Parameter ) ;, 6. Unterprogramme 6-7

Aufruf von Unterprogrammen (2) Der Aufruf ohne Zuweisung an eine Variable ist, syntaktisch gesehen, eine Anweisung (statement) und entspricht damit der oben erwähnten Prozedur. Solche Prozeduren sollten mit dem Typ void vereinbart werden. Der Aufruf mit Zuweisung an eine Variable ist, syntaktisch gesehen, ein Ausdruck (expression) und entspricht damit einer Funktion, bei der ein Wert zurückgegeben wird. 6. Unterprogramme 6-8

Beispiele für Unterprogramme void mache_garnichts () { } double square_root(double value) { return (sqrt(value)); } Aufrufe: double a, b;.. mache_garnichts();.. b = 4.0; a = square_root(b); 6. Unterprogramme 6-9

Formale und aktuelle Parameter Formale und aktuelle Parameter entsprechen einander in der Reihenfolge, in der sie in der Vereinbarung und im Aufruf auftreten (Stellungsparameter). Aktuelle und formale Parameter sollten in der Anzahl übereinstimmen. Aktuelle und formale Parameter sollten im Typ übereinstimmen. 6. Unterprogramme 6-10

Variable Parameterlisten Es dürfen beim Aufruf eines Unterprogramms auch mehr Parameter übergeben werden als vereinbart sind. Dazu ist in der Deklaration '...' als letzter Parameter notwendig. Dies ist sinnvoll, wenn vorab nicht bekannt ist, wieviele Parameter zur Laufzeit übergeben werden sollen. Beispiel: Die später noch einzuführende Funktion printf ist folgendermaßen deklariert: int printf (const char *format,... ) Sie gibt u.a. den Inhalt beliebig vieler Variablen auf dem Bildschirm aus. Merke: Es dürfen nie weniger Parameter als vereinbart übergeben werden, da ansonsten der Effekt des Aufrufs undefiniert ist! 6. Unterprogramme 6-11

6.3 Call-by-Value vs. Call-by-Reference Beispiel für schwierige Semantik: int i; void test(int k; int j) { k = k+1; j = 3*i; return; } /* test */ main () { int a[3]; a[0] = 1; a[1] = 2; a[2] = 3; i = 1; test(i, a[i]); return; } 6. Unterprogramme 6-12

Fragen bezüglich i und a[i]: Fragen bezüglich i und a[i]: Wie wird auf den aktuellen Parameter zugegriffen? indem innerhalb der Funktion Speicherplatz angelegt und der Wert dorthin kopiert wird? indem direkt auf den Speicherplatz der Variablen im Hauptprogramm zugegriffen wird? indem der Parameter-Ausdruck a[i] bei jeder Benutzung neu berechnet wird? 6. Unterprogramme 6-13

Call-by-Value Für jeden Parameter wird ein dem Typ entsprechender Speicherplatz lokal im Inneren der Funktion reserviert. Zum Zeitpunkt des Aufrufs wird der Wert des Ausdrucks berechnet, der als aktueller Parameter angegeben ist. Dieser Wert wird in den lokalen Speicherplatz im Inneren der Funktion hinein geschrieben. Alle Operationen innerhalb der Funktion werden auf den lokalen Parameter-Speicherplätzen ausgeführt. Also: Die Berechnungen im Inneren der Funktion haben keine Auswirkungen auf die Parameterwerte außerhalb der Funktion! Die Parameter sind nur Eingangsparameter. 6. Unterprogramme 6-14

Beispiel für den Call-by-Value int i, a[3]; void test (int k, int j) { k = k+1; j = 3*a[i]; return; } /* test */ main () { a[0] = 1; a[1] = 2; a[2] = 3; i = 1; test (i, a[i]); return; } Werte nach der Rückkehr in das Hauptprogramm: i 1 a[0] 1 a[1] 2 a[2] 3 6. Unterprogramme 6-15

Call-by-Reference Beim Eintritt in die Funktion wird die Speicheradresse des Parameters berechnet. Alle Operationen innerhalb der Funktion werden direkt auf der so berechneten Speicheradresse ausgeführt. Also: Änderungen des Parameterwertes wirken sich auch auf die Umgebung der Funktion aus. Geeignet für Eingangs- und Ausgangsparameter, d. h. mit Call-by-Reference können Daten des aufrufenden Hauptprogramms geändert werden. 6. Unterprogramme 6-16

Beispiel für den Call-by-Reference int i, a[3]; /* Deklaration der Parameter als Zeiger! */ void test (int *k, int *j) { *k = *k+1; *j = 3*a[i]; return; } /* test */ main () { a[0] = 1; a[1] = 2; a[2] = 3; i = 1; test (&i, &a[i]); return; } Werte nach der Rückkehr in das Hauptprogramm: i 2 a[0] 1 a[1] 9 a[2] 3 6. Unterprogramme 6-17

Call-by-Name Betroffen sind Ausdrücke als aktuelle Parameter Operationen werden auf den Original-Speicherplätzen außerhalb der Funktion ausgeführt Dabei erfolgt aber jetzt eine erneute Auswertung des Ausdrucks bei jeder Verwendung innerhalb der Funktion! Also: Der Call-by-Name führt dann zu anderen Werten als der Call-by-Reference, wenn mehrere Parameter übergeben werden, die voneinander abhängen. Nicht empfehlenswert, da schwer verständlich. In der Sprache C ist ein Call-by-Name nicht möglich! 6. Unterprogramme 6-18

Beispiel für den Call-by-Name int i, a[3]; void test (int *k, int *j) { *k = *k+1; *j = 3*a[i]; return; } /* test */ Call-by-Name ist in C nicht möglich. Dazu main () { a[0] = 1; müsste *j im Unterprogramm test nach der Anweisung k=*k+1 erneut ausgewertet werden, d.h., da *j für a[i] steht und a[1] = 2; i=*k ist, wäre j=a[2]. Damit würde das a[2] = 3; Programm folgende Ergebnisse liefern: i = 1; test (&i, &a[i]); i a[0] a[1] a[2] return; 2 1 2 9 } 6. Unterprogramme 6-19

Parameter-Übergabe in C Es gibt in C grundsätzlich nur den Call-by-Value. Ein Call-by-Reference kann in C durch die Übergabe von Zeigern (Speicheradressen) erreicht werden. 6. Unterprogramme 6-20

Syntax der Parameterliste (1) Parameterliste, Wertparameter Variablenreferenzparameter Routinenreferenzparameter 6. Unterprogramme 6-21

Syntax der Parameterliste (2) Wertparameter Typname Parametername Variablenreferenzparameter Typname * Parametername Routinenreferenzparameter Typname ( Routinenname ) *, ( Parametertyp ) 6. Unterprogramme 6-22

Beispiele: Binderegeln in C (1) a) Call-by-Value float betrag (float x) { if (x >= 0) return(x); else return(-x); } Aufgerufen wird die Funktion zum Beispiel durch: y = betrag(3.14*z); 6. Unterprogramme 6-23

Beispiele: Binderegeln in C (2) b) Call-by-Reference void tausch (int *a, int *b) { int hilf; hilf = *a; *a = *b; *b = hilf; return; } Aufgerufen wird die Funktion zum Beispiel durch tausch (&x,&y); wobei x und y als int deklariert sind. 6. Unterprogramme 6-24

Beispiele: Binderegeln in C (3) c) Funktionen als Parameter Annahme: (*F)(float) ist eine beliebige reellwertige Funktion mit (*F)(a) < 0 und (*F)(b) > 0. nullstelle" berechnet nun nach der Methode der Intervallhalbierung eine Nullstelle von (*F). 6. Unterprogramme 6-25

Beispiele: Binderegeln in C (4) float nullstelle(float(*f)(float), float a, float b) { float mittelpunkt = 0.0; while (fabs((*f)(mittelpunkt) > (1e-10))) { mittelpunkt = (a+b)/2; if ( (*F)(mittelpunkt) < 0) a = mittelpunkt; else b = mittelpunkt; F(x) } return (mittelpunkt); } a Mittelpunkt b 6. Unterprogramme 6-26

Beispiele: Binderegeln in C (5) Der Aufruf erfolgt z. B. durch: z = nullstelle(cos(),x,y); Achtung: Bei der Angabe der Routine (*F) als Parameter muss auf die Klammern geachtet werden, da man sonst eine Funktion angibt, die einen Zeiger auf ein float zurückgibt und nicht einen Funktionszeiger! 6. Unterprogramme 6-27

6.4 Standardfunktionen in C Beispiel für Standardfunktionen: In der Standard-include-Datei <math.h> vereinbarte mathematische Standardfunktionen: Aufruf Parametertyp Ergebnistyp Bedeutung abs(x) integer integer Betrag eines Integers labs (x) long long Betrag eines Longs fabs(x) float float Betrag eines floats ceil(x) double double kleinster ganzzahliger wert, der nicht kleiner als x ist floor double double größter ganzzahliger wert, der nicht größer als x ist sin(x) double double Sinusfunktion cos(x) double double Cosinusfunktion exp(x) double double Exponentialfunktion log(x) double double 10er-Logarithmus sqrt(x) double double Wurzel einer Zahl atan(x) double double Arcustangens pow(x;y) double double x hoch y 6. Unterprogramme 6-28

6.5 Gültigkeitsbereich von Namen Wenn Variable, Konstante usw. innerhalb einer Prozedur oder Funktion denselben Namen haben wie Variable, Konstante usw. außerhalb, muss klar sein, welches Objekt jeweils gemeint ist. Es gilt: Jede Vereinbarung eines Namens hat nur in dem Block Gültigkeit, in dem sie vorgenommen wird. Blöcke können geschachtelt werden. Also: Ein Name bezieht sich immer auf die am nächsten darüber liegende Deklaration. Namen müssen innerhalb eines Blockes eindeutig sein. Die Deklaration muss der Verwendung voran gehen. Ein innerhalb eines Blockes vereinbarter Name heißt lokal. Ein außerhalb des Blockes vereinbarter Name heißt global. 6. Unterprogramme 6-29

Blockstruktur (1) In C kann jeder Anweisungsblock am Beginn eigene Deklarationen enthalten. UP 1 Block 1 UP 2 UP n Block 2 Block 3. Hauptprogramm Block 4 Block 5 6. Unterprogramme 6-30

Blockstruktur (2) Achtung: In ANSI-C können Routinen nicht geschachtelt werden. Insbesondere darf auch das Hauptprogramm keine Unterprogramme enthalten. Es können jedoch Anweisungsblöcke geschachtelt werden. 6. Unterprogramme 6-31

Regeln für die Sichtbarkeit von Vereinbarungen Sichtbarkeit von äußeren Blöcken nach innen keine Sichtbarkeit von innen nach außen keine gegenseitige Sichtbarkeit für Blöcke derselben Schachtelungstiefe Beispiel: int a,b,c function g int x,y,z main int x,y b1 int d,e,f b2 int c,d,e 6. Unterprogramme 6-32

Gültigkeitsbereich vs. Lebensdauer (1) Der Gültigkeitsbereich eines Namens umfasst den Block, in dem der Name deklariert ist. Die Lebensdauer eines Objekts umfasst den Block, in dem es definiert ist. Es existiert nur so lange, wie Anweisungen des zugehörigen Blocks ausgeführt werden. Das Laufzeitsystem von C legt beim Eintritt in einen Block den Speicherplatz für die dort lokal benötigten Objekte an und gibt ihn beim Verlassen des Blocks wieder frei. Will man dies vermeiden, so benutzt man die static-deklaration: Wird eine Variable innerhalb einer Funktion als static deklariert, so behält sie ihren Wert auch nach Beendigung der Funktion. Bei erneutem Aufruf hat sie den Wert vom vorigen Verlassen der Funktion. Der Speicherplatz wird statisch reserviert. Beispiel: static int anzahl_funktionsaufrufe; 6. Unterprogramme 6-33

Gültigkeitsbereich vs. Lebensdauer (2) Merke: Objekte, die nur innerhalb eines Blocks benötigt werden, sollten innerhalb dieses Blocks vereinbart werden. Vorteile: Übersichtlichkeit Vermeidung von Seiteneffekten 6. Unterprogramme 6-34

6.6 Rekursion Da für alle Call-by-Value-Parameter und für alle lokalen Variablen Speicherplatz beim Prozedureintritt dynamisch angelegt wird, können Funktionen und Prozeduren in C rekursiv aufgerufen werden! Die Anweisungen innerhalb eines Prozedurrumpfes beziehen sich dabei jeweils auf die lokalen Variablen und Parameter. Bei der Rückkehr aus der Rekursion findet die Funktion dann jeweils wieder die alten Werte vor. 6. Unterprogramme 6-35

Beispiel für eine Rekursion in C int fak (int k) { if (k==0) return (1); else return (k*fak(k-1)); } fak(3) = 3* fak (2) 2* fak (1) 1* fak (0) 1 1* 1 2* 1 3* 2 6 6. Unterprogramme 6-36

Rekursion und Kellerspeicher (Stack) (1) Bei jedem rekursiven Aufruf wird ein neuer Speicherbereich für die lokalen Variablen und Parameter angelegt. Zugleich werden die lokalen Variablen und Parameter aus der nächst höheren Rekursionsstufe unzugänglich. Daher lässt sich der Speicher für Unterprogrammdaten als Kellerspeicher (Stack) organisieren. Genau das geschieht auch in den C-Laufzeitsystemen. Beim Umsetzen einer Rekursion in eine Iteration muss der Kellerspeicher oft vom Programmierer von Hand angelegt und verwaltet werden. 6. Unterprogramme 6-37

Rekursion und Kellerspeicher (Stack) (2) Beispiel: Fakultätsfunktion : globale Variable k:3 k:2 k:1 k:0 6. Unterprogramme 6-38

Seiteneffekte Auswirkungen von Funktionen und Prozeduren, die nicht unmittelbar aus der intendierten Semantik hervorgehen, heißen Seiteneffekte. Sie treten oft auf im Zusammenhang mit Funktionsaufrufen und globalen Variablen verschachtelten Zuweisungen Beispiel: x = 0; v = --x - (x=4); Makros Merke: Externe, global gültige Variablen sind nur für große, den Kern eines Programms bestimmende Datenstrukturen sinnvoll. Ansonsten sollten alle in einer Routine verwendeten Variablen entweder lokal sein oder als Parameter übergeben werden. 6. Unterprogramme 6-39

Beispiel für einen Seiteneffekt (1) /* Globale Variable */ int r; float s, wert; float hoch (float x, int y) { float u, v; u = 1; v = x; r = y; while (r > 0) { if (r%2) /* r ungerade? */ u = u*v; v = v*v; /* v-quadrat */ r = r/2; } return (u); } 6. Unterprogramme 6-40

Beispiel für einen Seiteneffekt (2) main () { printf ("Bitte ein Zahlenpaar eingeben; mit <ENTER> beenden: \n"); scanf ("%f",&s); scanf ("%d",&r); wert = hoch(s,r); printf ("%f hoch %d ist %f \n", s, r, wert); return; } Eine Eingabe von 2 7 erzeugt eine Ausgabe von "2 hoch 0 ist 49"! 6. Unterprogramme 6-41

6.7 Zeiger auf Funktionen In ANSI-C können Funktionen nicht innerhalb von anderen Funktionen definiert werden. Allerdings gibt es Zeiger auf Funktionen. Diese können als Argumente an andere Funktionen übergeben werden. Beispiel: n i= m f 2 () i soll berechnet werden für verschiedene Funktionen f Algorithmus: double sum_quadrat(double (*f)(), double m, double n) { double i, sum = 0.0; for (i = m; i <= n; i++) sum += (*f)(i) * (*f)(i) ; /* ineffizient */ return (sum); } Aufrufbeispiel: sum_quadrat(sin,a,b); 6. Unterprogramme 6-42

Zeiger auf Funktionen (2) Die Deklaration "double (*f)( )" sagt dem Compiler, dass f ein Zeiger auf eine Funktion ist, die einen double-wert zurück gibt. Damit ist: f Zeiger auf eine Funktion (* f) die Funktion selbst (* f) (i) ein Aufruf der Funktion (*f) mit dem Parameter-Wert i Achtung: "double * g()" deklariert einen Bezeichner g, der eine Funktion darstellt, die einen Zeiger auf einen double-wert zurückgibt! 6. Unterprogramme 6-43