Τμήμα Ηλεκτρονικών Μηχανικών Τ.Ε.Ι. Κρήτης Προγραμματισμός Η/Υ (ΤΛ2007 ) Δρ. Μηχ. Νικόλαος Πετράκης (npet@chania.teicrete.gr) Τέταρτη (4 η ) τρίωρη διάλεξη. Ιστοσελίδα Μαθήματος: https://eclass.chania.teicrete.gr/ Εξάμηνο: Εαρινό 2016-17
Παράδειγμα: εμβαδόν τριγώνου (1) #include <stdio.h> main() { float height, base, area; height = 10.2; /* χωρίς εισαγωγή δεδομένων */ base = 3.6; printf( The height of the triangle is: %f\n, height); printf( The base of the triangle is: %f\n, base); area = (height * base)/2; printf( The area of the triangle is %f\n, area); } return 0; 2
Παράδειγμα: εμβαδόν τριγώνου (2) #include <stdio.h> main() { float height, base, area; printf( Enter the height of the triangle : ); scanf( %f, &height); printf( \n ); /* με εισαγωγή δεδομένων */ printf( Enter the base of the triangle : ); scanf( %f, &base); printf( \n ); printf( The height of the triangle is: %f\n, height); printf( The base of the triangle is: %f\n, base); area = (height * base)/2; printf( The area of the triangle is %f\n, area); } return 0; 3
Παράδειγμα: εμβαδόν κύκλου /* Υπολογισμός εμβαδού κύκλου δίνοντας την ακτίνα */ #include <stdio.h> #define PI 3.14159265359 main() { int r; /* ακτίνα */ double emv; /* εμβαδόν */ printf("δώσε ακτίνα : "); scanf ("%d", &r); emv = PI*r*r; printf("κύκλος με ακτίνα %d έχει εμβαδό %f\n", r, emv); system("pause"); } 4
Παράδειγμα: Αντιστοιχία θερμοκρασιών (όχι καλό) #include <stdio.h> /* Τύπωσε τους βαθμούς σε κλίμακα Κελσίου και Φαρενάιτ. */ /* γνωρίζοντας τον τύπο: celcius = (5/9) (fahr 32) */ #define FAHR1 0 #define FAHR2 20 #define FAHR3 40 #define FAHR4 60 main() { int celcius1, celcius2, celcius3, celcius4; celcius1 = 5 * (FAHR1-32) / 9; printf("%d\t%d\n", FAHR1, celcius1); /* Τύπωσε ακέραιο, tab, ακέραιο */ celcius2 = 5 * (FAHR2-32) / 9; printf("%d\t%d\n", FAHR2, celcius2); /* Τύπωσε ακέραιο, tab, ακέραιο */ celcius3 = 5 * (FAHR3-32) / 9; printf("%d\t%d\n", FAHR3, celcius3); /* Τύπωσε ακέραιο, tab, ακέραιο */ celcius4 = 5 * (FAHR4-32) / 9; printf("%d\t%d\n", FAHR4, celcius4); /* Τύπωσε ακέραιο, tab, ακέραιο */ } Το αποτέλεσμα θα είναι: 0-17 20-6 40 4 60 15 Προβλήματα: α) η τιμή celsius δεν είναι αναγκαστικά ακέραια! β) τι θα κάναμε αν είχαμε πολύ περισσότερες τιμές να αντιστοιχίσουμε; 5
Παράδειγμα: Αντιστοιχία θερμοκρασιών (βελτιωμένο) /* δημιουργία και εμφάνιση πίνακα αντιστοιχίας θερμοκρασιών Fahrenheit- Celsius από το 0 μέχρι το 500, ανά 20, γνωρίζοντας ότι C= (5/9) (F-32) */ #include <stdio.h> main() { int fahr; float celsius; } int lower=0,upper= 500, step = 20; fahr=lower; printf("\n FAHRENHEIT CELSIUS "); printf("\n-----------------------------"); while(fahr <= upper) { celsius = (float)5/9*(fahr-32); printf("\n%6d\t\t%10.2f",fahr,celsius); fahr += step; } printf("\n"); system ("PAUSE"); Το αποτέλεσμα θα είναι: FAHRENHEIT CELSIUS ----------------------------- 0-17.78 20-6.67 40 4.44 60 15.56 80 26.67 100 37.78 120 48.89 140 60.00 160 71.11 180 82.22 200 93.33 220 104.44 240 115.56...... 480 248.89 500 260.00 Πιέστε ένα πλήκτρο για συνέχεια... 6
Παράδειγμα με while και if else (1) Εκφώνηση: Να γίνει ένα πρόγραμμα το οποίο να ζητάει από το πληκτρολόγιο τον βαθμό που πήρε κάποιος φοιτητής σε κάποιο μάθημα και αν είναι μεγαλύτερος από το πέντε ή τουλάχιστον ίσος με το πέντε να επιστρέφει στην οθόνη το μήνυμα «Πέρασες», διαφορετικά να εμφανίζει στην οθόνη το μήνυμα «Απορρίφθηκες». Σε περίπτωση που ο βαθμός είναι εκτός ορίων (δηλαδή, είτε είναι μικρότερος του μηδενός, είτε είναι μεγαλύτερος του δέκα) να εμφανίζει το κατάλληλο μήνυμα λάθους και στην συνέχεια να ξαναζητάει τον βαθμό μέχρι να λάβει κάποιον βαθμό εντός ορίων, οπότε και θα συνεχίσει την εκτέλεση του προγράμματος. 7
Παράδειγμα με while και if else (2) Λύση: main() { int v; } printf("δώστε βαθμό : "); scanf("%d", &v); while (v<0 v>10) { printf("βαθμός εκτός ορίων!\n\nξαναδώστε βαθμό : "); } scanf("%d", &v); if (v>=5) printf("πέρασες.\n\n"); else printf("απορρίφθηκες.\n\n"); system("pause"); return 0; 8
Εντολή επανάληψης for Συντάσσεται ως εξής: αρχικοποίηση μετρητή for ( ; ; ) εντολή; συνθήκη ή παράσταση βήμα μεταβολής μετρητή 9
Το παράδειγμα αντιστοίχισης θερμοκρασιών ξανά με for #include <stdio.h> #define LOWER 0 #define UPPER 500 #define STEP 20 main() { int fahr; float celsius; printf("\n FAHRENHEIT CELSIUS "); printf("\n-----------------------------"); for(farh=lower; fahr<=upper; farh+=step) { celsius=(float)5/9 *(fahr-32); printf("\n %5d\t\t%9.2f ",fahr,celsius); } } 10
Σχηματική Παρουσίαση της Διαδικασίας Προγραμματισμού Γνώση της περιοχής Του Προβλήματος/ Domain Knowledge Μεταφραστής και Συμβολομεταφραστής/ Compiler/Assembler/Linker Δεδομένα/Data Αναλυτής Προγραμματιστής Η/Υ Η/Υ Ορισμός του Προβλήματος/ Problem Definition Αλγόριθμος/ Algorithm Γλώσσα Μηχανής Πηγαίο πρόγραμμα (Source Code) σε κάποια Γλώσσα Προγραμματισμού, π.χ. C Αποτέλεσμα/ Result 11
Δημιουργώντας τον πηγαίο κώδικα Ο υπολογιστής δεν μπορεί να καταλάβει τον πηγαίο κώδικα. Όπως είδαμε ο υπολογιστής απαιτεί ψηφιακές ή δυαδικές οδηγίες οι οποίες ονομάζονται γλώσσα μηχανής. Η μετάφραση από πηγαίο κώδικα σε γλώσσα μηχανής γίνεται από τον μεταγλωττιστή (compiler). 12
Μετάφραση και ενοποίηση με την συμπερίληψη βιβλιοθηκών Για να μεταφράσουμε πηγαίο κώδικα της C σε Γλώσσα Μηχανής υπό τη παρουσία βιβλιοθηκών ο compiler εκτελεί τα παρακάτω βήματα. 1. Προ-επεξεργασία: Το πηγαίο πρόγραμμα γίνεται αρχικά αντικείμενο επεξεργασίας από μία εφαρμογή (που έρχεται με τον compiler) και ονομάζεται προ-επεξεργαστής (pre-processor). Ο προ-επεξεργαστής είναι κάτι σαν επεξεργαστής κειμένου: προσθέτει, αφαιρεί, και μεταβάλει το «κείμενο» του πηγαίου προγράμματος (source code). Όλες οι εντολές που είναι να εκτελεσθούν από τον προ-επεξεργαστή ξεκινούν με το σύμβολο #. Συγκεκριμένα η #include <stdio.h> παίρνει τον πηγαίο κώδικα της stdio.h και τον εισάγει στη θέση της εντολής #include <stdio.h>. Ουσιαστικά μετά την προ-επεξεργασία δεν υπάρχουν πλέον εντολές που ξεκινούν με #. 2. Μετάφραση και Συμβολομετάφραση: Tα βήματα αυτά παράγουν αντικείμενο κώδικα object code (σχεδόν γλώσσα μηχανής) 3. Ενοποίηση (linking): Το βήμα αυτό ενοποιεί αντικείμενο κώδικα (πιθανόν από διαφορετικά αρχεία πηγαίου κώδικα) σε ένα εκτελέσιμο αρχείο (π.χ..exe) σε καθαρή γλώσσα μηχανής. 13
Σφάλματα μεταγλώττισης Λάθος μεταγλώττισης εμφανίζεται όταν ο μεταγλωττιστής βρει κάτι στον πηγαίο κώδικα που δεν μπορεί να μεταγλωττίσει (ορθογραφικό, τυπογραφικό, λάθος συντακτικού της γλώσσας C). O μεταγλωττιστής σας λέει τι προκάλεσε το λάθος και πού (σε ποια σειρά κώδικα) υπάρχει το λάθος. Αυτό κάνει εύκολο τον εντοπισμό λαθών στον πηγαίο κώδικα. 1 #include <stdio.h> 2 main() 3 { 4 printf( Hello World! ) /* Λείπει το ; στο τέλος */ 5 } Ο μεταγλωττιστής θα εμφανίσει ένα λάθος στη σειρά 5 --- Error: ; expected. Χρησιμοποιώντας τη γνώση σας της γλώσσας C πρέπει να ερμηνεύσετε τα μηνύματα του μεταγλωττιστή. Αν είχαμε άλλο πρόβλημα όπως, π.χ.: 4 printf( Hello World!); /* Λείπει το στο τέλος */ Ο μεταγλωττιστής θα εμφανίσει πολλές σειρές λαθών όπως undefined identifier Hello, Lexical error, unterminated string, premature end of source file, κτλ. Εάν ο μεταγλωττιστής σας αναφέρει πολλά λάθη και εσείς βρείτε μόνο το ένα, διορθώστε αυτό το λάθος και μεταγλωττίστε ξανά. 14
Ερωτήσεις Ποιον συντάκτη (κειμενογράφο, text editor) μπορώ να χρησιμοποιήσω για να γράψω κώδικα σε C; Μπορώ να αγνοήσω τα μηνύματα λάθους; Μπορώ να αγνοήσω τα μηνύματα προειδοποιήσεων; Αν θέλω να δώσω σε κάποιον ένα πρόγραμμα που έφτιαξα ποια αρχεία πρέπει να δώσω; Αφού δημιουργήσω ένα εκτελέσιμο αρχείο, χρειάζεται να κρατήσω το αρχείο πηγαίου κώδικα (.c); Τι πρέπει να κάνω αν θέλω να τρέξω τον κώδικα μου, που είναι γραμμένος σε ANSI C, και σε άλλη πλατφόρμα; 15
Γενική μορφή προγράμματος στη C directives (οδηγίες) main() { variable declarations (δηλώσεις μεταβλητών) } statements (εντολές) 16
Οδηγίες Είναι εντολές για τον προ-επεξεργαστή Χρησιμοποιούνται συνήθως για τις παρακάτω περιπτώσεις: Να εισάγουν βιβλιοθήκες (αρχεία επικεφαλίδες - headers) π.χ. #include <stdio.h> Δε χρειάζεται να τροποποιήσετε τις πληροφορίες σε αυτά τα πρότυπα αρχεία. Μπορείτε να φτιάξετε άλλα δικά σας. #include mybestlibrary.h Να ορίσουν σταθερές ή μακροεντολές π.χ. #define FREEZING_POINT_CELCIUS 0.0 #define FREEZING_POINT_FARHENEIT 32.0 #define HALFOF(value) ((value)/2) 17
Εντολές Οι εντολές ορίζουν συγκεκριμένες λειτουργίες τις οποίες εκτελεί ένα πρόγραμμα σαν μέρος του αλγόριθμου που υλοποιεί Υπάρχουν πολλά είδη εντολών όπως οι: Ανάθεση (assignment statement) Εντολές συνθήκης (conditional statements) Εντολές βρόχου (iterative statements) Εντολές έκφρασης (expression statements) Οι εντολές τελειώνουν πάντα με ελληνικό ερωτηματικό (;) semicolon ενώ οι οδηγίες (directives) έχουν πάντα μήκος μία γραμμή. 18
Συναρτήσεις Οι συναρτήσεις είναι σαν τις ρουτίνες/υπο-ρουτίνες (routines, subroutines, procedures) σε άλλες γλώσσες προγραμματισμού. Ουσιαστικά είναι τα δομικά υλικά ενός προγράμματος. Οι συναρτήσεις πρέπει κατά το δυνατόν να παράγουν όσο το δυνατόν πιο συγκεκριμένη λειτουργία (high cohesion) και να εξαρτώνται όσο το δυνατόν λιγότερο η μία από την άλλη (low coupling). Υπάρχουν δύο μεγάλες κατηγορίες συναρτήσεων: Συναρτήσεις βιβλιοθήκης library functions (είναι κομμάτι της βιβλιοθήκης) Συναρτήσεις εφαρμογών application functions (ορίζονται από τον προγραμματιστή) Οι συναρτήσεις της C αποτελούνται από εντολές Μία συνάρτηση μπορεί να υπολογίζει ένα αποτέλεσμα και να το επιστρέφει στο σημείο της κλήσης (αλλά αυτό δεν είναι πάντα απαραίτητο) π.χ. Το πρόγραμμα int i = 0; i = addone(i) ; int addone(int j) { j = j+1; return j ; } Ορισμός της συνάρτησης 19
Η συνάρτηση main() Η συνάρτηση main() είναι μία ειδική συνάρτηση που πρέπει να έχει ορισθεί σε κάθε πρόγραμμα C. Η συνάρτηση main() είναι η πρώτη συνάρτηση που καλείται σε ένα πρόγραμμα C. Η κλήση γίνεται αυτόματα από το λειτουργικό σύστημα όταν το πρόγραμμα αρχίζει να «τρέχει». Η συνάρτηση main() μπορεί να επιστρέφει, ή να μην επιστρέφει κάποιο αποτέλεσμα. 20
Εκφράσεις (expressions) Οι εκφράσεις στη C είναι συντακτικές μορφές που παράγονται από το συνδυασμό μεταβλητών, σταθερών, και τελεστών (operators). Προς το παρόν θα ασχοληθούμε με ακέραιες και πραγματικές μεταβλητές. Μεταβλητές ακέραιου, και πραγματικού τύπου μπορούν να συνδυαστούν με αριθμητικούς τελεστές. Το σημαντικό στοιχείο είναι ο τύπος του αποτελέσματος που προκύπτει. 21
Προγράμματα της C Τα προγράμματα της C αποτελούνται από προτάσεις (εντολές, statements) και οι προτάσεις αποτελούνται από τελεστές και εκφράσεις. Μία πρόταση είναι μία πλήρης οδηγία προς τον υπολογιστή για να φέρει σε πέρας μία πράξη (λειτουργία). Οι προτάσεις της C τελειώνουν με ένα ελληνικό ερωτηματικό εκτός τις #define, #include. x = 2+3; είναι μία πρόταση εκχώρησης. Οδηγεί τον υπολογιστή να προσθέσει το 2 και το 3 και να εκχωρήσει το αποτέλεσμα στη μεταβλητή x. 22
Παραδείγματα x = 2+3 ; x = 2 + 3 ; Γενικά, ο μεταγλωττιστής δε λαμβάνει υπ όψη του κενά διαστήματα (spaces), στηλογνώμονες (tabs) και κενές γραμμές εκτός και αν αποτελούν τμήμα συμβολοσειρών κυριολεκτικών σταθερών (ορμαθοί - ακολουθίες χαρακτήρων = strings) (μεταξύ " ") 23
Παραδείγματα Οι προτάσεις καλό είναι να εισάγονται μία ανά γραμμή Μέσα σε σταθερές συμβολοσειρών δεν αγνοούνται τα κενά διαστήματα Έγκυρο: printf( Hello World! ); Όχι έγκυρο: printf( Hello World! ); Σωστό: printf( Hello \ World! ); 24
Προτάσεις Οι προτάσεις σε ένα πρόγραμμα πρέπει να εισάγονται μία ανά γραμμή με ένα τυποποιημένο σχήμα για τα διαστήματα γύρω από τις μεταβλητές και τους τελεστές. Κρατήστε ευανάγνωστο τον πηγαίο σας κώδικα. 25
Σύνθετες προτάσεις ή σύνθετες εντολές Μία σύνθετη πρόταση λέγεται μπλοκ (block) και είναι μία ομάδα 2 ή περισσότερων προτάσεων της C οι οποίες περιλαμβάνονται σε άγκιστρα. Να τοποθετείτε τα άγκιστρα μόνα τους στις προτάσεις για να είναι ξεκάθαρες η αρχή και το τέλος ενός μπλοκ. 26
Υπολογισμός των εκφράσεων Μία έκφραση είναι οτιδήποτε που υπολογίζεται σε μία αριθμητική τιμή. Η απλούστερη έκφραση της C αποτελείται από ένα απλό στοιχείο: Μία κυριολεκτική σταθερά, μία μεταβλητή ή συμβολική σταθερά. Μία κυριολεκτική σταθερά έχει τη δική της τιμή. Μία συμβολική σταθερά έχει την τιμή που της έχει δοθεί όταν δημιουργήθηκε, π.χ. με #define. Mία μεταβλητή έχει την τρέχουσα τιμή που της εκχωρήθηκε τελευταία από το πρόγραμμα. 27
Σύνθετες εκφράσεις Οι σύνθετες εκφράσεις αποτελούνται από απλές εκφράσεις συνδεδεμένες με τελεστές. 2+8; x=a+10; x=6+(y=4+5); 28
Μοναδιαίοι τελεστές μεταβολής κατά ένα ++x, --y, Πρόσθεση ή αφαίρεση της μονάδας από τον τελεστέο, ισοδύναμες των x=x+1, y=y-1. Δηλαδή αύξηση ή μείωση του τελεστέου κατά ένα. Χρησιμοποιούνται με μεταβλητές, όχι με σταθερές. 29
Μοναδιαίοι Τελεστές Οι δύο μοναδιαίοι τελεστές μπορούν να τοποθετηθούν πριν απο τον τελεστέο (μορφή προθέματος) ή μετά από τον τελεστέο (μορφή επιθέματος) και δεν είναι ισοδύναμοι. Όταν χρησιμοποιούνται σε προθεματική μορφή, οι τελεστές αύξησης και μείωσης τροποποιούν τον τελεστέο τους πριν χρησιμοποιηθεί. Όταν χρησιμοποιούνται σε επιθεματική μορφή, οι τελεστές αύξησης και μείωσης τροποποιούν τον τελεστέο τους αφού χρησιμοποιηθεί. 30
Τελεστές Παράδειγμα x=10; y=x++; Η τιμή της x είναι 11 και της y 10. Χρησιμοποιούμε και μετά αυξάνουμε Παράδειγμα x=10; y=++x; Η τιμή της x είναι 11 και της y 11. Αυξάνουμε και μετά χρησιμοποιούμε 31
32
Αποτέλεσμα 5 4 4 3 3 2 2 1 1 0 33
ΥΠΟΛΟΓΙΣΜΟΣ ΤΩΝ ΕΚΦΡΑΣΕΩΝ Ο υπολογισμός του αποτελέσματος μιας έκφρασης εξαρτάται από την προτεραιότητα και την συσχέτιση των τελεστών. Η προτεραιότητα καθορίζει τη σειρά εφαρμογής (order of application) των τελεστών. Για παράδειγμα, η έκφραση 2*2+4 υπολογίζεται με την τιμή 8 μιας και ο τελεστής του Πολ/σμού έχει μεγαλύτερη προτεραιότητα από τον τελεστή της Πρόσθεσης. Χρησιμοποιώντας παρενθέσεις μπορούμε να αλλάξουμε τη δομή μιας έκφρασης και ουσιαστικά να μεταβάλλουμε τον τρόπο υπολογισμού της. Για παράδειγμα η έκφραση 2*(2+4) υπολογίζεται και δίνει τιμή 12. Η συσχέτιση καθορίζει τη σειρά εφαρμογής τελεστών με την ίδια προτεραιότητα. Για παράδειγμα, θεωρώντας ότι οι τελεστές / και * έχουν την ίδια προτεραιότητα η συσχέτισή τους ορίζει ότι η έκφραση 6/2*3 υπολογίζεται με την τιμή 9, αντί την τιμή 1. 34
++, -- * / % + - Προτεραιότητα Μαθηματικών Τελεστών Από τα αριστερά προς τα δεξιά, αν σε μία έκφραση υπάρχουν τελεστές ίδιας προτεραιότητας x = 25 (2 * (10 + (8 /2 ))) 35
36
Αποτέλεσμα α = (5 == 5) α = 1 α = (5!= 5) α = 0 α = (12 == 12) + (5!= 1) α = 2 37