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

Σχετικά έγγραφα
Εισαγωγή στον Προγραμματισμό με C++

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

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

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

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

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

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

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

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

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

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

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

Προγραμματισμός Υπολογιστών & Υπολογιστική Φυσική

ΥΠΟΛΟΓΙΣΤΕΣ ΙI. Άδειες Χρήσης. Δείκτες Διδάσκοντες: Αν. Καθ. Δ. Παπαγεωργίου, Αν. Καθ. Ε. Λοιδωρίκης

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

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

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

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

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

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

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

Προγραμματισμός ΙI (Θ)

ΕΛΛΗΝΙΚΗ ΔΗΜΟΚΡΑΤΙΑ Ανώτατο Εκπαιδευτικό Ίδρυμα Πειραιά Τεχνολογικού Τομέα. Εισαγωγή στον Προγραμματισμό. Ενότητα 9: Συναρτήσεις Εμβέλεια

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

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

Προγραμματισμός Υπολογιστών & Υπολογιστική Φυσική

Προγραμματισμός Υπολογιστών & Υπολογιστική Φυσική

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

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

ΕΛΛΗΝΙΚΗ ΔΗΜΟΚΡΑΤΙΑ Ανώτατο Εκπαιδευτικό Ίδρυμα Πειραιά Τεχνολογικού Τομέα. Εισαγωγή στον Προγραμματισμό. Ενότητα 4: Έλεγχος Ροής. Κ.

ΕΛΛΗΝΙΚΗ ΔΗΜΟΚΡΑΤΙΑ Ανώτατο Εκπαιδευτικό Ίδρυμα Πειραιά Τεχνολογικού Τομέα. Εισαγωγή στον Προγραμματισμό. Ενότητα 8: Συναρτήσεις. Κ.

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

Προγραμματισμός Υπολογιστών & Υπολογιστική Φυσική

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

Ηλεκτρονικοί Υπολογιστές

Προγραμματισμός Η/Υ. Ενότητα 2β: Εισαγωγή στη C (Μέρος Δεύτερο)

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

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

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

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

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

ΕΛΛΗΝΙΚΗ ΔΗΜΟΚΡΑΤΙΑ Ανώτατο Εκπαιδευτικό Ίδρυμα Πειραιά Τεχνολογικού Τομέα. Εισαγωγή στον Προγραμματισμό

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

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

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

ΕΛΛΗΝΙΚΗ ΔΗΜΟΚΡΑΤΙΑ Ανώτατο Εκπαιδευτικό Ίδρυμα Πειραιά Τεχνολογικού Τομέα. Eισαγωγή στον Προγραμματισμό

6. ΠΙΝΑΚΕΣ & ΑΛΦΑΡΙΘΜΗΤΙΚΑ

Προγραμματισμός H/Y Ενότητα 4: Δείκτες. Επικ. Καθηγητής Συνδουκάς Δημήτριος Τμήμα Διοίκησης Επιχειρήσεων (Γρεβενά)

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

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

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

ΕΛΛΗΝΙΚΗ ΔΗΜΟΚΡΑΤΙΑ Ανώτατο Εκπαιδευτικό Ίδρυμα Πειραιά Τεχνολογικού Τομέα. Εισαγωγή στον Προγραμματισμό. Ενότητα 6: Πίνακες. Κ.

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

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

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

ΑΣΚΗΣΗ 5: ΠΙΝΑΚΕΣ. Σχήµα 1: H έννοια των πινάκων

ΕΛΛΗΝΙΚΗ ΔΗΜΟΚΡΑΤΙΑ Ανώτατο Εκπαιδευτικό Ίδρυμα Πειραιά Τεχνολογικού Τομέα. Συστήματα Αυτομάτου Ελέγχου. Ενότητα Α: Γραμμικά Συστήματα

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

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΥΠΟΛΟΓΙΣΤΩΝ & ΥΠΟΛΟΓΙΣΤΙΚΗ ΦΥΣΙΚΗ

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

