CE 120 Φροντιστήριο 7/10/2011 1
Απολογισµός εργαστηρίου Προσέξτε να έχετε µόνο ένα φάκελο µε όνοµα ce120! Προσέξτε να αποθηκεύετε το πρόγραµµά σας στο σωστό µέρος (πχ στο φάκελο ~/ce120/lab0 και όχι στο ~/Documents ) Για να κάνετε compile ένα πρόγραµµα, πρέπει να βρίσκεστε στον ίδιο φάκελο που βρίσκεται και το πρόγραµµα. Για να πακετάρετε (µε tar) ένα φάκελο, δεν πρέπει να είστε µέσα σε αυτόν, αλλά ένα φάκελο πίσω. 2
Την επόµενη εβδοµάδα Pair Programming driver & navigator switch every 15-30 minutes Μην ξεχνάτε: cc και στο δεύτερο µέλος Topic: Ερµηνεία των µηνυµάτων του compiler 3
Επανάληψη: η συνάρτηση main /* Εµφανίζει στην οθόνη το µήνυµα hello world */ #include <stdio.h> Ορίσµατα συνάρτησης int main(int argc, char* argv[]) { } printf("hello world\n"); return(0); Σχόλια Συµπερίληψη δηλώσεων εξωτερικών συναρτήσεων Επικεφαλίδα συνάρτησης (prototype) Σώµα (εντολές) 4
Επανάληψη: η συνάρτηση main /* Εµφανίζει στην οθόνη το µήνυµα Ένα block hello εντολών world */ Όλες οι εντολές (statements) περικλείεται σε άγκιστρα τελειώνουν µε ελληνικό #include <stdio.h> ερωτηµατικό (semi-colon) int main(int argc, char* argv[]) { printf("hello world\n") ; return(0) ; } Στοίχιση (indentation): Οι εντολές ενός block στοιχίζονται ένα tab (συνήθως 4 κενά) πιο µέσα από τα άγκιστρα. 5
Επανάληψη: Δεδοµένα & µνήµη Για κάθε δεδοµένο πρέπει να καθοριστεί από τον προγραµµατιστή: Η θέση µνήµης για την αποθήκευσή του Ο αριθµός bytes που χρειάζεται για την αποθήκευση των τιµών που µπορεί να λάβει Η κωδικοποίηση στο δυαδικό σύστηµα για κάθε τιµή του Αυτό µπορεί να γίνει εύκολα µε κατάλληλη υποστήριξη από τη γλώσσα προγραµµατισµού 6
Επανάληψη: Τύποι δεδοµένων Κάθε γλώσσα ορίζει ένα σύνολο από βασικούς τύπους δεδοµένων Κάθε βασικός τύπος έχει Προκαθορισµένο µέγεθος σε bytes Συγκεκριµένη κωδικοποίηση στο δυαδικό σύστηµα και αντίστοιχο πεδίο τιµών. Ο προγραµµατιστής προσδιορίζει τον τύπο για κάθε δεδοµένο. Με αυτό τον τρόπο, µέγεθος και κωδικοποίηση καθορίζονται έµµεσα ΣΗΜΑΝΤΙΚΟ: Στη µνήµη αποθηκεύονται απλά bits/bytes. Το πώς αυτά ερµηνεύονται είναι δουλειά του προγράµµατος! 7
Επανάληψη: Μεταβλητές Σε κάθε αντικείµενο δεδοµένων δίνουµε ένα µνηµονικό όνοµα. Χρησιµοποιούµε το όνοµα για να προσπελάσουµε το αντικείµενο δεδοµένων και να δούµε ή να αλλάξουµε την τιµή του. Μεταβλητή = Αντικείµενο δεδοµένων µε όνοµα ΚΑΙ τύπο 8
Παράδειγµα Δήλωση µεταβλητής µε όνοµα numstudents και τύπο int (ακέραιος/integer). Σε αυτή τη µεταβλητή θα αποθηκεύσουµε µια ακέραια τιµή η οποία εκφράζει το πλήθος φοιτητών. int main(int argc, char* argv[]) { int numstudents; numstudents = 30; } return(0); Ανάθεση τιµής σε µεταβλητή. Η τιµή 30 αποθηκεύεται στη θέση µνήµης που αντιστοιχεί στη numstudents 9
Παράδειγµα Δηλώσεις τριών ακέραιων µεταβλητών int main(int argc, char* argv[]) { int pizzas, pizzaslices; int totalslices; pizzas = 5; pizzaslices = Μεταβλητές 8; ίδιου τύπου µπορούν να δηλωθούν οµαδικά, στην ίδια totalslices δήλωση, = pizzas αν τις * χωρίσουµε pizzaslices; µε κόµµα } return(0); 10
Παράδειγµα Δηλώσεις τριών ακέραιων µεταβλητών int main(int argc, char* argv[]) { int pizzas, pizzaslices; int totalslices; pizzas = 5; pizzaslices = 8; Οι µεταβλητές πρέπει να έχουν περιγραφικά ονόµατα! totalslices = pizzas * pizzaslices; } return(0); 11
Παράδειγµα int main(int argc, char* argv[]) { int pizzas, pizzaslices; int totalslices; Ανάθεση τιµών σε µεταβλητές. pizzas = 5; pizzaslices = 8; Τι υπάρχει στις µεταβλητές πριν βάλουµε εµείς κάποια τιµή? } totalslices = pizzas * pizzaslices; Υπάρχουν άραγε κι άλλοι τρόποι return(0); να δώσουµε τιµή σε µια µεταβλητή? 12
Παράδειγµα int main(int Χρησιµοποιούµε argc, char* τις τιµές argv[]) των { µεταβλητών µας σε µια int pizzas, αριθµητική pizzaslices; έκφραση int totalslices; pizzas = 5; pizzaslices = 8; Ανάγνωση τιµών µεταβλητών totalslices = pizzas * pizzaslices; } return(0); Πολλαπλασιασµός 13
Παράδειγµα int main(int argc, char* argv[]) { int pizzas, pizzaslices; int totalslices; Ανάθεση τιµής (αποτέλεσµα πράξης πολ/σµού) σε µεταβλητή pizzas = 5; pizzaslices = 8; totalslices = pizzas * pizzaslices; } return(0); 14
Παράδειγµα Η ζωή των τριών µεταβλητών µας είναι από το σηµείο που τις δηλώσαµε µέχρι το τέλος του block στο οποίο int main(int argc, δηλώθηκαν. char* argv[]) { int pizzas, pizzaslices; int totalslices; Ζωή µεταβλητών pizzas = 5; = Διάστηµα κατά το οποίο ο αντίστοιχος pizzaslices = χώρος 8; στη µνήµη παραµένει δεσµευµένος = Διάστηµα κατά το οποίο µπορούµε να τις totalslices = χρησιµοποιήσουµε pizzas * pizzaslices; } return(0); 15
Compiler: Errors & warnings Error: Συντακτικό ή σηµασιολογικό λάθος. Όταν υπάρχουν λάθη, το πρόγραµµα δε µεταγλωττίζεται επιτυχώς και δεν παράγεται κώδικας µηχανής Warning: Προειδοποίηση για πιθανό λάθος. Στην πράξη: συνήθως είναι ένδειξη σηµαντικού λάθους. ΠΑΝΤΑ: Χρησιµοποιούµε -Wall για να βλέπουµε όλα τα warnings Διορθώνουµε όλα τα warnings Συµβουλή: Φτιάξτε το δικό σας "λεξικό" µηνυµάτων λάθους. Επίσης, google is your friend! 16
Παράδειγµα 17
Παράδειγµα Πού είναι το λάθος? Στην εντολή gcc 18
Παράδειγµα Ποιό είναι το µήνυµα λάθους? Δεν αναγνωρίζει την επιλογή -wall 19
Παράδειγµα Τι µπορεί να σηµαίνει αυτό? Δεν υπάρχει τέτοια επιλογή ή κάναµε τυπογραφικό λάθος. Πράγµατι, το σωστό είναι -Wall 20
Παράδειγµα Πού είναι το λάθος? Στο αρχείο lab0.c και για την ακρίβεια στη main 21
Παράδειγµα Πού ακριβώς είναι το λάθος? Στη γραµµή 5, στήλη 3 22
Παράδειγµα Γραµµή 5 (πατήστε F11 για να δείτε αρίθµηση γραµµών) Στήλη 3=ο τρίτος χαρακτήρας από την αρχή της γραµµής (δηλαδή το r του return) Όπως κινείται ο cursor, µπορείτε να δείτε εδώ την τρέχουσα στήλη (και γραµµή) 23
Παράδειγµα Ποιό είναι το µήνυµα λάθους? Έπρεπε να έχει ένα ; πριν το return 24
Παράδειγµα Τι µπορεί να σηµαίνει αυτό? Στη γραµµή 5 δεν υπάρχει τίποτα πριν το return (και δε θα έπρεπε), οπότε προχωράµε ανάποδα και πάµε στο τέλος της γραµµής 4. Πράγµατι, ξεχάσαµε το ; µετά την παρένθεση! 25
Compiler: Errors & warnings Διορθώνουµε τα λάθη µε τη σειρά από το πρώτο προς το τελευταίο. Μετά τη διόρθωση ενός λάθους, κάνουµε save και ξανά compile ΜΗΝ προσπαθείτε να διορθώσετε όλα τα λάθη µε τη µία! Μερικές φορές, από ένα πραγµατικό λάθος, µπορεί ο compiler να βγάλει πολλαπλά µηνύµατα. Μερικές φορές, µετά τη διόρθωση ενός λάθους, ο compiler είναι σε θέση να ανιχνεύσει κι άλλα λάθη που δεν είχε εντοπίσει την πρώτη φορά. 26
Ενότητα 2 27
Επίλυση Προβληµάτων Επίλυση προβλήµατος = Κατανόηση του προβλήµατος Σχεδίαση µιας λύσης Υλοποίηση της λύσης Βελτίωση της λύσης? 28
Επίλυση Προβληµάτων Αλγόριθµος µια σειρά από καλά ορισµένα βήµατα που λύνουν ένα πρόβληµα µια σειρά από καλά ορισµένα βήµατα που παίρνουν κάποια δεδοµένα και παράγουν κάποια έξοδο 29
Επίλυση Προβληµάτων Ένας αλγόριθµος πρέπει να είναι Ακριβής Δεν πρέπει να περιέχει διφορούµενα βήµατα Σωστός Πρέπει να δίνει σωστή λύση µε βάση τις προδιαγραφές. Πεπερασµένος Πρέπει να τερµατίζει Γενικός Πρέπει να λειτουργεί για κάθε στιγµιότυπο των δεδοµένων Αποδοτικός Πρέπει να χρησιµοποιεί λίγους πόρους (πχ. χρόνο, µνήµη) Παράδειγµα: Ας φτιάξουµε ένα φραπέ... 30
Επίλυση Προβληµάτων Κάθε αλγόριθµος διαχειρίζεται δεδοµένα Ο τρόπος µε τον οποίο οργανώνουµε τα δεδοµένα επηρεάζει την αποδοτικότητα του αλγορίθµου µας. Λύση = αλγόριθµος + οργάνωση δεδοµένων Περισσότερα στο µάθηµα "Δοµές δεδοµένων" Πρόγραµµα = µια σειρά από εντολές σε κάποια γλώσσα προγραµµατισµού, οι οποίες λένε στον υπολογιστή πώς να λύσει ένα πρόβληµα. Με άλλα λόγια, είναι η υλοποίηση ενός αλγορίθµου. 31
Προγραµµατισµός Ανάλυση προβλήµατος και σχεδιασµός λύσης Ποια είναι τα δεδοµένα? Ποια είναι η έξοδος? Πώς πάµε από τα δεδοµένα στην έξοδο? Διάσπαση της διαδικασίας σε υπο-προβλήµατα Υλοποίηση λύσης Έλεγχος λύσης Διόρθωση λύσης 32
Παραδείγµατα Έξοδος από την αίθουσα Υπολογίστε την επιφάνεια ενός σπιτιού Βρείτε το µεγαλύτερο από ένα σύνολο αριθµών Βρείτε ένα όνοµα στον τηλεφωνικό κατάλογο Ταξινοµήστε τους συµφοιτητές σας κατά ύψος 33