Προγραμματισμός Η/Υ (ΤΛ2007 )

Σχετικά έγγραφα
Δομημένος Προγραμματισμός (ΤΛ1006)

Δομημένος Προγραμματισμός (ΤΛ1006)

Προγραμματισμός Η/Υ (ΤΛ2007 )

Προγραμματισμός Η/Υ (ΤΛ2007 )

Δομημένος Προγραμματισμός (ΤΛ1006)

Δομημένος Προγραμματισμός (ΤΛ1006)

ΑΣΚΗΣΗ 6: ΔΕΙΚΤΕΣ. Σκοπός της Άσκησης. 1. Εισαγωγικά στοιχεία για τους Δείκτες

Διαδικασιακός Προγραμματισμός

Προγραμματισμός Η/Υ (ΤΛ2007 )

Διάλεξη 3η: Τύποι Μεταβλητών, Τελεστές, Είσοδος/Έξοδος

Προγραμματισμός Ι. Δυναμική Διαχείριση Μνήμης. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Προγραμματισμός Ι. Δείκτες. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

ΔΟΜΗΜΕΝΟΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ

Δομημένος Προγραμματισμός (ΤΛ1006)

Προγραμματισμός Η/Υ (ΤΛ2007 )

Υπολογισμός - Συλλογή Δεδομένων - Πίνακες

Δομημένος Προγραμματισμός

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

Εισαγωγή στον Προγραµµατισµό «C»

Διαδικασιακός Προγραμματισμός

Εισαγωγή στον Προγραμματισμό

Δομές Δεδομένων (Εργ.) Ακ. Έτος Διδάσκων: Ευάγγελος Σπύρου. Εργαστήριο 3 Επανάληψη Γ μέρος

ΔΟΜΗΜΕΝΟΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΜΑΘΗΜΑ 3 Ο. Σταθερές-Παράμετροι-Μεταβλητές Αριθμητικοί & Λογικοί Τελεστές Δομή ελέγχου-επιλογής Σύνθετοι έλεγχοι

ΔΟΜΗΜΕΝΟΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ

Προγραμματισμός Η/Υ (ΤΛ2007 )

3ο σετ σημειώσεων - Πίνακες, συμβολοσειρές, συναρτήσεις

Δομημένος Προγραμματισμός (ΤΛ1006)

Η γλώσσα προγραμματισμού C

Προγραμματισμός Η/Υ (ΤΛ2007 )

Προγραμματισμός Η/Υ (ΤΛ2007 )

Διάλεξη 11η: Δείκτες, μέρος 1

Εισαγωγή στον Προγραμματισμό (με. τη C)

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

Πίνακες: μια σύντομη εισαγωγή. Πίνακες χαρακτήρων: τα "Αλφαριθμητικά"

ΕΙΣΑΓΩΓΗ ΣΤΟΝ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

Εισαγωγή στον δομημένο προγραμματισμό

Στόχοι και αντικείμενο ενότητας. Εκφράσεις. Η έννοια του τελεστή. #2.. Εισαγωγή στη C (Μέρος Δεύτερο) Η έννοια του Τελεστή

Διάλεξη 9η: Πίνακες (arrays)

Διδάσκων: Παναγιώτης Ανδρέου

Εισαγωγή στον Προγραμματισμό

Δείκτες (Pointers) Ένας δείκτης είναι μια μεταβλητή με τιμή μια διεύθυνση μνήμης. 9.8

Προγραμματισμός Η/Υ (ΤΛ2007 )

Διαδικασιακός Προγραμματισμός

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

Προγραμματισμός Η/Υ (ΤΛ2007 )

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

Προγραμματισμός Η/Υ 1 (Εργαστήριο)

Εισαγωγή στον Προγραµµατισµό. Διάλεξη 2 η : Βασικές Έννοιες της γλώσσας προγραµµατισµού C Χειµερινό Εξάµηνο 2011

ΕΡΓΑΣΤΗΡΙΑΚΕΣ ΑΣΚΗΣΕΙΣ C ΣΕΙΡΑ 2 η

Μεταβλητές. Έστω η μεταβλητή

Στοιχειώδης προγραμματισμός σε C++

Πίνακες. 1 Πίνακες. 30 Μαρτίου 2014

Προγραμματισμός Ι. Προχωρημένα Θέματα. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Προγραμματισμός Η/Υ (ΤΛ2007 )

C: Από τη Θεωρία στην Εφαρµογή 2 ο Κεφάλαιο

Μεθόδων Επίλυσης Προβλημάτων

