1 / 29 Einstieg in die Informatik mit Java Schöner Programmieren Gerd Bohlender Institut für Angewandte und Numerische Mathematik
Gliederung 2 / 29 1 Überblick 2 Anordnung von Anweisungen 3 Kommentierung des Programms 4 Klammerung 5 Namen 6 Konstanten 7 Beispielprogramm
Gliederung 3 / 29 1 Überblick 2 Anordnung von Anweisungen 3 Kommentierung des Programms 4 Klammerung 5 Namen 6 Konstanten 7 Beispielprogramm
4 / 29 Überblick In diesem Kapitel wird beschrieben wie ein Java-Programm übersichtlich gestaltet werden sollte. Wichtig für eigenes Verständnis des Programms Wichtig für Dokumentation des Programms Unwichtig für den Computer Programmierstil Einrücken, Kommentare, Klammerung, Namen Beispiele Nur eine Anweisung pro Zeile, einheitliches Einrücken von Anweisungen
Gliederung 5 / 29 1 Überblick 2 Anordnung von Anweisungen 3 Kommentierung des Programms 4 Klammerung 5 Namen 6 Konstanten 7 Beispielprogramm
Aufteilung in Zeilen 6 / 29 In einer Zeile sollte nur je eine Anweisung stehen. Schlecht: mehrere Anweisungen pro Zeile x = 1; y = 2; i f ( x>y ) max=x ; else max=y ; Besser: nur eine Anweisung pro Zeile x = 1; y = 2; i f ( x>y ) max=x ; else max=y ;
Einheitlich Einrücken 7 / 29 Fortlaufende Anweisungen sollten gleich eingerückt werden, z.b. immer 2 Zeichen. Eventuell Tabulator verwenden, aber Vorsicht: kann auf unterschiedlichen Systemen unterschiedlich viele Leerzeichen erzeugen! Schlecht: ungleichmäßig eingerückt x = 1; y = 2; sum = x+y ; Besser: einheitlich eingerückt x = 1; y = 2; sum = x+y ;
8 / 29 Untergeordnete Anweisungen Einrücken Untergeordnete Anweisungen sollten stärker eingerückt werden, z.b. immer 2 Zeichen mehr als die übergeordnete Anweisung. Eventuell Tabulator verwenden, aber Vorsicht: kann auf unterschiedlichen Systemen unterschiedlich viele Leerzeichen erzeugen! Sehr wichtig um die Ebenen der Gültigkeit von Variablen und eine Struktur im Programm zu erkennen. Stellen an denen eingerückt werden sollte: nach jedem Schleifenkopf (for, while, do-while) bis zum Ende der Schleife bei einer bedingten Anweisung (if) steht else unter if, die Anweisungen im if- bzw. else-zweig werden stärker eingerückt bei einer switch-anweisung werden die case- und default-zweige stärker eingerückt bei langen Anweisungen, die nicht in eine Zeile passen, wird die Fortsetzungszeile eingerückt nach jedem Klassen- und Methodenkopf bis zur schließenden Klammer
Untergeordnete Anweisungen: Bedingte Anweisung 9 / 29 Schlecht: nicht stärker eingerückt i f ( x > y ) System. out. p r i n t l n ( x x ) ; else System. out. p r i n t l n ( x x x ) ; Besser: stärker eingerückt i f ( x > y ) System. out. p r i n t l n ( x x ) ; else System. out. p r i n t l n ( x x x ) ;
Untergeordnete Anweisungen: Schleife 10 / 29 Schlecht: nicht stärker eingerückt for ( i n t i =0; i <10; i ++) { System. out. p r i n t l n ( i ) ; System. out. p r i n t l n ( i i ) ; Besser: stärker eingerückt for ( i n t i =0; i <10; i ++) { System. out. p r i n t l n ( i ) ; System. out. p r i n t l n ( i i ) ;
Strukturierung durch Leerzeichen und Leerzeilen 11 / 29 Leerzeilen verwenden, um zusammenhängende Programmteile hervorzuheben. Insbesondere zur Trennung von Methoden, großen Schleifen, usw. Leerzeichen innerhalb einer Zeile verwenden, um die Struktur deutlich zu machen. Schlecht: undeutlich gegliedert double sum=0; for ( i n t i =0; i <10; i ++) sum=sum+ i i i ; System. out. p r i n t l n (sum ) ; Besser: durch Leerzeilen und Leerzeichen gegliedert double sum = 0; for ( i n t i =0; i <10; i ++) sum = sum + i i i ; System. out. p r i n t l n (sum ) ;
Verbundanweisungen einsetzen In bedingten Anweisungen und Schleifen sollten Verbundanweisungen eingesetzt werden, auch wenn dort nur eine Anweisung steht. Vorteil: wird später eine weitere Anweisung hinzugefügt, ist die Verbundklammer schon da, Vorteil: in dem Fall vergisst man gerne die Klammer einzufügen, was zu unerkannten Fehlern führt Nachteil: zusätzliche Schreibarbeit, mehr Programmzeilen Riskant: ohne Verbundanweisung while ( x > 0) x = x / 2 ; Fehler: zusätzliche Anweisung eingefügt while ( x > 0) x = x / 2 ; System. out. p r i n t l n ( x ) ; Die zusätzliche Anweisung steht entgegen der Erwartung außerhalb der Schleife. 12 / 29
Verbundanweisungen einsetzen 13 / 29 Besser: immer mit Verbundanweisung while ( x > 0) { x = x / 2 ; Besser: zusätzliche Anweisung eingefügt while ( x > 0) { x = x / 2 ; System. out. p r i n t l n ( x ) ; Die zusätzliche Anweisung steht automatisch wie gewünscht in der Schleife.
Beispiel: Einrücken 14 / 29 Beispiel public class Einruecken { double var1 = 0. 0 ; i n t var2 = 2; public s t a t i c double methode1 ( double x ) { double y = 0; for ( i n t i = 0; i < var2 ; i ++) { var1 = var2 x ; i f ( var1 == 4) { for ( i n t k = 1; k<5; k++) { y = y Math. s q r t ( k ) ; else { y = 1; return y ; public s t a t i c void main ( String [ ] s ) { System. out. p r i n t l n ( methode1 ( 2 ) ) ;
Gliederung 15 / 29 1 Überblick 2 Anordnung von Anweisungen 3 Kommentierung des Programms 4 Klammerung 5 Namen 6 Konstanten 7 Beispielprogramm
Kommentare Niemand macht sie gerne, aber spätestens einen Monat nachdem man ein Programm geschrieben hat, wird man für jeden Kommentar dankbar sein. Am Anfang der Klasse Autor, Datum, evtl. zusätzlich benötigte Klassen und eine kurze Beschreibung der Klasse bzw. des Programms angeben. Über jeden Methodenkopf jeweils eine Kurzbeschreibung der Aufgabe der jeweiligen Methode angeben. Wichtige Teile einer Methode zur besseren Übersicht ebenfalls kommentieren (z.b. Bedeutung von Variablen, Wirkung einer Schleife, Formel, erwartete Werte vor und nach dem Programmstück). Schwierige und unübersichtliche Algorithmen unbedingt kommentieren! In der Kürze liegt die Würze! Natürlich muss die Kommentierung zur Komplexität des Programms in einem angemessenen Verhältnis stehen. Zu lange Kommentare sind kontraproduktiv und erfordern nur mehr Zeit. 16 / 29
17 / 29 Beispiel / / Autor : Gerd Bohlender / / Datum : 15.11.2009 / / Demonstration des Kommentargebrauchs public class Kommentare { / / auszuwertende Funktion public s t a t i c i n t f u n k t i o n ( i n t x ) { return 3 x x + 2 x + 7; / / Polynom 2. Grades / / Hauptprogramm e r s t e l l t F u n k t i o n s t a b e l l e public s t a t i c void main ( S t r i n g [ ] s ) { System. out. p r i n t l n ( f ( x ) ) ; / / U e b e r s c h r i f t for ( i n t i = 0; i <10; i ++) / / 10 Werte von f System. out. p r i n t l n ( f u n k t i o n ( i ) ) ; / / drucken
Gliederung 18 / 29 1 Überblick 2 Anordnung von Anweisungen 3 Kommentierung des Programms 4 Klammerung 5 Namen 6 Konstanten 7 Beispielprogramm
19 / 29 Klammerung Klamern können die Lesbarkeit eines Programms deutlich verbessern! Im Zweifel lieber Klammern setzen, auch wenn es theoretisch nicht nötig ist. Bei untergeordneten Anweisungen lieber Verbundanweisungen einsetzen (siehe oben). Die öffnende geschweifte Klammer { kann am Zeilenende stehen (bei Schleifen, bedingten Anweisungen, Klassen, Methoden). Alternativ in einer eigenen Zeile vorne (das kostet aber eine zusätzliche Zeile). Die schließende geschweifte Klammer steht immer vorne, wie die erste Zeile des entsprechenden Sprachelements eingerückt (Schleife,...). In Ausdrücken: runde Klammern setzen, insbesondere wenn Priorität der Operatoren unklar ist.
Klammerung von Anweisungen 20 / 29 Beispiel / / SCHLECHT bei spaeteren Ergaenzungen for ( i n t i = 0; i <5; i ++) x = x + i ; Gutes Beispiel / / GUT ( 1. M ö g l i c h k e i t ) for ( i n t i = 0; i <5; i ++) { x = x + i ; / / GUT ( 2. M ö g l i c h k e i t ) for ( i n t i = 0; i <5; i ++) { x = x + i ;
Klammerung in algebraischen und boolschen Ausdrücken 21 / 29 Klammerung in algebraischen und boolschen Ausdrücken kann zur Verdeutlichung der Reihenfolge der Operationen eingesetzt werden. Man sollte lieber zu viel als zu wenig Klammern setzen, vor allem bei längeren boolschen Ausdrücken. Schlechtes Beispiel i f ( x < 10 && y >= x x+y == 100) { z = x y /10 + x / 2 / y + x ++ ++ y ; Gutes Beispiel i f ( ( x < 10 && y >= x ) ( x+y == 100 ) ) { z = ( x y ) / 1 0 + x / ( 2 y ) + ( (x ++)) (++y ) ;
Gliederung 22 / 29 1 Überblick 2 Anordnung von Anweisungen 3 Kommentierung des Programms 4 Klammerung 5 Namen 6 Konstanten 7 Beispielprogramm
23 / 29 Gute Namen schlechte Namen Klassennamen beginnen mit Großbuchstaben, dann folgen Kleinbuchstaben, z.b. Person, Student, Kursteilnehmer Variablennamen und Methodennamen beginnen mit Kleinbuchstaben, z.b. name, semester, ausgeben() In beiden Fällen werden Wortanfänge im Inneren des Namens groß geschrieben, z.b. PhysikStudent, JavaKursteilnehmer, anzahlderaufgaben, klausurnote, bearbeiteaufgabe() Konstanten werden in lauter Großbuchstaben geschrieben und ggf. mit Unterstrich unterteilt, z.b. DIM, MIN_OELSTAND, MAX_DRUCK Namen sollten ihre Bedeutung beschreiben, wie z.b. die vorigen Namen; schlecht sind dagegen i.a. nichtssagende Namen wie a, b, c, i, x
Gliederung 24 / 29 1 Überblick 2 Anordnung von Anweisungen 3 Kommentierung des Programms 4 Klammerung 5 Namen 6 Konstanten 7 Beispielprogramm
25 / 29 Konstanten im Programm Konstanten sollten nicht im ganzen Programm verstreut auftauchen, sondern am Anfang einer Methode / einer Klasse gesammelt werden. Dies gilt insbesondere bei Konstanten, die voneinander abhängen. Es sollten Konstanten am Methodenanfang / Klassenanfang definiert werden, ggf. unter Verwendung vorher definierter Konstanten bei der Initialisierung. Vorteil: Änderungen können zentral an einer Stelle ausgeführt werden.
Konstanten im Programm: Beispiel 26 / 29 Schlecht: verteilte Konstanten for ( i n t i =0; i <20; i ++) / / etwas tun for ( i n t i =0; i <40; i ++) / / doppelt so v i e l tun Besser: Konstantendefinitionen f i n a l i n t DIM = 20; f i n a l i n t ZWEIDIM = 2 DIM ; for ( i n t i =0; i <DIM ; i ++) / / etwas tun for ( i n t i =0; i <ZWEIDIM ; i ++) / / doppelt so v i e l tun
Gliederung 27 / 29 1 Überblick 2 Anordnung von Anweisungen 3 Kommentierung des Programms 4 Klammerung 5 Namen 6 Konstanten 7 Beispielprogramm
Beispiel: miserabel formatiertes Programm 28 / 29 Schlechtes Beispiel: Sternenhoelle / / E i n s t i e g i n die I n f o r m a t i k mit Java, Gerd. Bohlender@kit. edu, 17.11.09 / / Sternenhimmel malen / / Dieses B e i s p i e l i s t bewusst haesslich f o r m a t i e r t / / die Zeilen sind unklar eingerueckt und g e t r e n n t / / eine Zuordnung zusammengehoeriger Elemente ( z.b. i f else oder { ) / / i s t nur schwer moeglich / / welche Anweisungen in welcher for Schleife stehen, i s t kaum f e s t z u s t e l l e n / / Namen sind schlecht lesbar, nicht selbsterklaerend / / Kommentare sind kaum vorhanden und die vorhandenen sind s i n n l o s / / unverstaendliche L i t e r a l k o n s t a n t e n im ganzen Programm v e r s t r e u t / / keine Benutzerfuehrung durch v e r s t a e n d l i c h e Dialoge / / ALSO: SO NICHT!!! / / Besser i s t das B e i s p i e l Sternenhimmel import java. u t i l. ; public class Sternenhoelle5 { public s t a t i c void main ( String [ ] args ) { Scanner i = new Scanner (System. in ) ; double x = i. nextdouble ( ) / 100; i n t y =0, z, s ; / i f ( z<25) { / for ( z =0;z<25;++z ) { / / i s t z k l e i n e r a l s 25 for ( s =0;s<50;++s ) i f (Math. random ( ) < x ) { / / Math. random a u f r u f e n y ++; System. out. p r i n t ( ) ; else / / A l t e r n a t i v e System. out. p r i n t ( ) ; / / ausgeben System. out. p r i n t l n ( ) ; / / mehr ausgeben System. out. p r i n t l n (100.0 y / / / 100 mit y m u l t i p l i z i e r e n 1250+ % ) ;
Beispiel: gut formatiertes Programm 29 / 29 Gutes Beispiel: Sternenhimmel / / E i n s t i e g i n die I n f o r m a t i k mit Java, Gerd. Bohlender@kit. edu, 17.11.09 / / Sternenhimmel malen : W a h r s c h e i n l i c h k e i t s w e r t einlesen und / / auf einem rechteckigen B i l d s c h i r m mit dieser W a h r s c h e i n l i c h k e i t / / Sterne drucken, andernfalls Leerzeichen / / es g i b t auch ein Programm Sternenhoelle... import java. u t i l. ; public class Sternenhimmel5 { public s t a t i c void main ( S t r i n g [ ] args ) { / / die ueblichen Vorbereitungen... Locale. s e t D e f a u l t ( Locale.US ) ; Scanner sc = new Scanner ( System. in ) ; / / Prozentzahl der Sterne eingeben und i n W a h r s c h e i n l i c h k e i t umrechnen System. out. p r i n t ( Prozentzahl der Sterne? ) ; double wahrsch = sc. nextdouble ( ) / 1 0 0 ; / / Prozent /100 = W a h r s c h e i n l i c h k e i t f i n a l i n t MAX Z=25, MAX S=50; / / Zeilen und Spaltenzahl i n t anzahl = 0; / / t a t s a e c h l i c h e Anzahl der Sterne / / wuerfeln, Sterne drucken und zaehlen for ( i n t z e i l e = 0; z e i l e < MAX Z ; ++ z e i l e ) { / / alle Zeilen... for ( i n t spalt e = 0; spalte < MAX S ; ++ spalte ) { / / und Spalten bearbeiten / / f u e r jeden Punkt eine Z u f a l l s z a h l a l s W a h r s c h e i n l i c h k e i t bestimmen i f ( Math. random ( ) < wahrsch ) { / / mit d ieser W a h r s c h e i n l i c h k e i t... System. out. p r i n t ( ) ; / / einen drucken anzahl ++; / / Sterne zaehlen else { / / sonst : System. out. p r i n t ( ) ; / / Leerzeichen drucken / / Ende innere S c h l e i f e System. out. p r i n t l n ( ) ; / / Z e i l e beenden / / Ende aeussere S c h l e i f e / / am Ende S t a t i s t i k ausgeben, wieviele Sterne gedruckt wurden System. out. p r i n t l n ( Tatsaechlich wurden + 100.0 anzahl / ( MAX Z MAX S) + / / anzahl / Gesamtpunkte i n % umrechnen % Sterne erzeugt / / beachte : 100.0 erzwingt double D i v i s i o n ) ;