Σκοπός της Άσκησης ΑΣΚΗΣΗ 5: ΠΙΝΑΚΕΣ Ο σκοπός αυτής της εργαστηριακής άσκησης είναι η εξοικείωση µε τη χρήση πινάκων σαν διατάξεις αποθήκευσης δεδοµένων της Γλώσσας Προγραµµατισµού C. H συγκεκριµένη άσκηση πραγµατεύεται τα παρακάτω: ορισµόςαρχικοποίηση µονοδιάστατων-πολυδιάστατων πινάκων. 1. ΟΙ ΠΙΝΑΚΕΣ ΣΤΗ C Οι πίνακες στη C είναι µια λίστα µεταβλητών. Οι περισσότερες γλώσσες προγραµµατισµού χρησιµοποιούν τέτοιες λίστες. Έστω ότι θέλετε να τηρήσετε τις πωλήσεις 50 πωλητών. Μπορείτε να ορίσετε µέχρι 50 ονόµατα µεταβλητών και να εκχωρήσετε µια διαφορετική εγγραφή πωλητή ανα µεταβλητή. Ωστόσο, µια καλή πρακτική θα ήταν να χρησιµοποιηθεί µια διάταξη 50 στοιχείων αποθηκεύοντας το σύνολο για κάθε πωλητή στο αντίστοιχο στοιχείο του πίνακα. Το ακόλουθο σχήµα δείχνει τη διαφορά ανάµεσα στη χρήση των ξεχωριστών µεταβλητών και µιας διάταξης. Σχήµα 1: H έννοια των πινάκων 1.1 Ορισµός πινάκων Μπορείτε να ορίσετε ένα πίνακα µε οποιονδήποτε τύπο δεδοµένων: ακέραιοι, πραγµατικοί αριθµοί κινητής υποδιαστολής, χαρακτήρες κτλ. Όταν ορίζετε ένα πίνακα, ζητάτε από την γλώσσα C να δεσµεύσει θέσεις µνήµης γι αυτόν. Κάθε στοιχείο ενός πίνακα καταλαµβάνει το ίδιο ποσό µνήµης µε µια άλλη µεταβλητή του ίδιου τύπου δεδοµένων. Για παράδειγµα, κάθε στοιχείο σε έναν πίνακα χαρακτήρων καταλαµβάνει ένα byte. Το ίδιο ισχύει και για κάθε άλλο τύπο δεδοµένων. Η C αποθηκεύει όλα τα στοιχεία ενός πίνακα σε συνεχόµενες θέσεις στην µνήµη του υπολογιστή. Αυτό είναι σηµαντικό κυρίως σε πιο προχωρηµένα προγράµµατα. Πάντα το πρώτο στοιχείο προηγείται του δευτέρου, το δεύτερο του τρίτου κτλ. Η µνήµη βεβαιώνει ότι δεν περιέχει κενά µεταξύ των στοιχείων ενός πίνακα. Αν µια τιµή κινητής υποδιαστολής καταλαµβάνει τέσσερα bytes, τότε το επόµενο στοιχείο ενός πίνακα κινητής υποδιαστολής βρίσκεται πάντα ακριβώς τέσσερα byres µετά το προηγούµενο του. 1/7
#include <stdio.h> main () float expenses [10]; To παραπάνω πρόγραµµα δηλώνει έναν πίνακα τύπου float το οποίο αποτελείται από 10 στοιχεία. Καθένα από τα 10 είναι το ακριβές ισοδύναµο µιας απλής µεταβλητής float. Τα στοιχεία του πίνακα στην C αριθµούνται πάντοτε αρχίζοντας από το 0. Έτσι τα 10 στοιχεία του πίνακα αριθµούνται από το 0 µέχρι το 9 και αποθηκεύονται σε διαδοχικές θέσεις µνήµης όπως φαίνεται στο παρακάτω σχήµα. expenses[0] expenses[1] expenses[9] Σχήµα 2: ιαδοχική αποθήκευση των στοιχείων ενός πίνακα Ένα στοιχείο του πίνακα µπορεί να χρησιµοποιηθεί οπουδήποτε στο πρόγραµµα σας. Το κάθε στοιχείο του πίνακα προσπελαύνεται µε τη χρήση του ονόµατος της διάταξης, ακολουθούµενου από το δείκτη του στοιχείου. Όταν αναφέρεστε σε ένα στοιχείο του πίνακα, ο δείκτης του πίνακα µπορεί να είναι µια σταθερά ή µια ακέραια µεταβλητή. 1.2 Ονοµασία και ήλωση Πινάκων Οι κανόνες για την εκχώρηση ονοµάτων σε πίνακες είναι ίδιοι µε τους κανόνες για τον ορισµό ονοµάτων απλών µεταβλητών. Ένα όνοµα πίνακα πρέπει να είναι µοναδικό. εν µπορεί να χρησιµοποιηθεί για άλλο πίνακα ή για οποιοδήποτε άλλο προσδιοριστή (π.χ. µεταβλητή, σταθερά κτλ). Όταν δηλώνετε ένα πίνακα, µπορείτε να καθορίσετε τον αριθµό των στοιχείων µε µια σταθερά ή µε την οδηγία #define. #define MAX_SIZE 10 main() int expenses[max_size]; /* Orismos Pinaka typoy int 10 stoixeiwn */ long rate[20]; /* Orismos Pinaka typoy long 20 stoixeiwn */ 1.3 Μονοδιάστατος Πίνακας Ένας µονοδιάστατος πίνακας έχει µόνο ένα δείκτη. Ένας δείκτης είναι ένας αριθµός σε αγκύλες που έπεται του ονόµατος µιας διάταξης. Αυτός ο αριθµός µπορεί να προσδιορίζει τον αριθµό των ξεχωριστών στοιχείων σε µια διάταξη. Τα επιµέρους στοιχεία του πίνακα µπορούν να προσπελάσουν µε τη χρήση του ονόµατος του πίνακα, ακολουθούµενου από το δείκτη του στοιχείου, µέσα σε αγκύλες. 2/7
#define MAX_SIZE 10 main () int expenses[max_size]; /* Orismos Pinaka typoy int 10 stoixeiwn */ int i; expenses[0]= 4; /* Ekxwrisi sto prwto stoixeio toy pinaka tin timi 4 */ expenses[2]= 5*2-1; /* Exxwrisi sto trito stoixeio toy pinaka */ Σε ένα πίνακα µε n στοιχεία, η επιτρεπόµενη περιοχή δεικτών είναι από 0 µέχρι n-1. Εάν χρησιµοποιείτε την τιµή δείκτη µεγαλύτερη από n-1, µπορεί να έχετε σφάλµατα στο πρόγραµµα. Ο µεταγλωττιστής (compiler) δεν αναγνωρίζει αν το πρόγραµµα χρησιµοποιεί ένα δείκτη εκτός των επιτρεπόµενων ορίων. 1.4 Αρχικοποίηση Πινάκων Υπάρχουν δύο τρόποι αρχικοποίησης στοιχείων ενός πίνακα: Κατά τον ορισµό Μέσα στο πρόγραµµα Χρησιµοποιώντας αγκύλες, µπορείτε να αρχικοποιήσετε οποιονδήποτε τύπο πίνακα. Για παράδειγµα για ένα πίνακα µε τις ηλικίες πέντε παιδιών µπορούµε να γράψουµε το παρακάτω παράδειγµα main () int ages[5]=2,4,5,10,12; /* Orismos kai Arxikopoisi Pinaka typoy */ /* int 5 stoixeiwn */ Όταν αρχικοποιείτε ένα πίνακα οποιουδήποτε τύπου δεν χρειάζεται να ορίσετε ρητά το µέγεθος. Η C γνωρίζει στην περίπτωση αυτή να δεσµεύει να δεσµεύει τις σχετικές θέσεις µνήµης. void main () int ages[]=2,4,5,10,12; /* Orismos kai Arxikopoisi Pinaka typoy */ /* int 5 stoixeiwn */ Στα περισσότερα προγράµµατα, σπάνια γνωρίζετε τα περιεχόµενα ενός πίνακα όταν τους ορίζετε. Συνήθως του εκχωρείτε ως τιµές δεδοµένα του χρήστη ή από αρχείο δίσκου. Ο βρόχος for µπορεί να χρησιµοποιηθεί για την εκχώρηση τιµών σε πίνακες. 3/7
#define ARRAY_SIZE 10 void main () int ages[array_size]; /* Orismos Pinaka typoy int 5 stoixeiwn */ int index; for (index=0; index<array_size; index++) ages[index]=(index+2); 1.5 Πολυδιάστατοι Πίνακες Οι πολυδιάστατοι πίνακες είναι πίνακες µε περισσότερους από έναν δείκτες. Ένας µονοδιάστατος πίνακας είναι µια λίστα τιµών. Ένας πολυδιάστατος πίνακας προσοµοιώνει έναν πίνακα τιµών ή πολλούς πίνακες τιµών. Για παράδειγµα µπορείτε να γράψετε ένα πρόγραµµα που να παίζει ντάµα. Η ντάµα περιέχει 64 τετράγωνα τακτοποιηµένα σε οκτώ γραµµές και οκτώ στήλες. Το πρόγραµµα αυτό θα µπορούσε να αναπαριστά την επιφάνεια της ντάµας ως µια δισδιάστατη διάταξη όπως φαίνεται στο παρακάτω σχήµα. Σχήµα 3: ιαδοχική αποθήκευση των στοιχείων ενός πίνακα Για να δεσµεύσετε πολυδιάστατους πίνακες, πρέπει να πληροφορήσετε την C ότι ο πίνακας έχει περισσότερες από µια διαστάσεις. Έτσι, στις παρενθέσεις γράφετε περισσότερες από µια διαστάσεις. Έτσι στις παρενθέσεις γράφετε περισσότερους από ένα δείκτες, έναν για κάθε διάσταση. H C είναι ελαστική σχετικά µε τον ορισµό ενός πολυδιάστατου πίνακα κατά την αρχικοποίηση του ή κατά τον ορισµό του. Όπως µε τους µονοδιάστατους πίνακες, αρχικοποιείτε τους πολυδιάστατους πίνακες µε αγκύλες που ορίζουν διαστάσεις main() float utilities[12][4]; /* Desmyesi 48 stoixeiwn typoy flοat */ int test[2][4] = 14,30,12,81, 15,27,40,9; 4/7
1.6 Η συνάρτηση sizeof Λόγω του τρόπου λειτουργίας της µνήµης, δεν θα πρέπει να επιχειρήσετε να δηµιουργήσετε περισσότερα από 64 ΚΒ µεταβλητών δεδοµένων. Γενικά 64 ΚΒ είναι αρκετός χώρος για δεδοµένα προγραµµάτων. Το µέγεθος µιας διάταξης σε bytes εξαρτάται από τον αριθµό των στοιχείων που έχει, καθώς και από το µέγεθος κάθε στοιχείου. Για να υπολογίσετε τον απαιτούµενο αποθηκευτικό χώρο για µία διάταξη, πρέπει να πολλαπλασιάσετε τον αριθµό των στοιχείων στη διάταξη επί το µέγεθος του στοιχείου. Ένας εναλλακτικός τρόπος υπολογισµού είναι η χρήση της συνάρτησης sizeof.h συνάρτηση sizeof επιστρέφει τον αριθµό των bytes που δεσµεύει το όρισµα της. Αν ζητήσετε το µέγεθος ενός πίνακα, η sizeof() επιστρέφει τον αριθµό των bytes που δεσµεύονται για ολόκληρο τον πίνακα. #include <stdio.h> void main () int scores[100]; /* Orismos Pinaka typoy int 100 stoixeiwn */ int n; n=sizeof(scores); printf("n equals to %d\n",n); Στην οθόνη του υπολογιστή εµφανίζεται το παρακάτω αποτέλεσµα n equals to 400 bytes (σε πολύ παλιούς υπολογιστές ή και σε κάποιους καινούργιους ή μελλοντικούς αυτή η τιμή μπορεί να είναι διαφορετική). 5/7
2. ΕΡΓΑΣΤΗΡΙΑΚΟ ΜΕΡΟΣ 1. Να γραφεί πρόγραµµα που να εκτελεί τα παρακάτω: Να δηµιουργεί ένα πίνακα 50 στοιχείων τύπου int Να τον γεμίζει με τυχαίες τιμές από το 1 έως το 100 Να εκτυπώνει τον πίνακα Να υπολογίζει το µεγαλύτερο και το µικρότερο αριθµό στον πίνακα. Να υπολογίζει το µέσο όρο 2. Να γραφεί πρόγραµµα που να εκτελεί τα παρακάτω Να δηµιουργεί ένα πίνακα 10 στοιχείων τύπου float Να τον γεμίζει με τιμές από το 0.5 έως το 50 που θα δίνει ο χρήστης. Σε περίπτωση λάθους εισόδου να ξαναζητάει είσοδο από τον χρήστη (να κάνετε χρήση της δομής do-while). Να υπολογίζει το µεγαλύτερο και τον µικρότερο αριθµό στον πίνακα. Να υπολογίζει το πλήθος των στοιχείων που είναι μεγαλύτερα από το µέσο όρο. Να αναζητάει αν υπάρχει στον πίνακα η τιμή 35 και να εμφανίζει την θέση του στον πίνακα ή μήνυμα ότι δεν υπάρχει. 3. Να γραφεί πρόγραμμα σε C που να διαβάζει από το πληκτρολόγιο τους βαθμούς 10 φοιτητών και να γίνεται έλεγχος ότι ο χρήστης δίνει πραγματικούς αριθμούς από 0 έως 10, αλλά μόνο με ένα δεκαδικό ψηφίο, αλλιώς το πρόγραμμα ξαναζητάει το βαθμό. Οι βαθμοί αυτοί θα πρέπει να αποθηκεύονται σε ένα μονοδιάστατο πίνακα. Στη συνέχεια το πρόγραμμα να υπολογίζει και να εμφανίζει τα παρακάτω: το πλήθος των μαθητών που έχουν βαθμό πάνω από το μέσο όρο. το μεγαλύτερο βαθμό καθώς και τον α/α του φοιτητή (ή των φοιτητών) που έχουν αυτό το βαθμό. Π.χ. Μέγιστος βαθμός: 9,5. Φοιτητές: 2, 3, 10 α/α -> αύξων αριθμός. Προσέξτε ότι ο α/α των φοιτητών είναι από 1 έως 10. 4. Να δηµιουργήσετε δύο πίνακες Α[2][4] και Β[2][4] τύπου float µε αρχικοποίηση των τιµών κατά τον ορισµό τους. Να γραφεί πρόγραµµα µε τα ακόλουθα χαρακτηριστικά Προσθέτει τους δύο πίνακες Α+Β και εμφανίζει το αποτέλεσμα Αντιµεταθέτει τις τιµές του Α µε αυτές του Β και τους εκτυπώνει Μεταφέρεται τις τιμές του Β σε ένα πίνακα C[4][2] μεταφέροντας τα στοιχεία των γραμμών του Β στις στήλες του C. Πολλαπλασιάζει τους δύο πίνακες Α*C και αποθηκεύει το αποτέλεσμα σε ένα πίνακα D. Εμφανίζει τον πίνακα D. 5. Να αποθηκεύσετε σε ένα δισδιάστατο πίνακα τις θερμοκρασίες 4 πόλεων (Αθήνα, Θεσσαλονίκη, Πάτρα, Ηράκλειο) για κάθε μέρα του Δεκεμβρίου 2017. Οι τιμές να δίνονται μέσα στο πρόγραμμα ως εξής: 2,0,-3,-7,6,15,10,11,4,2,12,23,13,14,5,1,-1,-3,-7,0,5,3,10,9,14,20,14,12,10,11,6, 4,2,12,21,13,14,5,1,-1,-3,-2,0,5,3,10,9,14,20,14,12,10,11,6,2,0,-3,4,-4,15,10,11, 6,15,10,11,4,2,12,2,0,-3,4,25,13,14,5,1,10,9,14,25,14,12,-1,-3,-9,0,5,3,12,10,4, 2,15,10,0,-3,4,6,11,4,13,14,5,2,12,12,1,-1,-3,-3,9,14,0,5,3,10,20,10,11,6,14,12 Στη συνέχεια να βρείτε και να εκτυπώσετε την θερμότερη και την ψυχρότερη μέρα του μήνα για κάθε μία πόλη. Π.χ. Αθήνα: Θερμότερη μέρα (23 C), 13 Δεκ Ψυχρότερη μέρα (-7 C), 4 Δεκ, 20 Δεκ Στη συνέχεια να βρείτε και να εκτυπώσετε την θερμότερη και την ψυχρότερη πόλη για κάθε μέρα του μήνα. Π.χ. 1 Δεκ: Θερμότερη πόλη (6 C), Πάτρα Ψυχρότερη πόλη (2 C), Αθήνα, Ηράκλειο 6/7
6. Μια µικρή αεροπορική εταιρεία έχει µόλις αγοράσει έναν υπολογιστή για το νέο της αυτοµατοποιηµένο σύστηµα κρατήσεων θέσεων. Σας έχουν ζητήσει να προγραµµατίσετε το νέο σύστηµα. Πρόκειται να γράψετε ένα πρόγραµµα για να εκχωρείτε θέσεις σε κάθε πτήση του µόνου αεροπλάνου της εταιρείας (ΧΩΡΗΤΙΚΟΤΗΤΑ 20 θέσεις). Το πρόγραµµα σας θα πρέπει να προβάλλει το ακόλουθο µενού επιλογών Please type 1 for first class Please type 2 for economy Select: Εάν πληκτρολογήσετε 1, τότε το πρόγραµµα θα εκχωρεί ένα κάθισµα στην πρώτη θέση (Θέσεις 1-5). Εάν πληκτρολογήσετε 2,τότε το πρόγραµµα θα δίνει ένα κάθισµα στην οικονοµική θέση (Θέσεις 6-20). Το πρόγραµµα σας θα πρέπει να προβάλλει ένα έντυπο επικύρωσης δείχνοντας τον αριθµό καθίσµατος και αν είναι στην πρώτη ή στην οικονοµική θέση. Το πρόγραµµα σας δεν θα πρέπει ποτέ να εκχωρεί ένα κάθισµα που έχει ήδη δοθεί. Όταν η πρώτη θέση είναι συµπληρωµένη, το πρόγραµµα σας θα ρωτά αν είναι δεκτή η τοποθέτηση στην οικονοµική θέση. Εαν ναι θα γίνεται η αντίστοιχη κράτηση. Εάν όχι, θα προβάλλεται το µήνυµα Next flight leaves in 3 hours. Υπόδειξη: Να χρησιµοποιήσετε ένα πίνακα για να αναπαραστήσετε τις θέσεις του αεροπλάνου. ώστε αρχική τιµή 0 σε όλα τα στοιχεία του πίνακα για να δηλώσετε ότι όλα τα καθίσµατα είναι κενά. Καθώς κάθε κάθισµα θα εκχωρείται σε κάποιον, ορίστε τα αντίστοιχα στοιχεία του πίνακα σε 1 για να δηλώσετε ότι το κάθισµα δεν είναι πλέον διαθέσιµο. 7/7