Tag 5 Repetitorium Informatik (Java) Dozent: Marius Kamp Lehrstuhl für Informatik 2 (Programmiersysteme) Friedrich-Alexander-Universität Erlangen-Nürnberg Wintersemester 2017/2018
Übersicht Methoden Deklaration von Methoden Methodenaufruf Parameterübergabe Gültigkeitsbereich von Variablen Wertrückgabe: return Ausblick: Rekursion Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 2 / 37
Methoden
Methoden: Motivation bisher: gesamter Code innerhalb der main-methode in Ordnung für kleine Anwendungen oder um Dinge auszuprobieren aber: undenkbar für größere Programme schwer verständlich und schwer überschaubar schwer wartbar Was tun, wenn man dieselbe Funktionalität an mehreren Stellen braucht? Informatiker sind faul und programmieren ungern mehrmals dasselbe Lösung: Programm modularisieren Programm in kleinere Einheiten aufteilen, die sich gegenseitig verwenden heute: Modularisierung mit Hilfe von Methoden später: Modularisierung mit Hilfe von Klassen Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 4 / 37
Kleiner Ausflug: Funktionen in der Mathematik Funktionen in der Mathematik: bilden einen oder mehrere Eingabewerte auf einen Ausgabewert ab zur Bestimmung des Ausgabewertes werden Eingabewerte eingesetzt Funktionsnamen können als Platzhalter verwendet werden Funktionen können sich gegenseitig verwenden Beispiele f (x) = 13x 2 + 3x + 21 g(x) = f (x 1) + f (x 2) h(x, y) = (x + y) 2 In vielen Programmiersprachen gibt es ein sehr ähnliches Konzept. Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 5 / 37
Funktionen in Java eine Funktion heißt in Java Methode kann (muss aber nicht) Eingabewerte annehmen Parameter kann (muss aber nicht) Ausgabewert zurückgeben jede Methode hat einen Namen kann an anderer Stelle als Platzhalter dienen Methodenaufruf Modularisierung des Programms Bereits bekannte Beispiele System. out. println ("Hallo, Welt "); // Ausgabe int a = Integer. parseint ( args [0]); // Konvertierung Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 6 / 37
Deklaration von Methoden (I) Methodendeklaration: Syntax Modifizierer R ü ckgabetyp Methodenname ( Parameterliste ) { Anweisungen ; // Methodenrumpf Hinweise Modifizierer: legen Eigenschaften der Methode fest für den Anfang immer public static, später mehr dazu... Rückgabetyp: Datentyp des Ausgabewertes void, falls die Methode keinen Ausgabewert zurückgibt Parameterliste: durch Kommata getrennte Liste von Parametern, jeweils mit Typ und Name (Datentyp1 Name1, Datentyp2 Name2,...) Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 7 / 37
Deklaration von Methoden (II) Methodendeklaration: Syntax Modifizierer R ü ckgabetyp Methodenname ( Parameterliste ) { Anweisungen ; // Methodenrumpf Hinweise Methodenname und Parameterliste bilden zusammen die Methoden-Signatur (anhand ihr wird entschieden, welche Methode bei einem Aufruf aufgerufen wird) Methodenrumpf: Anweisungen, die beim Aufruf der Methode ausgeführt werden sollen Deklaration von (lokalen) Variablen Anweisungen mit lesendem/schreibendem Zugriff auf Variablen oder Parameter Aufrufe weiterer Methoden unter Umständen Anweisungen zur Rückgabe eines Ausgabewertes (s.u.) Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 8 / 37
Beispiel: main-methode Modifizierer Rückgabetyp Methodenname public static void main(string[] args) { System.out.println("Hallo, Welt"); Parameterliste Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 9 / 37
Beispiel: Methode zur Ausgabe Aufgabe Methode gebesummeaus, die die Summe zweier übergebener Ganzzahlen ausgibt. Überlegungen Modifizierer: public static weil wir noch nichts anderes kennen... Rückgabetyp: void die Methode gibt zwar etwas aus, aber keinen Wert zurück Parameterliste: zwei Parameter vom Typ int Mögliche Lösung // Deklaration von gebesummeaus : public static void gebesummeaus ( int a, int b) { System. out. println (a + b); // <- Methodenaufruf von println Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 10 / 37
Deklaration von Methoden (III) Anmerkungen zu Deklarationen eine Methode wird immer innerhalb einer Klasse deklariert Methode kann nicht innerhalb einer anderen Methode deklariert werden es können beliebig viele Methoden in beliebiger Reihenfolge deklariert werden Beispiele public class Beispiel { public static void main ( String [] args ) { //... public static void gebesummeaus ( int a, int b) { //... public static int berechnesumme ( int a, int b, int c) { //... Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 11 / 37
Methodenaufruf Methodenaufruf: Syntax Methodenname ( Argument1, Argument2,...) Hinweise Aufruf erfolgt durch Angabe des Methodennamens und der Argumentliste Argumente werden in die Parameter der aufgerufenen Methode eingesetzt Zuordnung durch Position: erstes Argument erster Parameter,... Klammern-Paar auch dann, wenn die Methode keine Parameter benötigt! aufrufende Methode wird auch als Aufrufer bezeichnet Merken Nur die main-methode wird beim Programmstart automatisch aufgerufen. Alle anderen Methoden müssen direkt oder indirekt von der main-methode aufgerufen werden, damit sie ausgeführt werden. Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 12 / 37
Methodenaufruf Beispiele public static void gebesummeaus ( int a, int b) { System.out. println (a + b); public static void main ( String [] args ) { int x = 11; gebesummeaus (47, x); System.out. println (" Ende "); Ausgabe Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 13 / 37
Methodenaufruf Beispiele public static void gebesummeaus ( int a, int b) { System.out. println (a + b); public static void main ( String [] args ) { int x = 11; gebesummeaus (47, x); System.out. println (" Ende "); Ausgabe Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 13 / 37
Methodenaufruf Beispiele public static void gebesummeaus ( int a, int b) { System.out. println (a + b); public static void main ( String [] args ) { int x = 11; gebesummeaus (47, x); System.out. println (" Ende "); Ausgabe Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 13 / 37
Methodenaufruf Beispiele public static void gebesummeaus ( int a, int b) { System.out. println (a + b); public static void main ( String [] args ) { int x = 11; gebesummeaus (47, x); System.out. println (" Ende "); a = 47 b = 11 Ausgabe Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 13 / 37
Methodenaufruf Beispiele public static void gebesummeaus ( int a, int b) { System.out. println (a + b); public static void main ( String [] args ) { int x = 11; gebesummeaus (47, x); System.out. println (" Ende "); Ausgabe 58 Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 13 / 37
Methodenaufruf Beispiele public static void gebesummeaus ( int a, int b) { System.out. println (a + b); public static void main ( String [] args ) { int x = 11; gebesummeaus (47, x); System.out. println (" Ende "); Ausgabe 58 Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 13 / 37
Methodenaufruf Beispiele public static void gebesummeaus ( int a, int b) { System.out. println (a + b); public static void main ( String [] args ) { int x = 11; gebesummeaus (47, x); System.out. println (" Ende "); Ausgabe 58 Ende Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 13 / 37
Verwendung des Rückgabewerts falls Rückgabetyp = void: Methode gibt Rückgabewert zurück ( Ergebnis ) kann wie jeder andere Wert des entsprechenden Typs verwendet werden Zuweisung zu Variable eines passenden Typs Verwendung in einer Berechnung Argument für weiteren Methodenaufruf... Beachte den Unterschied: Eine Methode gibt etwas aus Ausgabe am Bildschirm (mit println) Eine Methode gibt etwas zurück Berechnung und dann return (später). Beispiele int ergebnis = summe (23, 72); // entspricht : ergebnis = 95; int dreimaleingabe = 3 * Integer. parseint ( args [0]); gebesummeaus ( Integer. parseint ( args [0]), Integer. parseint ( args [1])); Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 14 / 37
Übergabe von Argumenten Methodenaufruf: Syntax Methodenname ( Argument1, Argument2,...) Hinweise Aufruf muss zur Methoden-Signatur einer deklarierten Methode passen Methode mit demselben Methodennamen muss deklariert worden sein die Anzahl der Parameter und Argumente muss übereinstimmen die Typen der Parameter und Argumente müssen übereinstimmen genauer: die Typen müssen jeweils durch Typumwandlung kompatibel sein So nicht... gebeproduktaus (1, 2); // nicht deklariert gebesummeaus (1); // zu wenige Argumente gebesummeaus (13.03, 0); // falscher Datentyp des ersten Arguments Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 15 / 37
Wertparameter-Semantik Java: Parameterübergabe stets nach Wertparameter-Semantik (call by value) als Argumente an eine Methode übergebene Werte sind nur Kopien eine Änderung in der Methode hat keine Auswirkungen beim Aufrufer Hinweis Für Arrays (und andere Objekte) ist die Sache etwas komplizierter. Trotzdem gilt, dass diese nach Wertparameter-Semantik übergeben werden (s. u.). Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 16 / 37
Wertparameter-Semantik: Beispiel Beispiel zur Wertparameter-Semantik public class Programm { public static void main ( String [] args ) { int a = 13; einemethode (a); System. out. println (a); public static void einemethode ( int parameter ) { parameter = 3; Ausgabe benutzer@faui06a: /ordner$ java Programm 13 Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 17 / 37
Wertparameter-Semantik bei Arrays Falls das Folgende unklar ist: Keine Sorge, Details zu Referenzen gibt es in den kommenden Tagen, inklusive einer genaueren Erklärung auch Arrays werden nach Wertparameter-Semantik übergeben allerdings: Arrays sind Objekte in einer Array-Variable steht lediglich eine Referenz auf das Array es wird die Referenz auf das Array kopiert, nicht das Array selbst wenn innerhalb der Methode der Inhalt des Arrays verändert wird und kein neues Array erzeugt wird, sind die Änderungen beim Aufrufer sichtbar Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 18 / 37
Wertparameter-Semantik bei Arrays: Beispiel Beispiel zur Wertparameter-Semantik public class Programm { public static void main ( String [] args ) { int [] a = {13, 3, 42; einemethode (a); System. out. println ( java. util. Arrays. tostring (a )); public static void einemethode ( int [] parameter ) { parameter [2] = 19; Ausgabe benutzer@faui06a: /ordner$ java Programm [13, 3, 19] Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 19 / 37
Gültigkeitsbereich von Variablen (I) Variablen sind nur in dem Block, in dem sie deklariert wurden, gültig dies schließt auch die in diesem Block enthaltenen Blöcke mit ein Gültigkeitsbereich von Variablen definiert, an welchen Stellen welche Variablen verwendet werden können Beispiel zum Gültigkeitsbereich von Variablen public static void main ( String [] args ) { int a = 3; while (a > 0) { int b = 3* a; // in jeder Iteration eine " neue " Variable! a = a -1; // hier sind a und b g ü ltig // hier ist nur a g ü ltig Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 20 / 37
Gültigkeitsbereich von Variablen (II) in einer Methode deklarierte Variablen sind in anderen Methoden nicht gültig sog. lokale Variablen Beispiel zum Gültigkeitsbereich von lokalen Variablen public static void einemethode () { int a; anderemethode (); public static void anderemethode () { // hier existiert keine Variable a Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 21 / 37
Gültigkeitsbereich von Variablen (III) Variablen-Bezeichner aus übergeordneten Blöcken dürfen in Java nicht wiederverwendet werden (Ausnahme: bei Instanz-/Klassen-Variablen) So nicht! public static void methode ( int a) { if (a > 0) { int b = a * 3; So schon! public static void methode ( int a) { if (a > 0) { int b = a * 3; while (a > 0) { int b = a * 5; // Redefinition! while (a > 0) { int c = a * 5; // frischer Name Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 22 / 37
Gültigkeitsbereich von Variablen (IV) Variablen-Bezeichner aus anderen Blöcken können wiederverwendet werden unterschiedliche Variablen mit demselben Namen Beispiel 1 public static void einemethode () { int a; anderemethode (); public static void anderemethode () { int a; // " neue " Variable Beispiel 2 public static void methode ( int a) { if (a > 0) { int b = a * 3; else { int b = a * 5; // " neue " Variable Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 23 / 37
Wertrückgabe return bisher: Methoden ohne Ergebnis mit Rückgabetyp void jetzt: Methoden mit Wertrückgabe, die Ergebnis an den Aufrufer zurückgeben return-anweisung, um zurückzugebenden Wert zu setzen return-anweisung: Syntax return R ü ckgabewert ; Hinweise der Typ des Rückgabewerts muss zum Rückgabetyp der Methode passen genauer: durch (implizite) Typumwandlung kompatibel sein die aktuelle Methode wird nach einem return sofort beendet Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 24 / 37
Beispiel: Berechnung der n-ten Potenz Aufgabe Methode, die die Potenz x n für beliebige (ganzzahlige) x und n berechnet. Mögliche Lösung public static int potenz ( int x, int n) { int potenz = 1; for ( int i = 0; i < n; ++i) { potenz = potenz * x; return potenz ; Aufruf int potenz = potenz (13, 3); Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 25 / 37
Notwendigkeit von return-anweisungen falls Rückgabetyp = void: Methode muss in jedem Fall Wert zurückgeben return-anweisung auf allen möglichen Pfaden (Verzweigungen,...)! andernfalls meldet der Compiler: missing return statement auch im Fehlerfall muss die Methode einen Rückgabewert bereitstellen Sonderfall: Eine sogenannte Exception (Ausnahme) kann eine return-anweisung im Fehlerfall ersetzen ( AuD-Vorlesung). So nicht... public static int foo ( int a) { if (a == 13) { return 3; // fehlende return - Anweisung! Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 26 / 37
Beispiel: zifferalsstring() Beispiel: zifferalsstring() public static String zifferalsstring ( int ziffer ) { if ( ziffer == 0) return " null "; else if ( ziffer == 1) return " eins "; else if ( ziffer == 2) return " zwei "; else if ( ziffer == 3) return " drei "; else if ( ziffer == 4) return " vier "; else if ( ziffer == 5) return "fünf"; else if ( ziffer == 6) return " sechs "; else if ( ziffer == 7) return " sieben "; else if ( ziffer == 8) return " acht "; else if ( ziffer == 9) return " neun "; else { return ""; // Fehlerfall Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 27 / 37
Beispiel: zifferalsstring(), Alternative mit Array Beispiel: zifferalsstring() public static String zifferalsstring ( int ziffer ) { String [] ziffern = {" null ", " eins ", " zwei ", " drei ", " vier ", "fünf", " sechs ", " sieben ", " acht ", " neun "; if (( ziffer < 0) ( ziffer >= ziffern. length )) { return ""; // Fehlerfall return ziffern [ ziffer ]; Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 28 / 37
Beispiel: Verzweigung (I) public static boolean einemethode ( int a) { if (a < 5) { return false ; else if (a >= 5) { return true ; benutzer@faui06a: /ordner$ javac Programm.java Programm.java:8: missing return statement ˆ 1 error Was ist passiert? Für uns ist klar, dass immer ein return erreicht wird, für den Compiler jedoch nicht! Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 29 / 37
Beispiel: Verzweigung (II) So geht s! public static boolean einemethode ( int a) { if (a < 5) { return false ; else { // hier wird kein if mehr ben ö tigt return true ; Geht sogar noch besser! public static boolean einemethode ( int a) { return (a >= 5); Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 30 / 37
Rekursion (I) Vorneweg: Nicht entmutigen lassen! Hier sollen nur die absoluten Grundlagen der Rekursion vermittelt werden. Viel mehr Details und Erklärungen dazu gibt es in der AuD-Vorlesung und -Übung. Rekursive Funktionen in der Mathematik Eine rekursive Funktion ist eine durch sich selbst definierte Funktion. Beispiel: Fakultät Fakultät n! einer Zahl n N: n! := 1 2 n { 1 falls n = 0 rekursive Definition: n! := n (n 1)! sonst Rekursion in der Programmierung Eine rekursive Methode ruft sich (unter gewissen Bedingungen) selbst auf. Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 31 / 37
Rekursion (II) Von der rekursiven Definition... n! := { 1 falls n = 0 n (n 1)! sonst...zur (möglichen) Umsetzung in Java public static int fak( int n) { if (n == 0) { return 1; else { return n * fak (n -1); // rekursiver Aufruf Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 32 / 37
Rekursion (III) rekursiver Aufruf: Aufruf einer Methode von sich selbst dabei werden (fast) immer von Aufruf zu Aufruf die Argumente verändert rekursiver Aufruf bearbeitet anderes (meist: kleineres ) Problem Intention: komplexes Problem in kleinere Probleme aufteilen Ziel: kleinere Probleme einfacher zu lösen als ursprüngliches Problem Beispiel: Fakultät n! := { 1 falls n = 0 n (n 1)! sonst Die Berechnung von n! wird auf das kleinere, einfachere Problem der Berechnung von (n 1)! zurückgeführt. Für n = 0 ist das Problem trivial lösbar. Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 33 / 37
Basisfall Rekursionsfall (I) bei der Ausführung einer rekursiven Methode unterscheidet man zwei Fälle: Rekursionsfall: Funktion ruft sich tatsächlich selbst auf Basisfall: Funktion ruft sich nicht (mehr) selbst auf Basisfall und Rekursionsfall im Beispiel public static int fak( int n) { if (n == 0) { return 1; // Basisfall else { return n * fak (n -1); // Rekursionsfall Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 34 / 37
Basisfall Rekursionsfall (II) Basisfall Der Basisfall stellt die Abbruchbedingung dar und sorgt dafür, dass die Rekursion irgendwann abbricht. Es muss sichergestellt werden, dass der Basisfall immer nach endlich vielen Schritten erreicht wird, andernfalls entsteht eine Endlos-Rekursion. Unsere Implementierung public static int fak ( int n) { if (n == 0) { return 1; else { return n * fak (n -1); Geht kaputt... Wird die Methode initial mit einem negativen Wert für n aufgerufen, wird der Basisfall nie erreicht. Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 35 / 37
Beispiel: Summe von 0 bis n Ziel Rekursive Methode, die die Summe von 0 bis n berechnet. Idee Problem auf einfacheres Problem reduzieren: Um die Summe von 0 bis n zu berechnen, berechnet man zunächst die Summe von 0 bis (n 1) und addiert anschließend n. Mögliche Lösung public static int summe ( int n) { if ( n == 0) { // Basisfall : Die Summe 0 bis 0 ist trivial.. return 0; //... und wir wissen, dass es 0 ist return n + summe (n -1); Informatik-Repetitorium Tag 5 WS 2017/2018 Lehrstuhl für Informatik 2 (Programmiersysteme) 36 / 37
Fragen? Fragen! (hilft auch den anderen)