Προγραμματισμός H/Y Ενότητα 1: Εισαγωγή. Επικ. Καθηγητής Συνδουκάς Δημήτριος Τμήμα Διοίκησης Επιχειρήσεων (Γρεβενά)

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

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

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

ΥΠΟΛΟΓΙΣΤΕΣ ΙI. Άδειες Χρήσης. Τύποι δεδομένων, μεταβλητές, πράξεις. Διδάσκοντες: Αν. Καθ. Δ. Παπαγεωργίου, Αν. Καθ. Ε. Λοιδωρίκης

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

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

ΑΡΧΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ

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

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

ΕΛΛΗΝΙΚΗ ΔΗΜΟΚΡΑΤΙΑ Ανώτατο Εκπαιδευτικό Ίδρυμα Πειραιά Τεχνολογικού Τομέα. Εισαγωγή στον Προγραμματισμό. Ενότητα 3: Είσοδος και Έξοδος Δεδομένων

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

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

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

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

Ειδικά Θέματα Προγραμματισμού

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

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

Προγραμματισμός H/Y Ενότητα 6: Δομές (structures) Επικ. Καθηγητής Συνδουκάς Δημήτριος Τμήμα Διοίκησης Επιχειρήσεων (Γρεβενά)

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

Αντικειμενοστραφής Προγραμματισμός

Προγραμματισμό για ΗΜΥ

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

a = 10; a = k; int a,b,c; a = b = c = 10;

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

Στην ενότητα αυτή θα µελετηθούν τα εξής επιµέρους θέµατα: ΕΠΛ 131 Αρχές Προγραµµατισµού I 3-2

Τμήμα Μηχανικών Πληροφορικής και Τηλεπικοινωνιών

ΑΡΧΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ

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

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

ΥΠΟΛΟΓΙΣΤΕΣ ΙΙ. Τι περιλαμβάνει μια μεταβλητή; ΔΕΙΚΤΕΣ. Διεύθυνση μεταβλητής. Δείκτης

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

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

Αντικειμενοστραφείς Γλώσσες Προγραμματισμού C++ / ROOT

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

Προγραμματισμός Υπολογιστών & Υπολογιστική Φυσική

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

ΑΡΧΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ

Δομές Δεδομένων. Καθηγήτρια Μαρία Σατρατζέμη. Τμήμα Εφαρμοσμένης Πληροφορικής. Δομές Δεδομένων. Τμήμα Εφαρμοσμένης Πληροφορικής

Βασικές Αρχές Προγραμματισμού

Transcript:

ΕΛΛΗΝΙΚΗ ΔΗΜΟΚΡΑΤΙΑ Τεχνολογικό Εκπαιδευτικό Ίδρυμα Πειραιά Δομημένος Προγραμματισμός Ενότητα 7: Δείκτες Κουκουλέτσος Κώστας Τμήμα Μηχανικών Ηλεκτρονικών Υπολογιστικών Συστημάτων

Άδειες Χρήσης Το παρόν εκπαιδευτικό υλικό υπόκειται σε άδειες χρήσης Creative Commons. Για εκπαιδευτικό υλικό, όπως εικόνες, που υπόκειται σε άλλου τύπου άδειας χρήσης, η άδεια χρήσης αναφέρεται ρητώς.

Χρηματοδότηση Το παρόν εκπαιδευτικό υλικό έχει αναπτυχθεί στα πλαίσια του εκπαιδευτικού έργου του διδάσκοντα. Το έργο «Ανοικτά Ακαδημαϊκά Μαθήματα στο Ανώτατο Εκπαιδευτικό Ίδρυμα Πειραιά Τεχνολογικού Τομέα» έχει χρηματοδοτήσει μόνο τη αναδιαμόρφωση του εκπαιδευτικού υλικού. Το έργο υλοποιείται στο πλαίσιο του Επιχειρησιακού Προγράμματος «Εκπαίδευση και Δια Βίου Μάθηση» και συγχρηματοδοτείται από την Ευρωπαϊκή Ένωση (Ευρωπαϊκό Κοινωνικό Ταμείο) και από εθνικούς πόρους.

