Στο τέλος του πίνακα περιεχομένων υπάρχουν σε μορφή κατάλληλη για εκτύπωση
Βιβλία του μαθήματος
Θα διανεμηθούν τα βιβλία:
Ε. Α. Παπαθανασίου. Στοιχεία Υπολογιστικών Συστημάτων. Εκδόσεις Ευγ. Μπένου, Αθήνα 1998.
Γ. Λιακέας. Εισαγωγή στην Java. Κλειδάριθμος, Αθήνα, 2000.
'Αλλα βιβλία σχετικά με το μάθημα είναι:
Η. Λυπιτάκης, Ο σύγχρονος κόσμος των Υπολογιστών. Λυπιτάκης, 1997.
Μ. Μπεκάκος Εισαγωγή στην πληροφορική. Οικονομικό Πανεπιστήμιο Αθηνών, 1998.
L. Goldschlager and A. Lister. Εισαγωγή στη σύγχρονη επιστήμη των υπολογιστών. Διάυλος, 1994.
Peter Rechenberg. Εισαγωγή στην Πληροφορική. Κλειδάριθμος, 1992.
K. N. King. Java Programming: From the Beginning. W.W. Norton & Company, 2000.
Ron White, Timothy Downs, Stephen Adams. How Computers Work. 5th edition, Que, 1999.
J. Glenn Brookshear. Computer Science: an overview. 8th edition. Addison Wesley Longman, 2004.
Βαθμολογία
Ο τελικός βαθμός κάθε φοιτητή θα βασίζεται σε 2 κριτήρια:
Στην απόδοση του στις υποχρεωτικές ασκήσεις
Στις τελικές γραπτές εξετάσεις
Απαραίτητη προϋπόθεση για να περάσει ο φοιτητής το μάθημα είναι η απόδοσή του σε κάθε κατηγορία να καλύπτει τουλάχιστον τη βάση.
Η συμμετοχή κάθε κριτηρίου στη διαμόρφωση του τελικού βαθμού είναι περίπου ως εξής:
Πόσοι ηλεκτρονικοί υπολογιστές υπάρχουν στο Πανεπιστήμιο;
Πως χρησιμοποιούνται;
(Μην ξεχάσετε τους υπολογιστές που αποτελούν τμήματα συσκευών ή
ολοκληρωμένων εφαρμογών.)
Ποιά είναι η σχέση της πληροφορικής με τη διοικητική επιστήμη;
Ποιά είναι η σχέση της διοικητικής επιστήμης με την πληροφορική;
Πως συνδέονται οι εφαρμογές της πληροφορικής με την παραγωγικότητα
και την ανεργία;
Ελληνικό άλφα πεζό με τόνο (ά) 940
Ελληνικό ωμέγα κεφαλαίο (Ω) 937
Αραβικό γράμμα SEEN μόνο 65201
Αραβικό γράμμα SEEN αρχικό 65202
Αραβικό γράμμα SEEN μέσο 65203
Αραβικό γράμμα SEEN τελικό 65204
Παράσταση των χαρακτήρων "HELLO, WORLD! ABCDEFGHIJKLM 0123456789"
σε διάτρητη κάρτα.
Παράσταση των χαρακτήρων "HELLO, WORLD! ABCDEFGHIJKLM 0123456789"
σε διάτρητη ταινία.
___________
| o o. |
| o .o o|
| o o.o |
| o o.o |
| o o.ooo|
| o o.o |
| o . |
| o o .ooo|
| o o.ooo|
| o o . o |
| o o.o |
| o .o |
| o . o|
| o . |
| o . o|
| o . o |
| o . oo|
| o .o |
| o .o o|
| o .oo |
| o .ooo|
| o o. |
| o o. o|
| o o. o |
| o o. oo|
| o o.o |
| o o.o o|
| o . |
| oo . |
| oo . o|
| oo . o |
| oo . oo|
| oo .o |
| oo .o o|
| oo .oo |
| oo .ooo|
| ooo. |
| ooo. o|
___________
Διαιρούμε διαδοχικά με το 2 και γράφουμε τα υπόλοιπα από δεξιά προς τα αριστερά.
Για ευκολία συχνά παριστάνουμε τετράδες ψηφίων του δυαδικού συστήματος στο
δεκαεξαδικό (hexadecimal)
σύστημα (με βάση το 16) σύμφωνα με τον παρακάτω πίνακα:
Ν16
Ν2
0
0000
1
0001
2
0010
3
0011
4
0100
5
0101
6
0110
7
0111
8
1000
9
1001
A
1010
B
1011
C
1100
D
1101
E
1110
F
1111
Παράδειγμα:
FOOD16 = 1111 0000 0000 11012
Πρόσθεση και πολλαπλασιασμός
Πρόσθεση
Ψηφίο 1
Ψηφίο 2
'Aθροισμα
Κρατούμενο
0
0
0
0
0
1
1
0
1
0
1
0
1
1
0
1
Παράδειγμα:
1110
+10111
------
100101
Δηλαδή
11102 + 101112 = 1001012 ή
1410 + 2310 = 3710
Πολλαπλασιασμός
Παράδειγμα:
1011
X 11
------
1011
+1011
------
100001
Δηλαδή
10112 + 112 = 1000012 ή
1110 + 310 = 3310
Αρνητικοί αριθμοί και αφαίρεση
Αφαίρεση με το μέθοδο του συμπληρώματος
Παράδειγμα 1
X = 4 - 3 <=>
X + 10 = 4 + (10 - 3) <=>
X + 10 = 4 + 7 <=>
X = 4 + 7 - 10 <=>
X = 11 - 10 <=>
X = 1
Παράδειγμα 2
X = 45 - 23 <=>
X + 100 = 45 + (100 - 23) <=>
X + 100 = 45 + 77 <=>
X = 45 + 77 - 100 <=>
X = 122 - 100 <=>
X = 22
Η εύρεση του
συμπληρώματος (complement)
ως προς ένα ΒN (π.χ. 10 - 3 ή 100 - 23)
και η απαλειφή του όρου ΒN στο τέλος είναι πράξεις εύκολες.
Αν θεωρήσουμε πως όλοι οι αριθμοί μας είναι μικρότεροι από ΒN/2
και στο τέλος κάθε πράξης απαλείφουμε τον όποιο όρο ΒN
τότε μπορούμε να παριστάνουμε τους αρνητικούς αριθμούς ως θετικούς
με βάση το συμπλήρωμά τους από το ΒN
(π.χ. το -3 ως 7 για ΒN = 101 ή
το -23 ως 77 για ΒN = 102)
και να κάνουμε πρόσθεση αντί για αφαίρεση.
Εύρεση του συμπληρώματος στο δυαδικό σύστημα
Παράδειγμα για τον αριθμό 01002 και ΒN = 24
(100002):
10000
-0100
-----
1100
Στο δυαδικό σύστημα το αποτέλεσμα της αφαίρεσης του αριθμού Α από το
ΒN (δηλαδή η παράσταση του -Α με το μέθοδο του συμπληρώματος)
μπορεί να υπολογιστεί εύκολα με δύο ισοδύναμους τρόπους:
Αντιστρέφουμε τα 0 σε 1 και 1 σε 0 και προσθέτουμε 1:
0100 -> 1011
1011 + 1 = 1100
Αντιγράφουμε από δεξιά προς τα αριστερά όλα τα 0 και το πρώτο 1 και
αντιστρέφουμε τα υπόλοιπα 0 σε 1 και 1 σε 0:
Ο τρόπος παράστασης του αριθμού κινητής υποδιαστολής μπορεί να διαφέρει
σε πολλά σημεία από υπολογιστή σε υπολογιστή
(μήκος σημαινόμενου και εκθέτη, παράσταση αρνητικού σημαινόμενου και εκθέτη,
κανονικοποίηση του σημαινόμενου).
Σήμερα οι περισσότεροι υπολογιστές παριστάνουν τους αριθμούς κινητής υποδιαστολής σύμφωνα με το πρότυπο IEEE-488.
Για αριθμούς διπλής ακρίβειας π.χ.
H τιμή του Β είναι 2.
Το πρόσημο του αριθμού παριστάνεται από ένα ξεχωριστό bit
Ο εκθέτης καταλαμβάνει 11 bit
Το σημαινόμενο τμήμα καταλαμβάνει 52 bit
Ο εκθέτης φυλάσσεται αυξημένος κατά 1023 για να παριστάνονται
και να συγκρίνονται εύκολα αριθμοί με αρνητικό εκθέτη
Το πρώτο bit του σημαινόμενου τμήματος που είναι 1
παραλείπεται και υπονοείται.
Για παράδειγμα το π στο δυαδικό σύστημα εφράζεται ως:
11.0010 0100 0011 1111 0110 1010 1000 1000 1000 0101 1010 0011 0000 10....
και στο πρότυπο ΙΕΕΕ-488
με εκθέτη 1 (που παριστάνεται ως 1024) ως:
0C75:0000 0E PUSH CS
0C75:0001 1F POP DS
0C75:0002 BA0E00 MOV DX,000E
0C75:0005 B409 MOV AH,09
0C75:0007 CD21 INT 21
0C75:0009 B8014C MOV AX,4C01
0C75:000C CD21 INT 21
Πηγαίος κώδικας
// Draw the circle and numbers
g.setFont(clockFaceFont);
g.setColor(handColor);
circle(xcenter,ycenter,50,g);
g.setColor(numberColor);
g.drawString("9",xcenter-45,ycenter+3);
g.drawString("3",xcenter+40,ycenter+3);
g.drawString("12",xcenter-5,ycenter-37);
g.drawString("6",xcenter-3,ycenter+45);
W. Buchholz.
Fingers or fists.
Communications of the ACM, (2):3–11, December 1959.
Robert G. Burger and
R. Kent Dybvig.
Printing floating-point numbers quickly and accurately.
ACM SIGPLAN Notices, 31(5):108–116, May 1996.
ACM SIGPLAN '96 Conference on Programming Language Design and Implementation.
William D. Clinger.
How to read floating-point numbers accurately.
ACM SIGPLAN Notices, 25(6):92–101, 1990.
ACM SIGPLAN '90 Conference on Programming Language Design and Implementation.
IEEE standard for binary
floating-point arithmetic.
Published by the Institute of Electrical and Electronics Engineers, 1985.
ANSI/IEEE Std 754-1995).
Μετατρέψτε τους αριθμούς 15, -7 και 24 σε δυαδικό σύστημα 4 bit.
Μετατρέψτε τους αριθμούς 1010 και 0101 από παράσταση 4 bit (με
αρνητικούς) στο δεκαδικό σύστημα.
Υπολογίστε 01101 + 01111. Μετατρέψτε τα στοιχεία και σε δεκαδικό σύστημα.
Υπολογίστε 11010 + 11011.
Θεωρήστε πως οι αριθμοί παριστάνουν αρνητικούς αριθμούς με τη
μέθοδο του συμπληρώματος.
Μετατρέψτε τα στοιχεία και σε δεκαδικό σύστημα.
Υπολογίστε 1101 - 1. Μετατρέψτε τα στοιχεία και σε δεκαδικό σύστημα.
Εκτελέστε την πράξη 12 - 7 στο δυαδικό σύστημα παριστάνοντας τον
αρνητικό αριθμό με τη μέθοδο του συμπληρώματος.
Υπολογίστε 1010 * 101.
Εκτιμήστε (σε βήματα) το χρόνο που απαιτεί ο πολλαπλασιασμός
σε σχέση με την πρόσθεση σε έναν ηλεκτρονικό υπολογιστή. Μπορεί να
υπάρξει τρόπος ο πολλαπλασιασμός να εκτελεστεί ταχύτερα;
Η πρόσθεση;
Μετατρέψτε τους αριθμούς 53, -543 από το οκταδικό σύστημα στο δεκαεξαδικό.
Εκφράστε τον αριθμό 262150 στο δυαδικό σύστημα.
Με πόσα bit μπορεί να παρασταθεί ως βάση και εκθέτης του 2;
Τι παριστάνουν οι παρακάτω δεκαεξαδικοί αριθμοί ως χαρακτήρες ASCII;
22 41 74 68 65 6e 73 20 55 6e 69 76 65 72 73 69
74 79 20 6f 66 20 45 63 6f 6e 6f 6d 69 63 73 20
61 6e 64 20 42 75 73 69 6e 65 73 73 22 20 0d 0a
Η μουσική σε CD ήχου αποθηκεύεται με ρυθμό 44.100 δείγματα των 16 bit ανά
κανάλι ήχου και δευτερόλεπτο.
Πόσος χώρος χρειάζεται για να αποθηκευτεί στερεοφωνική μουσική
(δύο κανάλια ήχου) διάρκειας 74 λεπτών;
Συμπιέστε την παρακάτω ακολουθία με βάση τις διαφορές ανάμεσα στους
αριθμούς.
Πόσα bit χρειάζονται για την ασυμπίεστη ακολουθία και πόσα για τη
συμπισμένη;
2
5
9
12
15
20
22
18
13
7
Με βάση τον πίνακα παράστασης χαρακτήρων που επιτρέπει τη διόρθωση
Ο παρακάτω πίνακας εμφανίζει τους χαρακτήρες του πίνακα
ASCII που μπορούν να εμφανιστούν στην οθόνη μαζί με την
τιμή τους σε δεκαεξαδικό σύστημα και την αντίστοιχη περιγραφή.
20 Space
! 21 Exclamation mark
" 22 Quotation mark
# 23 Number sign
$ 24 Dollar sign
% 25 Percent sign
& 26 Ampersand
' 27 Apostrophe
( 28 Left parenthesis
) 29 Right parenthesis
* 2a Asterisk
+ 2b Plus sign
, 2c Comma
- 2d Hyphen-minus
. 2e Full stop
/ 2f Solidus
0 30 Digit zero
1 31 Digit one
2 32 Digit two
3 33 Digit three
4 34 Digit four
5 35 Digit five
6 36 Digit six
7 37 Digit seven
8 38 Digit eight
9 39 Digit nine
: 3a Colon
; 3b Semicolon
< 3c Less-than sign
= 3d Equals sign
> 3e Greater-than sign
? 3f Question mark
@ 40 Commercial at (papaki)
A 41 Latin capital letter a
B 42 Latin capital letter b
C 43 Latin capital letter c
D 44 Latin capital letter d
E 45 Latin capital letter e
F 46 Latin capital letter f
G 47 Latin capital letter g
H 48 Latin capital letter h
I 49 Latin capital letter i
J 4a Latin capital letter j
K 4b Latin capital letter k
L 4c Latin capital letter l
M 4d Latin capital letter m
N 4e Latin capital letter n
O 4f Latin capital letter o
P 50 Latin capital letter p
Q 51 Latin capital letter q
R 52 Latin capital letter r
S 53 Latin capital letter s
T 54 Latin capital letter t
U 55 Latin capital letter u
V 56 Latin capital letter v
W 57 Latin capital letter w
X 58 Latin capital letter x
Y 59 Latin capital letter y
Z 5a Latin capital letter z
[ 5b Left square bracket
\ 5c Reverse solidus
] 5d Right square bracket
' 5e Circumflex accent
_ 5f Low line
` 60 Grave accent
a 61 Latin small letter a
b 62 Latin small letter b
c 63 Latin small letter c
d 64 Latin small letter d
e 65 Latin small letter e
f 66 Latin small letter f
g 67 Latin small letter g
h 68 Latin small letter h
i 69 Latin small letter i
j 6a Latin small letter j
k 6b Latin small letter k
l 6c Latin small letter l
m 6d Latin small letter m
n 6e Latin small letter n
o 6f Latin small letter o
p 70 Latin small letter p
q 71 Latin small letter q
r 72 Latin small letter r
s 73 Latin small letter s
t 74 Latin small letter t
u 75 Latin small letter u
v 76 Latin small letter v
w 77 Latin small letter w
x 78 Latin small letter x
y 79 Latin small letter y
z 7a Latin small letter z
{ 7b Left curly bracket
| 7c Vertical line
} 7d Right curly bracket
~ 7e Tilde
Παράρτημα: οι νεοελληνικοί χαρακτήρες στο πρότυπο Unicode
Ο παρακάτω πίνακας εμφανίζει τους νεοελληνικούς
χαρακτήρες στο πρότυπο κωδικοποίησης Unicode
μαζί με την τιμή τους σε δεκαεξαδικό σύστημα και την αντίστοιχη περιγραφή.
'Α 0386 Capital alpha with acute
Έ 0388 Capital epsilon with acute
Ή 0389 Capital eta with acute
Ί 038a Capital iota with acute
Ό 038c Capital omicron with acute
Ύ 038e Capital upsilon with acute
Ώ 038f Capital omega with acute
ΐ 0390 Small iota with acute and diaeresis
Α 0391 Capital alpha
Β 0392 Capital beta
Γ 0393 Capital gamma
Δ 0394 Capital delta
Ε 0395 Capital epsilon
Ζ 0396 Capital zeta
Η 0397 Capital eta
Θ 0398 Capital theta
Ι 0399 Capital iota
Κ 039a Capital kappa
Λ 039b Capital lamda
Μ 039c Capital mu
Ν 039d Capital nu
Ξ 039e Capital xi
Ο 039f Capital omicron
Π 03a0 Capital pi
Ρ 03a1 Capital rho
Σ 03a3 Capital sigma
Τ 03a4 Capital tau
Υ 03a5 Capital upsilon
Φ 03a6 Capital phi
Χ 03a7 Capital chi
Ψ 03a8 Capital psi
Ω 03a9 Capital omega
ϊ 03aa Capital iota with diaeresis
ϋ 03ab Capital upsilon with diaeresis
ά 03ac Small alpha with acute
έ 03ad Small epsilon with acute
ή 03ae Small eta with acute
ί 03af Small iota with acute
ΰ 03b0 Small upsilon with acute and diaeresis
α 03b1 Small alpha
β 03b2 Small beta
γ 03b3 Small gamma
δ 03b4 Small delta
ε 03b5 Small epsilon
ζ 03b6 Small zeta
η 03b7 Small eta
θ 03b8 Small theta
ι 03b9 Small iota
κ 03ba Small kappa
λ 03bb Small lamda
μ 03bc Small mu
ν 03bd Small nu
ξ 03be Small xi
ο 03bf Small omicron
π 03c0 Small pi
ρ 03c1 Small rho
ς 03c2 Small final sigma
σ 03c3 Small sigma
υ 03c4 Small tau
υ 03c5 Small upsilon
φ 03c6 Small phi
χ 03c7 Small chi
ψ 03c8 Small psi
ω 03c9 Small omega
ϊ 03ca Small iota with diaeresis
ϋ 03cb Small upsilon with diaeresis
ό 03cc Small omicron with acute
ύ 03cd Small upsilon with acute
ώ 03ce Small omega with acute
Δομικά στοιχεία υπολογιστών
Λογικές πύλες
Πύλη άρνησης (NOT) Y = !A
A
Y
0
1
1
0
Πύλη σύζευξης (AND) Y = A && B
A
B
Y
0
0
0
0
1
0
1
0
0
1
1
1
Πύλη διάζευξης (OR) Y = A || B
A
B
Y
0
0
0
0
1
1
1
0
1
1
1
1
Πύλη αποκλειστικής διάζευξης (XOR) Y = A ^ B
A
B
Y
0
0
0
0
1
1
1
0
1
1
1
0
Μερικές φορές θα συναντήσετε και παλαιότερα σύμβολα για τις ίδιες πύλες
όπως αυτά που απεικονίζονται στο διάγραμμα που ακολουθεί:
Αθροιστές
Με βάση τις πύλες μπορούν να κατασκευστούν κυκλώματα που κάνουν
υπολογισμούς.
Η ΚΜΕ διαβάζει δεδομένα και εκτελεί εντολές από την κεντρική μνήμη του
υπολογιστή.
Υπάρχουν ΚΜΕ που περιέχουν και άλλα στοιχεία όπως μονάδες
εισόδου / εξόδου για να επιτρέψουν την υλοποίηση υπολογιστών με λίγα
δομικά στοιχεία.
Οι πιο εξειδικευμένες από αυτές λέγονται
μικροελεγκτές (microcontrolers).
Διάγραμμα εσωτερικής δομής και εξωτερικής επικοινωνίας του επεξεργαστή
16 bit (υψηλής ολοκλήρωσης για ενσωματωμένες εφαρμογές) 80186.
Σχεδιάστε με τη χρήση πυλών NAND (Negative AND) τις παρακάτω πύλες:
AND
OR
NOT
Σχεδιάστε έναν αθροιστή 2 bit.
Πόσες πύλες AND, OR, NOT χρειάζονται για την κατασκευή ενός αθροιστή
32 bit;
Αν για την κατασκευή κάθε πύλης AND και OR χρειάζονται δύο τρανζίστορ και
για κάθε πύλη NOT ένα, πόσα τρανζίστορ χρειάζονται για την
κατασκευή του αθροιστή 32 bit;
Σχεδιάστε με τη βοήθεια δισταθών κυκλωμάτων έναν μετρητή 3 bit.
Ο επεξεργαστής Alpha DECchip 21064 περιέχει 1.680.000 τρανζίστορ
σε chip διαστάσεων 1.4 x 1.7 cm.
Υπολογίστε κατά προσέγγιση τις διαστάσεις ενός τρανζίστορ.
Dawson R. Engler and
Wilson C. Hsieh.
DERIVE: A tool that automatically reverse-engineers instruction encodings.
In Proceedings of the ACM SIGPLAN Workshop on Dynamic and Adaptive
Compilation and Optimization (Dynamo '00), pages 12–22. ACM Press,
July 2000.
ACM SIGPLAN Notices 35(7).
Free Software Foundation.
Using as, 1999.
http://www.gnu.org/manual/gas-2.9.1/.
John L. Hennessy
and David A. Patterson.
Computer Architecture: A Quantitative Approach, pages 89–197.
Morgan Kaufmann Publishers, second edition, 1996.
Γράψτε σε συμβολική γλώσσα σειρά εντολών που να θέτουν τις διευθύνσεις
από 1000 - 2000 σε 0.
Γράψτε σε συμβολική γλώσσα σειρά εντολών που να αποθηκεύουν στις
διευθύνσεις από 1000 - 1200 τους άρτιους αριθμούς από 0 - 400.
Γράψτε σε συμβολική γλώσσα σειρά εντολών που να μεταφέρουν τα
περιεχόμενα των διευθύνσεων από 1000 - 2000 στην περιοχή 4000.
Υπολογίστε πόσες εντολές θα εκτελεστούν για την παραπάνω διαδικασία.
Αν ο υπολογιστής εργάζεται με ρολόι 1.5GHz και εκτελεί μια εντολή
κάθε δύο κύκλους του ρολογιού σε πόσο χρόνο θα εκτελεστεί η παραπάνω
διαδικασία;
Περιγράψτε πως εκτελείται από την ΚΜΕ η εντολή SUB [1234+BX+SI], CX.
Εργαστηριακές ασκήσεις
1. Αθροίζοντας αριθμούς
Ανοίξτε παράθυρο εντολών (run - command) ή φορτώστε το λειτουργικό σύστημα MS-DOS
Δώστε την εντολή debug
C:>debug
Δώστε την εντολή Α (assemble)
-a
Γράψτε τις συμβολικές εντολές (mov ax, 0) κλπ.
Οι διευθύνσεις μνήμης εμφανίζονται μόνες τους.
Τα σχόλια που ακολουθούν το ; δε χρειάζεται να γραφούν.
0C20:0100 mov ax,0 ; Βάλε (move) στον καταχωρητή ΑΧ την τιμή 0
0C20:0103 mov bx,0 ; Βάλε (move) στον καταχωρητή ΒΧ την τιμή 0
0C20:0106 add bx, ax ; Πρόσθεσε στον ΒΧ τον ΑΧ
0C20:0108 inc ax ; Αύξησε (increment) τον ΑΧ κατά 1
0C20:0109 cmp ax, a ; Σύγκρινε (compare) τον ΑΧ με το 10
0C20:010C jbe 106 ; 'Αλμα αν το αποτέλεσμα είναι μικρότερο ή ίσο (jump below or equal) στη διεύθυνση 106
0C20:010E int 3 ; Διακοπή της λειτουργίας
0C20:010F ; Πατήστε ENTER εδώ
Δείτε την κωδικοποίηση των εντολών με την εντολή U (unassemble):
Εκτελέστε το πρόγραμμά σας και εξετάστε το αποτέλεσμα στον καταχωρητή ΒΧ.
Είναι αυτό που περιμένατε;
-g=100
AX=000B BX=0037 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0C20 ES=0C20 SS=0C20 CS=0C20 IP=010E NV UP EI PL NZ NA PO NC
0C20:010E CC INT 3
Εκτελέστε το πρόγραμμά σας βήμα βήμα με την εντολή T (trace):
-t=100
AX=0000 BX=0000 CX=0000 DX=0080 SP=FFEE BP=0000 SI=0000 DI=0000
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Καταχωρητές
DS=0C1C ES=0C1C SS=0C1C CS=0C1C IP=0103 NV UP EI PL ZR NA PE NC
^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^
| Ενδείκτες διακλάδωσης
Μετρητής προγράμματος
0C1C:0103 BB0000 MOV BX,0000
^^^^ ^^^^^^^^^^^^^^^
Διεύθυνση μνήμης Επόμενη εντολή που θα εκτελεστεί
-t
AX=0000 BX=0000 CX=0000 DX=0080 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0C1C ES=0C1C SS=0C1C CS=0C1C IP=0106 NV UP EI PL ZR NA PE NC
0C1C:0106 01D8 ADD AX,BX
-t
AX=0000 BX=0000 CX=0000 DX=0080 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0C1C ES=0C1C SS=0C1C CS=0C1C IP=0108 NV UP EI PL ZR NA PE NC
0C1C:0108 40 INC AX
-t
AX=0001 BX=0000 CX=0000 DX=0080 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0C1C ES=0C1C SS=0C1C CS=0C1C IP=0109 NV UP EI PL NZ NA PO NC
0C1C:0109 3D0A00 CMP AX,000A
-t
AX=0001 BX=0000 CX=0000 DX=0080 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0C1C ES=0C1C SS=0C1C CS=0C1C IP=010C NV UP EI NG NZ AC PO CY
0C1C:010C 76F8 JBE 0106
-t
AX=0001 BX=0000 CX=0000 DX=0080 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0C1C ES=0C1C SS=0C1C CS=0C1C IP=0106 NV UP EI NG NZ AC PO CY
0C1C:0106 01D8 ADD AX,BX
...
Αυξήστε το όριο της άθροισης από 10 σε 100:
-a109
0C20:0109 cmp ax, 64 ; Σύγκρινε τον καταχωρητή ΑΧ με το 100
0C20:010C ; Πατήστε ENTER εδώ
-g=100
Εκτελέστε το πρόγραμμά σας και εξετάστε το αποτέλεσμα στον καταχωρητή ΒΧ.
Είναι αυτό που περιμένατε;
AX=0065 BX=13BA CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0C20 ES=0C20 SS=0C20 CS=0C20 IP=010E NV UP EI PL NZ NA PO NC
0C20:010E CC INT 3
Βγήτε από το πρόγραμμα debug
-q
C:>
2. Εμφάνιση των χαρακτήρων του πίνακα ASCII
Γράψτε το πρόγραμμα:
C:\>debug
-a
0C1C:0100 mov dl,20 ; Πρώτος χαρακτήρας ASCII (το κενό)
0C1C:0102 mov ah,2 ; Εντολή για εμφάνιση του χαρακτήρα στην οθόνη
0C1C:0104 int 21 ; Εκτέλεση της εντολής του DOS
0C1C:0106 add dl,1 ; Αύξησε το χαρακτήρα κατά 1
0C1C:0109 cmp dl,80 ; Είναι ο τελευταίος; (128)
0C1C:010C jne 102 ; Αν όχι πήγαινε στη διεύθυνση 102 (jump not equal)
0C1C:010E int 3 ; Διακοπή του προγράμματος
0C1C:010F ; Πατήστε ENTER εδώ
Δείτε την κωδικοποίηση των εντολών με την εντολή U (unassemble):
-u100
0C1C:0100 B220 MOV DL,20
0C1C:0102 B402 MOV AH,02
0C1C:0104 CD21 INT 21
0C1C:0106 80C201 ADD DL,01
0C1C:0109 80FA80 CMP DL,80
0C1C:010C 75F4 JNZ 0102
0C1C:010E CC INT 3
Εκτελέστε το πρόγραμμά σας και δείτε το αποτέλεσμα στην οθόνη σας.
-g=100
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmno
pqrstuvwxyz{|}~¦
AX=027F BX=0000 CX=0000 DX=0080 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0C1C ES=0C1C SS=0C1C CS=0C1C IP=010E NV UP EI PL ZR NA PE NC
0C1C:010E CC INT 3
3. Συνεχίζοντας
Δοκιμάστε να γράψετε και να εκτελέσετε και άλλα μικρά προγράμματα ή
παραλλαγές αυτών που γράψατε.
Ο τρόπος που θα εκτελεστούν οι παραπάνω εντολές από την ΚΜΕ
σύμφωνα με το κύκλο των εντολών είναι ο εξής:
0100 B80100 MOV AX,0001
ΜΠ
ΚΔιΜ
ΚΔεΜ
ΚΕ
ΑΧ
Α
B
Γ
Ανάκληση
100
100
-
B80100
-
-
-
-
Αποκωδικοποίηση
103
100
-
B80100
-
0001
-
-
Εκτέλεση
103
100
-
B80100
-
0001
-
0001
Εγγραφή
103
100
-
B80100
0001
0001
-
0001
0103 050400 ADD AX,0004
ΜΠ
ΚΔιΜ
ΚΔεΜ
ΚΕ
ΑΧ
Α
B
Γ
Ανάκληση
103
103
-
050400
0001
-
-
-
Αποκωδικοποίηση
106
103
-
050400
0001
0001
0004
-
Εκτέλεση
106
103
-
050400
0001
0001
0004
0005
Εγγραφή
106
103
-
050400
0005
0001
0004
0005
0106 A31000 MOV [0010],AX
ΜΠ
ΚΔιΜ
ΚΔεΜ
ΚΕ
ΑΧ
Α
B
Γ
Ανάκληση
106
106
-
A31000
0005
-
-
-
Αποκωδικοποίηση
109
106
-
A31000
0005
0000
0010
-
Εκτέλεση
109
0010
0005
A31000
0005
0000
0010
0010
Πρόσβαση μνήμης
109
0010
0005
A31000
0005
0000
0010
0010
0109 3D0500 CMP AX,0005
ΜΠ
ΚΔιΜ
ΚΔεΜ
ΚΕ
ΑΧ
Α
B
Γ
Ανάκληση
109
109
-
3D0500
0005
-
-
-
Αποκωδικοποίηση
10C
109
-
3D0500
0005
0005
0005
-
Εκτέλεση
10C
109
-
3D0500
0005
0005
0005
0000
010C 74F2 JZ 0100
ΜΠ
ΚΔιΜ
ΚΔεΜ
ΚΕ
ΑΧ
Α
B
Γ
Ανάκληση
10C
10C
-
74F2
0005
-
-
-
Αποκωδικοποίηση
10E
10C
-
74F2
0005
010E
FFF2
-
Εκτέλεση
10E
10C
0005
74F2
0005
010E
FFF2
0100
Πρόσβαση μνήμης
100
10C
0005
74F2
0005
010E
FFF2
0010
Λειτουργικά συστήματα
Ορισμός και λειτουργίες
Το λειτουργικό σύστημα (operating system)
είναι το βασικό πρόγραμμα συστήματος ενός ηλεκτρονικού υπολογιστή.
Ελέγχει τη διαχείριση των πόρων του υπολογιστή και θέτει τα θεμέλεια
για τη λειτουργία των προγραμμάτων εφαρμογών.
Το λειτουργικό σύστημα ως ένας ανώτερος υπολογιστής.
Συζητήστε πως (και αν) παρέχονται και υλοποιούνται τα παρακάτω στοιχεία
στο λειτουργικό συστήμα Windows 2000 καθώς και στο λειτουργικό σύστημα
ενός απλού κινητού τηλεφώνου:
Το επίπεδο εφαρμογής στο Internet καλύπτει τα επίπεδα
εφαρμογής και παρουσίασης του OSI.
Τα πιο συχνά πρωτόκολλα που χρησιμοποιούνται από τους
χρήστες είναι:
Telnet
χρήση από απόσταση
FTP
μεταφορά αρχείων
SMTP
μεταφορά email
POP/IMAP
ανάγνωση email
HTTP/HTML
πρόσβαση στο Web
Μια σειρά από πρωτόκολλα στο επίπεδο αυτό υποστηρίζουν τη λειτουργία και
τη διαχείριση του δικτύου:
DNS
Κατανεμημένος κατάλογος ονομάτων
SNMP
Διαχείριση από απόσταση
BOOTP
Αρχικό φόρτωμα κώδικα
RARP
Αντίστροφη μετατροπή διευθύνσεων
Μεταφορά
Στο επίπεδο της μεταφοράς χρησιμοποιούνται δύο πρωτόκολλα:
TCP
Transmission Control Protocol
UDP
User Datagram Protoco
Δίκτυο
Στο επίπεδο του δικτύου το Internet Protocol (IP) μαζί με το
Internet Control Message Protocol εξασφαλίζουν τη μεταφορά δεδομένων
από τον αποστολέα στον παραλήπτη.
Το παρακάτω σχήμα παριστάνει τη σχέση ανάμεσα στα διάφορα πρωτόκολλα
του internet:
Οι διευθύνσεις αποστολέα και παραλήπτη περιγράφονται με 32 bit
που παριστάνονται για ευκολία με 4 δεκαδικούς αριθμούς (π.χ. 192.168.135.4).
Ένας αρχικός αριθμός από bit (π.χ. 24) παριστάνει το δίκτυο στο οποίο
ανήκει ένας συγκεκρικένος υπολογιστής, ενώ τα υπόλοιπα ξεχωρίζουν τον
υπολογιστή από τους υπόλοιπους στο ίδιο δίκτυο.
TCP
Το πρωτόκολλο TCP (Transmission Control Protocol) επιτρέπει τη σύνδεση
δύο διεργασιών και τη μεταξύ τους επικοινωνία.
Το TCP θεωρεί ότι το δίκτυο στο οποίο βασίζεται παρέχει τη δυνατότητα μεταφοράς
πακέτων χωρίς εγγυήσεις σχετικά με τη σειρά που θα παραδοθούν,
την απώλεια πακέτων ή τη διπλή παράδοσή τους.
Πάνω από ένα τέτοιο δίκτυο το TCP παρέχει αξιόπιστη μεταφορά δεδομένων.
Οι βασικές υπηρεσίες που παρέχει το TCP είναι οι παρακάτω:
Μεταφορά δεδομένων
Αξιοπιστία
Έλεγχο ροής
Πολυπλεξία
Συνδέσεις
Προτεραιότητα
Η μορφή της επικεφαλίδας του TCP είναι η παρακάτω:
Παραπομπές σε άλλες σελίδες ή περιεχόμενο γίνονται με την
τυποποιημένη χρήση των Uniform Resource Locators (URL).
Τόσο ο πελάτης, όσο και ο υπηρέτης μπορούν να προσαρμόσουν
δυναμικά το περιεχόμενο μιας σελίδας.
Προσδιορισμός στοιχείων με URI
Ο προσδιορισμός στοιχείων στο Web
γίνεται με τη χρήση των Uniform Resource Locators.
Διακρίνονται σε απόλυτα (π.χ. http://www.amazon.com) και σχετικά
(π.χ. info.gif).
Αποτελούνται από
το πρωτόκολλο,
τον προσδιορισμό του μηχανήματος που περιέχει το περιεχόμενο,
τον προσδιορισμό της διαδρομής και
το αρχείο.
Η χρήση τους επιτρέπει τον προσδιορισμό άλλων σελίδων τοπικά, σε άλλα
μηχανήματα, καθώς και ερωτήσεων:
Το πρωτόκολλο HTTP υποστηρίζει τις παρακάτω μεθόδους επικοινωνίας:
GET
HEAD
POST
PUT
DELETE
TRACE
Παράδειγμα:
GET /pub/WWW/TheProject.html HTTP/1.1
Host: www.w3.org
Περιγραφή σελίδων με HTML
H HTML είναι μια εφαρμογή της SGML για την περιγραφή σελίδων στο Web.
Περιοχές του κειμένου σημειώνονται με ετικέτες (tags).
Κάθε ετικέτα περιλαμβάνει το όνομά της και παραμέτρους.
Οι ετικέτες γράφονται ως εξής:
<όνομα ετικέτας παράμετροι>
Μια περιοχή του κειμένου μπορεί να σημειωθεί ως εξής:
<ετικέτα>
περιοχή που σημειώνεται
</ετικέτα>
Βασικές ετικέτες που υποστηρίζει η HTML είναι οι παρακάτω:
HTML
περιγραφή ολόκληρης σελίδας
HEAD
επικεφαλίδα της σελίδας
BODY
κείμενο της σελίδας
H1-H6
επικεφαλίδες του κειμένου
P
αλλαγή παραγράφου
UL
λίστα με τελείες
OL
αριθμημένη λίστας
LI
στοιχείο λίστας
BR
αλλαγή γραμμής
HR
οριζόντια γραμμή
IMG
εικόνα
A
(anchor) σημείο πρόσβασης από ή σε υπερκείμενο
PRE
προστοιχειοθετημένο κείμενο
DL, DT, DD
λίστα περιγραφών, περιγραφές
I
πλάγιοι χαρακτήρες
B
έντονοι χαρακτήρες
Παράδειγμα σελίδας:
<!doctype html public "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<TITLE>Τίτλος της σελίδας</title>
<META NAME="GENERATOR" CONTENT="thread.pl">
<META NAME="AUTHOR" CONTENT="Diomidis Spinellis">
<META HTTP-EQUIV="Content-type" CONTENT="text/html; charset=ISO-8859-7">
<LINK REV="made" HREF="mailto:dspin@aegean.gr">
<LINK REL="ToC" href="./web/index.htm">
<LINK REV="Subdocument" href="./web/index.htm">
<LINK REL="previous" href="./web/http.htm">
<LINK REL="next" href="./web/cgi.htm">
</HEAD>
<BODY> <H1>Επικεφαλίδα πρώτου επιπέδου</H1><HR>
Κείμενο που περιέχει ένα σημείο κατάληξης υπερκειμένου
<a name="G42"> (<em>με έντονο κείμενο</em>)</a>
και μια λίστα:
<ul>
<li> στοιχείο 1
<li> στοιχείο 2
</ul>
<p>
Νέα παράγραφος με ένωση υπερκειμένου στο
<A HREF="http://www.aueb.gr">Οικονομικό Πανεπιστήμιο Αθηνών</A>
<HR>
</BODY>
</HTML>
Ποια είναι τα επίπεδα του προτύπου OSI;
Γράψτε ένα παράδειγμα τεχνολογίας για το κάθε επίπεδο.
Πως μετατρέπεται ένα όνομα όπως www.slashdot.org σε διεύθυνση του Internet;
Σε τι διαφέρει το πρότυπο HTTP από το πρότυπο HTML;
Πως μπορεί η ίδια σελίδα του ιστού (π.χ. http://www.amazon.com) να εμφανίζεται με διαφορετικά στοιχεία σε διαφορετικούς χρήστες;
Εκτιμήστε τον αριθμό των μηχανημάτων και των σελίδων web που υπάρχουν
σήμερα στο Internet.
Ξεκινήστε από στοιχεία που ξέρετε για εσάς, τους συμφοιτητές σας και τη σχολή.
Εργαστηριακή άσκηση
Κατασκευάστε την προσωπική σας σελίδα σε HTML
Φορτώστε τη σελίδα αυτή στον Internet Explorer και δώστε την εντολή
View - Source για να δείτε το περιεχόμενό της.
Φυλάξτε τη σελίδα αυτή στον προσωπικό σας φάκελα με την εντολή
File - Save As.
Douglas E. Comer and
David L. Stevens.
Internetworking with TCP/IP, volume II: Design, Implementation and
Internals.
Prentice-Hall, 1991.
Douglas E. Comer and
David L. Stevens.
Internetworking with TCP/IP, volume III: Client-Server Programming and
Applications (BSD Socket Version.
Prentice-Hall, 1993.
Stefanos
Gritzalis and Diomidis Spinellis.
Addressing threats and security issues in World Wide Web
technology.
In Proceedings CMS '97 3rd IFIP TC6/TC11 International joint working
Conference on Communications and Multimedia Security, pages 33–46,
Athens, Greece, September 1997. IFIP, Chapman & Hall.
Fred Halsall.
Data Communications, Computer Networks and OSI.
Addison-Wesley, second edition, 1988.
Αλγόριθμος (algorithm) είναι μια
διαδικασία που επεξεργαζόμενη ορισμένα στοιχεία με
πεπερασμένο αριθμό βημάτων παράγει ένα
συγκεκριμένο επιθυμητό αποτέλεσμα.
Κάθε βήμα της διαδικασίας αποτελείται από μονοσήμανταεκτελέσιμες πράξεις.
Εύρεση ν!
Παραγοντικό του Ν στο Χ
Πριν: Ν: φυσικός αριθμός
Μετά: Χ = Ν!
Είσοδος:
Ν : Φυσικός αριθμός
Εξοδος:
Χ : Φυσικός αριθμός
Κ : Φυσικός αριθμός
Χ <- 1
Κ <- Ν
Οσο Κ > 0
Χ <- Χ * Κ
Κ <- Κ - 1
Τέλος (όσο)
Είσοδος:
πλευρά_α, πλευρά_β, πλευρά_γ : Φυσικός αριθμός
Εξοδος:
εμβαδό : Φυσικός αριθμός
αριθμός_πλακών : Φυσικός αριθμός
συνολικό_βάρος : Πραγματικός αριθμός
είναι_ισοσκελές : Λογική τιμή
Προϋποθέσεις και μετά-συνθήκες
Πριν: Ν Φυσικός αριθμός
Μετά: Χ = Ν!
Εκχωρήσεις
ύψος <- συν(κλίση) * πλευρά
μέσο <- ύψος / 2
Βρόχοι
Οσο υπόλοιπο_χρημάτων > 0
δώσε_χαρτονόμισμα
Τέλος (όσο)
Επανάλαβε
μείωσε_αέρα
Οσο στροφές_κινητήρα < 900
Για πάντα
έλεγξε_παραμέτρους_λειτουργίας_εργοστασίου
Τέλος (για πάντα)
Αποφάσεις
Αν ζωές_παίκτη > 0 Τότε
ξεκίνα_νέο_παιγνίδι
Αλλιώς
εμφάνισε "Game Over"
Τέλος (Αν)
Αν στροφές > 8700 Τότε
διάκοψε_την_τροφοδοσία
Τέλος (Αν)
Αν ομάδα ΠΑΟ Τότε
χρώμα <- πράσινο
Αλλιώς Αν ομάδα Ολυμπιακός Τότε
χρώμα <- κόκκινο
Αλλιώς Αν ομάδα ΑΕΚ Τότε
χρώμα <- κίτρινο
Τέλος (Αν)
Γλώσσες προγραμματισμού
Επιβάλλουν την έκφραση ενός αλγορίθμου με τυπική μορφή.
Χρησιμοποιούνται άμεσα ή έμμεσα από τον υπολογιστή.
Διαφορετικές γλώσσες διαθέτουν διαφορετικά επίπεδα και μέσα έκφρασης.
Γλώσσα μηχανής
89 D9
B8 01 00
83 F9 00
74 05
F7 E1
49
EB F6
Συμβολική γλώσσα
; Παραγοντικό του BX στο AX
MOV CX, BX ; Μετρητής στο CX
MOV AX, 1 ; Αρχική τιμή 1
LOOP: CMP CX, 0 ; Τέλος;
JZ DONE ; Ναι, έξοδος
MUL CX ; Όχι, πολλαπλασίασε ΑΧ με CX
DEC CX ; Επόμενη τιμή του CX
JMP LOOP ; Πίσω στο βρόχο
DONE:
Fortran 77
C Return factorial of N
C
FUNCTION IFACTORIAL(N) INTEGER N INTEGER IFACTORIAL INTEGER IRESULT, I
IRESULT = 1 DO I = 1, N
IRESULT = IRESULT * I END DO
IFACTORIAL = IRESULT
END
Fortran 95
! Return factorial of n
function factorial(n) result (nfac) integer, intent(in) :: n integer :: factorial integer :: i
nfac = 1 do i = 1, n
nfac = nfac * i end do
end function factorial
C
/* Παραγοντικό */ int
factorial(int n)
{ int result; int count;
count = n;
result = 1; while (count > 0) {
result = result * count;
count = count - 1;
} return (result);
}
/* Παραγοντικό (με λιγότερες εντολές) */ int
factorial(int n)
{ int result = 1;
for (; n; n--)
result *= n; return (result);
}
Prolog
factorial(0, 1).
% To N_Factorial είναι ισοδύναμο με Ν!
factorial(N, N_Factorial) :-
N > 0,
M is N - 1,
factorial(M, M_Factorial),
N_Factorial is M_Factorial * N.
Lisp
;; Επιστρέφει το παραγοντικό του n
(define (factorial n)
(if (= n 1)
1
(* n (factorial (- n 1)))))
Basic
500 REM Return factorial of N in variable FACT
510 FACT = 1
520 FOR I = 1 TO N
530 FACT = FACT * I
540 NEXT I
550 RETURN
Visual Basic
' Παραγοντικό του Ν FUNCTION Factorial(N AS INTEGER) AS INTEGER DIM Count AS INTEGER DIM Result AS INTEGER
Count = N
Result = 1 WHILE Count > 0
Result = Result * Count
Count = Count - 1 WEND
ENDFUNCTION
Pascal
(* Παραγοντικό του Ν *) function factorial(N : Integer) : Integer; var
Count, Result : Integer; begin
Count := N; Result := 1; While Count > 0 Do begin Result := Result * Count;
Count := Count - 1 end;
Factorial := Result end (* Factorial *);
Java
// Υπολογισμός ν παραγοντικού publicint παραγοντικό(int ν) { int αποτέλεσμα; int μετρητής;
μετρητής = ν;
αποτέλεσμα = 1; while (μετρητής > 0) {
αποτέλεσμα = αποτέλεσμα * μετρητής;
μετρητής = μετρητής - 1;
} return (αποτέλεσμα);
}
Πίνακες
Οι πίνακες (arrays) επιτρέπουν τη χρήση πολλών ομοίου τύπου στοιχείων.
Συνήθως το στοιχείο i ενός πίνακα A προσδιορίζεται ως A[i] ή A(i).
Μπορούν να οριστούν και πίνακες πολλαπλών διαστάσεων με στοιχεία
αντίστοιχα προσδιορισμένα ως A[i,j] κ.λπ.
Συνήθως υλοποιούνται με τη διαδοχική φύλαξη των στοιχείων τους στη
μνήμη.
Παράδειγμα
class Sum { staticint sum(int a[]) { int i, sum = 0;
for (i = 0; i < a.length; i++)
sum += a[i]; return sum;
}
Οι εγγραφές (records) επιτρέπουν τον ομαδικό χειρισμό
διαφορετικού τύπου στοιχείων.
Συνήθως το στοιχείο i μιας εγγραφής A προσδιορίζεται ως A.i
Μπορούν να οριστούν και πίνακες που περιέχουν εγγραφές ή εγγραφές
που περιέχουν πίνακες.
Συνήθως υλοποιούνται με τη διαδοχική φύλαξη των στοιχείων τους στη
μνήμη.
Παράδειγμα
struct point { double x; /* X coordinate */ double y; /* Y coordinate */
};
struct customer { char name[50]; /* Customer name */ int balance; /* Account balance */
};
struct customer customer_list[100];
main()
{ struct point a, b;
a.x = 5;
a.y = 9;
b.x = 12;
b.y = 19;
}
Δομές με δείκτη
Οι δείκτες (pointers) αντιπροσωπεύουν δεδομένα
που έχουν καταχωρηθεί σε κάποια άλλα θέση της μνήμης.
Επιτρέπουν τον εύκολο ορισμό και χειρισμό σύνθετων δομών.
Τέτοιες δομές μπορεί να είναι
program fun;
(* Παραγοντικό του Ν *)
function factorial(N : Integer) : Integer;
var
Count, Result : Integer;
begin
Count := N;
Result := 1;
While Count > 0 Do
begin
Result := Result * Count;
Count := Count - 1
end;
Factorial := Result
end (* Factorial *);
procedure clear_screen;
const number_of_lines = 24;
var i : integer;
begin
for i := 0 to number_of_lines do
writeln('');
end (*clear_screen*);
begin
clear_screen;
writeln(factorial(5));
end.
Παράδειγμα κλάσης σε Java
class Point extends Object {
private int x;
private int y;
public void MoveTo(int x, int y) {
this.x = x;
this.y = y;
}
public int GetX() {
return (x);
}
}
Αναδρομικές τεχνικές
Διαδικασίες, συναρτήσεις και δομές που ορίζονται
αναδρομικά (recursively)
μπορούν εύκολα να ανιμετωπιστούν με τη χρήση αναδρομικών τεχνικών
προγραμματισμού.
Παράδειγμα
class Recurse { staticvoid russian_doll(int size) { int i;
System.out.print("["); for (i = 0; i < size; i++)
System.out.print("-");
System.out.println("]"); if (size > 1)
russian_doll(size - 1);
}
Εκφράστε με ψευδοκώδικα τη διαδικασία μιας πρόσφατης συναλλαγής σας
με το Δημόσιο.
Εκφράστε με ψευδοκώδικα τον τρόπο με τον οποίο δίνονται ρέστα
στα καταστήματα.
Βελτιώστε τον κώδικα φυλάσσοντας σε πίνακες τις αξίες και
ποσότητες των νομισμάτων που υπάρχουν στο ταμείο.
Εκφράστε με ψευδοκώδικα τη διαδικασία πολλαπλασιασμού δύο
αριθμών Μ, Ν σε λογ2(MAX(N,M)) βρόχους.
Μπορείτε να χρησιμοποιήσετε πρόσθεση, σύζευξη και ολίσθηση.
Σε μια δηλωτική (declarative)
ή εφαρμοστική (applicative)
γλώσσα
το πρόγραμμα εκφράζει τη δομή του προβλήματος που θέλουμε
να επιλύσουμε.
Η γλώσσα προγραμματισμού παρέχει τον κατάλληλο μηχανισμό ελέγχου
ο οποίος χρησιμοποιόντας τη δομή που έχουμε ορίσει καταλήγει
στο επιθυμητό αποτέλεσμα.
Επεξεργάζεται το πρόγραμμα εκτελώντας απλούς
συμβολικούς μετασχηματισμούς και παράγει ένα αντίστοιχο πρόγραμμα.
Χρησιμοποιείται σε συμβολικές γλώσσες, τη Fortran (Ratfor), τη C, και τη C++.
Επιτρέπει την εκτέλεση του προγράμματος βήμα-βήμα, την
εξέταση και αλλαγή μεταβλητών του
και γενικά ενέργειες που αποσκοπούν στην ανίχνευση
λαθών που μπορεί να περιέχει το πρόγραμμα.
J.W. Backus, F.L.
Bauer, J.Green, C.Katz, J.McCarthy, P. Naur, A.J.Perlis, H. Rutishauser,
K. Samuelson, B. Vauquois, J.H. Wegstein, A. van Vinjgaarden, and M. Woodger.
Revised report on the algorthmic language ALGOL 60.
IFIP, 1960.
Brian W. Kernighan.
Why Pascal is not my favorite programming language.
Technical Report 100, Bell Laboratories, Murray Hill, New Jersey 07974, July
1981.
Larry Wall and
Randal L. Schwartz.
Programming Perl.
O'Reilly and Associates, Sebastopol, CA, USA, 1990.
Richard L. Wexelblat.
Maxims for malfeasant designers, or how to design languages to make programming
as difficult as possible.
In Proceedings of the 2nd International Conference on Software
Engineering, pages 331–336, San Fransisco, CA, USA, October 1976.
IEEE Computer Society Press.
Ασκήσεις
Σε τι υπερέχουν και σε τι υστερούν οι
δηλωτικές και σε τι οι αλγοριθμικές γλώσσες;
Περιγράψτε σε BNF τη γλώσσα με την οποία απαγγέλει την ώρα η
φωνή στο 141. Λάβετε υπόψη σας ότι μηδενικά λεπτά και δευτερόλεπτα
δεν απαγγέλονται.
Μεταγλωττίστε σε συμβολική γλώσσα 8086 τον υπολογισμό της
έκφρασης της C
Η ιδιότητα της ζωτικότητας (liveness) σε μια σειρά από
παράλληλες (concurrent) διεργασίες σχετίζεται με το
ρυθμό της προόδου που επιτυγχάνεται.
Ένα σύνολο διεργασιών βρίσκεται σε
αδιέξοδο (deadlock) αν κάθε διεργασία του
συνόλου περιμένει ένα γεγονός που μόνο μια άλλη διεργασία του συνόλου
μπορεί να προκαλέσει.
(Tanenbaum)
Τα αδιέξοδα δημιουργούνται ως αποτέλεσμα της διαχείρισης των πόρων
από τις διαδικασίες.
Κάθε πόρος (resource) μπορεί να είναι
προεκχωρήσιμος (preemptable) δηλαδή να
αποδεσμευτεί από μια διεργασία που τον κατέχει χωρίς παρενέργιες ή
μη προεκχωρήσιμος (nonpreemptable).
Παραδείγματα της πρώτης κατηγορίας είναι ο δίσκος και η μνήμη.
Παραδείγματα της δεύτερης κατηγορίας είναι ο εκτυπωτής και η μονάδα ταινίας.
Τυπικά μια διεργασία χρησιμοποιεί έναν πόρο ως εξής:
Ζητά τον πόρο από το λειτουργικό σύστημα (αίτηση χρήσης).
Χρησιμοποιεί τον πόρο.
Ενημερώνει το λειτουργικό σύστημα ότι δε χρειάζεται άλλο τον πόρο
(αποδέσμευση).
Οι παρακάτω συνθήκες πρέπει να ικανοποιούνται για να δημιουργηθεί
αδιέξοδο:
Αμοιβαίος αποκλεισμός
Κάθε πόρος είναι δεσμευμένος ή διαθέσιμος.
Δέσμευση και αναμονή
Διεργασίες που δεσμεύουν πόρους μπορούν να
ζητούν και νέους.
Μη προεκχώρηση
Μόνο η διεργασία που έχει δεσμεύσει τους πόρους μπορεί
να τους αποδεσμεύσει.
Κυκλική αναμονή
Οι διαδικασίες που ζητούν πόρους πρέπει να σχηματίζουν
κύκλο.
Οι τρόποι με τους οποίους αντιμετωπίζονται τα αδιέξοδα έχουν να
κάνουν με την άρση μιας από τις παραπάνω συνθήκες.
Οι δειπνούντες φιλόσοφοι
Αδιέξοδο
Επανάλαβε
Πιάσε το αριστερό πηρούνι
Πιάσε το δεξί πηρούνι
Φάε
Άφησε τα πηρούνια
Σκέψου
Τέλος
Επανάλαβε
Πιάσε το αριστερό πηρούνι
Αν δεν υπάρχει δεξί πηρούνι
Άσε το αριστερό πηρούνι
Επανάλαβε
Τέλος
Πιάσε το δεξί πηρούνι
Φάε
Άφησε τα πηρούνια
Σκέψου
Τέλος
Edsger W. Dijkstra.
Co-operating sequential processes.
In F. Genuys, editor, Programming Languages: NATO Advanced Study
Institute, pages 43–112. Academic Press, London, 1968.
John Hughes.
Why functional programming matters.
In David A. Turner, editor, Research Topics in Functional
Programming, chapter 2, pages 17–42. Addison-Wesley, 1990.
Also appeared in the April 1989 issue of The Computer Journal.
Περιγράψτε σε ψευδοκώδικα πως πρέπει να γίνεται ανάληψη χρημάτων
από λογαριασμό με έλεγχο μη υπέρβασης του υπολοίπου.
Χρησιμοποιήστε σηματοφόρους για να ελέγξετε το ενδεχόμενο
ταυτόχρονης ανάληψης από δύο υποκαταστήματα.
Περιγράψτε λογικό πρόγραμμα για την εύρεση δρομολογίων ανάμεσα
σε τυχαίες πόλεις.
Ορίστε κάνοντας χρήση της κληρονόμικότητας πιθανές ιδιότητες
των παρακάτω τάξεων:
Λιοντάρι
Έμβιο
Θηλαστικό
Καρχαρίας
Έντομο
Ψάρι
Ζωγραφίστε τη σχέση των τάξεων με τη μορφή δέντρου.
Για να μεταγλωττίσουμε το πρόγραμμα πρέπει να το αποθηκεύσουμε σε
ένα αρχείο με όνομα ίδιο με το όνομα της κλάσης που περιέχει τη συνάρτηση
main.
Το επίθεμα (suffix) του αρχείου πρέπει να είναι .java.
Με την εντολή javacόνομα αρχείου μεταγλωττίζουμε
το πρόγραμμα από Java σε μορφή που να μπορεί να εκτελεστεί.
Για να εκτελέσουμε το πρόγραμμα χρησιμοποιούμε την εντολή
javaόνομα κλάσης.
Τα προγράμματα της Java αποτελούνται από ορισμένες βασικές τάξεις στοιχείων:
Τα κενά, όπως ο χαρακτήρας ' ' και η αλλαγή της γραμμής.
Αυτά γενικά δεν επηρεάζουν καθόλου τη συμπεριφορά του προγράμματος.
Για παράδειγμα μπορούσαμε να γράψουμε το πρόγραμμα ως εξής:
Χρησιμοποιούμε κενά (spaces) για να κάνουμε το
πρόγραμμα πιο εύληπτο.
Τα ονόματα των συναρτήσεων (functions),
κλάσεων (classes) και των
μεταβλητών.
Αυτά αρχίζουν με έναν λατινικό αλφαβητικό χαρακτήρα και
μπορούν να ακολουθούνται από άλλους ή/και ψηφία.
Η δήλωση της κλάσης.
Αυτή γράφεται ως το όνομα τη κλάσης ακολουθούμενο από
το περιεχόμενο της κλάσης μέσα σε άγκιστρα ({ }).
Το όνομα του αρχείου πρέπει να είναι ίδιο με το όνομα της κλάσης.
Για την ώρα χρησιμοποιούμε την κλάση για να ορίσουμε μέσα τις
κάποιες συναρτήσεις.
Σε επόμενα μαθήματα θα μάθουμε τι ακριβώς είναι η κλάση
και πως οι συναρτήσεις που ορίζονται στην κλάση αυτή
είναι στην πραγματικότητα μέθοδοι.
Οι δηλώσεις των συναρτήσεων.
Αυτές γράφονται ως το όνομα τη συνάρτησης ακολουθούμενο από
παρενθέσεις και το περιεχόμενο της συνάρτησης μέσα σε άγκιστρα ({ }).
Αν μια συνάρτηση δέχεται ορίσματα, αυτά δηλώνονται μέσα στις παρενθέσεις
που ακολουθούν το όνομα τις συνάρτησης.
Η συνάρτηση main έχει ειδικό νόημα.
Ορίζει το σημείο από το οποία θα αρχίσει να εκτελείται το πρόγραμμα.
Το περιεχόμενο των συναρτήσεων.
Αυτό αποτελείται από εντολές.
Κάθε εντολή τερματίζεται με μια λατινική
άνω τελεία (semicolon) (; - ελληνικό ερωτηματικό).
Οι εντολές μέσα στη συνάρτηση εκτελούνται με τη σειρά
από πάνω προς τα κάτω εκτός να έχουμε ορίσει κάτι διαφορετικό.
Οι κλήσεις άλλων συναρτήσεων.
Αυτές αποτελούν ένα βασικό είδος εντολής.
Η κλήση μιας συνάρτησης αποτελείται από το όνομα της συνάρτησης
ακολουθούμενο από το όρισμα (argument) της
συνάρτησης μέσα σε παρενθέσεις.
Αν η συνάρτηση δέχεται πολλαπλές παραμέτρους, τότε αυτές
χωρίζονται με κόμματα.
Ορισμός απλών συναρτήσεων
Στο πρόγραμμα που εξετάσαμε εμφανίζονται δύο συναρτήσεις:
η συνάρτηση main την οποία ορίσαμε εμείς και
η συνάρτηση System.out.println την οποία καλέσαμε.
Σε ένα πρόγραμμα είναι δυνατός ο ορισμός (definition)
και η κλήση (call) και άλλων συναρτήσεων.
Το παρακάτω πρόγραμμα τυπώνει και αυτό "hello, world" στην οθόνη.
class HelloFun { staticvoid hello() {
System.out.println("Hello, world.");
}
Με τον τρόπο αυτό μπορούμε να ομαδοποιήσουμε τα τμήματα του
προγράμματός μας και να χρησιμοποιήσουμε ορισμένα τμήματα πολλές
φορές.
Όταν καλείται μια συνάρτηση, αυτή εκτελείται βήμα προς βήμα μέχρι
να τελειώσουν οι εντολές που την απαρτίζουν.
Τότε η εκτέλεση του προγράμματος επιστρέφει (returns)
στην επόμενη εντολή από αυτή που κάλεσε τη συνάρτηση.
Στην Java οι διαδικασίες ορίζονται ως συναρτήσεις που δεν επιστρέφουν
τίποτα.
Αυτό γίνεται γράφοντας ως τύπο που επιστρέφει η συνάρτηση τη λέξη
void (κενό).
Ασκήσεις
Εξοικείωση με το μεταγλωττιστή και τη διαδικασία προγραμματισμού
Να πληκτρολογήσετε, μεταγλωττίσετε και να εκτελέσετε ένα πρόγραμμα
σε Java που να τυπώνει "I am learning Java"
Πειραματιστείτε αλλάζοντας διάφορα στοιχεία του προγράμματος.
(Το πιθανότερο είναι οι περισσότερες αλλαγές σας να καταλήγουν σε λάθη.)
Φτιάξτε ένα πρόγραμμα το οποίο να τυπώνει με * ένα τετράγωνο
στην οθόνη σαν το παρακάτω:
Για να επαναλαμβανόμενα στοιχεία του τετραγώνου να ορίσετε δύο συναρτήσεις
οι οποίες να τα τυπώνουν και να τις καλέσετε όσες φορές και με τη σειρά
που χρειάζεται.
Βιβλιογραφία
Γιώργος Λιακέας
Εισαγωγή στην Java. σ. 1-31,
Εκδόσεις Κλειδάριθμος 2001.
Οι σταθερές αυτές χρησιμοποιούνται συχνά για να παραστήσουν μηνύματα
προς το χρήστη (π.χ. "Παρακαλώ βάλτε την κάρτα σας στην υποδοχή") ή
και μεταξύ υπολογιστών (π.χ. "RCPT TO: dspin@aegean.gr").
Ένα άλλο είδος σταθερών είναι αυτές που παριστάνουν αριθμητικές
τιμές (π.χ. 42 ή 3.1415927).
Υπάρχουν ακόμα σταθερές που παριστάνουν χαρακτήρες και γράφονται
μέσα σε μονά εισαγωγικά ('β', 'a') και δύο σταθερές που παριστάνουν τις
αληθείς και ψευδές τιμές: true, false
Εκτύπωση τιμών
Για να χρησιμοποιήσουμε απλές εντολές εισόδου και εξόδου στοιχείων
εισάγουμε στο πρόγραμμά μας τη βιβλιοθήκη (library)
BIO (basic input/output) με την εντολή
import gr.aueb.dds.BIO;
Μπορούμε να τυπώσουμε στοιχεία χωρίς να αλλάξουμε στο τέλος
γραμμή στην οθόνη με την εντολή BIO.print.
Μπορούμε να τυπώσουμε στοιχεία και να αλλάξουμε στο τέλος
γραμμή στην οθόνη με την εντολή BIO.println.
Για να τυπώσουμε τιμές μαζί τις "προσθέτουμε"
στη συμβολοσειρά-όρισμα του println.
Μπορούμε να "προσθέσουμε" και να τυπώσουμε μαζί απεριόριστο αριθμό
από σταθερές (ακεραίους, συμβολοσειρές, αριθμούς κινητής υποδιαστολής).
Παράδειγμα:
BIO.println("Students get grades from " + 0 + " to " + 10);
BIO.println("The number " + 3.1415927 + " is an approximation of pi.")
Απλές πράξεις
Οι αριθμητικές τιμές της Java μπορούν να συνδυαστούν με τη
χρήση των παρακάτω τελεστών (operands):
Πράξη
Τελεστής της Java
Πρόσθεση
+
Αφαίρεση
-
Πολλαπλασιασμός
*
Διαίρεση
/
Υπόλοιπο ακέραιας διαίρεσης
%
Για τον υπολογισμό μιας τιμής, πρώτα εκτελούνται οι πράξεις ανάμεσα
στους τελεστές * / % και μετά οι πράξεις ανάμεσα στους τελεστές + -.
Η παραπάνω σειρά μπορεί να μεταβληθεί με τη χρήση παρενθέσεων.
Παραδείγματα
BIO.println("one plus one = " + (1 + 1));
BIO.println("The room's area is " + (3 * 5) + " sq. m");
BIO.println(36.7 + " degrees Celsius = " + (32 + 9.0 / 5.0 * 36.7) + " degrees Fahrenheit.");
BIO.println(1 + 2 * 3); /* Prints 7 */
BIO.println((1 + 2) * 3); /* Prints 9 */
Οι μεταβλητές που χρησιμοποιούμε για να αποθηκεύμουμε τιμές κατά
το διάστημα που υπολογίζεται μια συνάρτηση ορίζονται στην αρχή της
αντίστοιχης συνάρτησης μετά το σύμβολο "{".
Ο ορισμός τους γίνεται γράφοντας τον τύπο της μεταβλητής
(int για ακέραιες τιμές, double για τιμές κινητής υποδιαστολής)
ακολουθούμενο από το όνομα της μεταβλητής.
Στο τέλος του ορισμού γράφουμε το χαρακτήρα ";".
Μπορούμε να ορίσουμε πολλές μεταβλητές ίδιου τύπου χωρίζοντάς τις
με ",".
Παράδειγμα:
class Vars { publicstaticvoid main(String args[]) { int faces; double x, y;
}
}
Για να δώσουμε μια τιμή σε μια μεταβλητή χρησιμοποιούμε τη
σύνταξη:
μεταβλητή = τιμή;
για παράδειγμα:
faces = 2 * 8 + 12;
Στη συνέχεια μπορούμε να χρησιμοποιούμε την τιμή της μεταβλητής
όπως και οποιοδήποτε άλλη σταθερά. Παράδειγμα:
class Area { publicstaticvoid main(String args[]) { int faces; double len;
len = 12.5;
faces = 6;
BIO.println("The area is " + (len * len * faces));
}
}
Είσοδος στοιχείων
Μπορούμε να κάνουμε το πρόγραμμά μας να σταματήσει την εκτέλεσή
του για να διαβάσει από το χρήστη κάποιες τιμές.
Για παράδειγμα το πρόγραμμα ελέγχου μια μηχανής αυτόματης
ανάληψης χρημάτων σταματά την εκτέλεσή του όταν τυπώνει την
ερώτηση "Δώστε το ποσό που θέλετε να αναλάβετε" και περιμένει
από το χρήστη να γράψει την αντίστοιχη τιμή.
Η συνάρτηση της βιβλιοθήκης BIO readInt σταματά την εκτέλεση ενός
προγράμματος περιμένοντας ο χρήστης του έναν ακέραιο και μετά
ENTER.
Η συνάρτηση επιστρέφει στο τέλος τον ακέραιο που έδωσε ο χρήστης.
Αντίστοιχα για να διαβάσουμε τιμές κινητής υποδιαστολής χρησιμοποιούμε
τη συνάρτηση readDouble για χαρακτήρες τη συνάρτηση readChar ενώ για να διαβάσουμε
μια ολόκληρη γραμμή τη συνάρτηση readString.
Το παρακάτω πρόγραμμα μετατρέπει ταχύτητες από km/h σε m/s:
import gr.aueb.dds.BIO;
// Convert speed from km/h into m/s class SpeedConvert { publicstaticvoid main(String args[]) { double kmh_speed;
Παρατήρηση: αφού ο χρήστης γράψει την τιμή πρέπει να πατήσει το πλήκτρο
ENTER για να συνεχίσει το πρόγραμμα τη λειτουργία του.
Ασκήσεις
Είσοδος έξοδος και υπολογισμοί
Να γράψετε ένα πρόγραμμα που θα διαβάζει από το χρήστη το αρχικό ποσό
μιας κατάθεσης και το ετήσιο επιτόκιο και θα τυπώνει το τελικό ποσό της
κατάθεσης μετά από την πάροδο ενός έτους.
Παράδειγμα της εκτέλεσης του πρόγραμματος:
Initial capital = 1000000
Interest rate = 3.2
Th capital at the end of year 1 will be 1032000
Βιβλιογραφία
Γιώργος Λιακέας
Εισαγωγή στην Java. σ. 39-49,
Εκδόσεις Κλειδάριθμος 2001.
Οι αριθμητικές τιμές της Java μπορούν να συγκριθούν με τη
χρήση των παρακάτω τελεστών:
Σύγκριση
Τελεστής της Java
Ίσο
==
Διάφορο
!=
Μικρότερο
<
Μεγαλύτερο
>
Μικρότερο ή ίσο
<=
Μεγαλύτερο ή ίσο
>=
Για τον υπολογισμό μιας τιμής, πρώτα εκτελούνται οι πράξεις ανάμεσα
στους τελεστές * / %, μετά οι πράξεις ανάμεσα στους τελεστές + -,
μετά ανάμεσα στους τελεστές < > <= >= και μετά
ανάμεσα στους τελεστές == και !=.
Η παραπάνω σειρά μπορεί να μεταβληθεί με τη χρήση παρενθέσεων.
Το αποτέλεσμα της κάθε σύγκρισης είναι
αληθές (true) αν η σύγκριση ισχύει
και
ψευδές (false) αν η σύγκριση δεν ισχύει.
Τις περισσότερες φορές θέλουμε να εκτελέσουμε πάνω από μια εντολή
πολλαπλές φορές οπότε περικλείουμε όλες τις αντίστοιχες εντολές μέσα σε
αγκύλες "{" και "}":
while (συνθήκη) {
εντολή1;
εντολή2;
εντολή3;
}
Η εντολή που ακολουθεί το while εκτελείται όσο η συνθήκη είναι
αληθής, δηλαδή έχει τιμή διάφορη του 0.
Παράδειγμα (τυπώνει τους αριθμούς από το 0 μέχρι το 9):
import gr.aueb.dds.BIO;
class Counter { publicstaticvoid main(String args[])
{ int i;
i = 0; while (i < 10) {
BIO.println(i);
i = i + 1;
}
}
}
Αν η συνθήκη δεν είναι αληθής όταν εκτελεστεί το while για πρώτη
φορά τότε η εντολή που περιέχεται σε αυτό δε θα εκτελεστεί.
Η δομή ελέγχου while μπορεί να χρησιμοποιηθεί οπουδήποτε θα μπορούσε
και οποιαδήποτε άλλη εντολή (π.χ. η println) δηλαδή ακόμα και μέσα σε μια άλλη
while.
Το παρακάτω παράδειγμα τυπώνει στην οθόνη ένα τριγωνικό σχήμα:
import gr.aueb.dds.BIO;
class Triangle { publicstaticvoid main(String args[]) { int row, stars;
Ορισμένες φορές θέλουμε να ελέγχουμε τη συνθήκη στο τέλος
του βρόχου, δηλαδή η εντολή να εκτελεστεί τουλάχιστον μια φορά.
Στις περιπτώσεις αυτές χρησιμοποιούμε τη δομή ελέγχου do while
Αυτή χρησιμοποιείται ως εξής:
do
εντολή; while (συνθήκη);
Τις περισσότερες φορές θέλουμε να εκτελέσουμε πάνω από μια εντολή
πολλαπλές φορές οπότε περικλείουμε όλες τις αντίστοιχες εντολές μέσα σε
αγκύλες "{" και "}":
do {
εντολή1;
εντολή2;
εντολή3;
} while (συνθήκη);
Η εντολή που ακολουθεί το do εκτελείται μια φορά και συνεχίζει
να εκτελείται όσο η συνθήκη είναι αληθής, δηλαδή έχει τιμή διάφορη του 0.
Σημαντικό ρόλο έχει αυτή η δομή ελέγχου όταν διαβάζουμε στοιχεία
από το χρήστη και θέλουμε να ελέγξουμε την είσοδο για λάθη.
Παράδειγμα (εισάγει έναν αριθμό μικρότερο του 10):
import gr.aueb.dds.BIO;
class CheckGrade { publicstaticvoid main(String args[])
{ int number;
do {
BIO.print("Enter a number less than 10: ");
number = BIO.readInt();
} while (number >= 10);
BIO.println("You entered " + number);
}
}
όπως φαίνεται από το παρακάτω παράδειγμα:
Enter a number less than 10: 34
Enter a number less than 10: 50
Enter a number less than 10: 2
You entered 2
Αν η συνθήκη δεν είναι αληθής όταν εκτελεστεί το do για πρώτη
φορά τότε η εντολή που περιέχεται σε αυτό θα εκτελεστεί τουλάχιστον μια φορά.
Η δομή ελέγχου do μπορεί να χρησιμοποιηθεί οπουδήποτε θα μπορούσε
και οποιαδήποτε άλλη εντολή (π.χ. η BIO.println()) δηλαδή ακόμα και μέσα σε μια άλλη
do ή while.
Λογικοί τελεστές
Τα λογικά αποτελέσματα στη Java μπορούν να συνδυαστούν με τη
χρήση των παρακάτω λογικών τελεστών:
Τα αποτελέσματα χρήσης των τελεστών παριστάνονται από τους
παρακάτω πίνακες τιμών:
A
B
A && B
A || B
false
false
false
false
false
true
false
true
true
false
false
true
true
true
true
true
A
!A
false
true
true
false
Οι τελεστές && και || υπολογίζουν μόνο τους απαραίτητους
τελεστέους (ράθυμος υπολογισμός (lazy evaluation)).
Έτσι μπορούμε να τους χρησιμοποιήσουμε σε περιπτώσεις που το δεξί
μέρος δεν πρέπει να υπολογιστεί αν δεν έχει την κατάλληλη τιμή το αριστερό:
if (a != 0 && b / a > 100) {
// ...
}
Η προτεραιότητα υπολογισμού των τελεστών ορίζεται τώρα ως εξής:
()
! + -
* / %
+ -
< <= > >=
== !=
&&
||
Παράδειγμα
Ο παρακάτω βρόχος μπορεί να αποτελεί τμήμα του προγράμματος
ελέγχου ενός τραπεζικού μηχανήματος αυτομάτων συναλλαγών:
{ int secret, pin, tries;
secret = 1234; /* Customer's secret PIN */
tries = 0; do {
BIO.print("Δώστε το PIN σας: ");
pin = BIO.getInt();
tries = tries + 1;
} while (pin != secret && tries < 4);
/* Correct PIN entered or number of tries exhausted */
}
Βιβλιογραφία
Γιώργος Λιακέας
Εισαγωγή στην Java. σ. 91-95,
Εκδόσεις Κλειδάριθμος 2001.
Μπορούμε να εκτελέσουμε ορισμένες εντολές υπό συνθήκη με τη
δομή ελέγχου if.
Αυτή χρησιμοποιείται ως εξής:
if (συνθήκη)
εντολή;
Όπως και με τις εντολές while και do όταν θέλουμε να εκτελέσουμε πάνω
από μια εντολή υπό συνθήκη περικλείουμε όλες τις αντίστοιχες εντολές μέσα σε
αγκύλες "{" και "}":
if (συνθήκη) {
εντολή1;
εντολή2;
εντολή3;
}
Οι εντολή που ακολουθεί το if εκτελείται αν η συνθήκη είναι
αληθής.
Παράδειγμα (υπολογίζει και τυπώνει την απόλυτη τιμή των αριθμών που διαβάζει
μέχρι να συναντήσει το 0):
import gr.aueb.dds.BIO;
class MakePositive { publicstaticvoid main(String args[]) { int num;
do {
num = BIO.readInt(); if (num < 0)
num = -num;
BIO.println(num);
} while (num != 0);
}
}
Η δομή ελέγχου if μπορεί να ακολουθηθεί και από τη δομή else
για να προσδιορίσουμε εντολές που θα εκτελεστούν αν η συνθήκη δεν
ισχύει.
Παράδειγμα:
if (grade >= 5)
BIO.println("Περνάει"); else
BIO.println("Απορρίπτεται");
Χρειάζεται προσοχή όταν η else ακολουθεί δύο συνεχόμενες if.
Στην περίπτωση αυτή, η else συσχετίζεται με την κοντινότερη if.
Για να εκφράσουμε διαφορετική συσχέτιση πρέπει να χρησιμοποιήσουμε
αγκύλες { }.
Παράδειγμα (τυπώνει μόνο όταν η μεταβλητή printed είναι ψευδής):
if (exam >= 5) { if (!printed)
BIO.println("Περνάει");
} else if (!printed)
BIO.println("Απορρίπτεται");
printed = true;
Το παρακάτω παράδειγμα (χωρίς αγκύλες) δεν εκτελείται σύμφωνα με τον
τρόπο που είναι στοιχισμένο
if (exam >= 5) if (!printed)
BIO.println("Περνάει"); else if (!printed)
BIO.println("Απορρίπτεται");
printed = true;
αλλά ως εξής (δεν τυπώνει ποτέ "Απορρίπτεται"):
if (exam >= 5) if (!printed)
BIO.println("Περνάει"); else if (!printed)
BIO.println("Απορρίπτεται");
printed = true;
Μπορούμε να συνδυάσουμε συνεχόμενα else if για πολλαπλούς
ελέγχους. Παράδειγμα:
Τελεστές μοναδιαίας αύξησης και μείωσης, αποτέλεσμα ανάθεσης
Ο τελεστής ++ στη χρήση ++var αυξάνει την τιμή της μεταβλητής
var κατά ένα.
Η τιμή της μεταβλητής var που χρησιμοποιείται στην παράσταση είναι αυτή
που προκύπτει μετά την αύξηση.
Παράδειγμα (τυπώνει 5, 5):
i = 4;
BIO.print(++i);
BIO.println(i);
Ο τελεστής ++ στη χρήση var++ επίσης αυξάνει την τιμή της μεταβλητής
var κατά ένα.
Η τιμή της μεταβλητής var που χρησιμοποιείται στην παράσταση είναι αυτή
που ήταν πριν την αύξηση.
Παράδειγμα (τυπώνει 4, 5):
i = 4;
BIO.print(i++);
BIO.println(i);
Τα αντίστοιχα ισχύουν και για τον τελεστή -- που μειώνει την τιμή
μιας μεταβλητής κατά 1.
Η παράσταση "var = value" έχει ως τιμή την τιμή της μεταβλητής.
Παράδειγμα (τυπώνει 2, 2):
i = 4;
BIO.print(i = 2);
BIO.println(i);
Με τον τρόπο αυτό μπορούμε με συντομία να αναθέσουμε την ίδια τιμή
σε πολλές μεταβλητές (οι μεταβλητές i και j γίνονται 0):
i = j = 0;
Ο τύπος του χαρακτήρα
Μπορούμε να ορίσουμε μεταβλητές τύπου χαρακτήρα
με τον τύπο char:
publicstaticvoid main(String args[])
{ char c;
}
Οι μεταβλητές αυτές μπορούν να αποθηκεύσουν έναν ακριβώς χαρακτήρα.
Οι σταθερές τύπου χαρακτήρα γράφονται με τη χρήση των μονών εισαγωγικών:
Η συνάρτηση BIO.readChar() διαβάζει έναν χαρακτήρα και επιστρέφει
την τιμή του ως ακέραιο ή την ακέραια τιμή -1 αν δεν υπάρχουν
άλλοι χαρακτήρες για να διαβαστούν.
Στη συνέχεια μπορούμε να μετατρέψουμε τον ακέραιο κωδικό του
χαρακτήρα σε χαρακτήρα με τη σύνταξη (char)code.
Παράδειγμα:
int code; char c;
code = BIO.readChar(); if (code == -1)
BIO.println("End of file reached"); else {
c = (char)code;
print("Read character: ");
println(c);
}
Στο λειτουργικό σύστημα MS-DOS δηλώνουμε πως δεν υπάρχουν
άλλοι χαρακτήρες να διαβαστούν από το πληκτρολόγιο με το
συνδυασμό πλήκτρων CTRL-Z.
Η συνάρτηση BIO.print(c) τυπώνει το χαρακτήρα c στην οθόνη.
Στα λειτουργικά συστήματα MS-DOS, Windows NT και Unix μπορούμε
να ζητήσουμε η είσοδος ενός προγράμματος να προέρχεται από ένα αρχείο
με την ακολουθία:
program <file
Αντίστοιχα μπορούμε να ζητήσουμε η έξοδος ενός προγράμματος να οδηγηθεί
σε ένα αρχείο με την ακολουθία:
program >file
Με τον τρόπο αυτό οι συναρτήσεις BIO.readChar() και BIO.print() αποκτούν
ιδιαίτερη χρησιμότητα, διότι μας δίνουν τη δυνατότητα να δημιουργούμε
και να εξετάζουμε αρχεία.
Το παρακάτω πρόγραμμα αντιγράφει την είσοδό του στην έξοδο:
import gr.aueb.dds.BIO;
class CopyFile { publicstaticvoid main(String args[]) { int c;
while ((c = BIO.readChar()) != -1)
BIO.print((char)c);
}
}
(Το αποτέλεσμα της εντολής ανάθεσης είναι η τιμή της μεταβλητής και με
τον τρόπο αυτό η ανάθεση γίνεται μαζί με τον έλεγχο.)
Με το παραπάνω πρόγραμμα μπορούμε να αντιγράψουμε ένα αρχείο με την
ενολή:
Να γράψετε ένα πρόγραμμα που να διαβάζει χαρακτήρες
από την είσοδό του μέχρι να τερματιστεί το αρχείο εισόδου.
Στο τέλος να τυπώνει τον αριθμό των χαρακτήρων, γραμμών,
ψηφίων (0-9), πεζών χαρακτήρων (a-z) και κεφαλαίων χαρακτήρων (A-Z)
που διάβασε.
Σημείωση 1: Οι χαρακτήρες στο σύστημα που χρησιμοποιούμε είναι
ταξινομημένοι αλφαβητικά. Η παράσταση c >= 'a' && c <= 'z' είναι αληθής
για πεζούς χαρακτήρες στη μεταβλητή c.
Σημείωση 2: Οι γραμμές τερματίζονται με το χαρακτήρα διαφυγής '\n'.
Παράδειγμα:
C:>java CharCount
This is a test
of my input! (02 lines)
^Z
41 character(s)
2 line(s)
2 digit(s)
24 lowercase (a-z)
1 uppercase (A-Z)
Εκτελέστε το πρόγραμμά σας με είσοδο τον εαυτό του.
Μαθηματικές συναρτήσεις, πέντε παραδείγματα
Η βιβλιοθήκη μαθηματικών
Το παρακάτω απόσπασμα είναι η τεκμηρίωση της βιβλιοθήκης της
Java για τις διαθέσιμες μαθηματικές σταθερές και συναρτήσεις.
Όλες χρησιμοποιούνται με το πρόθεμα "Math.".
Παράδειγμα:
double x = Math.cos(Math.PI / 2.);
Field Summary
static double
E
The double value that is closer than any other to
e, the base of the natural logarithms.
static double
PI
The double value that is closer than any other to
pi, the ratio of the circumference of a circle to its diameter.
Method Summary
static double
abs(double a)
Returns the absolute value of a double value.
static float
abs(float a)
Returns the absolute value of a float value.
static int
abs(int a)
Returns the absolute value of an int value.
static long
abs(long a)
Returns the absolute value of a long value.
static double
acos(double a)
Returns the arc cosine of an angle, in the range of 0.0 through
pi.
static double
asin(double a)
Returns the arc sine of an angle, in the range of -pi/2 through
pi/2.
static double
atan(double a)
Returns the arc tangent of an angle, in the range of -pi/2
through pi/2.
static double
atan2(double a,
double b)
Converts rectangular coordinates (b, a)
to polar (r, theta).
static double
ceil(double a)
Returns the smallest (closest to negative infinity)
double value that is not less than the argument and is
equal to a mathematical integer.
static double
cos(double a)
Returns the trigonometric cosine of an angle.
static double
exp(double a)
Returns the exponential number e (i.e., 2.718...) raised to
the power of a double value.
static double
floor(double a)
Returns the largest (closest to positive infinity)
double value that is not greater than the argument and
is equal to a mathematical integer.
static double
IEEEremainder(double f1,
double f2)
Computes the remainder operation on two arguments as prescribed
by the IEEE 754 standard.
static double
log(double a)
Returns the natural logarithm (base e) of a double
value.
static double
max(double a,
double b)
Returns the greater of two double values.
static float
max(float a,
float b)
Returns the greater of two float values.
static int
max(int a,
int b)
Returns the greater of two int values.
static long
max(long a,
long b)
Returns the greater of two long values.
static double
min(double a,
double b)
Returns the smaller of two double values.
static float
min(float a,
float b)
Returns the smaller of two float values.
static int
min(int a,
int b)
Returns the smaller of two int values.
static long
min(long a,
long b)
Returns the smaller of two long values.
static double
pow(double a,
double b)
Returns of value of the first argument raised to the power of the
second argument.
static double
random()
Returns a double value with a positive sign, greater
than or equal to 0.0 and less than 1.0.
static double
rint(double a)
Returns the double value that is closest in value to
a and is equal to a mathematical integer.
static long
round(double a)
Returns the closest long to the argument.
static int
round(float a)
Returns the closest int to the argument.
static double
sin(double a)
Returns the trigonometric sine of an angle.
static double
sqrt(double a)
Returns the correctly rounded positive square root of a
double value.
static double
tan(double a)
Returns the trigonometric tangent of an angle.
static double
toDegrees(double angrad)
Converts an angle measured in radians to the equivalent angle
measured in degrees.
static double
toRadians(double angdeg)
Converts an angle measured in degrees to the equivalent angle
measured in radians.
Επίλυση δευτεροβάθμιας εξίσωσης
import gr.aueb.dds.BIO;
/*
* Solve a qudratic equation ax^2 + bx + c = 0
* Demonstrates the use of math calculations, functions, case analysis
*/ class Quadratic { publicstaticvoid main(String args[]) { double a, b, c; // Equation factors double d; // Discriminant
BIO.print("a=");
a = BIO.readDouble();
BIO.print("b=");
b = BIO.readDouble();
BIO.print("c=");
c = BIO.readDouble();
if (a == 0) { if (b == 0) {
BIO.println("No solutions");
} else {
// Not really quadratic; one root
BIO.print("r=");
BIO.println(-c / b);
}
} else {
// One complex, one, or two roots
d = b * b - 4 * a * c; if (d < 0) {
// Complex root
BIO.print("r=");
// Real part
BIO.print(-b / 2 / a);
BIO.print("+");
// Imaginary part
BIO.print(Math.sqrt(-d) / 2 / a);
BIO.println("i");
} elseif (d == 0) {
// Two equal roots
BIO.print("r1=r2=");
BIO.println(-b / 2 / a);
} else {
// Two different real roots
BIO.print("r1=");
BIO.println((-b + Math.sqrt(d)) / 2 / a);
BIO.print("r2=");
BIO.println((-b - Math.sqrt(d)) / 2 / a);
}
}
}
}
Σημείωση
Στην πράξη ο παραπάνω κώδικας είναι αριθμητικά ασταθής.
Για να λύσουμε τη δευτεροβάθμια εξίσωση: a x2 +
b x +
c = 0
αν η τιμή του a ή του c ή και των δύο είναι πολύ μικρή
τότε μια από τις ρίζες περιλαμβάνει την αφαίρεση δύο σχεδόν ίσων
αριθμών (του β και της διακρίνουσας) και το αποτέλεσμα δε θα είναι ακριβές.
Για το λόγο αυτό υπολογίζουμε τις δύο ρίζες ως εξής:
/*
* Read numbers until 0 is entered.
* Print the maximum number read.
* Demonstrates the use of a variable to hold the temporary maximum value
*/ class FindMax { publicstaticvoid main(String args[]) { double val; double maxVal = -1e308; // Very small number
while ((val = BIO.readDouble()) != 0) if (val > maxVal)
maxVal = val;
BIO.println(maxVal);
}
}
Μετρητής λέξεων
import gr.aueb.dds.BIO;
/*
* Count number of words.
* We define a word as a sequence of latin alphabetic characters.
* Demonstrates the use of toggle variables to hold state.
*/ class WordCount { publicstaticvoid main(String args[]) { int code; char c; boolean inWord = false; // True when scanning a word int count = 0;
while ((code = BIO.readChar()) != -1) {
c = (char)code; if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
// Word character if (!inWord)
inWord = true;
} else {
// Non word character if (inWord) {
// A word just finished
inWord = false;
count++;
}
}
}
BIO.println(count);
}
}
Έλεγχος ISBN
import gr.aueb.dds.BIO;
/*
* Read an ISBN number and verify if its checksum is ok.
* Demonstrates conversion of characters to integers, post-decrement,
* checksums.
*/ class Isbn { publicstaticvoid main(String args[]) { int count = 10; // Digit count and weight int sum = 0; // Checksum int code, value; char c;
while (count > 0) {
code = BIO.readChar(); if (code == -1) {
BIO.println("Short ISBN"); return;
}
c = (char)code;
// Integer representation of the digit if (c == 'X')
value = 10; else
// Should use Character.digit(c, 10)
value = c - '0'; if (value < 0 || value > 10) {
BIO.println("Bad ISBN character"); return;
}
sum = sum + value * count--;
} if (sum % 11 == 0)
BIO.println("ISBN checks ok"); else
BIO.println("ISBN is wrong");
}
}
Εξηγήσεις
Γιατί πολλαπλασιάζουμε με count;
Για να ανιχνεύουμε εναλλαγές ψηφίων.
Γιατί διαιρούμε με το 11;
Ο αριθμός που διαιρούμε πρέπει να είναι μεγαλύτερος από κάθε ψηφίο και από τον
αριθμό των θέσεων.
Πρέπει ακόμα, να μην έχει παράγοντα κάποιον από τους αριθμούς αυτούς
(στην πράξη, να είναι πρώτος).
Ζάρια
import gr.aueb.dds.BIO;
/*
* Dice thrower
* Demonstrates random number, functions, character graphics
*/ class Dice {
/*
* Calculate a random dice throw and display it as follows:
* 1-3:
* # #
* # #
* # #
* 4-6:
* # # # # # #
* # # #
* # # # # # #
*/ staticvoid dice() { int n = (int)(Math.random() * 6) + 1;
BIO.println("[" + n + "]");
BIO.println();
// Top row
// Left if (n == 2 || n >= 4) BIO.print("* "); else BIO.print(" ");
// Middle if (n == 3) BIO.print("* "); else BIO.print(" ");
// Right if (n >= 4) BIO.println("* "); else BIO.println(" ");
// Middle row
// Left if (n == 6) BIO.print("* "); else BIO.print(" ");
// Middle if (n % 2 == 1) BIO.print("* "); else BIO.print(" ");
// Right if (n == 6) BIO.println("* "); else BIO.println(" ");
// Bottom row
// Left if (n >= 4) BIO.print("* "); else BIO.print(" ");
// Middle if (n == 3) BIO.print("* "); else BIO.print(" ");
// Right if (n == 2 || n >= 4) BIO.println("* "); else BIO.println(" ");
BIO.println();
}
/*
* Clear the screen by displaying 25 empty lines
*/ staticvoid clearScreen() { int i;
Όσο τα προγράμματα που γράφουμε γίνονται πιο περίπλοκα αναγκαζόμαστε να
χρησιμοποιούμε διάφορες τεχνικές για την αποσφαλμάτωσή τους.
Μερικές από αυτές είναι:
ο διαχωρισμός του προγράμματος σε ξεχωριστές δομικές μονάδες
και ο ξεχωριστός έλεγχος της κάθε μιας με ένα
πρόγραμμα ελέγχου (test harness).
Η προσθήκη εντολών εκτύπωσης σε σημεία που θέλουμε να ελέγξουμε
τη ροή του προγράμματος ή τις τιμές των μεταβλητών του.
Την εκτέλεση των εντολών αυτών μπορούμε να την ελέξγουμε με μια συνθήκη
π.χ. τη μεταβλητή debug την οποία αλλάζουμε όταν το πρόγραμμα μπει σε
παραγωγή.
Την εκτέλεση του προγράμματος σε αποσφαλματωτή.
Το παρακάτω πρόγραμμα περιέχει εντολές εκτύπωσης κάτω από τον έλεγχο
της μεταβλητής debug.
import gr.aueb.dds.BIO;
/*
* Solve a qudratic equation ax^2 + bx + c = 0
* Demonstrates the use of debug print statements
*/ class Quadratic { publicstaticvoid main(String args[]) { double a, b, c; // Equation factors double d; // Discriminant boolean debug; // True during development, false in production
debug = false;
BIO.print("a=");
a = BIO.readDouble();
BIO.print("b=");
b = BIO.readDouble();
BIO.print("c=");
c = BIO.readDouble();
if (debug == true) {
BIO.println("a=" + a);
BIO.println("b=" + b);
BIO.println("c=" + c);
} if (a == 0) { if (debug)
BIO.println("a == 0"); if (b == 0) {
BIO.println("No solutions");
} else {
// Not really quadratic; one root
BIO.print("r=");
BIO.println(-c / b);
}
} else {
// Zero or two roots if (debug)
BIO.println("a != 0");
d = b * b - 4 * a * c; if (debug)
BIO.println("d=" + d); if (d < 0) {
// Complex root
BIO.print("r=");
// Real part
BIO.print(-b / 2 / a);
BIO.print("+");
// Imaginary part
BIO.print(Math.sqrt(-d) / 2 / a);
BIO.println("i");
} elseif (d == 0) {
// Two equal roots
BIO.print("r1=r2=");
BIO.println(-b / 2 / a);
} else {
BIO.print("r1=");
BIO.println((-b + Math.sqrt(d)) / 2 / a);
BIO.print("r2=");
BIO.println((-b - Math.sqrt(d)) / 2 / a);
}
}
}
}
Ασκήσεις
Να γράψετε ένα πρόγραμμα που να αφαιρεί τους κωδικούς επισημείωσης
(ακολουθίες της μορφής <tag options>)
από αρχεία HTML.
Το πρόγραμμα θα δέχεται στην είσοδό του HTML και θα παράγει
απλό κείμενο χωρίς τις ακολουθίες επισημείωσης.
Εκτελέστε το πρόγραμμα με είσοδο τη σελίδα αυτή, όπως θα την έχετε φυλλάξει
από το Web.
Γράψτε ένα πρόγραμμα που να διαβάζει αριθμούς από την είσοδό του μέχρι
να συναντήσει το 0.
Στο τέλος το πρόγραμμα πρέπει να εμφανίσει τον μέγιστο, τον ελάχιστο και
τον μέσο όρο των αριθμών που διάβασε.
Να γράψετε ένα πρόγραμμα που να λύνει ένα σύστημα δύο εξισώσεων με
δύο αγνώστους.
Προτείνετε στοιχεία εισόδου και αναμενόμενα αποτελέσματα για να ελέγξετε το
πρόγραμμα.
Να γράψετε ένα πρόγραμμα που να σας επιτρέπει να παίζετε ρουλέτα με
τον υπολογιστή.
Στην αρχή ξεκινάτε με ένα συγκεκριμένο ποσό στα χέρια σας.
Σε κάθε γύρο το πρόγραμμα σας ρωτάει πόσα χρήματα θέλετε να ποντάρετε και
σε ποιο νούμερο θέλετε να τα βάλετε (χρησιμοποιήστε -1 για όλα τα μαύρα
και -2 για όλα τα κόκκινα).
Στη συνέχεια το πρόγραμμα τυπώνει το σημείο που έπεσε η μπίλια
(χρησιμοποιήστε γραφικά και τη φαντασία σας για να δείξετε την κίνηση
αυτή) καθώς και το αποτέλεσμα για τον παίκτη (κερδισμένος / χαμένος)
και τα χρήματα που έχει τώρα στη διάθεσή του.
Το παιγνίδι τελειώνει όταν τελειώσουν τα χρήματα του παίκτη.
Πρόσθετες δομές ελέγχου: switch for break continue
Η εντολή for
Μπορούμε να συμπυκνώσουμε τον έλεγχο ενός βρόχου με την εντολή
for.
Αυτή χρησιμοποιείται ως εξής:
for (αρχική παράσταση; παράσταση συνθήκης; τελική παράσταση)
εντολή;
Ο βρόχος που ορίζει η for εκτελείται ως εξής:
Υπολογίζεται η αρχική παράσταση.
Υπολογίζεται η παράσταση συνθήκης και αν είναι αληθής τότε εκτελείται η εντολή.
Υπολογίζεται η τελική παράσταση.
Ο βρόχος συνεχίζει από το βήμα 2.
Παράδειγμα (τυπώνει τους αριθμούς 0-9):
import gr.aueb.dds.BIO;
class Count { publicstaticvoid main(String args[]) { int i;
for (i = 0; i < 10; i++)
BIO.println(i);
}
}
Η εντολή for είναι ισοδύναμη με την παρακάτω while:
αρχική παράσταση; while (παράσταση συνθήκης) {
εντολή;
τελική παράσταση;
}
Οποιαδήποτε από τις τρεις παραστάσεις μπορεί να παραληφθεί.
Ανάλογα με το με ποια σταθερή ισούται η τιμή της παράστασης
εκτελείται η αντίστοιχη εντολή.
Αν καμία από τις σταθερές δεν ταυτίζεται με την τιμή της παράστασης
τότε εκτελείται η εντολή που ακολουθεί την default (αν υπάρχει), αλλιώς
δεν εκτελείται καμία εντολή.
Παράδειγμα (τυπώνει την είσοδο μετατρέποντας χαρακτήρες που παριστάνονται
με ακολουθίες διαφυγής στις αντίστοιχες ακολουθίες):
import gr.aueb.dds.BIO;
class PrintEscapes { publicstaticvoid main(String args[]) { int c;
while ((c = BIO.readChar()) != -1) switch (c) { case '\n':
BIO.print("\\n"); break; case '\r':
BIO.print("\\r"); break; case '\t':
BIO.print("\\t"); break; default:
BIO.print((char)c);
}
}
}
Με είσοδο τον εαυτό του παράγει το παρακάτω αποτέλεσμα:
Το break δηλώνει ότι ο έλεγχος του προγράμματος μετά την εντολή
συνεχίζει στο τέλος της switch.
Σε αντίθετη περίπτωση ο έλεγχος του προγράμματος συνεχίζει στην επόμενη
case.
Η ιδιότητα αυτή μας επιτρέπει να δηλώσουμε πολλαπλές τιμές.
Το παρακάτω παράδειγμα μετατρέπει όλα τα πεζά φωνήεντα σε a
και σύμφωνα σε z
import gr.aueb.dds.BIO;
class MapChars { publicstaticvoid main(String args[]) { int c;
while ((c = BIO.readChar()) != -1) switch (c) { case 'a': case 'e': case 'i': case 'o': case 'u': case 'y':
BIO.print('a'); break; case 'b': case 'c': case 'd': case 'f': case 'g': case 'h': case 'j': case 'k': case 'l': case 'm': case 'n': case 'p': case 'q': case 'r': case 's': case 't': case 'v': case 'w': case 'x': case 'z':
BIO.print('z'); break; default:
BIO.print((char)c);
}
}
}
Με είσοδο τον εαυτό του παράγει το παρακάτω αποτέλεσμα:
Η εντολή continue μας επιτρέπει να συνεχίσουμε την εκτέλεση
μιας δομής ελέγχου βρόχου (for, while, do) από το σημείο ελέγχου
της συνθήκης.
Είναι κυρίως χρήσιμη όταν θέλουμε να κάνουμε έναν έλεγχο στην
κορυφή του βρόχου για κάποια ειδική περίπτωση.
Το παρακάτω παράδειγμα μετατρέπει κάθε πέμπτο πεζό φωνήεν σε a
και σύμφωνο σε z:
import gr.aueb.dds.BIO;
class MapChars { publicstaticvoid main(String args[]) { int c, i;
i = 0; while ((c = BIO.readChar()) != -1) { if (i++ % 5 != 0) {
BIO.print((char)c); continue;
} switch (c) { case 'a': case 'e': case 'i': case 'o': case 'u': case 'y':
BIO.print('a'); break; case 'b': case 'c': case 'd': case 'f': case 'g': case 'h': case 'j': case 'k': case 'l': case 'm': case 'n': case 'p': case 'q': case 'r': case 's': case 't': case 'v': case 'w': case 'x': case 'z':
BIO.print('z'); break; default:
BIO.print((char)c);
}
}
}
}
Δομές με ετικέτες
Οι εντολές break και continue διακόπτουν ή συνεχίζουν μόνο
τον εσωτερικό βρόχο στον οποίο βρίσκονται.
Ορισμένες φορές όμως θέλουμε να διακόψουμε ή να συνεχίσουμε
έναν βρόχο που βρίσκεται έξω από την εσωτερική δομή ελέγχου.
Στις περιπτώσεις αυτές μπορούμε να ονομάσουμε
την εξωτερική δομή ελέγχου με τη χρήση μιας ετικέτας (label)
και να την δώσουμε ως όρισμα στην αντίστοιχη εντολή break ή continue.
Το όνομα της ετικέτας πρέπει να έχει ίδια μορφή με τα ονόματα των
μεταβλητών.
Η ονομασία μιας δομής με ετικέτα γίνεται με σύνταξη της μορφής:
ετικέτα: while (συνθήκη) {
εντολές;
}
ετικέτα: do {
εντολές;
} while (συνθήκη);
ετικέτα: for (αρχή; συνθήκη; επανάληψη) {
εντολές;
}
Στη συνέχεια μπορούμε να δώσουμε το όνομα της ετικέτας ως όρισμα
σε μια break ή continue.
Το παρακάτω παράδειγμα μετατρέπει όλα τα πεζά φωνήεντα σε a
και σύμφωνα σε z.
Ο έλεγχος για το τέλος του αρχείου έχει μεταφερθεί μέσα στη δομή switch.
import gr.aueb.dds.BIO;
class MapChars { publicstaticvoid main(String args[]) { int c;
charloop: for (;;) {
c = BIO.readChar(); switch (c) { case -1: // End of file breakcharloop; case 'a': case 'e': case 'i': case 'o': case 'u': case 'y':
BIO.print('a'); break; case 'b': case 'c': case 'd': case 'f': case 'g': case 'h': case 'j': case 'k': case 'l': case 'm': case 'n': case 'p': case 'q': case 'r': case 's': case 't': case 'v': case 'w': case 'x': case 'z':
BIO.print('z'); break; default:
BIO.print((char)c);
}
}
}
}
Να γράψετε ένα πρόγραμμα που να διαβάζει χαρακτήρες
από την είσοδό του μέχρι να συναντήσει την τελεία.
Οι χαρακτήρες που διαβάζει να εκτυπώνονται σύμφωνα με το διεθνές
φωνητικό αλφάβητο:
Alpha Bravo Charlie Delta Echo Foxtrot Golf Hotel India
Juliet Kilo Lima Mike November Oscar Papa Quebec Romeo
Sierra Tango Uniform Victor Whiskey Xray Yankee Zulu.
Τα ψηφία 1-9 να εκτυπώνονται με επαναλαμβανόμενα αστέρια (*)
αντίστοιχα με το ψηφίο.
Χαρακτήρες για τους οποίους δεν υπάρχει αντιστοιχία να εκτυπώνονται
ως έχουν.
Παράδειγμα:
Είσοδος:
Hello 2 you!.
Αποτέλεσμα:
Hotel Echo Lima Lima Oscar ** Yankee Oscar Uniform!
Ορισμός συναρτήσεων
Δήλωση συναρτήσεων
Μπορούμε να ορίσουμε δικές μας συναρτήσεις με τον εξής τρόπο:
προσδιοριστές τύπος αποτελέσματος
όνομα συνάρτησης(δηλώσεις παραμέτρων)
{
δηλώσεις τοπικών μεταβλητών;
εντολές; return (τιμή);
}
Οι παράμετροι της συνάρτησης είναι μια σειρά από τύπους και ονόματα
μεταβλητών χωρισμένα με κόμμα.
Όταν καλείται μια συνάρτηση οι μεταβλητές που ορίστηκαν ως παράμετροι
παίρνουν τις τιμές που δόθηκαν στο όρισμα κατά την κλήση.
Η εντολή return μπορεί να εμφανιστεί σε οποιοδήποτε σημείο της συνάρτησης.
Στο σημείο εκείνο σταματά η εκτέλεση της συνάρτηση και ο
έλεγχος ροής (control flow) του προγράμματος
συνεχίζει από το σημείο που κλήθηκε η συνάρτηση.
Η τιμή που ακολουθεί την return είναι η τιμή που επιστρέφει η συνάρτηση.
Οι συναρτήσεις μπορούν να οριστούν με οποιαδήποτε σειρά μέσα στην κλάση.
Παράμετροι τιμής
Οι μεταβλητές που αποτελούν το όρισμα της συνάρτησης αποκτούν
την τιμή που θα δώσουμε όταν καλέσουμε τη συνάρτηση.
Οποιαδήποτε μετατροπή στην τιμή των μεταβλητών αυτών δεν
επηρεάζει την τιμή κάποιας μεταβλητής που δόθηκε ως παράμετρος
κατά την κλήση της συνάρτησης.
Παράδειγμα (τυπώνει 10, 20, 10):
import gr.aueb.dds.BIO;
class Byval { staticvoid
print_n2n(int n)
{
BIO.println(n);
n = n * 2;
BIO.println(n);
}
publicstaticvoid
main(String args[])
{ int i = 10;
print_n2n(i);
BIO.println(i);
}
}
Έτσι μπορούμε να χρησιμοποιούμε τις μεταβλητές του ορίσματος
σαν κανονικές μεταβλητές χωρίς να χρειάζεται (ούτε και να
επιτρέπεται) να τις ορίσουμε μέσα στο σώμα της συνάρτησης.
Αν υπάρχουν άλλες μεταβλητές ορισμένες έξω από το τμήμα με το ίδιο
όνομα, τότε όσο ο έλεγχος του προγράμματος βρίσκεται μέσα στο τμήμα,
η μεταβλητή που χρησιμοποιείται είναι αυτή που έχει οριστεί στο τμήμα.
Η τιμή μιας μεταβλητής που έχει οριστεί μέσα σε ένα τμήμα χάνεται
όταν ο έλεγχος του προγράμματος βγει από το τμήμα αυτό.
Γενικά, καλό είναι οι μεταβλητές να ορίζονται κοντά στο τμήμα
που χρησιμοποιούνται.
Σε μικρές συναρτήσεις αυτό είναι εφικτό με τον ορισμό τους στην αρχή της
συνάρτησης.
Όταν όμως μια μεταβλητή έχει ρόλο μόνο μέσα σε ένα περιορισμένο τμήμα,
τότε καλό είναι να οριστεί μέσα στο τμήμα.
Καλό είναι στο σώμα του προγράμματός μας να μην υπάρχουν
μαγικοί αριθμοί (magic numbers)
(όπως 3.1415, 1024, 6.02e23, 9.81), αλλά να τους ορίζουμε μέσα στην
κλάση που χρησιμοποιούνται ως σταθερές (pi, kbyte, avogadro, g).
Ασκήσεις
Να υλοποιήσετε σε Java ένα πρόγραμμα που να τυπώνει
σχήματα σαν το παρακάτω:
Οι κλάσεις χρησιμοποιούνται για την υλοποίηση
αφηρημένων τύπων δεδομένων (abstract data types).
Για το σκοπό αυτό μπορούμε να ορίσουμε μέλη (members)
της κλάσης:
μεταβλητές και συναρτήσεις
που είναι ορατά μόνο από συναρτήσεις που αναφέρονται στον τύπο αυτό
(private) καθώς και μεταβλητές και συναρτήσεις που είναι καθολικά
ορατά (public).
Οι μεταβλητές ορίζουν πεδία και οι συναρτήσεις ορίζουν
μεθόδους των αντικειμένων της κλάσης.
Αφού δηλωθεί μια κλάση (σε ένα αρχείο κλάση.java)
μπορούν να οριστούν μεταβλητές (αντικείμενα) με το όνομα (τύπο) της κλάσης.
Πρόσβαση στις μεθόδους της κλάσης έχουν οι μεταβλητές αυτές με τη
σύνταξη μεταβλητή.συνάρτηση.
Κάθε αντικείμενο της κλάσης έχει ένα δικό του αντίγραφο των πεδίων
που έχουμε ορίσει.
Σε αντίθεση με τους βασικούς τύπους της Java (int, boolean, double)
που ο ορισμός τους καθορίζει και την περιοχή της μνήμης που φυλάσσονται
τα αντίστοιχα στοιχεία, οι μεταβλητές που ορίζονται ως αντικείμενα περιέχουν
απλώς έναν δείκτη σε περιοχή της μνήμης που πιθανώς να περιέχει τα στοιχεία
για το συγκεκριμένο αντικείμενο.
Αφού ορίσουμε μια μεταβλητή ως αντικείμενο, πρέπει να καθορίσουμε
και την περιοχή της μνήμης στην οποία θα φυλάσσονται τα πεδία του.
Αυτή μπορεί να είναι:
Νέα περιοχή μνήμης οριζόμενη με τη σύνταξη
objectVariable = new ObjectType();
Παράδειγμα:
Point a;
a = new Point();
Αντιγράφοντας στο συγκεκριμένο αντικείμενο κάποιο άλλο
το οποίο έχει ήδη οριστεί:
Παράδειγμα:
Point a, b;
a = new Point();
b = a;
Στην περίπτωση αυτή, τα δύο αντικείμενα μοιράζονται (share)
την ίδια περιοχή της μνήμης.
Παράδειγμα:
import gr.aueb.dds.BIO;
class Point { privateint x, y;
// Return x coordinate publicint getx() { return x; }
// Return y coordinate publicint gety() { return y; }
// Set coordinate to x, y publicvoid setpos(int sx, int sy) {
x = sx;
y = sy;
}
// Display point coordinates publicvoid display() {
BIO.print("(x=" + x);
BIO.println(", y=" + y + ")");
}
// Test point functionality publicstaticvoid main(String args[])
{
Point a, b;
Point c;
a = new Point();
a.setpos(2, 3);
BIO.println("a.getx()=" + a.getx());
b = new Point();
b.setpos(8, 7);
c = b;
BIO.print("b=");
b.display();
BIO.print("c=");
c.display();
c.setpos(66, 100);
b.display();
}
}
Οι συναρτήσεις της κλάσης μπορούν να έχουν πρόσβαση στα στοιχεία της
κλάσης με τους εξής τρόπους:
με το όνομά τους (π.χ. x),
μέσω της ορισμένης από τη γλώσσα
μεταβλητής this που δείχνει στην κλάση (π.χ. this.x),
Παράδειγμα:
publicvoid setpos(int sx, int sy) { this.x = sx;
y = sy;
}
Χωρισμός κλάσεων σε αρχεία
Έχοντας ορίσει μια κλάση, μπορούμε να χηρισμοποιήσουμε αντικείμενα
της κλάσης αυτής σε άλλες κλάσεις.
Τις άλλες κλάσεις μπορούμε να τις ορίσουμε σε ξεχωριστά αρχεία.
Όταν γράψουμε όλα τα αρχεία, μεταγλωττίζουμε το αρχείο .java που
περιέχει τη μέθοδο main.
Παράδειγμα:
Αρχείο Point.java
import gr.aueb.dds.BIO;
class Point { privateint x, y;
publicvoid setpos(int sx, int sy) {
x = sx;
y = sy;
} publicvoid display() {
BIO.print("(x=" + x);
BIO.println(", y=" + y + ")");
}
}
Αρχείο TestPoint.java
import gr.aueb.dds.BIO;
class TestPoint { publicstaticvoid main(String args[])
{
Point a;
a = new Point();
a.setpos(2, 3);
a.display();
}
}
Ορατότητα
Όταν χρησιμοποιούμε μεταβλητές μιας κλάσης που έχουμε ορίσει μέσα
σε μια άλλη, τότε μπορούμε να χρησιμοποιήσουμε όλα τα πεδία και όλες
τις μεθόδους που έχουν οριστεί με τον προσδιοριστή public.
Αντίθετα, δεν μπορούμε να χρησιμοποιήσουμε σε άλλες κλάσεις
πεδία και μεθόδους που έχουμε ορίσει ως private.
Αυτές μπορούν να χρησιμοποιηθούν μόνο μέσα από μεθόδους της
κλάσης στην οποία ορίζονται.
Στο παρακάτω παράδειγμα στην κλάση Point τα στοιχεία public είναι τα
x, y, και moveToCenter().
Αντίθετα τα μέλη (ιδιότητες) της κλάσης visible και serialNumber και η
μέθοδος setpos
δεν είναι ορατά και προσβάσιμα παρά μόνο από τις συναρτήσεις (μεθόδους)
της κλάσης.
Αρχείο Point.java
import gr.aueb.dds.BIO;
class Point {
// Public fields publicint x, y; privateboolean visible; privateint serialNumber;
// Private method privatevoid setpos(int sx, int sy) {
x = sx;
y = sy;
}
// Public methd publicvoid moveToCenter() {
setpos(0, 0);
}
}
Αρχείο TestPoint.java
import gr.aueb.dds.BIO;
class TestPoint { publicstaticvoid main(String args[])
{
Point a;
a = new Point();
a.moveToCenter();
// Use public field
a.x = 10;
}
}
Η μέθοδος κατασκευής καλείται κάθε φορά που δημιουργείται
ένα νέο αντικείμενο (με τη χρήση new ObjectType).
Η μέθοδος καταστροφής καλείται κάθε φορά που παύει να υπάρχει
ένα αντικείμενο δηλαδή αντίστοιχα όταν τελειώνει το πρόγραμμα, όταν
η ροή βγαίνει από το τοπικό τμήμα, ή όταν το σύστημα αποκομιδής αχρήστων
της Java καταστρέφει το συγκεκριμένο αντικείμενο.
Το όρισμα που δηλώνουμε στη μέθοδο κατασκευής επιτρέπει προσδιορισμό
ιδιοτήτων του αντικειμένου που δημιουργούμε (π.χ. τον αριθμό στοιχείων
σε έναν πίνακα) ή αρχικών τιμών.
Για το ίδιο αντικείμενο μπορούμε να ορίσουμε πολλές μεθόδους κατασκευής
με διαφορετικά ορίσματα.
Η μέθοδος καταστροφής δε δέχεται κάποιο όρισμα.
Η μέθοδος κατασκευής και η μέθοδος καταστροφής δε χρειάζονται κάποιον
προσδιοριστή (static, public, void).
Η κλήση της συνάρτησης κατασκευής μπορεί να γίνει κατά τον
ορισμό μιας μεταβλητής με τη μορφή "κλάση μεταβλητή = new κλάση(όρισμα)".
Παράδειγμα:
import gr.aueb.dds.BIO;
class Point { privateint x, y;
// Point constructor
Point(int ix, int iy) {
x = ix;
y = iy;
}
// Point destructor publicvoid finalize() {
BIO.println("Another point bites the dust");
BIO.print("The point was at ");
display();
}
publicvoid display() {
BIO.print("(x=" + x);
BIO.println(", y=" + y + ")");
} staticpublicvoid main(String args[]) {
Point a = new Point(1, 2);
Point b = new Point(5, 8);
a = b;
// Force the garbage collector to run
System.gc();
}
}
Ιδιότητες και μέθοδοι της κλάσης
Σε μια κλάση μπορούν να δηλωθούν (με τον προσδιορισμό static)
μεταβλητές οι οποίες υπάρχουν μόνο μια φορά για όλη την κλάση,
καθώς και συναρτήσεις που μπορούν
να κληθούν με τη σύνταξη κλάση.συνάρτηση.
Οι μεταβλητές αυτές χρησιμοποιούνται για την επεξεργασία στοιχείων
που αφορούν ολόκληρη την κλάση και όχι τα αντικείμενά της.
Οι συναρτήσεις που έχουν οριστεί static δεν έχουν πρόσβαση σε μη
static μεταβλητές ούτε στη μεταβλητή this.
Το παρακάτω παράδειγμα ορίζει έναν μετρητή numPoints που μετρά πόσα
σημεία είναι ενεργά καθώς και την αντίστοιχη συνάρτηση πρόσβασης getNumPoints:
import gr.aueb.dds.BIO;
class Point { privateint x, y;
// Count number of points used privatestaticint numPoints;
// Point constructor
Point(int ix, int iy) {
x = ix;
y = iy;
numPoints++; // Adjust points counter
}
// Point constructor
Point(int xy) {
x = y = xy;
numPoints++; // Adjust points counter
}
// Point destructor publicvoid finalize() {
BIO.println("Another point bites the dust");
BIO.print("The point was at ");
display();
numPoints--; // Adjust points counter
}
// Return number of points currently used publicstaticint getNumPoints() { return numPoints;
}
staticpublicvoid main(String args[]) {
Point a = new Point(1, 2);
Point b = new Point(5, 8);
Point c = new Point(7);
c.display();
a = b;
BIO.println(getNumPoints() + " points are alive now");
BIO.println("Garbage collecting");
// Force the garbage collector to run
System.gc();
BIO.println(Point.getNumPoints() + " points are alive now");
}
}
Φροντιστηριακή άσκηση
Να υλοποιηθεί σε Java μια κλάση που να παριστάνει αντικείμενα
σε κίνηση με ιδιότητες την αρχική τους θέση και
την ταχύτητά τους στους άξονες x και y και τις παρακάτω μεθόδους:
void setInitialPosition(double x, double y)
Θέτει την αρχική θέση του αντικειμένου.
void setVelocity(double x, double y)
Θέτει την ταχύτητα x, y του αντικειμένου.
double GetXPosition(int t)
Επιστρέφει τη θέση x του αντικειμένου κατά τη χρονική στιγμή t.
double GetYPosition(int t)
Επιστρέφει τη θέση y του αντικειμένου κατά τη χρονική στιγμή t.
Με βάση το παραπάνω να υλοποιηθεί πρόγραμμα που
Ορίζει δύο αντικείμενα.
Για κάθε ένα από τα αντικείμενα ζητάει από το χρήστη την αρχική του θέση,
την ταχύτητά του και ένα χρόνο t και εμφανίζει στην οθόνη τη θέση του κατά το
χρόνο t.
Σημείωση: η θέση κάθε αντικειμένου υπολογίζεται μόνο με βάση την αρχική του
θέση και την ταχύτητά του.
Παράδειγμα:
A1x=6
A1y=12
A1 vx=1
A1 vy=1
t=2
A1x=8 A1y=14
A2x=6
A2y=67
A2 vx=10
A2 vy=10
t=1
A2x=16 A2y=77
Ασκήσεις
Να υλοποιηθούν σε Java οι κλάσεις andgate, orgate, notgate.
Οι κλάσεις αυτές θα προσομοιάζουν τις αντίστοιχες λογικές πύλες.
Κάθε κλάση να έχει μεθόδους που να θέτουν τις εισόδους (π.χ. setA, setB)
και μέθοδο που να επιστρέφει την τιμή της εξόδου (π.χ. getOutput).
Με τη χρήση των παραπάνω κλάσεων (και μόνο) να υλοποιήσετε
μια κλάση που να προσομοιάζει έναν ημιαθροιστή.
Η κλάση αυτή να έχει μεθόδους που να θέτουν τις δύο εισόδους και
μεθόδους που να επιστρέφουν το άθροισμα και το κρατούμενο.
Να γράψετε ένα πρόγραμμα σε Java που να τυπώνει τους πίνακες
αλήθειας για τις παραπάνω κλάσεις.
(Προαιρετικά) Με τη χρήση των παραπάνω κλάσεων να υλοποιήσετε
μια κλάση που να προσομοιάζει έναν πλήρη αθροιστή.
Η κλάση αυτή πρέπει να έχει μεθόδους που να θέτουν τις δύο εισόδους και το
κρατούμενο εισόδου καθώς και μεθόδους που να επιστρέφουν το άθροισμα και
το κρατούμενο εξόδου.
Βιβλιογραφία
Γιώργος Λιακέας
Εισαγωγή στην Java. σ. 141-152
Εκδόσεις Κλειδάριθμος 2001.
Μπορούμε να ορίσουμε μια ομάδα μεταβλητών ίδιου τύπου στην
οποία θα έχουμε πρόσβαση με βάση το όνομά της και έναν
δείκτη (index) ως πίνακα (array).
Ο ορισμός γίνεται ως εξής:
τύπος μεταβλητή[]
Παράδειγμα:
int values[];
ορίζει έναν πίνακα ακεραίων με όνομα values.
Οι πίνακες συμπεριφέρονται ως αντικείμενα της Java.
Ο χώρος για τα στοιχεία κάθε πίνακα ορίζεται με τον τελεστή new.
Το παρακάτω παράδειγμα ορίζει πως ο πίνακα values περιέχει χώρο για
δέκα ακεραίους.
int values[];
values = newint[10]
Πρόσβαση σε στοιχεία ενός πίνακα μπορούμε να έχουμε μόνο αφού ο πίνακας
αποκτήσει τιμή με τη new ή με αντιγραφή της αναφοράς κάποιου άλλου
πίνακα.
Πρόσβαση στα στοιχεία ενός πίνακα έχουμε με βάση το όνομα του
πίνακα και έναν ακέραιο δείκτη.
Ο δείκτης πρέπει να λαμβάνει τιμές από το 0 μέχρι τον αριθμό των στοιχείων - 1.
Το πεδίο του πίνακα length περιέχει τον αριθμό των στοιχείων
του πίνακα.
Το πεδίο length μπορούμε μόνο να το διαβάσουμε.
Το παρακάτω παράδειγμα διαβάζει 10 ακεραίους και τους τυπώνει με την
ανάποδη σειρά:
import gr.aueb.dds.BIO;
class Reverse { publicstaticvoid main(String args[]) { int values[] = newint[10];
for (int i = 0; i < values.length; i++)
values[i] = BIO.readInt(); for (int i = values.length - 1; i >= 0; i--)
BIO.println(values[i]);
}
}
Πίνακες πολλαπλών διαστάσεων
Μπορούμε να ορίσουμε πίνακες πολλαπλών διαστάσεων ακολουθώντας τον
ορισμό των στοιχείων της μιας διάστασης από τον ορισμό των στοιχείων
της επόμενης.
Παράδειγμα:
double matrix[][];
matrix = newdouble[4][3]
Ο παραπάνω ορισμός ορίζει απλώς έναν πίνακα τεσσάρων στοιχείων
(γραμμών) κάθε ένα από τα οποία είναι ένας πίνακας τριών στοιχείων (στηλών).
Η πρόσβαση στα στοιχεία των πινάκων πολλαπλών διαστάσεων γίνεται
όπως και στα στοιχεία των πινάκων μιας διάστασης.
Παράδειγμα (τυπώνει όλα τα στοιχεία του πίνακα):
int i, j;
for (i = 0; i < matrix.length; i++) { for (j = 0; j < matrix[i].length; j++)
BIO.print(matrix[i][j] + " ");
BIO.println();
}
Πίνακες ως ορίσματα
Για να ορίσουμε ότι μια παράμετρος συνάρτησης είναι πίνακας
γράφουμε τον ορισμό του πίνακα στις παραμέτρους της συνάρτησης.
Παράδειγμα:
/*
* Return the sum of a vector v elements.
*/ staticdouble vector_sum(double v[]) { int i; double sum = 0.0;
for (i = 0; i < v.length; i++)
sum = sum + v[i]; return (sum);
}
Για να περάσουμε έναν πίνακα ως όρισμα σε μια συνάρτηση
γράφουμε απλώς το όνομά του στις παραμέτρους.
Παράδειγμα:
Όταν περνάει ένας πίνακας ως όρισμα σε συνάρτηση δεν περνάει ένα
αντίγραφο της τιμής του, όπως όταν περνάει μια απλή μεταβλητή,
αλλά μια αναφορά (reference) στον ίδιο τον
πίνακα.
Αλλαγές στα στοιχεία του πίνακα που γίνονται μέσα στη συνάρτηση
αναφέρονται στον πίνακα που πέρασε ως όρισμα.
Ο τρόπος αυτός κλήσης λέγεται
κλήση κατ' αναφορά (call by reference).
Παράδειγμα:
/*
* Set all n elements of vector v to the value d
*/ void vector_setvalue(double v[], double d) { int i;
Μπορούμε να δώσουμε αρχικές τιμές στα στοιχεία ενός πίνακα
αν μετά τη δήλωσή του γράψουμε τις τιμές των στοιχείων
χωρισμένες με κόμματα μέσα σε άγκιστρα.
Στην περίπτωση αυτή διατίθεται αυτόματα και ο ανάλογος χώρος
για την αποθήκευση των στοιχείων.
Παράδειγμα:
Οι τελεστές που δεν έχουμε εξετάσει μέχρι τώρα είναι
(με σειρά προτεραιότητας) οι παρακάτω:
<<
ολίσθηση προς τα αριστερά
>>
ολίσθηση προς τα δεξιά
>>
ολίσθηση προς τα δεξιά με εισαγωγή μηδενικών
&
δυαδική ή λογική σύζευξη
|
δυαδική ή λογική διάζευξη
^
δυαδική ή λογική αποκλειστική διάζευξη
?:
υπολογισμός υπό συνθήκη
*= /= %= += -= <<= >>=
>>>= &= ^= |=
ανάθεση με τελεστή
Ασκήσεις
Πίνακες
Γράψτε ένα πρόγραμμα το οποίο διαβάζει χαρακτήρες από την
είσοδό του μέχρι το τέλος του αρχείου (EOF).
Στη συνέχεια τυπώνει ένα ραβδόγραμμα με αστεράκια για κάθε έναν από
τους εμφανιζόμενους χαρακτήρες.
Επιπλέον για τους χαρακτήρες που εμφανίζονται
στην είσοδο του προγράμματος τις μέγιστες και τις ελάχιστες φορές
εμφανίζει τον αντίστοιχο χαρακτήρα καθώς και τον αριθμό των
φορών που εμφανίστηκε.
Παράδειγμα εξόδου:
a ********
b ****
e ************
z *
Most frequent: e; 12 time(s).
Least frequent: z; 1 time(s).
Σημείωση: Αν η είσοδος του προγράμματος δεν περιέχει ελληνικούς χαρακτήρες,
τότε μπορείτε να φυλάξετε τη συχνότητα του κάθε χαρακτήρα σε έναν πίνακα
128 θέσεων με δείκτη τον ίδιο το χαρακτήρα.
Βιβλιογραφία
Γιώργος Λιακέας
Εισαγωγή στην Java. σ. 113-117
Εκδόσεις Κλειδάριθμος 2001.
class Tree {
// Tree properties privateint treeWidth; // Width of the tree privateint trunkWidth; // Width of the trunk privateint trunkHeight; // Height of the trunk privatechar treeFill; // Fill character
// Constructor
// ew : Tree body width
// uw : Trunk width
// uh : Trunk heigth
// f : fill character
Tree(int ew, int uw, int uh, char f) {
treeWidth = ew;
trunkWidth = uw;
trunkHeight = uh;
treeFill = f;
}
// Draw a tree publicvoid draw() {
body();
trunk();
}
// Draw the tree's body privatevoid body() { int i;
for (i = 1; i < treeWidth; i = i + 2) {
DrawChar.space((treeWidth - i) / 2);
fill(i);
BIO.println();
}
}
// Draw the tree's trunk privatevoid trunk() { int j;
class Snow { privatedouble density; // Snow density: 0 very dense, 1 no snow privatechar symbol; // Symbol to use for snowflakes privateint lines; // Lines to draw
// Constructor
Snow(double d, char s, int l) {
density = d;
symbol = s;
lines = l;
}
// Draw the snow publicvoid draw() { int i;
for (i = 0; i < lines; i++) { if (Math.random() > density)
snowFlakes();
BIO.println();
}
}
// Draw a line of random snowflakes privatevoid snowFlakes() { int width = 70;
while (width > 0) { int s = (int)(Math.random() * 10 * density);
DrawChar.space(s);
BIO.print(symbol);
width = width - s - 1;
}
}
// Test the class publicstaticvoid main(String args[]) {
Snow s = new Snow(0.1, '*', 4);
s.draw();
}
}
Κλάση DrawChar
import gr.aueb.dds.BIO;
// Character drawing functions class DrawChar {
// Repeat character c, n times on screen publicstaticvoid repeatChar(int n, char c) { int k;
for (k = 0; k < n; k++)
BIO.print(c);
}
// Display n space characters publicstaticvoid space(int n) {
repeatChar(n, ' ');
}
/*
* Draw a christmas card
* Uses classes Snow and Tree
*/ class Xmas { publicstaticvoid main(String args[]) {
// Three types of snow
Snow top = new Snow(0.2, '*', 5);
Snow middle = new Snow(0.3, ',', 7);
Snow bot = new Snow(0.4, '.', 7);
// And three different trees
Tree small = new Tree(8, 2, 2, '!');
Tree big = new Tree(18, 3, 4, '#');
Tree tiny = new Tree(6, 1, 2, '!');
Κάθε υποκλάση κληρονομεί (inherits) τις μεθόδους
και τις ιδιότητες που έχουν οριστεί ως public στη βασική κλάση.
Η υποκλάση δεν έχει πρόσβαση στις μεθόδους και τις ιδιότητες
που έχουν οριστεί ως private στη βασική κλάση.
Η υποκλάση μπορεί να ορίσει νέες ιδιότητες και μεθόδους και να
υπερσκελίσει (override)
ιδιότητες και μεθόδους που έχει ορίσει η βασική κλάση.
Έτσι, οι περισσότερες κλάσεις αντικαθιστούν τη μέθοδο toString()
που επιστρέφει μια συμβολοσειρά που αντιστοιχεί στο περιεχόμενο ενός
αντικειμένου και παρέχεται από την Java για όλα τα αντικείμενα με μια πιο
εξειδικευμένη μέθοδο.
Μέσα από την κλάση μπορούμε να αναφερθούμε στη βασική κλάση
με τον προσδιορισμό super.
Παράδειγμα:
import gr.aueb.dds.BIO;
class Shape { privateint x, y; // Position publicvoid setPosition(int px, int py) {
x = px;
y = py;
} public String toString() { return "Shape(" + x + ", " + y + ")";
}
}
class Circle extends Shape { privateint radius; publicvoid setRadius(int r) {
radius = r;
} public String toString() { returnsuper.toString() + ": Circle(" + radius + ")";
}
}
Η παραπάνω διάταξη μπορεί να παρασταθεί σχηματικά ως εξής:
Μπορούμε να ορίσουμε μια άλλη κατηγορία μεθόδων και ιδιοτήτων
με τον προσδιορισμό protected.
Αυτές είναι προσβάσιμες από τις υποκλάσεις της
κλάσης μας, αλλά όχι από άλλες συναρτήσεις.
Παράδειγμα:
class Shape { privateint x, y; // Position protectedint getX() { return x; } protectedint getY() { return y; } publicvoid setPosition(int px, int py) {
x = px;
y = py;
} public String toString() { return "Shape(" + x + ", " + y + ")";
}
}
Μια αναφορά (αντικείμενο) σε μια υποκλάση μπορεί αυτόματα να μετατραπεί σε
αναφορά (αντικείμενο) της βασικής της κλάσης.
Αυτό επιτρέπεται διότι κάθε αντικείμενο μιας υποκλάσης
είναι (is a) και αντικείμενο της βασικής κλάσης.
Το αντικείμενο συνεχίζει να διατηρεί τις ιδιότητες της υποκλάσης
μετά τη μετατροπή και μπορεί να μετατραπεί πίσω στην ίδια υποκλάση
με τη χρήση ρητού τελεστή μετατροπής (cast).
Παράδειγμα:
staticpublicvoid main(String args[])
{
Rectangle r = new Rectangle();
Shape s;
r.setposition(1, 2);
r.setdimensions(50, 50);
s = r;
s.setposition(10, 20);
BIO.println(r);
BIO.println(s);
r = (Rectangle)s;
}
Δυναμική διεκπεραίωση
Οι υποκλάσεις μιας κλάσης μπορούν να αντικαταστήσουν μια μέθοδό της
με μια που θα ορίσουν αυτές.
Όταν κληθεί η μέθοδος που έχει αντικατασταθεί από μια υποκλάση
μέσω ενός αντικειμένου της βασικής κλάσης το οποίο έχει προέλθει από αντικείμενο
κάποιας υποκλάσης τότε θα κληθεί η αντίστοιχη μέθοδος της υποκλάσης
από την οποία έχει προέλθει το αντικείμενο.
το δυναμικό καθορισμό της συμπεριφοράς ενός αντικειμένου ανάλογα με
την κλάση του κατά την εκτέλεση του προγράμματος,
την αλλαγή της συμπεριφοράς μιας παλιάς κλάσης από μια νεώτερη
(υποκλάση της) και
την ενοποιημένη διαχείριση διαφορετικών αντικειμένων μέσω της βασικής
τους κλάσης.
Η δυνατότητα αυτή προάγει τη Java από γλώσσα που υποστηρίζει τα
αντικείμενα σε αντικειμενοστρεφή γλώσσα.
Αφηρημένες κλάσεις
Αν μια μέθοδος μιας κλάσης οριστεί με τον προσδιοριστή abstract
και χωρίς σώμα τότε η συνάρτηση αυτή είναι
ιδεατή (abstract) δηλαδή δεν έχει υλοποίηση στη
συγκεκριμένη κλάση.
Παράδειγμα:
Αν μια κλάση περιέχει (ή έχει κληρονομήσει)
τουλάχιστον μια ιδεατή μέθοδο τότε και αυτή πρέπει να οριστεί με τον
προσδιοριστή abstract και
ονομάζεται ιδεατή (abstract).
Οι ιδεατές κλάσεις χρησιμοποιούνται μόνο για να ορίσουν γενικές έννοιες
από τις οποίες εκπορεύονται συγκεκριμένες κλάσεις.
Σε αντικείμενα μιας ιδεατής κλάσης μπορούν να ανατεθούν αντικείμενα
από μη ιδεατές υποκλάσεις της.
Τα ίδια όμως τα αντικείμενα μιας ιδεατής κλάσης δεν μπορούν ποτέ να
δημιουργηθούν αυτούσια.
Για παράδειγμα, ένας σχεδιασμός του πληροφοριακού συστήματος του
Πανεπιστημίου μπορεί να ορίσει την ιδεατή κλάση person ως βασική
κλάση για τις υποκλάσεις student, employee και visitor.
Αν και δε θα μπορεί να ένα νέο αντικείμενο με βάση την αφηρημένη κλάση
person, αυτή μπορεί να περιέχει ορισμένα βασικά χαρακτηριστικά όπως
birth_date και να επιβάλει την υλοποίηση συγκεκριμένων μεθόδων
όπως home_page_URL() ορίζοντάς τις ως ιδεατές.
Παράδειγμα
Το παρακάτω παράδειγμα ορίζει τη βασική κλάση Shape και τις υποκλάσεις
της Circle και Rectangle.
Η μέθοδος area μπορεί να οριστεί
για τις υποκλάσεις και κατά την εκτέλεση του προγράμματος να εκτελεστεί
η σωστή έκδοσή της.
Η συνάρτηση toString της Shape εκμεταλλεύεται τη δυνατότητα αυτή και
μπορεί να κληθεί (και να δουλέψει σωστά) με όρισμα οποιαδήποτε από τις
υποκλάσεις της shape.
import gr.aueb.dds.BIO;
abstractclass Shape { privatedouble x, y; // Position protecteddouble getX() { return x; } protecteddouble getY() { return y; } publicvoid setposition(double px, double py) {
x = px;
y = py;
} publicabstractdouble area(); public String toString() { return "Shape(x=" + x + ", y=" + y + ", area=" + area() + ")";
}
}
s[1] = c;
c.setposition(3, 4);
c.setradius(10); for (int i = 0; i < s.length; i++)
BIO.println(s[i]);
}
}
Το παραπάνω πρόγραμμα θα τυπώσει:
Shape(x=1.0, y=2.0, area=2500.0): Rectangle(50.0 x 50.0)
Shape(x=3.0, y=4.0, area=628.3185307179587): Circle(10.0)
Ασκήσεις
Να υλοποιηθούν σε Java οι κλάσεις AndGate, OrGate, NotGate.
Οι κλάσεις αυτές θα προσομοιάζουν τις αντίστοιχες λογικές πύλες.
Κάθε κλάση να έχει μεθόδους που να θέτουν τις εισόδους (π.χ. setA, setB)
και μέθοδο που να επιστρέφει την τιμή της εξόδου (π.χ. getOutput).
Με τη χρήση των παραπάνω κλάσεων (και μόνο) να υλοποιήσετε
μια κλάση που να προσομοιάζει έναν ημιαθροιστή.
Η κλάση αυτή να έχει μεθόδους που να θέτουν τις δύο εισόδους και
μεθόδους που να επιστρέφουν το άθροισμα (getSum) και το κρατούμενο
(getCarryOut).
Να γράψετε ένα πρόγραμμα σε Java που να τυπώνει τους πίνακες
αλήθειας για τις παραπάνω κλάσεις.
(Προαιρετικά) Με τη χρήση των παραπάνω κλάσεων να υλοποιήσετε
μια κλάση που να προσομοιάζει έναν πλήρη αθροιστή.
Η κλάση αυτή πρέπει να έχει μεθόδους που να θέτουν τις δύο εισόδους και το
κρατούμενο εισόδου (setCarryIn) καθώς και μεθόδους που να επιστρέφουν
το άθροισμα και το κρατούμενο εξόδου.
Με τη χρήση του πλήρη αθροιστή και τους τελεστές bit της Java
μπορεί να υλοποιηθεί μια κλάση αθροιστή ακεραίων αριθμών (wordadder) με
τον παρακάτω τρόπο:
/*
* wordadder.java
*
* D. Spinellis, February 2000, December 2001
*/
import gr.aueb.dds.BIO;
class WordAdder { privateint a, b; publicvoid setA(int v) { a = v;} publicvoid setB(int v) {b = v;} publicint getSum() {
FullAdder fa[] = new FullAdder[32]; int i, bit; int result = 0;
for (i = 0; i < 32; i++)
fa[i] = new FullAdder();
fa[0].setCarryIn(false);
// bit is the bit position to add for (i = 0, bit = 1; i < 32; bit <<= 1, i++) {
fa[i].setA((a & bit) != 0);
fa[i].setB((b & bit) != 0);
// Propagate carry if (i < 31)
fa[i + 1].setCarryIn(fa[i].getCarryOut());
// Merge adder output into result if (fa[i].getSum())
result |= bit;
} return (result);
}
// Test harness publicstaticvoid main(String args[]) { int a, b;
WordAdder wa = new WordAdder();
Η τεχνολογία λογισμικού (software engineering)
είναι ο κλάδος αυτός της πληροφορικής που έχει ως σκοπό την
εξεύρεση τεχνικών και εργαλείων που η χρησιμοποίησή τους στην
παραγωγή λογισμικού να εξασφαλίζει για το παραγόμενο προϊόν:
Για την κατανόηση, τον προσδιορισμό και την έκφραση των απαιτήσεων από το
λογισμικό είναι απαραίτητο ένα
ιδεατό μοντέλο (conceptual model) των διεργασιών
του συστήματος στο οποίο θα λειτουργήσει το λογισμικό.
Τα μοντέλα αυτά χρησιμοποιούν τις παρακάτω τεχνικές
παράστασης:
Ορίζουμε ως επαλήθευση (verification) τη διεργασία
που προσδιορίζει το αν το προϊόν ενός σταδίου ανάπτυξης του κύκλου ζωής
του λογισμικού είναι σύμφωνο με τις προδιαγραφές που τέθηκαν στο προηγούμενο
στάδιο.
Ορίζουμε ως επικύρωση (validation) τη διεργασία που
προσδιορίζει κατά το τέλος ανάπτυξης του λογισμικού το αν το προϊόν που
αναπτύχθηκε είναι σύμφωνο με τις προδιαγραφές του.
Πρέπει να κατασκευαστεί λογισμικό που θα καθοδηγεί τον ταμία
ενός καταστήματος στο να δίνει τα σωστά ρέστα στους πελάτες.
Καταγράψτε ενδεικτικά το περιεχόμενο κάθε στάδιου του κύκλου ζωής
του λογισμικού αυτού.
Περιγράψτε με συντομία το περιεχόμενο των απαιτήσεων ενός συστήματος
διασφάλισης ποιότητας για μια από τις παρακάτω δραστηριότητες:
Εκδρομή στο εξωτερικό
Ληστεία τράπεζας
Διοίκηση του Ελληνικού Κράτους
Θέματα εξετάσεων
Πιλοτικά θέματα
ΟΙΚΟΝΟΜΙΚΟ ΠΑΝΕΠΙΣΤΗΜΙΟ ΑΘΗΝΩΝ
Τμήμα Δοικητικής Επιστήμης και Τεχνολογίας
ΠΛΗΡΟΦΟΡΙΑΚΕΣ ΚΑΙ ΕΠΙΚΟΙΝΩΝΙΑΚΕΣ ΤΕΧΝΟΛΟΓΙΕΣ
Πιλοτικά Θέματα
Διδάσκων: Επικ. Καθ. Διομήδης Σπινέλλης
Θέμα 1ο:
Μετατρέψτε
τον αριθμό που απαρτίζεται από το πρώτο και τα δύο τελευταία ψηφία του αριθμού
μητρώου σας από το δεκαδικό στο δυαδικό σύστημα. Στη μετατροπή
πρέπει να φαίνεται ο τρόπος με τον οποίο φτάσατε στο συγκεκριμένο
αποτέλεσμα.
Δώστε τον πίνακα τιμών για τη διαφορά (δ) και το κρατούμενο
(κ) που προκύπτει από τον υπολογισμό της διαφοράς
δύο bit x, y: (δ, κ) = x - y. Χρησιμοποιώντας
πύλες σύζευξης, διάζευξης και άρνησης σχεδιάστε το λογικό κύκλωμα
που υπολογίζει τα (δ, κ) από τα (x, y).
Θέμα 2ο:
Ποια βασικά δομικά στοιχεία απαρτίζουν ένα μηχάνημα αυτομάτων
συναλλαγών (ATM); Πως επικοινωνούν
αυτά μεταξύ τους;
Τι ρόλους επιτελεί στο παραπάνω μηχάνημα το λειτουργικό
του σύστημα;
Θέμα 3ο:
Περιγράψτε διαγραμματικά τον κύκλο ζωής του λογισμικού.
Εξηγήστε πως είναι δυνατή η εκτέλεση από τον υπολογιστή
προγραμμάτων γραμμένων στη συμβολική γλώσσα του
επεξεργαστή καθώς και σε γλώσσες υψηλού επιπέδου
όπως η Java.
Θέμα 4ο:
Για να επιλύσετε ένα πρόβλημα που αναφέρεται σε ένα πολύ
μεγάλο πλήθος στοιχείων έχετε να επιλέξετε ανάμεσα σε
αλγορίθμους πολυπλοκότητας
Α: O(n3), Β: Ο(log n), Γ:
O(2n), Δ: Ο(1), Ε: O(n), και
ΣΤ: O(n5). Ταξινομήστε
τους αλγορίθμους με βάση το θεωρητικό χρόνο εκτέλεσής
τους και εξηγήστε ποιόν αλγόριθμο θα επιλέγατε.
Γράψτε ποιες εντολές του επεξεργαστή Intel IA-32 θα εκτελεστούν
από τη στιγμή που ο μετρητής προγράμματος αποκτήσει
την τιμή 100 μέχρι τη στιγμή που θα αποκτήσει την τιμή 10D. Δώστε
τις τιμές των καταχωρητών μετά την εκτέλεση κάθε εντολής.
0100 mov eax, 3 ; Move / Ανάθεση τιμής
0103 mov esi, 0 ; Move / Ανάθεση τιμής
0106 add esi, eax ; Add / Πρόσθεση
0108 sub eax, 1 ; Subtract / Αφαίρεση
010B jnz 106 ; Jump if Not Zero / Άλμα υπό συνθήκη (διάφορο του 0)
010D ...
Θέμα 5ο:
Γράψτε σε Java ένα πρόγραμμα που θα διαβάζει από την είσοδό του
ποσά εκφρασμένα σε δραχμές και θα τυπώνει το αντίστοιχο ποσό σε ευρώ.
Το πρόγραμμα θα τερματίζει τη λειτουργία του όταν διαβάζει το ποσό 0.
Στο τέλος θα εμφανίζει σε δραχμές και σε ευρώ το σύνολο των ποσών που
μετέτρεψε.
Θέμα 6ο:
Η γλώσσα επισημείωσης HTML χρησιμοποιεί την ακολουθία "<tag ...>"
για να προσδιορίσει χαρακτηριστικά του κειμένου.
Να γράψετε ένα πρόγραμμα σε Java που να διαβάζει HTML ως χαρακτήρες από την
είσοδό του μέχρι να τερματιστεί το αρχείο εισόδου.
Το πρόγραμμα θα εμφανίζει στην έξοδό του το κείμενο της εισόδου χωρίς τις
ακολουθίες επισημείωσης. Παράδειγμα:
Είσοδος:
<html>
<body>
<h1>Εισαγωγή</h1>
Κείμενο της εισαγωγής
</body>
</html>
Έξοδος:
Εισαγωγή
Κείμενο της εισαγωγής
Το πρόγραμμα δε χρειάζεται να ελέγχει μη κανονικά σχηματισμένη HTML (π.χ. επισημειώσεις μέσα σε επισημειώσεις).
Διάρκεια εξέτασης 3 ώρες.
Καλή επιτυχία!
Απάντηση στο 6ο θέμα
import gr.aueb.dds.BIO;
class Detag { publicstaticvoid main(String args[]) { int c; boolean print = true;
while ((c = BIO.readChar()) != -1) { if ((char)c == '<')
print = false; if (print)
BIO.print((char)c); if ((char)c == '>')
print = true;
}
}
}
Η βιβλιοθήκη BIO παρέχει εύκολες, αποδοτικές και σωστές μεθόδους για την
είσοδο και έξοδο στοιχείων σε εφαρμογές που εκτελούνται από τη γραμμή
εντολών.
Δουλεύει σωστά και αποδοτικά τόσο όταν το πρόγραμμα διαβάζει στοιχεία από
το χρήστη, όσο και όταν τα στοιχεία προέρχονται από κάποιο αρχείο.
Η βιβλιοθήκη BIO εξασφαλίζει:
την εύκολη και ευσύνοπτη είσοδο και έξοδο στοιχείων από το πρόγραμμα,
τη σωστή μετατροπή χαρακτήρων από τις κωδικοσελίδες του λειτουργικού
συστήματος στους κωδικούς Unicode της Java,
τον έλεγχο λαθών σε όλες τις λειτουργίες εισόδου και εξόδου και τον
αυτόματο τερματισμό του προγράμματος με επεξηγηματικό μήνυμα όταν ανιχνευτεί
λάθος,
την αποδοτική είσοδο και έξοδο στοιχείων με τη χρήση ενταμιευτών,
το αυτόματο άδειασμα των ενταμιευτών σε αλληλεπιδραστικές εφαρμογές,
όταν αυτό απαιτείται.
Για να πετύχει τους παραπάνω στόχους
η βιβλιοθήκη BIO συνδέεται απλοϊκά με τις υπόλοιπες βιβλιοθήκες της Java
και κάνει μια σειρά από υποθέσεις για λογαριασμό του προγραμματιστή.
Έτσι, η βιβλιοθήκη BIO είναι κατάλληλη μόνο για εκπαιδευτικούς
σκοπούς και όχι για κώδικα παραγωγής.
Εγκατάσταση
Η βιβλιοθήκη BIO πρέπει να είναι σωστά εγκατεστημένη στους υπολογιστές
του εργαστηρίου και δε χρειάζεται άλλη εγκατάσταση.
Για να την εγκαταστήσετε σε άλλο μηχάνημα πρέπει να ακολουθήσετε την
παρακάτω διαδικασία:
Αντιγράψτε το αρχείο με τον πηγαίο κώδικα
BIO.java.
Μεταγλωττίστε το αρχείο με την εντολή javac BIO.java.
Δέστε την τιμή της μεταβλητής CLASSPATH με την εντολή SET
Δημιουργήστε σε έναν από τους καταλόγους που περιέχει η CLASSPATH
(π.χ. c:\jdk\jre\lib) έναν δέντρο υποκαταλόγων gr\aueb\dds.
Αντιγράψτε στο κατάλογο dds τα μεταγλωττισμένα αρχεία .class που
έχουν δημιουργηθεί σε προηγούμενο βήμα.
Η βιβλιοθήκη BIO παρέχεται ελεύθερα για κάθε χρήση σύμφωνα με την
παρακάτω άδεια:
(C) Copyright 2001 Diomidis Spinellis. All rights reserved.
Permission to use, copy, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
Τελευταία αλλαγή: Τετάρτη, 6 Φεβρουαρίου 2008 4:07 μμ
Εκτός αν αναφέρεται κάτι διαφορετικό, όλο το πρωτότυπο υλικό της σελίδας αυτής
του οποίου δημιουργός είναι ο Διομήδης Σπινέλλης παρέχεται σύμφωνα με τους
όρους της άδειας
«Creative Commons Attribution-Share Alike 3.0 Greece License».