Διάλεξη 5: Δείκτες και Συναρτήσεις

Π. Σταθοπούλου ή Οµάδα Α (Φοιτητές µε µονό αριθµό Μητρώου ) ιδασκαλία : Παρασκευή 11πµ-13µµ ΗΛ7

int array[10]; double arr[5]; char pin[20]; Προγραµµατισµός Ι

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

Διαδικαστικός Προγραμματισμός

Διάλεξη 6: Δείκτες και Πίνακες

Α. unsigned int Β. double. Γ. int. unsigned char x = 1; x = x + x ; x = x * x ; x = x ^ x ; printf("%u\n", x); Β. unsigned char

Τμήμα Πληροφορικής & Επικοινωνιών Δρ. Θεόδωρος Γ. Λάντζος

Προγραμματισμός Η/Υ (ΤΛ2007 )

ΘΕΜΑΤΑ ΕΞΕΤΑΣΗΣ ΚΑΙ ΑΠΑΝΤΗΣΕΙΣ

Προγραμματισμός Ι. Εγγραφές. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Διαδικασιακός Προγραμματισμός

ΤΕΜ-101 Εισαγωγή στους Η/Υ Εξεταστική Ιανουαρίου 2011 Θέματα Β

5ο σετ σημειώσεων - Δείκτες

Κεφάλαιο 8.7. Πολυδιάστατοι Πίνακες (Διάλεξη 19)

Προγραμματισμός Ι. Χαρακτήρες. Πανεπιστήμιο Πελοποννήσου Τμήμα Πληροφορικής & Τηλεπικοινωνιών

Προγραμματισμός Η/Υ (ΤΛ2007 )

Ανάπτυξη και Σχεδίαση Λογισμικού

ΠΑΝΕΠΙΣΤΗΜΙΟ ΘΕΣΣΑΛΙΑΣ ΣΧΟΛΗ ΘΕΤΙΚΩΝ ΕΠΙΣΤΗΜΩΝ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ

ΕΙΣΑΓΩΓΗ ΣΤΗΝ ΑΝΑΛΥΣΗ ΑΛΓΟΡΙΘΜΩΝ

Ορισμός μεταβλητών δεικτών και αρχικοποίηση

Διαδικασιακός Προγραμματισμός

Η πρώτη παράμετρος είναι ένα αλφαριθμητικό μορφοποίησης

Προγραμματισμός Ι (ΗΥ120)

Στόχοι και αντικείμενο ενότητας. Τύπος πίνακα. Τύπος πίνακα (συν.) #6. Πίνακες και Δείκτες

Μεθόδων Επίλυσης Προβλημάτων

Προγραμματισμός Ι. Δομές & Ενώσεις. Πανεπιστήμιο Πελοποννήσου Τμήμα Πληροφορικής & Τηλεπικοινωνιών

ΔΟΜΗΜΕΝΟΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ

ΕΡΓΑΣΤΗΡΙΟ 1 - ΣΗΜΕΙΩΣΕΙΣ

Κλήση Συναρτήσεων ΚΛΗΣΗ ΣΥΝΑΡΤΗΣΕΩΝ. Γεώργιος Παπαϊωάννου ( )

Εισαγωγή στη γλώσσα προγραμματισμού C++

Εισαγωγή στον Προγραμματισμό

Γλώσσες Προγραμματισμού

Σημειώσεις του εργαστηριακού μαθήματος Πληροφορική ΙΙ. Εισαγωγή στην γλώσσα προγραμματισμού

Δομημένος Προγραμματισμός (ΤΛ1006)

ΒΑΣΙΚΟΙ ΤΥΠΟΙ ΚΑΙ ΠΙΝΑΚΕΣ

ΣΥΝΑΡΤΗΣΕΙΣ (Functions)

Προγραμματισμός Η/Υ Ι (Χρήση της C) 6 η Θεωρία ΜΟΝΟΔΙΑΣΤΑΤΟΙ ΠΙΝΑΚΕΣ

Προγραμματισμός Υπολογιστών με C++

Εισαγωγή στην C. Μορφή Προγράµµατος σε γλώσσα C

Εισαγωγή στον προγραμματισμό. Τμήμα Πληροφορικής & Επικοινωνιών ΤΕΙ Σερρών Εργαστήριο 2

Ανάπτυξη και Σχεδίαση Λογισμικού

Π. Σταθοπούλου ή Οµάδα Α (Φοιτητές µε µονό αριθµό Μητρώου ) ιδασκαλία : Παρασκευή 11πµ-13µµ ΗΛ7

Transcript:

Τμήμα Ηλεκτρονικών Μηχανικών Τ.Ε.Ι. Κρήτης Προγραμματισμός Η/Υ (ΤΛ2007 ) Δρ. Μηχ. Νικόλαος Πετράκης (npet@chania.teicrete.gr) Ιστοσελίδα Μαθήματος: https://eclass.chania.teicrete.gr/ Εξάμηνο: Εαρινό 2014-15

Δείκτες και διατάξεις (πίνακες) Η σχέση των διατάξεων και των δεικτών είναι πολύ σημαντική Εάν θυμηθούμε τη δήλωση μίας διάταξης float a[10]; /* Μονοδιάστατη διάταξη 10 στοιχείων τύπου float */ a[0] a[1]... a[9] Ουσιαστικά η μεταβλητή a υποδηλώνει τη διεύθυνση του πρώτου του στοιχείου (δηλαδή του a[0]), και μετά τόσες θέσεις μνήμης όσες να χωρέσουν 10 πραγματικοί αριθμοί κινητής υποδιαστολής (float). Με αυτό τον τρόπο η C απεικονίζει εσωτερικά τους πίνακες (διατάξεις). 2

Δείκτες και διατάξεις (πίνακες) Ένα όνομα διάταξης χωρίς αγκύλες είναι ένας δείκτης στο πρώτο στοιχείο της διάταξης. Είναι ένας σταθερός δείκτης. Η έκφραση array είναι ισοδύναμη με &array[0] Μπορούμε να δηλώσουμε ένα μεταβλητό δείκτη και να του δώσουμε αρχική τιμή να δείχνει στη διάταξη. int array[100], *p_array; /* πρόσθετος κώδικας */ p_array = array; O παραπάνω κώδικας δίνει αρχική τιμή στο μεταβλητό δείκτη p_array τη διεύθυνση του πρώτου στοιχείου της array[] Εδώ, ο p_array είναι ένας μεταβλητός δείκτης που μπορεί να πάρει και άλλες τιμές και να δείχνει σε άλλα στοιχεία της διάταξης. 3

Δείκτες και διατάξεις (πίνακες) short int a[10], *p; p = &a[0]; p a[0] a[1] 1000 1001 1002 1003 *p = 5; /* To a[0] παίρνει τιμή 5 */ Ένας δείκτης πρέπει να αυξηθεί κατά 2 για να προσπελάσει επιτυχώς τα στοιχεία σε μία διάταξη τύπου short int Άρα θα έχουμε &a[0] = 1000, &a[1] = 1002 κλπ. Η συνάρτηση sizeof (τύπος_δεδομένων) μας επιστρέφει τον αριθμό των bytes που καταλαμβάνει κάποιος τύπος δεδομένων ή μεταβλητή. 4

Ακόμα ένα παράδειγμα Να γίνει ένα πρόγραμμα το οποίο θα διαβάζει ένα αρχείο κειμένου (πρότυπη είσοδο) γραμμή-γραμμή και θα την εμφανίζει στην οθόνη (πρότυπη έξοδο) μόνο εφόσον περιέχει κάποιο συγκεκριμένο συνδυασμό χαρακτήρων, ενώ όταν φτάσει στο τέλος του αρχείου να εμφανίζει το πλήθος των γραμμών που περιείχαν τον ζητούμενο συνδυασμό. Περίγραμμα προγράμματος ενόσω (υπάρχει άλλη γραμμή, διάβασέ την) εάν (η γραμμή περιέχει τον συνδυασμό) εμφάνισέ την αύξησε τον μετρητή κατά ένα εμφάνισε τον συνολικό αριθμό γραμμών που βρέθηκαν να περιέχουν το συνδυασμό. Θα βρείτε την λύση, που δόθηκε στον πίνακα, στις σημειώσεις της θεωρίας. 5

Δείκτες διεύθυνσης ως ορίσματα Μία από τις σημαντικές χρήσεις των δεικτών είναι ότι επιτρέπουν την διοχέτευση ορισμάτων σε συναρτήσεις με αναφορά (by reference). Αυτό σημαίνει ότι αντί να περνάμε ένα αντίγραφο του ορίσματος στην αντίστοιχη παράμετρο, περνάμε τη διεύθυνση του ορίσματος. Οπότε, κάθε αλλαγή στην παράμετρο (στο σώμα της συνάρτησης) ουσιαστικά μεταβάλει τα περιεχόμενα στη θέση μνήμης του ορίσματος! 6