Σκοποί ενότητας 1. Nα κατανοήσουν την έννοια του δείκτη προς μία μεταβλητή και τον τρόπο ορισμού ενός δείκτη. 2. Να εξοικειωθούν την χρήση τελεστών με δείκτες και με τις πράξεις με δείκτες 3. Να γνωρίσουν την σχέση μεταξύ δείκτη και πίνακα και να τον τρόπο αναφοράς σε στοιχεία του πίνακα με χρήση δείκτη 4. Να κατανοήσουν του ειδικούς δείκτες null και void καθώς και τους συνδυασμούς δείκτη με σταθερές

Περιεχόμενα ενότητας Μεταβλητές και Μνήμη Η Μνήμη του Υπολογιστή Ορισμός δείκτη Ο τελεστής * με δείκτες Χρήση των δεικτών Σύνοψη Πράξεις με δείκτες Δείκτες και τελεστές αύξησης και μείωσης Πίνακες και δείκτες Δείκτες τύπου void Παράμετροι συναρτήσεων και printf Δείκτες και σταθερές

Μεταβλήτες και Μνήμη Η μνήμη αποτελείται από θέσεις (cells) στις οποίες αποθηκεύονται δεδομένα. Κάθε θέση έχει την δική του διεύθυνση. Το μέγεθος κάθε κελιού είναι 1 byte. Μία μεταβλητή καταλαμβάνει μία ή περισσότερες συνεχόμενες θέσεις στην μνήμη. Μνήμη που καταλαμβάνει μία μεταβλητή Οι θέσεις (bytes) που καταλαμβάνει μία μεταβλητή εξαρτάται από τον τύπο του δεδομένου. Για τους γνωστούς τύπους οι θέσεις είναι» char 1 byte» int 4 bytes» float 4 bytes» double 8 bytes Για να υπολογιστεί το μέγεθος μίας μεταβλητής χρησιμοποιώ την συνάρτηση sizeof πχ:» printf("%d",sizeof(int)); // εμφανίζει τον αριθμό 4

Η Μνήμη του Υπολογιστή Μία μεταβλητή τύπου int καταλαμβάνει 4 bytes. Σχηματικά μπορούμε να αναπαραστήσουμε την εντολή με τον παρακάτω τρόπο Μία γλώσσα προγραμματισμού μας παρέχει ένα εύκολο τρόπο να προσπελάσουμε την μνήμη του υπολογιστή με τα ονόματα των μεταβλητών. Είναι ευθύνη του μεταγλωττιστή (compiler) να θυμάται τις διευθύνσεις με τα ονόματα των μεταβλητών. Ουσιαστικά τα ονόματα είναι συντομεύσεις για τις διευθύνσεις ώστε ο προγραμματιστής να δουλεύει πιο εύκολα.

Ορισμός δείκτη (1/2) Ο δείκτης είναι μία μεταβλητή που σαν περιεχόμενο έχει μία διεύθυνση της μνήμης. Πχ.» int a=11;» int * pa; H pa είναι μία μεταβλητή που δείχνει την διεύθυνση μίας μεταβλητής ακέραιου τύπου. Για να δώσω μία τιμή στο pa χρησιμοποιώ τον τελεστή διεύθυνσης & (reference operator)» pa=&a;

Ορισμός δείκτη (2/2) Η μεταβλητή pa έχει σαν περιεχόμενο την διεύθυνση της μεταβλητής a που δείχνει (&a = address of a ). Με τον τελεστή * μπορώ να εμφανίσω την τιμή που βρίσκεται στην διεύθυνση που δείχνει (περιέχει) ο δείκτης δηλαδή:» printf("%d",*pa); //εμφανίζει τον αριθμό 11

Ο τελεστής * με δείκτες Το σύμβολο * χρησιμοποιείται με δύο σκοπούς Για να δηλώσει δείκτες Σαν τελεστής έμμεσης αναφοράς (dereference operator, indirection operator) για την από-αναφοροποιηση (dereferencing) στην τιμή της μεταβλητής που δείχνει ένας δείκτης, δηλαδή o τελεστής επιτρέπει την έμμεση αναφορά σε τιμή μίας μεταβλητής.» double a = 11.5;» double *pa = &a; //dilonei deikti pros double» printf("%f", *pa); //dereferencing kai emfanisi timis

