-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathConsole.html
More file actions
904 lines (901 loc) · 53.3 KB
/
Console.html
File metadata and controls
904 lines (901 loc) · 53.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
<!DOCTYPE html><html lang="de"><head>
<title>Variationen zum Thema: Java</title>
<meta name="title" content="Variationen zum Thema: Java">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta charset="UTF-8">
<meta name="description" content="Introduction to Java Programming">
<meta name="keywords" content="java,introduction">
<meta name="author" content="Ralph P. Lano">
<meta name="robots" content="index,follow">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="book.css">
</head>
<body><center>
<div id="wrap">
<ul class="sidenav">
<p><a href="index.html">Variationen zum Thema</a><a href="index.html">Java</a></p>
<li><a href="Karel.html">Karel</a></li>
<li><a href="Graphics.html">Graphics</a></li>
<li><a href="Console.html">Console</a></li>
<li><a href="Agrar.html">Agrar</a></li>
<li><a href="MindReader.html">MindReader</a></li>
<li><a href="Swing.html">Swing</a></li>
<li><a href="Asteroids.html">Asteroids</a></li>
<li><a href="Stocks.html">Stocks</a></li>
</ul>
<div class="content"><p>
<img alt="" src="images/c08baf41-0039-4102-9b2c-ef97f4d8ce6a.png" style="display: block; margin-left: auto; margin-right: auto; width: 267px; height: 158px;" /></p>
<h1>
Console</h1>
<p>
Konsolenprogramme sind eigentlich noch einfacher zu schreiben als Grafikprogramme. Aber sie sind etwas abstrakter, deswegen beschäftigen wir uns erst jetzt mit ihnen. Es geht häufig darum mit dem Benutzer unseres Programmes zu interagieren. Ausserdem werden viele Konzepte die wir in den letzten beiden Kapiteln kennengelernt und verwendet haben, näher erklärt und vertieft.</p>
<p>
.</p>
<h2>
<img alt="" src="images/consoleProgram.png" style="margin-left: 10px; margin-right: 10px; width: 200px; height: 100px; float: right;" />ConsoleProgram</h2>
<p>
Schauen wir uns ein einfaches 'HelloWorld' Konsolenprogramm an:</p>
<pre>
import acm.program.ConsoleProgram;
public class HelloWorld extends ConsoleProgram {
public void run() {
<span style="color:#0000ff;">println("Hello World!");</span>
}
}</pre>
<p>
Wie üblich interessieren uns nur die Zeilen in der run() Methode. Die besagen, dass der Computer doch den Text in Anführungszeichen, also "Hello World", in einem Konsolenfenster ausgeben soll. Dabei ist 'println' die Kurzform von 'print line' und bedeutet genau das, also schreibe eine Zeile ins Konsolenfenster.</p>
<p>
.</p>
<h2>
readInt()</h2>
<p>
Konsolenprogramme wären recht langweilig wenn es nur 'println()' geben würde. Das Gegenstück dazu ist <em>readInt()</em>. Es erlaubt dem Benutzer unseres Programms eine Zahl einzugeben.</p>
<pre>
int n1 = readInt("Enter number one: ");</pre>
<p>
Dabei ist der Text in Anführungszeichen nicht unbedingt notwendig, aber er gibt dem Benutzer einen Hinweis darauf was er denn tun soll.</p>
<p>
.</p>
<h2>
<img alt="" src="images/addTwoIntegers.png" style="margin-left: 10px; margin-right: 10px; width: 200px; height: 100px; float: right;" />Übung: AddTwoIntegers</h2>
<p>
Schauen wir uns gleich mal ein Beispiel an. Wir wollen zwei Zahlen addieren und das Resultat auf der Konsole ausgeben. </p>
<pre>
println("This program adds two numbers.");
int n1 = readInt("Enter number one: ");
int n2 = readInt("Enter number two: ");
int sum = n1 + n2;
println( "The sum is: " + sum );</pre>
<p>
Die erste Zeile teilt dem Benutzer einfach mit was das Programm macht. Dann wird der Benutzer aufgefordert die erste Zahl einzugeben. Das Programm wartet jetzt solange bis der Benutzer eine Zahl eingibt. Danach fordert es den Benutzer auf die zweite Zahl einzugeben. Nachdem der Benutzer dies getan hat, addieren wir die beiden Zahlen <em>n1</em> und <em>n2</em>. Wir speichern das Resultat in der Variablen <em>sum</em>. In der letzten Zeile wird dann die Summe ausgegeben.</p>
<p>
Frage: Wie würde wohl ein Programm aussehen, das zwei Zahlen subtrahiert?</p>
<p>
.</p>
<h2>
Variablen</h2>
<p>
Die Frage die wir uns sofort stellen, was ist eine <em>Variable</em>? Variablen sind ein bischen wie Schachteln in die man Sachen reintun kann. Was für Sachen kann man da reintun? Z.B. Zahlen oder GRects. Das muss man aber immer explizit sagen was in die Schachtel rein kann. Also z.B. in eine Schachtel für Zahlen kann man nur Zahlen rein tun, und in eine Schachtel für GRects kann man nur GRects rein tun. Variablen haben auch immer einen Namen, z.B. 'n1' oder 'fritz'.</p>
<p>
<img alt="" src="images/326453ea-b08c-4c56-a18a-d0704d8ff997.png" style="margin-left: 10px; margin-right: 10px; width: 107px; height: 103px; float: right;" />Außen auf der Schachtel steht ein Name, z.B. 'n1' oder 'fritz'. Wenn wir also z.B. sagen</p>
<pre>
int n1;</pre>
<p>
dann heißt das es gibt eine Schachtel die den Namen 'n1' hat. Wenn wir dann sagen</p>
<pre>
n1 = 6;</pre>
<p>
dann ist das so wie wenn wir die Zahl 6 in die Schachtel hineintun. Man nennt das auch Zuweisung, also der Schachtel 'n1' wird die Zahl '6' zugewiesen. Wenn man will kann man die Zahl die in der Schachtel ist auch ändern. Man macht dann einfach eine neue Zuweisung und sagt</p>
<pre>
n1 = 5;</pre>
<p>
d.h., wir ersetzen die alte Zahl durch die neue Zahl '5'. Außen auf der Schachtel steht aber nachwievor 'n1'.</p>
<p>
<img alt="" src="images/a41fa673-8c0a-4c37-a383-096c11cb0060.png" style="margin-left: 10px; margin-right: 10px; width: 110px; height: 103px; float: right;" />Wir können aber nicht nur Zahlen in die Schachteln tun, sondern auch andere Sachen. Z.B. mit</p>
<pre>
GRect fritz;</pre>
<p>
sagen wir, dass es eine Schachtel gibt, die 'fritz' heißt. In diese Schachtel können wir GRects reintun, also mit</p>
<pre>
fritz = new GRect(50, 50);</pre>
<p>
legen wir ein neues GRect das 50 Pixel breit und 50 Pixel hoch ist in die Schachtel. Ganz wichtig, in eine Schachtel für GRects können wir keine Zahlen tun, und in eine Schachtel für Zahlen können wir keine GRects tun.</p>
<p>
.</p>
<h2>
Deklaration und Zuweisung</h2>
<p>
Wenn wir sagen</p>
<pre>
int n1;</pre>
<p>
dann <em>deklarieren</em> wir eine Variable. Die Variable heißt 'n1' und ist vom Typ Zahl (int ist eine Abkürzung für Englisch 'integer', was soviel wie Ganzzahl bedeutet). Wenn wir dann sagen</p>
<pre>
n1 <span style="color:#0000ff;">=</span> 6;</pre>
<p>
machen wir eine <em>Zuweisung</em>, wir weisen also der Variablen 'n1' den Wert '6' zu. Das '=' bedeutet also nicht Gleichheit, sondern Zuweisung. Das ist ganz wichtig.</p>
<p>
<img alt="" src="images/9e4eacca-64b8-4b55-8c81-4a58fa273f9d.png" style="margin-left: 10px; margin-right: 10px; width: 306px; height: 115px; float: right;" />Was die Namen von Variablen angeht, so können diese fast beliebig sein, sie dürfen aus Buchstaben, Zahlen und dem Unterstrich bestehen. Einige Wörter sind allerdings nicht erlaubt, wie z.B. 'if' und 'for', weil diese bereits von Java verwendet werden. Auch dürfen Namen nicht mit Zahlen beginnen und Umlauten sollte man generell vermeiden. Und man muss immer auf Groß- / Kleinschreibung achten!</p>
<p>
Eine Variable hat also immer einen Namen, einen Typ und einen Wert. </p>
<p>
<b>SEP: Die Namen von Variablen sollten immer beschreibend sein, also z.B. 'blueRect'.</b></p>
<p>
.</p>
<h2>
Typen</h2>
<p>
Was für Typen gibt es denn? Im letzten Kapitel haben wir schon einige kennengelernt: GRect, GOval, GLine u.s.w. sind alles Typen, genauer gesagt <em>Datentypen</em>. Es gibt aber auch andere Typen. Die die uns in diesem Kapitel beschäftigen werden sind die sogenannten <em>primitiven</em> Datentypen. Von denen gibt es in Java acht, aber uns interessieren nur die folgenden vier:</p>
<ul>
<li>
<strong>int:</strong> Ganzzahlen, also 1,2,3, usw. aber auch die 0 und die -5, also positive und negative ganze Zahlen.</li>
<li>
<strong>double:</strong> Gleitkommazahlen, also Zahlen wie 3.14 oder 0.333 usw, (Beim Programmieren verwenden wir wie im Englischen den '.' anstelle des ',').</li>
<li>
<strong>boolean:</strong> wird für logische Werte verwendet, kann nur die zwei Werte <em>true</em> oder <em>false</em> haben.</li>
<li>
<strong>char:</strong> Buchstaben, wie z.B. 'a', 'b', aber auch Sonderzeichen wie '.' und '$' usw.</li>
</ul>
<p>
Manchmal stellt sich die Frage, soll ich jetzt einen 'int' oder einen 'double' verwenden? Die Antwort ist ganz einfach: kann man etwas zählen, dann verwendet man einen 'int'. Für alles was man nicht zählen kann verwendet man den 'double' Datentyp. Mit dem <em>boolean</em> Datentyp beschäftigen wir uns weiter unten, der <em>char</em> Datentyp muß noch ein Kapitel warten.</p>
<p>
<b>SEP: Für alles was man zählen kann, verwenden wir den Datentyp <em>int</em>.</b></p>
<p>
.</p>
<h2>
Ausdruck</h2>
<p>
Das Wort <em>Ausdruck</em> wie wir es verwenden, hat nichts mit 'ausdrucken' zu tun. Sondern wird eher im Sinne von 'mathematischer Ausdruck' verwendet. Wir haben schon ein Beispiel gesehen, nämlich</p>
<pre>
int sum = <span style="color:#0000ff;">n1 + n2</span>;</pre>
<p>
Hier steht auf der linken Seite der Zuweisung eine Variable, 'sum', und auf der rechten Seite steht ein mathematischer Ausdruck, und zwar die Summe der Zahlen 'n1' und 'n2'. Genauer, die Summe der Zahlen die in den Schachteln 'n1' und 'n2' drinnen sind. </p>
<p>
Was dies Zeile also bedeutet ist folgendes: Hole die Zahlen die in der Schachtel 'n1' und in der Schachtel 'n2' stehen, addiere diese und speichere das Resultat in die Schachtel 'sum'. Man kann das sehr schön mit dem Program 'Jeliot' veranschaulichen [1].</p>
<p>
.</p>
<h2>
Übung: Jeliot</h2>
<p>
Jeliot ist ein sehr schönes Programm, dass uns hilft zu visualisieren was passiert, wenn wir die drei Zeilen</p>
<pre>
int n1 = 6;
int n2 = 4;
int sum = n1 + n2;</pre>
<p>
ausführen. Wir sehen links im Codefenster unsern Code. Wir können diesen Code Schritt für Schritt durchlaufen. Und auf der rechten Seite sehen wir einmal den Bereich für die Methoden (Method Area) in dem wir auch unsere Schachteln 'n1', 'n2' und 'sum' sehen. Sowie den Bereich für die Auswertung von Ausdrücken (Expression Evaluation Area). Wir sehen, wie gerade der Ausdruck '6+4=' ausgewertet wird. Im nächsten Schritt wird dann das Resultat ('10') in die Schachtel 'sum' gesteckt.</p>
<p>
<img alt="" src="images/jeliot.png" style="margin-left: 10px; margin-right: 10px; width: 586px; height: 255px;" /></p>
<p>
.</p>
<h2>
Operatoren</h2>
<p>
Karel hat Angst vor Operatoren. Er denkt dann immer an Krankenhaus. Wir verwenden das Wort <em>Operator</em> wieder eher im mathematischen Sinne, also 'plus', 'minus', 'mal' und 'geteilt durch'. In Java verwenden wir dafür die Zeichen '+', '-', '*' und '/'. </p>
<p>
.</p>
<h2>
Division</h2>
<p>
Bei 'plus', 'minus' und 'mal' kann nicht viel schief gehen, die funktionieren immer. Aber bei der Division kann einiges schief gehen. Das erste an das wir uns vielleicht noch erinnern ist Division durch Null: das gibt immer Ärger. Das zweite was Ärger macht ist Ganzzahldivision, also was ist 5 / 2? Damals in der zweiten Klasse war das einfach 2. Aber dann später hat irgendjemand gesagt es ist 2.5. Also was nun?</p>
<p>
Das kommt drauf an. Wenn wir mit Ganzzahlen arbeiten, also mit <em>int</em>, dann ist es 2. Wenn wir mit Gleitkommazahlen arbeiten, also mit <em>double</em>, dann ist es 2.5. Das kann zu interessanten Problemen führen. Nehmen wir das folgende Beispiel:</p>
<pre>
int x = 1 + 3 * 5 / 2;</pre>
<p>
<img alt="" src="images/math1352.png" style="margin-left: 10px; margin-right: 10px; width: 140px; float: right; height: 56px;" />Was ist der Wert von 'x'? Sieben oder acht? Mit Jeliot kann man Schritt für Schritt nachvollziehen, wie der Computer das ausrechnet. Zunächst einmal gilt 'Punkt vor Strich', d.h. die Addition wird als letztes ausgeführt. Dann stellt sich aber die Frage wird zu erst '3*5' oder '5/2' ausgerechnet? Hier gilt die Regel von links nach rechts, also wie beim Lesen, man liest (bei uns wenigstens) von links nach rechts. Also wird zuerst '3*5' berechnet, das Ergebnis durch 2 geteilt. Weil es sich um Ganzzahldivision handelt kommt dabei 7 und nicht 7.2 heraus. Wenn wir dann die 7 zu 1 addieren, erhalten wir 8 als Ergebnis.</p>
<p>
Was passiert nun wenn wir anfangen Ganzzahlen (int) und Gleitkommazahlen (double) zu mischen? Also, so was wie 5 / 2.0? Dann tut der Computer so wie wenn alle Zahlen Gleitkommazahlen wären.</p>
<p>
.</p>
<h2>
<img alt="" src="images/average.png" style="margin-left: 10px; margin-right: 10px; width: 200px; height: 100px; float: right;" />Übung: AverageTwoIntegers</h2>
<p>
Man könnte denken, dass Probleme mit der Ganzzahldivision eher selten vorkommen, dem ist aber überhaupt nicht so, und das Beispiel <em>AverageTwoIntegers</em> soll das verdeutlichen.</p>
<p>
Ähnlich wie bei AddTwoIntegers lesen wir zunächst zwei Ganzzahlen ein. Und wenn jemand etwas nachlässig ist, schreibt er evtl folgende Anweisung um den Durchschnitt zweier Zahlen zu berechnen:</p>
<pre>
int average = n1 + n2 / 2;</pre>
<p>
Interessanterweise funktioniert das sogar, z.B. wenn n1=1 und n2=3 ist. Allerdings für andere Zahlenwerte merkt man sehr schnell, dass da etwas nicht stimmt.</p>
<p>
Natürlich war der Fehler die fehlenden Klammern! Also, versuchen wir es doch mit folgendem Ausdruck:</p>
<pre>
int average = ( n1 + n2 ) / 2;</pre>
<p>
Der funktioniert schon viel besser, aber immer nur wenn n1+n2 eine gerade Zahl ist. Naja klar, der Fehler liegt im Datentyp: "average" muss ein <em>double</em> sein:</p>
<pre>
double average = ( n1 + n2 ) / 2;</pre>
<p>
</p>
<p>
Aber auch das hilft nicht wirklich. Der Teufel liegt im Detail: da n1 und n2 vom Datentyp <em>int</em> sind UND auch 2 vom Datentyp <em>int</em> ist, führt der Computer Ganzzahldivision aus. Die Lösung für das Problem lautet:</p>
<pre>
double average = ( n1 + n2 ) / <span style="color:#0000ff;">2.0</span>;</pre>
<p>
Obwohl dieser Fehler im nachhinein offensichtlich ist und die Lösung trivial, tritt er überraschenderweise sehr, sehr häufig auf.</p>
<p>
<b>SEP: Man sollte seinen Code immer ausführlich testen.</b></p>
<p>
.</p>
<h2>
Punkt vor Strich</h2>
<p>
Vorrangsregeln wie 'Punkt vor Strich' gibt es ganz viele in Java. Grob gilt folgende Hierarchie:</p>
<ol>
<li>
Klammern: ()</li>
<li>
*, /, %</li>
<li>
+, -</li>
</ol>
<p>
also zuerst Klammern, dann Multiplikation, Division und Restwert, und schließlich Addition und Subtraktion. Aber es kann noch viel komplizierter werden mit so Operatoren wie '^', '&', '|', usw. Deswegen empfiehlt es sich immer soviele Klammern wie möglich zu setzen.</p>
<p>
<strong>SEP: Um Ärger zu vermeiden, verwende viele Klammern!</strong></p>
<p>
.</p>
<h2>
Restwert</h2>
<p>
Allerdings gibt es in Java noch einen weiteren Operator, den <em>Restwert</em> (English: modulo oder genauer remainder). Das letzte mal haben wir wahrscheinlich in der zweiten Klasse davon gehört, und zwar als wir noch nicht richtig dividieren konnten. Wenn wir damals 5 / 2 ausgerechnet haben, dann hieß das Ergebnis: zwei Restwert eins. Oder bei 4 / 2 hieß das Ergebnis zwei Restwert null. Können wir uns noch dunkel erninnern? </p>
<p>
Es stellt sich heraus, dass der Restwert Operator äussert nützlich ist, deswegen gibt es in Java dafür ein extra Zeichen, das Prozentzeichen: '%'. Eigentlich verwenden wir den Restwert Operator jeden Tag: wenn wir sagen es ist 2 Uhr nachmittags, dann haben wir implizit 14 % 12 im Kopf ausgerechnet.</p>
<p>
.</p>
<h2>
Übung: Gerade Zahlen, ungerade Zahlen</h2>
<p>
<img alt="" src="images/95e52edc-59c9-477a-a561-ddc5df1d9cb5.png" style="margin-left: 10px; margin-right: 10px; width: 96px; height: 236px; float: right;" />Eine sinnvolle Übung ist es die Zahlen von 0 bis 6 aufzulisten und für jede dieser Zahlen den Restwert auszurechnen, also %2. Wir sehen, dass für gerade Zahlen der Restwert immer null ist und für ungerade Zahlen der Restwert immer eins. Das ist sehr nützlich, denn manchmal wollen wir wissen ob eine Zahl gerade oder ungerade ist.</p>
<p>
.</p>
<h2>
Konstanten</h2>
<p>
Manche Variablen ändern sich nicht, sind also eigentlich Konstanten. Z.B die Kreiszahl 'Pi' hat immer den Wert '3.1415...'. Wir können das markieren mit dem Schlüsselwort <em>final</em>:</p>
<pre>
<span style="color:#0000ff;"> final</span> double PI = 3.1415;</pre>
<p>
Konstanten können nachdem sie einmal initialisiert wurden nicht mehr verändert werden. Das mag am anfang etwas umständlich erscheinen, später werden wir aber sehen, dass die Verwendung von Konstanten zu viel besserem Code führt.</p>
<p>
<strong>SEP: Konstanten sollten immer ganz in Großbuchstaben geschrieben werden, also z.B. 'MAX_NUM', damit man sie sofort von normalen Variablen unterscheiden kann.</strong></p>
<p>
.</p>
<h2>
<img alt="" src="images/area.png" style="margin-left: 10px; margin-right: 10px; width: 200px; height: 100px; float: right;" />Übung: Area</h2>
<p>
Schreiben Sie ein ConsoleProgram, das den Benutzer nach der Radius eines Kreises fragt, und dann dessen Fläche berechnet (Fläche = PI * Radius * Radius) und diese im Konsolenfenster ausgibt (println()). Dabei sollte PI als Konstante im Programm verwendet werden.</p>
<p>
.</p>
<h2>
Boolesche Werte</h2>
<p>
Bisher haben wir uns mit den Zahlen, <em>int</em> und <em>double</em>, auseinandergesetzt. Jetzt wollen wir uns kurz den logischen Werten, auch <em>boolean</em> genannt, widmen. Um zu verstehen worum es geht betrachten wir die Ungleichung</p>
<pre>
3 > 5</pre>
<p>
also die Frage, ist drei größer als fünf. Die Antwort ist Nein. Man sagt auch die Aussage '3 > 5' ist falsch, <em>false</em> auf Englisch. Um damit umgehen zu können hat man den Datentyp <em>boolean</em> erfunden:</p>
<pre>
boolean b = 3 > 5;</pre>
<p>
d.h., also die Variable <em>b</em> ist vom Datentyp <em>boolean</em> und kann die Werte <em>true</em> oder <em>false</em> einnehmen. Das Ganze sollte uns etwas an Karel's Sensoren erinnern: z.B. der <em>beepersPresent()</em> Sensor hat immer <em>true</em> zurückgegeben, wenn ein Beeper da war und <em>false</em>, wenn keiner da war.</p>
<p>
.</p>
<h2>
Bedingungen</h2>
<p>
Richtig Sinn machen boolesche Ausdrücke nur wenn sie in einer Bedingung verwendet werden. Bei Karel haben wir ja schon die <em>if</em> Anweisung kennen gelernt:</p>
<pre>
if ( beepersPresent() ) {
pickBeeper();
} else {
putBeeper();
}</pre>
<p>
<img alt="" src="images/condition.png" style="margin-left: 10px; margin-right: 10px; width: 200px; height: 100px; float: right;" />Das Gleiche können wir jetzt auch mit einem Konsolenprogramm machen:</p>
<pre>
int x = readInt("Enter a number: ");
if ( <span style="color:#0000ff;">x > 5</span> ) {
println("Number is larger than 5.");
} else {
println("Number is less than or equal to 5.");
}</pre>
<p>
Dass es sich bei 'x > 5' eigentlich um einen booleschen Ausdruck handelt, ist eigentlich eher nebensächlich.</p>
<p>
<strong>SEP: Wir sollten bei einer if Anweisung immer die geschweiften Klammern benutzen!</strong></p>
<p>
.</p>
<h2>
Vergleiche</h2>
<p>
Welche anderen Vergleiche außer '>' gibt es noch? Insgesamt sechs:</p>
<pre>
== gleich
!= nicht gleich
> größer
< kleiner
>= größer oder gleich
<= kleiner oder gleich
</pre>
<p>
.</p>
<h2>
<img alt="" src="images/dayOfWeek.png" style="margin-left: 10px; margin-right: 10px; width: 200px; height: 100px; float: right;" />Übung: DayOfTheWeek</h2>
<p>
Schreiben wir ein Programm, das ausgibt, ob ein Tag ein Werktag, ein Samstag oder ein Sonntag ist:</p>
<pre>
int day = readInt("Enter day of week as int (0-6): ");
if (day == 0) {
println("Sunday");
} else if (day <= 5) {
println("Weekday");
} else {
println("Saturday");
}</pre>
<p>
Falls also der Tag gleich null ist, dann ist es Sonntag; andernfalls, falls der Tag kleiner oder gleich 5 ist, dann ist es ein Werktag; andernfalls muss es der Samstag sein. Man bezeichnet diese Form der verketteten if Anweisung auch als 'cascading if'.</p>
<p>
.</p>
<h2>
switch Anweisung</h2>
<p>
Die <em>switch</em> Anweisung gab es bei Karel noch nicht, aber sie stellt sich als sehr praktisch heraus. Im Prinzip macht sie das gleiche wie das 'cascading if', nur etwas eleganter:</p>
<pre>
int day = readInt("Enter day of week as int (0-6): ");
switch (day) {
case 0:
println("Sunday");
break;
case 6:
println("Saturday");
break;
default:
println("Weekday");
break;
}</pre>
<p>
Warum das eleganter sein soll wird sich etwas später zeigen.</p>
<p>
<strong>SEP: Man sollte immer ein <em>default</em> bei der switch Anweisung haben, bzw. den letzten <em>else</em> Zweig beim cascading if.</strong></p>
<p>
.</p>
<h2>
<img alt="" src="images/dayOfWeek2.png" style="margin-left: 10px; margin-right: 10px; width: 200px; height: 100px; float: right;" />Übung: DayOfTheWeek</h2>
<p>
Wir wollen unser DayOfTheWeek Problem jetzt mit der <em>switch</em> Anweisung lösen. Zunächst verwenden wir den Code wie oben, uns testen ob er auch funktioniert. Testen heißt, dass wir jede möglich Eingabe testen. (Was passiert wenn wir -1 oder 42 eingeben?)</p>
<p>
Frage: Was passiert wenn wir eine der <em>break</em> Anweisungen weglassen?</p>
<p>
.</p>
<h2>
Boolesche Operatoren</h2>
<p>
Erinnern wir uns an LumberjackKarel: im letzten Schritt, wenn Karel alle Bonbons einsammeln soll um sie auf einen großen Haufen zu legen, wäre es toll gewesen wenn wir zwei Bedingungen gleichzeitig hätten testen können, also ist links frei <em>und</em> ist ein Bonbon da:</p>
<pre>
while ( leftIsBlocked() <strong><span style="color:#0000ff;">&&</span></strong> beepersPresent() ) {...}
</pre>
<p>
Hier bedeutet das '&&' soviel wie 'und', also nur wenn beide Bedingungen erfüllt sind, soll Karel etwas machen. Ähnlich praktisch wäre es gewesen wenn wir Karel nur dann etwas hätten machen lassen wenn etwas <em>nicht</em> erfüllt ist,</p>
<pre>
if ( <strong><span style="color:#0000ff;">!</span></strong>beepersPresent() ) {...}
</pre>
<p>
Hier bedeutet das '!' soviel wie 'nicht'. Schließlich, hatten wir das Beispiel von AriadneKarel wo Karel etwas tun sollte, wenn entweder vor ihm eine Wand war <em>oder</em> keine Bonbons da war:</p>
<pre>
if ( frontIsBlocked() <span style="color:#0000ff;"><strong>||</strong></span> noBeepersPresent() ) {...}
</pre>
<p>
Das '||' bedeutet 'oder' im Sinne von entweder-oder.</p>
<p>
Diese drei Operatoren sind die sogenannten booleschen Operatoren:</p>
<pre>
! not
&& and
|| or
</pre>
<p>
Die Reihenfolge spiegelt auch die Vorrangsregeln wider, also '!' hat eine höhere Priorität als 'and'.</p>
<p>
.</p>
<h2>
Wahrheitstabellen</h2>
<p>
Es ist üblich die booleschen Operationen in sogenannten Wahrheitstabellen (truth tables) darzustellen. Dabei sind <em>in1</em> und <em>in2</em> die zwei Operanden, und <em>out</em> ist das Resultat, z.B.</p>
<pre>
boolean out = in1 && in2;</pre>
<p>
für die '<em>and</em>' Operation. Die Wahrheitstabellen für die drei logischen Operationen sehen wie folgt aus:</p>
<p>
<img alt="" src="images/98bce237-bbb2-4d00-adad-cfeb82d7d284.png" style="margin-left: 10px; margin-right: 10px; width: 464px; height: 167px;" /></p>
<p>
.</p>
<h2>
Übung: LeapYear</h2>
<p>
Es gibt einen coolen booleschen Ausdruck der uns angibt, ob ein Jahr ein Schaltjahr ist oder nicht:</p>
<pre>
boolean p = ((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0);</pre>
<p>
Um den Ausdruck zu verstehen, schreibt man sich am besten die Wahrheitstabellen (truth table) dafür auf.</p>
<p>
<img alt="" src="images/29d01bac-4234-46ed-9a3f-4c12bcf33588.png" style="margin-left: 10px; margin-right: 10px; width: 405px; height: 319px;" /></p>
<p>
.</p>
<h2>
while Schleife</h2>
<p>
Wir haben die <em>while</em> Schleife schon bei Karel kennengelernt:</p>
<pre>
while ( frontIsClear() ) {
move();
}
</pre>
<p>
<img alt="" src="images/CounterWithWhile.png" style="margin-left: 10px; margin-right: 10px; width: 200px; height: 100px; float: right;" />Die <em>while</em> Schleife wird solange ausgeführt, solange eine bestimmte Bedingung erfüllt ist. Als einfach Beispiel wollen wir die Zahlen von 0 bis 9 ausgeben.</p>
<pre>
int i = 0;
while ( <span style="color:#0000ff;">i < 10</span> ) {
println( i );
i = i + 1;
}
</pre>
<p>
In der ersten Zeile deklarieren wir eine Variable namens <em>i</em> von Datentyp <em>int</em> auf den Wert 0. Dann testen wir ob <em>i</em> kleiner als 10 ist. Solange dies der Fall ist, drucken wir den momentanen Wert von <em>i</em> im Konsolenfenster, und dann erhöhen wir den Wert von <em>i</em> um eins. </p>
<p>
Diese letzte Zeile mag etwas ungewöhnlich sein (speziell Mathematiker haben ein Problem damit). Aber es ist wichtig sich daran zu erinnern, dass '=' nicht für Gleichheit steht, sondern für <em>Zuweisung</em>. Also</p>
<pre>
i = i + 1;</pre>
<p>
bedeutet soviel wie: nimm den momentanen Wert von <em>i</em>, addiere dazu eins, und weise das Resultat dann der Variablen <em>i</em> zu.</p>
<p>
.</p>
<h2>
Übung: CounterWithWhile</h2>
<p>
Als kleine Übung probieren wir den Zählercode aus: einfach die Zeilen oben in die run() Methode eines ConsolePrograms einfügen. Was passiert, wenn wir anstelle von <em>println()</em> nur <em>print()</em> verwenden?</p>
<p>
.</p>
<h2>
<img alt="" src="images/CounterWithWhile.png" style="margin-left: 10px; margin-right: 10px; width: 200px; height: 100px; float: right;" />for Schleife</h2>
<p>
Wir haben die <em>for</em> Schleife ja schon ganz am Anfang bei Karel kennengelernt. Damals hat uns nur die Zahl, wie oft die Schleife durchlaufen wird, interessiert. Jetzt sind wir aber soweit den Rest auch zu verstehen. Die folgende <em>for</em> Schleife gibt auch die Zahlen von 0 bis 9 aus:</p>
<pre>
for ( int i = 0; i < 10; i++ ) {
println(i);
}</pre>
<p>
Im Allgemeinen sieht eine <em>for</em> Schleife immer wie folgt aus:</p>
<pre>
for ( init; condition; step ) {
statements;
}</pre>
<p>
Als erstes wird der <em>init</em> Schritt ausgeführt, meist so etwas wie 'int i = 0'. Dann wird die <em>condition</em> gecheckt, also ist 'i < 10'? Falls ja werden die <em>statements</em> innerhalb der Schleife ausgeführt. Zum Schluß wird dann <em>step</em> ausgeführrt, also 'i++'. Das wird solange getan bis die <em>condition</em> nicht mehr erfüllt ist.</p>
<p>
Was bedeutet dieses 'i++'? Man nennt es den Inkrement Operator, und er bedeutet soviel wie die Zeile</p>
<pre>
i = i + 1;</pre>
<p>
also der Wert der Variablen <em>i</em> wird um eins erhöht. Es gibt auch einen Dekrement Operator der genau das Gegenteil macht: 'i--'.</p>
<p>
.</p>
<h2>
Übung: for Schleife in Jeliot</h2>
<p>
Um die <em>for</em> Schleife noch besser zu verstehen, sehen wir uns die Schleife mal in Jeliot an, und beobachten Schritt für Schritt was passiert.</p>
<p>
<img alt="" src="images/JeliotForLoop.png" style="margin-left: 10px; margin-right: 10px; width: 586px; height: 255px;" />.</p>
<p>
.</p>
<h2>
for versus while</h2>
<p>
Wie wir gesehen haben, machen <em>while</em> Schleife und <em>for</em> Schleife eigentlich das Gleiche. Daher stellt sich die Frage wann verwendet man welche? </p>
<ul>
<li>
<strong>for:</strong> verwenden wir, wenn wir von vornherein wissen wie oft etwas ausgeführt wird, z.B.,<br />
<span style="font-family:courier new,courier,monospace;">for ( int i=0; i<10; i++ ) {...} </span></li>
<li>
<strong>while:</strong> verwenden wir wenn wir noch nicht genau wissen wie oft eine Schleife ausgeführt wird, z.B.,<br />
<span style="font-family:courier new,courier,monospace;">while ( frontIsClear() ) {...} </span></li>
</ul>
<p>
.</p>
<h2>
OBOB: FillRowKarel</h2>
<p>
Es gibt noch eine Schleife über die wir noch nicht gesprochen haben, den 'Loop and a Half': Er ist die Lösung unseres OBOB Problems. Erinnern wir uns an FillRowKarel:</p>
<pre>
while ( frontIsClear() ) {
putBeeper();
move();
}
putBeeper();
</pre>
<p>
Das Problem liegt darin, dass wir das 'putBeeper()' Kommando zweimal benötigen. Diese Duplizierung von Code tritt bei jedem OBOB auf und doppelter Code ist immer etwas Schlechtes.</p>
<p>
<strong>SEP: Vermeide doppelten Code.</strong></p>
<p>
.</p>
<h2>
Loop and a Half</h2>
<p>
Die Lösung ist eigentlich ganz einfach und heißt 'Loop and a Half':</p>
<pre>
while ( true ) {
putBeeper();
if ( frontIsBlocked() ) <span style="color:#0000ff;">break</span>;
move();
}
</pre>
<p>
Analysieren wir den Code: Zunächst einmal haben wir eine Endlosschleife, 'while (true)'. Allerdings können wir mit der Anweisung <em>break</em> diese Endlosschleife beenden, also aus ihr herausspringen. Das machen wir dann wenn vor Karel eine Wand ist, 'if ( frontIsBlocked() )'. Jetzt sehen wir auch warum es 'Loop and a Half' heißt: die Schleife wird im letzten Schritt nur zur Hälte ausgeführt. Um den Code zu verstehen, sollten wir ihn Schritt für Schritt auf einem Stück Papier durchgehen.</p>
<p>
.</p>
<h2>
<img alt="" src="images/cashRegister.png" style="margin-left: 10px; margin-right: 10px; width: 200px; height: 100px; float: right;" />Übung: CashRegister</h2>
<p>
Eine schöne und typische Anwendung für den 'Loop and a Half' ist die Kasse in einem Laden: wir haben z.B. fünf Sachen in unserem Einkaufswagen und wollen jetzt bezahlen. Der Kassierer tippt also die Preise der einzelnen Waren, eine nach der anderen in die Kasse, die diese addiert und am Ende gibt sie aus wieviel wir bezahlen sollen:</p>
<pre>
int total = 0;
while (true) {
int price = readInt("Enter price: ");
if ( price == 0 ) <span style="color:#0000ff;">break</span>;
total += price;
}
println("Your total is: " + total);
</pre>
<p>
Da aber nicht alle Leute immer genau fünf Sachen kaufen, brauchen wir irgendein Abbruchkriterium: in unserem Fall ist es wenn der Kassierer die 0 für den Preis eingibt. Man nennt dieses Abbruchkriterium im Englischen manchmal auch den Sentinel.</p>
<p>
Frage: Könnten wir auch eine negative Zahl als Abbruchkriterium verwenden?</p>
<p>
<strong>SEP: Man sollte möglichst nicht mehrere 'breaks' verwenden.</strong></p>
<p>
.</p>
<h2>
Post-Increment vs Pre-Increment</h2>
<p>
Wir haben bisher nur den Inkrement Operator als Post-Inkement Operator gesehen, es gibt ihn aber auch als Pre-Inkement. Der Unterschied ist, dass einmal das ’++’ vor der Variablen steht (pre) oder danach (post). Also:</p>
<pre>
int x = 5;
int y = x++; // Post: y=5
</pre>
<p>
oder</p>
<pre>
int x = 5;
int y = ++x; // Pre: y=6
</pre>
<p>
Der Unterschied ist subtil, und man bemerkt ihn nur wenn dieser Operator in Zusammenhang mit Assignments oder anderen Operationen steht:</p>
<pre>
int a = 6;
<span style="color:#0000ff;">int x = ++­­a;</span>
int y = x++;
</pre>
<p>
In der zweiten Zeile wird zuerst (pre) die Variable <em>a</em> um eins erhöht, und danach die Zuweisung gemacht. In der letzten Zeile, wird zuerst die Zuweisung gemacht, und danach (post) die Variable <em>x</em> um eins erhöht.</p>
<p>
.</p>
<hr />
<h1>
Review</h1>
<p>
Was haben es geschafft! Dieses Kapitel war etwas schwieriger als die beiden vorhergehenden. Dafür geht es von nun an aber bergab. Was haben wir in diesem Kapitel gelernt? Wir haben</p>
<ul>
<li>
Variablen kennengelernt,</li>
<li>
uns an den Restwert Operator erinnert,</li>
<li>
unseren ersten Kontakt mit Konstanten gehabt,</li>
<li>
Boolesche Operatoren und Wahrheitstabellen zum ersten Mal gesehen,</li>
<li>
festgestellt, dass die <em>if</em> und die <em>switch</em> Anweisung sehr ähnlich sind,</li>
<li>
gelernt wann wir eine <em>for</em> und wann eine <em>while</em> Schleife verwenden sollen und</li>
<li>
im 'Loop and a Half' die Lösung für unser OBOB Problem gefunden.</li>
</ul>
<p>
Das wichtigste in diesem Kapitel war, dass wir unsere ersten Schritte auf eine solide Basis gestellt haben.</p>
<p>
.</p>
<hr />
<h1>
Projekte</h1>
<p>
Die folgenden Projekte sind vielleicht nicht ganz so interessant wie die des letzten Kapitels. Aber sie stellen die Grundlage für die folgenden Kapitel dar.</p>
<p>
.</p>
<h2>
<img alt="" src="images/countdown.png" style="margin-left: 10px; margin-right: 10px; width: 200px; height: 100px; float: right;" />Countdown</h2>
<p>
Karel liebt Raketen und besonders den Countdown kurz vorher. Deswegen wollen wir ein Programm schreiben, dass auf der Konsole die Zahlen von 10 bis 0 ausgibt.</p>
<p>
.</p>
<p>
.</p>
<h2>
<img alt="" src="images/calculator.png" style="margin-left: 10px; margin-right: 10px; width: 200px; height: 100px; float: right;" />Calculator</h2>
<p>
Das mit dem DoubleBeeper war für Karel ziemlich viel Arbeit. Mit Konsolenprogrammen und Variablen geht das viel einfacher. Deswegen wollen wir ein Konsolenprogrammen schreiben, das zwei Zahlen addiert. </p>
<p>
Was etwas störend an dem Programm ist, das man es jedes mal neu starten muss, wenn man eine neue Addition machen will. Was könnte man tun, damit das Programm mehrere Additionen (immer von zwei Zahlen) erlaubt?</p>
<p>
.</p>
<h2>
<img alt="" src="images/temperature.png" style="margin-left: 10px; margin-right: 10px; width: 200px; height: 100px; float: right;" />Temperature</h2>
<p>
Karel liebt Amerika, aber er kann nichts mit diesen Fahrenheit anfangen. Deswegen schreiben wir ihm ein Programm, das Fahrenheit in Celsius umrechnet. Wir bitten den Benutzer uns eine Temperatur in Fahrenheit zu geben. Mittels readInt() speichern wir diese in der Variablen <em>f</em>. Und mit der Formel</p>
<pre>
int c = (int) ( (5.0 / 9.0) * (<span style="color:#0000ff;">f</span> - 32) );</pre>
<p>
können wir das in Celsius umrechnen. </p>
<p>
Neu an dieser Formel ist was das <span style="font-family:courier new,courier,monospace;">(int)</span> macht: Es handelt sich hier um einen <em>Cast</em> oder Typumwandlung auf Deutsch. Dazu müssen wir kurz überlegen um welchen Datentype es sich denn bei <span style="font-family:courier new,courier,monospace;">(5.0 / 9.0) * (f - 32)</span> handelt? Sobald einer der Operanden ein <em>double</em> ist, wird das ganze Ergebnis in einen <em>double</em> umgewandelt. Dann haben wir aber auf der einen Seite der Zuweisung einen <em>double</em> stehen und auf der anderen aber eine <em>int</em>. Das ist nicht gut. Deswegen konvertieren wir den <em>double</em> in einen <em>int</em>, und genau das macht <span style="font-family:courier new,courier,monospace;">(int)</span>.</p>
<p>
.</p>
<h2>
<img alt="" src="images/squares.png" style="margin-left: 10px; margin-right: 10px; width: 200px; height: 100px; float: right;" />Squares</h2>
<p>
Als Beispiel für die Verwendung von Konstanten wollen wir ein ConsoleProgram schreiben, das die Quadratzahlen der Zahlen von 0 bis MAX_NUM ausgibt, wo MAX_NUM eine Konstante sein soll die auf den Wert 10 gesetzt wird.</p>
<p>
<strong>SEP: Zauberzahlen (magic numbers): Zauberzahlen sind Zahlen die irgendwo in unserem Code auftauchen, und man hat meist keine Ahnung wo sie herkommen und was sie bedeuten. Deswegen sollten alle Zahlen ausser die 0, 1 und 2 als Konstanten deklariert werden.</strong></p>
<p>
.</p>
<h2>
<img alt="" src="images/evenodd.png" style="margin-left: 10px; margin-right: 10px; width: 200px; height: 100px; float: right;" />EvenOdd</h2>
<p>
Wir wollen ein kleines ConsoleProgram schreiben, dass die Zahlen von 0 bis 10 listet, daneben den Wert der Zahl % 2, und schließlich ob die Zahl gerade oder ungerade ist.</p>
<p>
.</p>
<p>
.</p>
<h2>
<img alt="" src="images/money.png" style="margin-left: 10px; margin-right: 10px; width: 200px; height: 100px; float: right;" />Money</h2>
<p>
Wenn wir in unseren Programmen mit Geld zu tun haben stellt sich zunächst die Frage sollen wir dafür einen <em>int</em> Datentyp oder einen <em>double</em> Datentyp verwenden? Die Antwort ist ganz einfach, wenn man sich die Frage stellt: kann man Geld zählen? Für alles was man zählen kann verwendet man den int Datentyp.</p>
<p>
Das heißt wenn wir mit Geld arbeiten sollten wir immer mit Cents rechnen. Allerdings wenn wir diese dann ausgeben, wäre es besser wenn wir nicht 120 Cents ausgeben würden sondern 1,20 Euro. Auch hier ist der Restwert Operator '%' von großem Nutzen:</p>
<pre>
int money = 120;
int euros = money / 100;
int cents = money % 100;
println("The amount is " + euros + "," + cents + " Euro.");
</pre>
<p>
Um sicher zu stellen, dass unser Code wirklich funktioniert, sollten wir verschiedene Eingaben ausprobieren. Gute Testkandidaten sind die Eingaben: 120, 90, 100, 102 und 002. Hat unser Programm immer die richtige Ausgabe zurückgegeben?</p>
<p>
.</p>
<h2>
<img alt="" src="images/bigmoney.png" style="margin-left: 10px; margin-right: 10px; width: 200px; height: 100px; float: right;" />BigMoney</h2>
<p>
Bei Beträgen über tausend Euro wird noch bei den Tausendern und auch bei den Millionen noch ein Punkt eingefügt, also z.B.: 1.001.233,45 Euro. Wir wollen also eine Methode <em>formatNumericString(int cent)</em> schreiben, die einen Geldbetrag in Cent als Übergabeparameter erhält, und einen String zurückliefert, der richtig formatiert ist. Wenn wir das Programm testen, sollten wir den obigen Betrag verwenden. Wir werden feststellen, dass es Sinn macht eine Methode <em>padWithZeros()</em> zu schreiben.</p>
<p>
Auch hier sollten wir verschiedene Eingaben testen, z.B. 100123345, 100123305, und 05.</p>
<p>
.</p>
<h2>
<img alt="" src="images/time.png" style="margin-left: 10px; margin-right: 10px; width: 200px; height: 100px; float: right;" />Time</h2>
<p>
Menschen bevorzugen es die Uhrzeit in Stunden, Minuten und Sekunden anzugeben. Computer hingegen denken nur in Sekunden, also Sekunden die seit Mitternacht vergangen sind. Deswegen wollen wir ein Programm schreiben, das aus den Sekunden die seit Mitternacht vergangen sind, die momentane Uhrzeit berechnet. Dazu benötigen wir wieder den Restwert Operator. Unter Umständen macht es auch wieder Sinn eine Methode <em>padWithZeros()</em> zu schreiben, die sicher stellt, dass anstelle von "6" Minuten "06" Minuten angezeigt werden. </p>
<p>
Zum Testen sollten wir mindestens die folgenden Eingaben ausprobieren: 5, 61, 85, 3600, 3601.</p>
<p>
.</p>
<h2>
<img alt="" src="images/leapYear.png" style="margin-left: 10px; margin-right: 10px; width: 200px; height: 100px; float: right;" />LeapYear</h2>
<p>
Wir haben ja oben gesehen wie man feststellt ob ein Jahr ein Schaltjahr ist. Mit diesem Wissen wollen wir ein Konsolenprogramm schreiben, das ausgibt, ob das Jahr in dem jemand geboren wurde ein Schaltjahr war. Z.B., sollte 1996, 2000, und 2004 ein Schaltjahr sein, 1900 und 2000 sollten aber keine sein.</p>
<p>
.</p>
<h2>
<img alt="" src="images/truuthTables.png" style="margin-left: 10px; margin-right: 10px; width: 200px; height: 100px; float: right;" />TruthTables*</h2>
<p>
In diesem Projekt wollen wir uns mit dem boolschen Datentyp und den logischen Operatoren && (und), || (oder) und ^ (exklusives oder) auseinandersetzen. Wir wollen dafür ein Programm schreiben, dass die Wahrheitstabellen für alle drei Operatoren berechnet und ausgibt. Evtl hilfreich ist der folgende Trick wie man aus einem <em>int</em> Datentyp einen <em>boolean</em> Datentyp erzeugt:</p>
<pre>
int in1 = 0;
boolean b1 = (in1 != 0);</pre>
<p>
.</p>
<h2>
<img alt="" src="images/menuProgram.png" style="margin-left: 10px; margin-right: 10px; width: 200px; height: 100px; float: right;" />InteractiveMenuProgram</h2>
<p>
Sehr häufig benötigt man in einem Konsolenprogramm eine Art Menu. Der Benutzer kann über die Eingabe einer Zahl zwischen verschiedenen Menupunkten auswählen. Wir wollen daher ein Programm schreiben, in dem der Benutzer zwischen drei Möglichkeiten auswählen kann: wenn er '0' eingibt, soll das Programm beendet werden, wenn er '1' eingibt soll eine Nachricht ausgegeben werden, und wenn er '2' eingibt soll gar nichts passieren. Als erste soll ihm natürlich mitgeteilt werden was seine Optionen sind:</p>
<pre>
println("0: Exit / 1: Print message / 2: Do nothing");</pre>
<p>
Dann beginnt ein 'Loop and a Half', also <span style="font-family:courier new,courier,monospace;">while (true)</span>. Wir fragen den Benutzer nach seiner Wahl</p>
<pre>
int choice = readInt("Your choice: ");</pre>
<p>
Wenn der Benutzer die '0' eingibt beenden wir den 'Loop and a Half'</p>
<pre>
if (choice == 0) break;</pre>
<p>
Danach folgt dann ein <em>switch</em> oder <em>cascading if</em> für die Wahlmöglichkeiten '1' und '2'.</p>
<p>
.</p>
<h2>
<img alt="" src="images/yearlyRate.png" style="margin-left: 10px; margin-right: 10px; width: 200px; height: 100px; float: right;" />YearlyRate</h2>
<p>
Karel will sich ein Auto kaufen, deswegen hat er angefangen zu sparen. Er will sich einen Mini kaufen (Mercedes ist zu teuer), und er hat einen gebrauchten für 5000 Euro gesehen. Er hat einen günstigen Kredit bei einer Bank von 5% pro Jahr gesehen. Wie hoch ist seine jährliche Rate, wenn er den Kredit in 5 Jahren abbezahlt haben will?</p>
<p>
Karel braucht also ein Programm bei dem er die Kreditsumme (k) eingeben kann, den Zinssatz (z) und die Laufzeit in Jahren (n). Das Programm soll ihm dann sagen wie hoch seine jährliche Rate (y) ist. Die Formel dafür kann man aus der Wikipedia unter Sparkassenformel nachsehen [2]:</p>
<pre>
double q = 1.0 + z;
double qn = Math.pow(q, n); // q^n
double y = k * qn * (q-1) / (qn-1);</pre>
<p>
Hilfreich zu wissen ist noch, dass man Gleitkommazahlen mit readDouble() einlesen kann.</p>
<p>
.</p>
<h2>
<img alt="" src="images/chess.png" style="margin-left: 10px; margin-right: 10px; width: 200px; height: 229px; float: right;" />ChessBoard</h2>
<p>
Wir wollen ein Schachbrettmuster mit Hilfe von GRects zeichnen. Natürlich muss das ein GraphicsProgram sein. Es ist eine schöne, aber nicht ganz leichte Anwendung von Schleifen und Restwertoperator '%'.</p>
<p>
.</p>
<hr />
<h1>
Fragen</h1>
<ol>
<li>
Nennen Sie vier der primitiven Datentypen von Java.<br />
</li>
<li>
Was ist eine Zauberzahl (magic number)?<br />
</li>
<li>
Was ist der Unterschied zwischen einem GraphicsProgram und einem ConsoleProgram?<br />
</li>
<li>
In der Vorlesung haben Sie von vielen Software Engineering Prinzipien gehört. Geben Sie drei Beispiele.<br />
</li>
<li>
Beim Programmieren gibt es einige typische Fehler die immer wieder passieren (Common Errors). Nennen Sie zwei dieser Fehler.<br />
</li>
<li>
Schreiben Sie ein ConsoleProgram, das den Benutzer nach der Radius eines Kreises fragt, und dann dessen Fläche berechnet (Fläche = PI * Radius * Radius) und diese auf der Console ausgibt.<br />
</li>
<li>
Was ist der Unterschied zwischen 'print("hi")' und 'println("hi")'?<br />
</li>
<li>
Was macht die 'readInt()' Methode?<br />
</li>
<li>
Was sind die Werte der Variablen 'x' und 'y' nachdem die folgenden drei Zeilen ausgeführt wurden?<br />
<span style="font-family:courier new,courier,monospace;">a = 6;<br />
x = ++­­a;<br />
y = x++;</span><br />
</li>
<li>
Was ist das Ergebnis der folgenden Ausdrücke:<br />
<span style="font-family:courier new,courier,monospace;">- int m = (int) 3.7688;<br />
- int n = 14 % 12;<br />
- int o = 4 + 5 * 3 / 2;</span><br />
</li>
<li>
Was ist das Resultat des folgenden Ausdrucks?<br />
<span style="font-family:courier new,courier,monospace;">int x = 3 - 3 * 6 / 4;</span><br />
</li>
<li>
Was ist der Unterschied zwischen<br />
a) 13 / 5<br />
b) 13 / 5.0<br />
</li>
<li>
Viele Programmierfehler rühren von fehlenden Klammern und/oder Leerzeichen. Die folgenden Beispiele sollen verdeutlichen, dass es einfacher ist Klammern zu setzen als die Operatorvorrangsregeln (rules of precedence) auswendig zu lernen.<br />
<br />
i) Was ist der Wert von 'j'?<br />
<span style="font-family:courier new,courier,monospace;">int i = 5;<br />
int j = i+++--i;</span><br />
<br />
ii) Was ist der Wert von 'y'?<br />
<span style="font-family:courier new,courier,monospace;">int y = 3 * 4 % 5 * 6 – 3;</span><br />
<br />
iii) Was ist der Wert von 'b'?<br />
<span style="font-family:courier new,courier,monospace;">int x = 5;<br />
int z = 3;<br />
boolean b = x != 5 || x < z == z < 3;</span><br />
</li>
<li>
Angenommen, Sie haben eine Varable x vom Typ int gegeben, also int x = 3;. Wie kann man diese in eine Variable namens y vom Typ double umwandeln (cast)?<br />
</li>
<li>
Beschreiben Sie mit Ihren eigenen Worten was der folgende Ausdruck bedeutet:<br />
<span style="font-family:courier new,courier,monospace;"> (x < 0) || (x > WIDTH)</span><br />
</li>
<li>
Was ist der Vorteil wenn man Konstanten verwendet?<br />
</li>
<li>
Vergleichen Sie die beiden 'switch' Beispiele unten, und beschreiben Sie ausgegeben wird.<br />
<span style="font-family:courier new,courier,monospace;">a) int day = 0;<br />
switch (day) {<br />
case 0:<br />
println("Sunday");<br />
break;<br />
case 6:<br />
println("Saturday");<br />
break;<br />
}</span><br />
<br />
<span style="font-family:courier new,courier,monospace;">b) int day = 0;<br />
switch (day) {<br />
case 0:<br />
println("Sunday");<br />
case 6:<br />
println("Saturday");<br />
}</span><br />
<br />
</li>
<li>
Welche Werte kann eine boolesche (boolean) Variable annehmen?<br />
</li>
<li>
Welchen Datentyp muss die Variable 'b' in dem Beispiel unten haben?<br />
<span style="font-family:courier new,courier,monospace;"> if ( b ) {<br />
println("hi");<br />
}</span><br />
</li>
<li>
Schreiben Sie den Test der feststellt, ob eine Zahl y ist durch 400 teilbar ist.<br />
</li>
<li>
Erinnern Sie sich an den Remainder ’%’ Operator? Geben Sie zwei Beispiele wofür man diesen gebrauchen kann.<br />
</li>
<li>
Menschen bevorzugen es Zeiten in Stunden, Minuten und Sekunden anzugeben. Computer bevorzugen es nur in Sekunden zu rechnen. So ist z.B. 13 Uhr 35 Minuten und 12 Sekunden für den Computer einfach 48912 Sekunden. Benutzen Sie dieses Wissen um die Computerzeit 't' in eine menschenlesbare Form, also Stunden, Minuten und Sekunden umzuwandeln. Sie dürfen auch mehrere Zwischenschritte verwenden.<br />
</li>
<li>
Wann sollte man eine for–Schleife und wann eine while–Schleife benutzen?<br />
</li>
<li>
Alles was man mit einer 'for' Schleife machen kann, kann man auch mit einer 'while' Schleife machen und umgekehrt. Schreiben Sie die folgende 'for' Schleife als 'while' Schleife um.<br />
<span style="font-family:courier new,courier,monospace;"> for (int i=0; i<5; i++) {<br />
println(i);<br />
}</span><br />
</li>
<li>
Beschreiben Sie den Aufbau des 'loop-and-a-half'. Welches Prolem löst dieser?<br />
</li>
<li>
Loop and a Half (Schleife und eine Halbe): Schreiben Sie das folgende Karel Beispiel mithilfe des Loop and a Half. Was ist der Vorteil des Loop and a Half?<br />
<span style="font-family:courier new,courier,monospace;"> public void run() {<br />
while ( frontIsClear() ) {<br />
putBeeper();<br />
}<br />
putBeeper();<br />
}</span></li>
</ol>
<p>
.</p>
<hr />
<h1>
Referenzen</h1>
<p>
Referenzen zu den Themen in diesem Kapitel finden sich in praktisch jedem Buch zu Java, insbesondere natürlich auch in [3].</p>
<p>
[1] Jeliot 3, Program Visualization application, University of Helsinki, <a href="http://cs.joensuu.fi/jeliot/description.php">cs.joensuu.fi/jeliot/description.php</a></p>
<p>
[2] Seite „Sparkassenformel“. In: Wikipedia, Die freie Enzyklopädie. URL: <a href="https://de.wikipedia.org/w/index.php?title=Sparkassenformel&oldid=143971427">https://de.wikipedia.org/w/index.php?title=Sparkassenformel&oldid=143971427</a></p>
<p>
[3] The Art and Science of Java, von Eric Roberts, Addison-Wesley, 2008</p>
<p>
.</p>
<p class="footer">
Copyright © 2016-2021 <a href="http://www.lano.de">Ralph P. Lano</a>. All rights reserved.
</p>
</div>
</center>
</div>
</body>
</html>