main() { int k = 10, *a; a = &k; plus(a); plus(a); Παράδειγμα Η παράμετρος x λαμβάνει ως τιμή τη διεύθυνση a και προσθέτει το περιεχόμενό της, το αποτέλεσμα θα είναι 40. return 0; } void plus(int *x) { *x = *x + *x; return ; } main() { int k = 10; } plus(&k); plus(&k); return 0; Η παράμετρος x λαμβάνει ως τιμή τη διεύθυνση της μεταβλητής k και προσθέτει το περιεχόμενό της. Το αποτέλεσμα θα είναι και πάλι 40. 7

Κι άλλο παράδειγμα Η παρακάτω συνάρτηση πραγματοποιεί αντιμετάθεση των περιεχομένων δύο μεταβλητών πραγματικού τύπου κινητής υποδιαστολής διπλής ακρίβειας. void swap (double *ptr_x, double *ptr_y) { double tmp; } tmp = *ptr_x; *ptr_x = *ptr_y; *ptr_y = tmp; return; Ενώ η εντολή κλήσης της συνάρτησης θα μπορούσε να είναι: main () { double a = 13.25, b = 8.79; } printf ("A = %.2f και Β = %.2f\n", a, b); swap(&a, &b); printf ("A = %.2f και Β = %.2f\n", a, b); return 0; 8

Δείκτης διεύθυνσης ως τιμή επιστροφής από συνάρτηση Οι δείκτες δεν χρησιμοποιούνται μόνο για διοχέτευση ορισμάτων σε συναρτήσεις. Χρησιμοποιούνται και για επιστροφή τιμών από συναρτήσεις π.χ.: int *max (int *, int *); void main() { int *p, x=10, y=20;... p = max(&x, &y);... } Σημαίνει ότι η max επιστρέφει δείκτη διεύθυνσης σε ακέραιο Διοχετεύουμε σαν ορίσματα τις διευθύνσεις των μεταβλητών x και y και παραλαμβάνουμε με δείκτες int * max (int *a, int *b) { if (*a > *b) return a; else return b; } 9

Σημείωση ΠΡΟΣΟΧΗ: Μην επιστρέφετε ως αποτέλεσμα συνάρτησης δείκτη σε τοπική μεταβλητή π.χ. int *fctn(void) { int i;... } return &i; Η μεταβλητή i δεν θα υπάρχει μετά το τέλος της συνάρτησης οπότε ο δείκτης (η διεύθυνση του i) θα είναι άκυρος 10

Αριθμητική δεικτών διεύθυνσης Μπορούμε να προσθέσουμε ένα ακέραιο αριθμό σε ένα δείκτη διεύθυνσης (pointer), να αφαιρέσουμε ένα ακέραιο αριθμό από ένα δείκτη, ή να αφαιρέσουμε ένα δείκτη διεύθυνσης από έναν άλλο. Όταν έχουμε να κάνουμε με διατάξεις (πίνακες), αυτές οι πράξεις γίνονται πολύ ενδιαφέρουσες. 11

Μεταβολή δείκτη διεύθυνσης Όταν αυξάνουμε ένα δείκτη, αυξάνουμε τη τιμή του. Όταν αυξάνουμε ένα δείκτη κατά 1, η αριθμητική δεικτών αυξάνει αυτόματα την τιμή του δείκτη έτσι ώστε να δείχνει στο επόμενο στοιχείο μίας διάταξης. Ας υποθέσουμε ότι ο ptr_chr είναι δείκτης προς κάποιο στοιχείο διάταξης. ptr_chr++ η τιμή του ptr_chr αυξάνεται κατά το μέγεθος του τύπου char (1 byte) και η ptr_chr δείχνει τώρα στο επόμενο στοιχείο της διάταξης (επόμενο χαρακτήρα) ptr_int++ η τιμή του ptr_int αυξάνεται κατά το μέγεθος του τύπου int (συνήθως 4 bytes) και η ptr_int δείχνει τώρα στο επόμενο στοιχείο της διάταξης. ptr_double++, αύξηση της αποθηκευμένης τιμής του δείκτη κατά 8 (bytes), δείχνει στο επόμενο στοιχείο ptr_chr += 3 ; (κατά 3 bytes, δείχνει 3 στοιχεία μετά), ptr_int += 4 ; (κατά 16 bytes, δείχνει 4 στοιχεία μετά), ptr_double += 10 ; (κατά 80 bytes, δείχνει 10 στοιχεία μετά) 12