Παράδειγμα» int a=11,b=88 ;» int * pa;» pa=&a ;» printf("%d %d %x %x\n", a,*pa,&a,&pa,pa);» printf("%d %d\n", sizeof(int), sizeof(pa)); Παρατηρήστε ότι H διεύθυνση που έχει αποθηκευτεί η μεταβλητή a εμφανίζεται με το &a. Οι τιμές του a και *pa είναι οι ίδιες Το περιεχόμενο του δείκτη pa που είναι η διεύθυνση 22ff44 συμπίπτει με την διεύθυνση &a που έχει αποθηκευτεί η a.

Xρήση των δεικτών Τα κύρια προτερήματα χρήσης δείκτη είναι Στις συναρτήσεις όπου επιτρέπεται επιστροφή πολλών τιμών Στους πίνακες που επιτρέπεται δυναμική κατανομή μνήμης δηλαδή η διάσταση του πίνακα να αλλάζει κατά την διάρκεια εκτέλεσης του προγράμματος ανάλογα με τις ανάγκες Η δυναμική χρήση μνήμης επιτρέπει δημιουργία συνδεδεμένης λίστας και άλλων δομών που χρησιμοποιούνται σε αλγόριθμους.

Παρατηρήσεις (1/2) 1) Για τον ορισμό του ενός δείκτη τα παρακάτω είναι ισοδύναμα.» int* a;» int * a;» int *a; 2) Για τον ορισμό περισσοτέρων του ενός δεικτών ο τελεστής * πρέπει να επαναλαμβάνεται:» int * a,* b,* c, d; Όλες οι μεταβλητές εκτός από την d είναι τύπου δείκτη, ενώ η d είναι ακέραια μεταβλητή. 3) Ένας δείκτης είναι σαν μία ακεραίου τύπου μεταβλητή. Απλά σαν τιμή έχουν ένα 16-δικό αριθμό που αναφέρεται σε μία διεύθυνση όπου περιέχεται ένας αριθμός του ιδίου τύπου με τον τύπο του δείκτη.

Παρατηρήσεις (2/2) 4) Αν έχω δύο δείκτες» int * pa, * pb; τότε η εκχώρηση pa=pb σημαίνει ότι ο δείκτης pa έχει την ίδια τιμή με το δείκτη pb δηλαδή και οι δύο δείκτες δείχνουν προς την ιδία διεύθυνση, αυτή που δείχνει ο pb 5) To πλήθος των bytes που δεσμεύονται για ένα δείκτη είναι 4 και δεν έχει σημασία ο τύπος δεδομένων που δείχνει ο δείκτης.

Παράδειγμα εμφάνισης τιμών»int a=11,b=22, c=33;»int * pa, * pb, * pc;»»pa=&a ;»pb=&b;»pc=&c;»»printf("%d %d %x %x\n",a,*pa,&a,&pa,pa);»printf("%d %d %x %x\n",b,*pb,&b,&pb,pb);»»pa=pb;»printf("%d %d %x %x\n",a,*pa,&a,&pa,pa);»printf("%d %d %x %x\n",b,*pb,&b,&pb,pb);

Παράδειγμα με δείκτες Ποία η έξοδος του παρακάτω προγράμματος» printf("program \n");» int k=1,n=20;» int* d1,*d2;» k++;--n;» printf(" %d %d \n",n,k);» k=40; n=60;d2=&k;d1=&n;» printf("%d %d \n",*d1,*d2);» *d1=*d2; ++k;n+=10 ;» printf("%d %d %d %d \n",k,n,*d1,*d2);

Σύνοψη (1/2) 1) Η δήλωση ενός δείκτη γίνεται με» int * pa, *pb; float * pd; 2) Αφού δηλωθούν οι μεταβλητές αρχικοποίηση γίνεται με εκχωρήσεις διευθύνσεων» pa=&a ; pb=&b; pd=&d; 3) Με την εντολή pa=pb ο δείκτης pa και ο pb έχουν το ίδιο περιεχόμενο 4) Με την εντολή *pa=*pb το περιεχόμενο της μεταβλητής που δείχνει ο pa αλλάζει τιμή

Σύνοψη (2/2) 5) Η εντολή *pb=44 έχει σαν αποτέλεσμα τιμή της μεταβλητής που δείχνει ο δείκτης pb γίνεται 44 6) Το σύμβολο * χρησιμοποιείται για να δηλώσει δείκτες και επίσης χρησιμοποιείται σαν τελεστής έμμεσης αναφοράς (indirection operator dereference operator) για την από αναφοροποιηση (dereferencing) στην τιμή της μεταβλητής που δείχνει ένας δείκτης, δηλαδή για την έμμεση αναφορά σε τιμή μίας μεταβλητής. 7) Ένας δείκτης μετά την δήλωσή του έχει απροσδιόριστη τιμή Όλα αυτό παρουσιάζονται στο επόμενο παράδειγμα

Παράδειγμα σύνοψης Ποιά η έξοδος του παρακάτω προγράμματος:» int a=11,b=22 ;» float d=12.33;» int * pa, *pb; float * pd;»» pa=&a ; pb=&b; pd=&d;» printf("%d %d %f\n",*pa, *pb, *pd);» pa=pb;» printf("%d %d \n",*pa, *pb);» pa=&a ; pb=&b;» *pa=*pb;» printf("%d %d \n",*pa, *pb);»» int *pc;» printf("%d \n",*pc);

Πράξεις με δείκτες (1/2) Οι δείκτες είναι σαν ακέραιες μεταβλητές. Προσθέτοντας ή αφαιρώντας από ένα δείκτη προστίθεται ή αφαιρείται το μέγεθος του τύπου του δείκτη Αν pd είναι ένας δείκτης και Type είναι ο τύπος του δείκτη. η πράξη pd++ ισοδυναμεί με την pd + siseof(type) και η τιμή του δείκτη αλλάζει

Πράξεις με δείκτες (2/2) Η πράξη pd-- ισοδυναμεί με την pd - siseof(type) και η τιμή του δείκτη αλλάζει η πράξη pd+n ισοδυναμεί με την pd + n*siseof(type) και η τιμή του δείκτη δεν αλλάζει Η πράξη pd-- ισοδυναμεί με την pd - n*siseof(type) και η τιμή του δείκτη δεν αλλάζει

Παράδειγμα»int a[ ]={50,55,60,65};»int* dk=&a[2];»int m;»m=*dk+1; printf("%d\n",m); //emfanizei ton 61»m=*(dk+1); printf("%d\n",m); //emfanizei to 65»dk--; printf("%d\n",*dk); //emfanizei to 55

Δείκτες και τελεστές αύξησης και μείωσης (1/3) Οι τελεστές ++ και - - έχουν μεγαλύτερη προτεραιότητα από τον τελεστή * (indirection operator). Επομένως η έκφραση *p++ όταν ο p έχει οριστεί σαν δείκτης είναι ισοδύναμη με την *(p++), δηλαδή αυξάνεται η τιμή του p ώστε να δείχνει στο επόμενο στοιχείο. Όμως σε εκφράσεις του τύπου κ=*p++ επειδή το ++ χρησιμοποιείται σαν επίθεμα η παράσταση υπολογίζεται σαν την τιμή που δείχνει ο δείκτης πριν γίνει αύξηση του δείκτη δηλαδή στην κ=*p++ πρώτα εφαρμόζεται ο τελεστής * αποδίδεται η τιμή στο κ και μετά εφαρμόζεται ο τελεστής ++.