Άλλοι χειρισμοί δεικτών διεύθυνσης Η μόνη άλλη λειτουργία της αριθμητικής δεικτών είναι η διαφορά και αφορά την αφαίρεση δύο δεικτών διεύθυνσης. Εάν έχουμε δύο δείκτες διεύθυνσης που να δείχνουν προς δύο στοιχεία του ίδιου πίνακα, μπορούμε να τους αφαιρέσουμε και να βρούμε πόσο απέχει το ένα στοιχείο από το άλλο. ptr1-ptr2 H C γνωρίζει τον τύπο δεδομένων που δείχνει ο δείκτης από τη δήλωσή του και μεταβάλει τη διεύθυνση που είναι αποθηκευμένη στον δείκτη κατά το μέγεθος του τύπου δεδομένων. 13

Άλλοι χειρισμοί δεικτών διεύθυνσης Τα χαμηλότερα στοιχεία μίας διάταξης (εκείνα με το χαμηλότερο δείκτη, δηλαδή τα πρώτα) έχουν πάντα χαμηλότερη διεύθυνση από τα υψηλότερα στοιχεία. Η σχέση ptr1 < ptr2 είναι αληθής αν το ptr1 δείχνει σε ένα χαμηλότερο μέλος της διάταξης από εκείνο στο οποίο δείχνει ο ptr2. Οι συγκρίσεις δεικτών είναι έγκυρες μόνο μεταξύ δεικτών που δείχνουν στην ίδια διάταξη. O πολλαπλασιασμός και η διαίρεση δεν έχουν νόημα με τους δείκτες. ptr *= 2 δίνει μήνυμα λάθους αν ptr είναι δείκτης 14

Άλλοι χειρισμοί δεικτών διεύθυνσης Εάν μία δηλωμένη διάταξη είναι η array[], η έκφραση *array είναι το πρώτο στοιχείο της διάταξης, η *(array + 1) είναι το δεύτερο στοιχείο της διάταξης, κτλ. Αν p_array είναι ένας δείκτης στο πρώτο στοιχείο μίας διάταξης δηλ. η διεύθυνση του πρώτου στοιχείου, ισοδύναμο με &array[0] Είναι αληθείς οι ακόλουθες σχέσεις: *(p_array) == array[0] *(p_array + 1) == array[1] *(p_array + n) == array[n] αλλά και οι ακόλουθες: *(array) == p_array[0] *(array + 1) *(array + n) == p_array[1] == p_array[n] Αυτό δείχνει την ισοδυναμία της σημειογραφίας δεικτών διάταξης και της σημειογραφίας δεικτών σε διάταξη. 15

Παράδειγμα int a[10], *p, *q, *w; p = &a[0]; p a[0] a[1] *p = 40; /* To a[0] παίρνει τιμή 40 */ q = p + 3; w = q-1; p w q a[0] a[1] a[2] a[3] a[4] 16

Αφαίρεση δεικτών διεύθυνσης Ας θεωρήσουμε: int a[10], *p, *q, i; p = &a[5]; q = &a[3]; i = p - q; /* Η τιμή της μεταβλητής i είναι 2 */ i = q - p; /* Η τιμή της μεταβλητής i είναι -2 */ Σημείωση: Η αριθμητική σε δείκτες έχει νόημα όταν χρησιμοποιείται σε διατάξεις όπως στα παραδείγματα παραπάνω. Η αφαίρεση μας λέει πόσο απέχουν τα στοιχεία μιας διάταξης και όχι αριθμητική διαφορά μεταξύ διευθύνσεων δεικτών διεύθυνσης. 17

Παράδειγμα #define N 100 int a[n], sum, *p; Προσθέτει όλα τα στοιχεία μίας διάταξης ακέραιων main() { sum = 0; for (p = &a[0]; p < &a[n]; p++) sum = sum + *p; return 0; } 18

Κι άλλα παραδείγματα Υλοποίηση ενός στοιχειώδους κατανεμητή μνήμης με συναρτήσεις για δέσμευση, alloc(n), και αποδέσμευση, afree(p), μνήμης. Συνάρτηση που να επιστρέφει τον ν-οστό όρο της ακολουθίας Fibonacci, όταν γνωρίζουμε ότι ο κάθε όρος προκύπτει από το άθροισμα των δύο προηγούμενων όρων και ότι ο πρώτος όρος ισούται με μηδέν (0), ενώ ο δεύτερος με ένα (1). Οι λύσεις, που δόθηκαν στον πίνακα, υπάρχουν στις σημειώσεις της θεωρίας. 19

Σύνοψη λειτουργιών δεικτών διεύθυνσης Εκχώρηση Έμμεση διευθυνσιοδότηση Διεύθυνση Αύξηση Μείωση Διαφορά Σύγκριση 20