Δείκτες και τελεστές αύξησης και μείωσης (2/3) Επίσης θα πρέπει να τονιστεί ότι ακόμη και η χρήση παρενθέσεων δεν αλλάζει το αποτέλεσμα και η παράσταση κ= *(p++) υπολογίζεται σαν την τιμή που δείχνει ο δείκτης πριν γίνει αύξηση του δείκτη. Δηλαδή οι παραστάσεις κ=*p++ και η κ= *(p++) αποδίδουν την ίδια τιμή στο κ και πρώτα εφαρμόζεται ο τελεστής *και μετά ο τελεστής ++. Παράδειγμα» int a[2]={10,20}; int* d, k ;» d=&a[0]; k=*(d++); printf("z= %d *d= %d\n",k,*d);» d=&a[0]; k=*d++; printf("z= %d *d= %d\n",k,*d);» //kai stis dio forew emfanizontai oi idies times k=10 *d=20

Δείκτες και τελεστές αύξησης και μείωσης (3/3) Μόνο στην περίπτωση που χρησιμοποιηθεί το ++ σαν πρόθεμα τότε υπολογίζεται η τιμή που δείχνει ο δείκτης αφού γίνει η αύξηση» d=&a[0]; k=*++d;» printf("z= %d *d= %d\n",k,*d);» // emfanizontai oi times z=20 *d=20

Πίνακες και δείκτες Στην C δείκτες και πίνακες έχουν στενή σχέση. Ο πίνακας a είναι ένας δείκτης του ιδίου τύπου με τον πίνακα και δείχνει στο πρώτο στοιχείο του πίνακα. Όταν ο compiler συναντά a[n] το μετατρέπει σε *(a+n). Επομένως το 1ο στοιχειο a[0] του πίνακα είναι το *a 2ο στοιχειο a[1] του πίνακα είναι το *(a+1) 3ο στοιχειο a[2] του πίνακα είναι το *(a+2) κλπ. Γενικά ισχύει To *(a+i) είναι ισοδύναμο το a[i] Το a+i είναι ισοδύναμο με το &a[i]

Παράδειγμα 1» int i;» int a[ ]={50,55,60,65};» printf("%d ",*a); //emfanizetai 50» printf("%d\n",*(a+3)); //emfanizetai 65» for (i=0;i<4;i++)» printf("%d ",*(a+i)); Για να δηλώσω ένα δείκτη που δείχνει στο πρώτο στοιχείο του πίνακα μπορώ να το κάνω με δύο τρόπους: int a[ ]={50,55,60,65}; int * da=a; εναλλακτικά χρησιμοποιώ την δήλωση int da=&a[0]

Παράδειγμα 2 Να ορισθεί πίνακας με 4 θέσεις και να μηδενιστούν τα στοιχεία του 1ος τρόπος int k; float p1[4]; printf("times for p1\n"); for( k=0;k<4;k++){ p1[k]=0; printf("%5d",p1[k]);} 2ος τρόπος float p2[4]; printf("\ntimes for p1\n"); for(k=0;k<4;k++){ *(p2+k)=0; printf("%5d",p2[k]);}

Πίνακα = σταθερός δείκτης Το αναγνωριστικό ενός πίνακα (όνομα) είναι ένας δείκτης που δείχνει στο πρώτο στοιχείο του πίνακα. Ενώ επιτρέπεται αλλαγή τιμής σε μία μεταβλητή τύπου δείκτη δεν επιτρέπεται αλλαγή τιμής σε ένα δείκτη όταν αυτός έχει δηλωθεί ότι είναι πίνακας. Ο δείκτης στην περίπτωση αυτή είναι ένας constant pointer. Ο λόγος είναι ότι αν αλλάξει η τιμή δεν θα υπάρχει πρόσβαση στα υπόλοιπα στοιχεία του πίνακα. Το παρακάτω παράδειγμα εξηγεί το γεγονός αυτό.

Παράδειγμα»int pin[ ]={1,2,3,4,5};»printf("%d\n",*pin);»int * diktis, * dikt, k=100;»diktis=pin;»printf("%d %d %d %d\n",*diktis,diktis[1],*(pin+2),*(diktis+3));»» //pin=dikt;» /* Auto einai lathos giati o pin einai enas constant pointer kai den epitrepetai na allazei h timi toy */»» //pin=&k; //oute afto epitrepetai»»diktis=&k; //afto epitrepetai»printf("%d\n",*diktis);

Πίνακες και δείκτες (1/2) Γενικά πίνακες και δείκτες μπορούν να χρησιμοποιηθούν εναλλακτικά ο ένας στην θέση του άλλου με ορισμένους περιορισμούς που θα δούμε παρακάτω.» int pin[ ]={1,2,3,4,5};» int * diktis» diktis=pin Η εντολή diktis=pin έχει σαν αποτέλεσμα ο δείκτης να δείχνει στην πρώτη θέση του πίνακα pin γιατί ο πίνακας θεωρείται σαν δείκτης. Ισοδύναμα αυτό μπορεί να γραφεί και σαν diktis=pin[0]

Πίνακες και δείκτες (2/2) Οι παρακάτω εκφράσεις είναι ισοδύναμες» pin[2] *(diktis+2) *(pin+2) Επίσης οι παρακάτω εκφράσεις είναι ισοδύναμες» &pin[2] diktis+2 Ένας δείκτης μπορεί να συμπεριφερθεί και σαν πίνακας και μπορεί να γραφεί έχοντας σε αγκύλες ένα αύξοντα αριθμό που αναφέρεται σε μία θέση στην μνήμη δηλαδή» diktis[2] αναφέρεται στην θέση pin[2]

Παράδειγμα» //(D_pointers_16)» int pin[ ]={1,2,3,4,5};» int * diktis;» diktis=pin;» //prosvasi sta stoixeia toy pinaka» printf("%d %d %d \n", pin[2], *(pin+2), *(diktis+2));» //Isodinames ekfraseis gia diefthinsi» printf("%x %x \n", &pin[2], diktis+2);» //xrisi deikti san pinaka» printf("%d %d \n", pin[2],diktis[2]);

Δείκτες τύπου void Ένας δείκτης μπορεί να είναι τύπου void δηλαδή δεν δείχνει σε συγκεκριμένο τύπο. Χρησιμοποιείται για δείκτες που ο τύπος τους είναι απροσδιόριστος. Δείκτες τύπου void μπορούν (και είναι σύνηθες) να μετατρέπονται σε συγκεκριμένου τύπο με την χρήση του type casting Ο τύπος δείκτη void μπορεί να πάρει τιμή με την χρήση & όμως δεν μπορούμε να κάνουμε πράξεις σε αυτόν» void *da» int a; da=&a; Στον παραπάνω δείκτη da δεν μπορούμε να αυξήσουμε τον δείκτη (πχ da++) επειδή δεν είναι γνωστή ή αύξηση που πρέπει να γίνει

Αρχικοποίηση και Δείκτης τύπου null (1/2) Ένας δείκτης όταν ορίζεται έχει απροσδιόριστη τιμή. Οι παρακάτω εντολές έχουν απόβλεπες ή καταστροφικές συνέπειες (crash) για το πρόγραμμα γιατί ο δείκτης αν και ορίζεται δεν έχει τιμή δηλαδή δεν δείχνει σε μία έγκυρη διεύθυνση της μνήμης (πχ με εντολή pa=&x)» int *pa;» *pa=10; Συνηθίζεται ένας δείκτης που δεν έχει τιμή να του αποδίδεται μηδενική (null) τιμή (που πρακτικά είναι το 0) Η μηδενική τιμή χρησιμοποιείται ώστε ο δείκτης να μην δείχνει σε θέση της μνήμης που να έχει κάποιο δεδομένο. Ένας δείκτης null είναι δείκτης που ορίζεται σε πολλές βιβλιοθήκες της C (όπως η stdio.h) και είναι σταθερός τύπος δείκτη μηδενικού τύπου.

Αρχικοποίηση και Δείκτης τύπου null (2/2) Kατά σύμβαση ένας δείκτης που προσωρινά δεν δείχνει σε έγκυρη διεύθυνση της μνήμης του δίδεται σαν τιμή η μηδενική τιμή με την εντολή pa=0 ή ακόμη πιο καθαρά με την εντολή pa=null; H αρχικοποίηση δείκτη σε μηδενική τιμή δεν αποφεύγει λάθη στο πρόγραμμα. Το παρακάτω πρόγραμμα και πάλι κολλάει γιατί προσπαθεί στον δείκτη NULL να βάλει τιμή 10» int *pa=null;» *pa=10;

Παράμετροι συναρτήσεων και printf Προσοχή: (1/2) οι παράμετροι σε μία κλήση συνάρτησης υπολογίζονται από τα δεξιά στα αριστερά. Στην περίπτωση της printf (που είναι συνάρτηση) συμβαίνει ακριβώς το ίδιο και η σειρά εκτίμησης των παραμέτρων που υπολογίζονται είναι από τα δεξιά προς τα αριστερά.» int a = 1 ;» printf ( "%d %d %d", a, ++a, a++ ) ;

Παράμετροι συναρτήσεων και printf To αποτέλεσμα θα έπρεπε να είναι 1 2 3. Όμως το αποτέλεσα είναι 3 3 1 επειδή ισχύει ο ανωτέρω κανόνας. Τι εμφανίζει το παρακάτω;» a = 1 ;» printf ( "%d %d %d\n\n", a, a++, a++ ) ; (2/2)

Παράδειγμα

Δείκτες και σταθερές Μία μεταβλητή όταν δηλωθεί σταθερού τύπου δεν μπορεί να αλλάξει η τιμή της δηλαδή δεν το επιτρέπει ο μεταγλωττιστής :» const int PI=3.14; Μπορούμε να κάνουμε χρήση σταθεράς και σε δείκτες. Θα εξετάσουμε παρακάτω του εξής τύπους: constant pointer to a type (Σταθερούς δείκτες) pointer to a constant type (Δείκτες προς σταθερές) constant pointer to a constant type (Σταθερούς Δείκτες προς σταθερές)

Σταθεροί Δείκτες (constant pointer to a type) (1/2) Επίσης μπορούμε να δηλώσουμε σταθερό δείκτη δηλαδή ένα δείκτη που η τιμή του δεν αλλάζει και ο δείκτης δείχνει πάντα προς την ίδια διεύθυνση (constant pointer to a type). Ένας πίνακας είναι μία τέτοια μεταβλητή δηλαδή constant pointer (σταθερός δείκτης)» int n = 43;» //orismos constant pointer to an integer» int *const pn = &n;

Σταθεροί Δείκτες (constant pointer to a type) (2/2)» //pn++; Lathos increment of read-only variable» //pn=&k; Lathos increment of read-only variable Όμως επιτρέπεται αλλαγή της τιμής που δείχνει ο δείκτης δηλαδή επιτρέπεται η εντολή» *pn=203

Δείκτες προς σταθερές (pointer to a constant type) (1/2) Μπορούμε να δηλώσουμε δείκτη προς σταθερή τιμή με την χρήση const.» int k=55,m=44;» const int *pk=&k;» //*pk=22; H timi stin opoia exei prosvasi o deiktis» // den epitrepetai na allaxei H δεύτερη εντολή δηλώνει ένα pointer to a constant int

Δείκτες προς σταθερές (pointer to a constant type) (2/2) Επομένως απαγορεύεται να αλλάξει η τιμή που δείχνει ο δείκτης (σειρά 3) με την χρήση του δείκτη δηλαδή απαγορεύεται η εντολή:» *pk=22; Επιτρέπεται όμως να αλλάξει η τιμή της κ μέσω της μεταβλητής κ δηλαδή η παρακάτω εντολή δεν είναι λάθος γιατί δεν αλλάζει με την χρήση του δείκτη:» k++; Επίσης επιτρέπεται να αλλάξει ο δείκτης γιατί δεν είναι σταθερός δηλαδή οι παρακάτω δύο εντολές επιτρέπονται:» pk++; pk=&m;

Σταθεροί Δείκτες προς σταθερές (constant pointer to a constant type) Επίσης μπορούμε να δηλώσουμε σταθερό δείκτη προς σταθερή τιμή (constant pointer to a constant type)» int m = 11;» const int *const pm = &m; Δεν μπορούμε να αλλάξουμε την τιμή του δείκτης αλλά ούτε το περιεχόμενο που ο δείκτης δείχνει.

Τέλος Ενότητας