Δείκτες Προγραμματισμός Ι lalis@inf.uth.gr.

Slides:



Advertisements
Παρόμοιες παρουσιάσεις
Το αλφαριθμητικό (string)
Advertisements

ΕΙΣΑΓΩΓΗ ΣΤΗΝ PHP. Τι θα μάθουμε;  Να καταλάβουμε τι είναι η PHP και πώς δουλεύουν τα PHP scripts  Τι χρειάζεται για να ξεκινήσουμε με την PHP  Να.
Στοιχειώδεις Δομές Δεδομένων TexPoint fonts used in EMF. Read the TexPoint manual before you delete this box.: AA A A A Τύποι δεδομένων στη Java • Ακέραιοι.
Πίνακες-Αλφαριθμητικά
Εισαγωγή στους Η/Υ Πίνακες.
Πινακες (Arrays) Σημασια Συνταξη Αρχικοποιηση Προσβαση Παραμετροι
Προγραμματισμός Ι Πίνακες •Ο πίνακας είναι μία συλλογή μεταβλητών ίδιου τύπου, οι οποίες είναι αποθηκευμένες σε διαδοχικές θέσεις μνήμης. Χρησιμοποιείται.
Δείκτες, Πίνακες και Δείκτες, Δείκτες σε Συναρτήσεις
ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ Αναφορές Στοίβα και Σωρός Μνήμης Αντικείμενα ως ορίσματα.
Αναδρομη και static Γραψετε την συναρτηση sequence_size που διαβαζει μια απροσδιοριστου μεγεθους σειρας και υπολογιζει και τυπωνει το μεγεθος της. int.
Αντικειμενοστραφής Προγραμματισμός
ΜΑΘ 3122 (106) Γλώσσα προγραμματισμού
Μάθημα : Βασικά Στοιχεία της Γλώσσας Java
ΤΕΧΝΙΚΕΣ Αντικειμενοστραφουσ προγραμματισμου
ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΙΑΔΙΚΑΣΤΙΚΟ ΠΡΟΓΡΑΜMΑΤΙΣΜΟ ΠΑΝΕΠΙΣΤΗΜΙΟ ΠΑΤΡΩΝ – ΠΟΛΥΤΕΧΝΙΚΗ ΣΧΟΛΗ ΤΜΗΜΑ ΜΗΧΑΝΙΚΩΝ Η/Υ ΚΑΙ ΠΛΗΡΟΦΟΡΙΚΗΣ.
Συναρτήσεις Κληση/Επιστροφη Παραμετροι
ΘΠ06 - Μεταγλωττιστές Πίνακας Συμβόλων, Σημασιολογικές Ενέργειες.
Τελεστές ανάθεσης (assignment)
ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ Στατικές μέθοδοι και μεταβλητές Εσωτερικές κλάσεις.
ΜΕΤΑΒΛΗΤΕΣ - ΤΥΠΟΙ ΜΑΘΗΜΑ 3.
ΕΠΑΝΑΛΗΨΗΕΠΑΝΑΛΗΨΗ ΠΡΟΓΡΑΜΜΑΤΑ. ΠΡΟΓΡΑΜΜΑ 1 ΕΞΗΓΗΣΤΕ ΤΙ ΕΞΟΔΟ ΠΑΡΑΓΕΙ ΤΟ ΠΑΡΑΚΑΤΩ ΠΡΟΓΡΑΜΜΑ #include int main() { char ch; int i; float fl; printf("dose.
ΤΕΛΕΣΤΕΣ II ΜΑΘΗΜΑ 5.
Η ΓΛΩΣΣΑ C ΜΑΘΗΜΑ 2.
Δείκτες, Πίνακες σε Δείκτες, Δείκτες σε Συναρτήσεις
Message Passing Interface (MPI) Συστήματα Παράλληλης Επεξεργασίας Εργαστήριο Υπολογιστικών Συστημάτων Αθήνα, Δεκέμβριος 2002.
Δείκτες (Pointers) – Δομές (Structs)
Ενότητα Α.4. Δομημένος Προγραμματισμός
ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ Αντικείμενα ως ορίσματα Εισαγωγή στις αναφορές.
ΕΙΣΑΓΩΓΗ ΣΤΗΝ ΠΛΗΡΟΦΟΡΙΚΗ
Εθνικό και Καποδιστριακό Πανεπιστήμιο Αθηνών – Τμήμα Πληροφορικής και Τηλεπικοινωνιών 1 Κεφάλαιο 4 Σημασιολογία μιας Απλής Προστακτικής Γλώσσας Προπτυχιακό.
Κεφάλαιο 10 – Υποπρογράμματα
Τμήμα Πληροφορικής και Τηλεπικοινωνιών
Υπερφόρτωση Τελεστών (Συνέχεια) Αντικειμενοστραφής Προγραμματισμός.
1 Τμήμα Μηχανικών Ηλεκτρονικών Υπολογιστών και Πληροφορικής Πανεπιστήμιο Πατρών ΟΝΤΟΚΕΝΤΡΙΚΟΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΙΙ (C++) Πίνακες.
ΗΥ150 – ΠρογραμματισμόςΚώστας Παναγιωτάκης ΗΥ-150 Προγραμματισμός Συναρτήσεις.
ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ Κλάσεις και Αντικείμενα Αναφορές.
ΗΥ150 – ΠρογραμματισμόςΞ. Ζαμπούλης ΗΥ-150 Προγραμματισμός Αρχεία.
ΗΥ150 – ΠρογραμματισμόςΚώστας Παναγιωτάκης ΗΥ-150 Προγραμματισμός Αλφαριθμητικά (Strings)
Προγραμματισμός Συναρτήσεις. Προγραμματισμός Μια συνάρτηση ορίζεται δίνοντας (α) τον τύπο του αποτελέσματος που.
Βασικά στοιχεία της Java
ΗΥ150 – ΠρογραμματισμόςΚώστας Παναγιωτάκης ΗΥ-150 Προγραμματισμός Συναρτήσεις (μέρος δεύτερο) και Μεταβλητές.
Κεφάλαιο 3 Τύποι Δεδομένων - Τελεστές. Πρωτογενείς τύποι δεδομένων: int, float, double, chars ΤύποςΌνομαΜέγεθος byte 8-bit signed, short 16-bit.
ΗΥ150 – ΠρογραμματισμόςΚώστας Παναγιωτάκης ΗΥ-150 Προγραμματισμός Τύποι Μεταβλητών Τελεστές Βασική Είσοδος/Έξοδος.
TEXNΟΛΟΓΙΑ ΚΑΙ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΥΠΟΛΟΓΙΣΤΩΝ ΠΑΝΕΠΙΣΤΗΜΙΟ ΠΑΤΡΩΝ – ΠΟΛΥΤΕΧΝΙΚΗ ΣΧΟΛΗ ΤΜΗΜΑ ΜΗΧΑΝΙΚΩΝ Η/Υ ΚΑΙ ΠΛΗΡΟΦΟΡΙΚΗΣ.
ΚΕΦΑΛΑΙΟ Το αλφάβητο της ΓΛΩΣΣΑΣ
Προγραμματισμός ΗΥ Ενότητα 6: Δισδιάστατοι πίνακες.
ΕΛΛΗΝΙΚΗ ΔΗΜΟΚΡΑΤΙΑ ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΡΗΤΗΣ «Εισαγωγή στον οντοκεντρικό προγραμματισμό (βασική εισαγωγή στο περιβάλλον εργασίας)» Ρουσσάκης Ιωάννης, ΤΕΙ Κρήτης,
Πίνακες στην JAVA ΕΡΓΑΣΤΗΡΙΟ AΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ (Διαφάνειες: ΧΟΧΟΛΗΣ ΔΙΟΝΥΣΙΟΣ Προσαρμογή 2014: Κώστας Στάμος)
ΔΠΘ-ΤΜΗΜΑ ΜΠΔ: ΕΙΣΑΓΩΓΗ ΣΤΟΥΣ Η/Υ 1 Εισαγωγή στη γλώσσα Προγραμματισμού C ΠΙΝΑΚΕΣ (arrays)
ΜΕΤΑΒΛΗΤΕΣ-ΣΤΑΘΕΡΕΣ -ΕΚΦΡΑΣΕΙΣ
Εισαγωγή στην Python.
Αρχεσ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ Η/Υ ΤΑξη Β΄
Δυναμικός Κατακερματισμός
Δεδομένα, μεταβλητές, υπολογισμοί
ΑΛΓΟΡΙΘΜΟΣ ΠΡΟΒΛΗΜΑ ΑΛΓΟΡΙΘΜΟΣ ΛΥΣΗ
Δείκτες 1/4 Σύμβαση Τελεστής &
ΠΛΗΡΟΦΟΡΙΚΗ ΤΕΧΝΟΛΟΓΙΑ ΚΑΙ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Η/Υ
Κλάσεις και αντικείμενα
Πίνακες Προγραμματισμός Ι
Αρχεσ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ Η/Υ ΤΑξη Β΄
Τύποι Μεταβλητών.
Τεχνολογία και Προγραμματισμός Υπολογιστών
Ενότητα 9: Δείκτες και Δυναμική Διαχείριση Μνήμης.
Τύποι Μεταβλητών Τελεστές Βασική Είσοδος/Έξοδος
Πίνακας Συμβόλων Διαλέξεις στο μάθημα: Μεταφραστές Γιώργος Μανής.
ΑΡΧΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ ΜΕ ΤΗ C
Εισαγωγή στον Προγ/μό Υπολογιστών
Εισαγωγή στον Προγραμματισμό με Python, ΑΠΘ ΑΡΙΣΤΟΤΕΛΕΙΟ ΠΑΝΕΠΙΣΤΗΜΙΟ ΘΕΣΣΑΛΟΝΙΚΗΣ Εισαγωγή στον Προγραμματισμό με Python Εβδομάδα 1: Βασικά στοιχεία.
Ανάπτυξη Εφαρμογών σε Προγραμματιστικό Περιβάλλον ΑΕΠΠ
ΕΚΦΡΑΣΕΙΣ, ΑΝΑΜΟΝΕΣ (DELAYS), ΗΧΟΙ
Μεταγράφημα παρουσίασης:

Δείκτες Προγραμματισμός Ι lalis@inf.uth.gr

Δείκτες Υπάρχουν περιπτώσεις που δεν ενδιαφέρει το περιεχόμενο αλλά η διεύθυνση μιας μεταβλητής. Χρειάζεται κατάλληλος μηχανισμός αναφοράς και επεξεργασίας τιμών που είναι διευθύνσεις μνήμης. Υπάρχουν μεταβλητές ειδικού τύπου: δείκτες. Μια μεταβλητή δείκτης μπορεί να χρησιμοποιηθεί για την αποθήκευση μιας ακέραιας τιμής που ερμηνεύεται σαν διεύθυνση μνήμης. Μέσω μιας μεταβλητής δείκτη μπορούμε να διαβάσουμε και να αλλάξουμε την τιμή που βρίσκεται αποθηκευμένη στην διεύθυνση που αυτή περιέχει. Προγραμματισμός Ι lalis@inf.uth.gr

Δείκτες και τύποι δεδομένων Η έννοια του δείκτη μπορεί να εφαρμοστεί σε κάθε τύπο Τ για να οριστεί ο τύπος δείκτης-σε-Τ. Υπάρχει συντακτική συμβατότητα ανάμεσα: στην τιμή που βρίσκεται στην διεύθυνση που περιέχει μια μεταβλητή δείκτης-σε-Τ και την τιμή μιας μεταβλητής τύπου Τ στην τιμή μιας μεταβλητής δείκτης-σε-Τ και την διεύθυνση μιας μεταβλητής τύπου Τ Η ειδική τιμή NULL (0) σημαίνει «καμία διεύθυνση», και είναι η συνηθισμένη τιμή αρχικοποίησης μιας μεταβλητής δείκτη. Η προσπάθεια προσπέλασης της διεύθυνσης 0 έχει σαν αποτέλεσμα τον τερματισμό του προγράμματος. Προγραμματισμός Ι lalis@inf.uth.gr

Τελεστές που αφορούν δείκτες Ο τελεστής & (reference) εφαρμόζεται σε μια μεταβλητή και επιστρέφει την διεύθυνση της. Ο τελεστής * (dereference) εφαρμόζεται σε μια μεταβλητή δείκτη-σε-Τ ώστε αυτή να ερμηνευτεί σαν μεταβλητή τύπου Τ – μπορεί να χρησιμοποιηθεί σε οποιαδήποτε έκφραση αποτίμησης ή/και ανάθεσης όπου αναμένεται μια μεταβλητή (ή τιμή) τύπου Τ. Μέσω ενός δείκτη που περιέχει την διεύθυνση μιας (συμβατικής) μεταβλητής μπορούμε να διαβάσουμε / αλλάξουμε έμμεσα την τιμή της μεταβλητής, χωρίς να φαίνεται στον κώδικα το όνομα της. Αυτό είναι μια μορφή παρενέργειας! Προγραμματισμός Ι lalis@inf.uth.gr

int *b,*c; /* δείκτες σε ακέραιο b,c */ a = 1; int a; /* ακέραιος a */ int *b,*c; /* δείκτες σε ακέραιο b,c */ a = 1; b = &a; /* b γίνεται διεύθυνση του a */ *b = 2; /* a γίνεται 2 */ *b = *b+1; /* a γίνεται 3 */ c = b; /* c γίνεται διεύθυνση του a */ *c = *c+2; /* a γίνεται 5 */ Προγραμματισμός Ι lalis@inf.uth.gr

διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 2 1 1 1 1 1 3 1 1 1 1 1 4 1 1 1 … char a; 1 1 1 1 a 1 1 1 1 2 1 1 1 1 1 3 1 1 1 1 1 4 1 1 1 1 5 1 1 1 1 1 1 6 1 1 1 1 1 1 7 1 1 1 1 1 1 8 1 1 1 1 1 1 ................ Προγραμματισμός Ι lalis@inf.uth.gr

διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 2 1 1 1 1 1 3 1 1 1 1 1 4 1 1 1 … char a; char *b; 1 1 1 1 a 1 1 1 1 2 1 1 1 1 1 3 1 1 1 1 1 4 1 1 1 1 5 1 1 1 1 1 1 b 6 1 1 1 1 1 1 7 1 1 1 1 1 1 8 1 1 1 1 1 1 ................ Προγραμματισμός Ι lalis@inf.uth.gr

διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 2 1 1 1 3 1 1 1 1 1 1 1 1 4 1 1 … char a; char *b; a='a'; 1 1 1 1 a 1 1 1 1 2 1 1 1 3 1 1 1 1 1 1 1 1 4 1 1 1 1 5 1 1 1 1 1 1 b 6 1 1 1 1 1 1 7 1 1 1 1 1 1 8 1 1 1 1 1 1 ................ Προγραμματισμός Ι lalis@inf.uth.gr

διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 2 1 1 1 3 1 1 1 1 1 1 1 1 4 1 1 … char a; char *b; a='a'; b=&a; 1 1 1 1 a 1 1 1 1 2 1 1 1 3 1 1 1 1 1 1 1 1 4 1 1 1 1 5 1 b 6 7 8 ................ Προγραμματισμός Ι lalis@inf.uth.gr

διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 2 1 1 1 3 4 1 1 1 1 5 1 6 7 8 … char a; char *b; a='a'; b=&a; *b='b'; 1 1 1 1 a 1 1 1 1 2 1 1 1 3 4 1 1 1 1 5 1 b 6 7 8 ................ Προγραμματισμός Ι lalis@inf.uth.gr

Παράκαμψη συντακτικού ελέγχου Ο συντακτικός έλεγχος μπορεί να παρακαμφθεί με χρήση type casting (δηλωμένης μετατροπής τύπου), έτσι ώστε μια οποιαδήποτε ακέραια τιμή να ανατεθεί (χωρίς μετατροπή) σε μια μεταβλητή δείκτη. Επιτρέπεται αριθμητική με δείκτες, π.χ. αν p είναι μια μεταβλητή δείκτης-σε-Τ, τότε η έκφραση p+i μεταφράζεται (αυτόματα) ως p+i*sizeof(T). Δεν υπάρχει τρόπος για τον μεταφραστή να ελέγξει αν μια τιμή που ανατίθεται σε μια μεταβλητή δείκτη-σε-Τ (μέσω type cast ή αριθμητικής) αντιστοιχεί πραγματικά στη διεύθυνση ενός αντικειμένου Τ. Την ευθύνη ανάθεσης κατάλληλων τιμών σε μεταβλητές δείκτη την έχει ο προγραμματιστής. Προγραμματισμός Ι lalis@inf.uth.gr

short int a; /* ακέραιος a (έστω 2 bytes) */ char *b; /* δείκτης σε χαρακτήρα b */ b=(char*)&a; /* b γίνεται διεύθυνση του a, αλλά η πρόσβαση μέσω b γίνεται με βάση τον τύπο char, ανά byte */ *b = *b+1; /* το πρώτο byte του a αυξάνεται κατά 1 */ b++; /* b γίνεται διεύθυνση του a + 1 */ *b = *b+1; /* το δεύτερο byte του a αυξάνεται κατά 1 */ b++; /* b γίνεται διεύθυνση του a + 2 */ *b = *b+1; /* το τρίτο(;) byte του a αυξάνεται κατά 1 */ Προγραμματισμός Ι lalis@inf.uth.gr

υποθέτουμε μέγεθος short 2 bytes 1 1 1 1 7 1 1 1 1 1 1 8 short int i; … char *c; διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 1 2 1 3 1 1 1 1 4 1 1 1 1 5 1 1 1 1 6 υποθέτουμε μέγεθος short 2 bytes 1 1 1 1 7 1 1 1 1 1 1 8 ................ Προγραμματισμός Ι lalis@inf.uth.gr

short int i; … char *c; i=0x6261; διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 3 1 1 1 1 4 1 1 1 1 5 1 1 1 1 6 1 1 1 1 7 1 1 1 1 1 1 8 ................ Προγραμματισμός Ι lalis@inf.uth.gr

short int i; … char *c; i=0x6261; c = (char *) &i; διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 2 1 3 4 5 6 7 1 1 1 1 1 1 8 ................ Προγραμματισμός Ι lalis@inf.uth.gr

putchar(*c); /* -> 'a' */ διεύθυνση περιεχόμενα short int i; … char *c; i=0x6261; c = (char *) &i; putchar(*c); /* -> 'a' */ διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 2 1 3 4 5 6 7 1 1 1 1 1 1 8 ................ Προγραμματισμός Ι lalis@inf.uth.gr

putchar(*c); /* -> 'a' */ c++; διεύθυνση περιεχόμενα short int i; … char *c; i=0x6261; c = (char *) &i; putchar(*c); /* -> 'a' */ c++; διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 2 1 3 1 4 5 6 7 1 1 1 1 1 1 8 ................ Προγραμματισμός Ι lalis@inf.uth.gr

putchar(*c); /* -> 'a' */ c++; putchar(*c); /* -> 'b' */ short int i; … char *c; i=0x6261; c = (char *) &i; putchar(*c); /* -> 'a' */ c++; putchar(*c); /* -> 'b' */ διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 2 1 3 1 4 5 6 7 1 1 1 1 1 1 8 ................ Προγραμματισμός Ι lalis@inf.uth.gr

putchar(*c); /* -> 'a' */ c++; putchar(*c); /* -> 'b' */ short int i; … char *c; i=0x6261; c = (char *) &i; putchar(*c); /* -> 'a' */ c++; putchar(*c); /* -> 'b' */ *c = *c + 1; διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 1 2 1 3 1 4 5 6 7 1 1 1 1 1 1 8 ................ Προγραμματισμός Ι lalis@inf.uth.gr

putchar(*c); /* -> 'a' */ c++; putchar(*c); /* -> 'b' */ short int i; … char *c; i=0x6261; c = (char *) &i; putchar(*c); /* -> 'a' */ c++; putchar(*c); /* -> 'b' */ *c = *c + 1; putchar(*c); /* -> 'c' */ διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 1 2 1 3 1 4 5 6 7 1 1 1 1 1 1 8 ................ Προγραμματισμός Ι lalis@inf.uth.gr

putchar(*c); /* -> 'a' */ c++; putchar(*c); /* -> 'b' */ short int i; … char *c; i=0x6261; c = (char *) &i; putchar(*c); /* -> 'a' */ c++; putchar(*c); /* -> 'b' */ *c = *c + 1; putchar(*c); /* -> 'c' */ printf("%x",i); /* 6361 */ διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 1 2 1 3 1 4 5 6 7 1 1 1 1 1 1 8 ................ Προγραμματισμός Ι lalis@inf.uth.gr

putchar(*c); /* -> 'a' */ c++; putchar(*c); /* -> 'b' */ short int i; … char *c; i=0x6261; c = (char *) &i; putchar(*c); /* -> 'a' */ c++; putchar(*c); /* -> 'b' */ *c = *c + 1; putchar(*c); /* -> 'c' */ printf("%x",i); /* 6361 */ διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 1 2 1 3 1 4 5 6 7 1 1 1 1 1 1 8 ................ Προγραμματισμός Ι lalis@inf.uth.gr

putchar(*c); /* -> 'a' */ c++; putchar(*c); /* -> 'b' */ short int i; … char *c; i=0x6261; c = (char *) &i; putchar(*c); /* -> 'a' */ c++; putchar(*c); /* -> 'b' */ *c = *c + 1; putchar(*c); /* -> 'c' */ printf("%x",i); /* 6361 */ *c = 0xFF; διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 3 1 4 5 6 7 1 1 1 1 1 1 8 ................ Προγραμματισμός Ι lalis@inf.uth.gr

Προσοχή Η ανάθεση τιμών σε μεταβλητές δείκτες γίνεται με αποκλειστική ευθύνη του προγραμματιστή, χωρίς να γίνεται κάποιος (ολοκληρωμένος) έλεγχος από τον μεταφραστή. Το παραμικρό λάθος όταν χρησιμοποιούμε δείκτες, μπορεί να οδηγήσει σε απρόβλεπτα αποτελέσματα. Χωρίς να το επιθυμούμε (ούτε να το αντιληφθούμε) μπορεί να αλλάξουμε κατά λάθος τιμές μεταβλητών, ακόμα και μεταβλητών-δεικτών ... Όπως και στην παράβαση των ορίων ενός πίνακα, τέτοια σφάλματα δύσκολα εντοπίζονται – αν έχουμε τύχη, τερματίζεται η εκτέλεση του προγράμματος. Προγραμματισμός Ι lalis@inf.uth.gr

Δείκτες και πίνακες Μια μεταβλητή «πίνακας από αντικείμενα τύπου Τ» μπορεί να θεωρηθεί ως (είναι συντακτικά συμβατή με) μια μεταβλητή «δείκτης-σε-Τ» με σταθερή τιμή την διεύθυνση του πρώτου στοιχείου του πίνακα. Αντίστροφα, μια μεταβλητή δείκτης-σε-Τ (και μια διεύθυνση μεταβλητής τύπου Τ) μπορεί να θεωρηθεί ως η αρχή ενός πίνακα από αντικείμενα τύπου Τ. Με χρήση δεικτών μπορεί να γίνει διέλευση των στοιχείων ενός πίνακα – αντί της συμβατικής μεθόδου πρόσβασης μέσω της θέσης τους. Υπάρχει συντακτική συμβατότητα ανάμεσα σε μεταβλητές «πίνακας από Τ» και «δείκτης σε Τ». Προγραμματισμός Ι lalis@inf.uth.gr

int a[5]; int * b = a; a[0] a[1] a[2] a[3] a[4] *b *(b+1) *(b+2) Προγραμματισμός Ι lalis@inf.uth.gr

διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 2 1 1 1 3 1 1 1 1 4 1 1 5 1 1 1 … char a[]={'a','b','c'}; 1 1 1 1 1 1 1 1 2 1 1 1 a[0] 3 1 1 1 1 a[1] 4 1 1 a[2] 5 1 1 1 1 1 1 6 1 1 1 1 1 1 7 1 1 1 1 1 1 8 1 1 1 1 1 1 ................ Προγραμματισμός Ι lalis@inf.uth.gr

διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 2 1 1 1 3 1 1 1 1 4 1 1 5 1 6 7 … char a[]={'a','b','c'}; char *b=a; 1 1 1 1 1 1 1 1 2 1 1 1 a[0] 3 1 1 1 1 a[1] 4 1 1 a[2] 5 1 6 b 7 8 ................ Προγραμματισμός Ι lalis@inf.uth.gr

διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 2 1 1 1 3 1 1 1 1 4 1 1 5 1 6 7 … char a[]={'a','b','c'}; char *b=a; b[0]++; 1 1 1 1 1 1 1 1 2 1 1 1 a[0] 3 1 1 1 1 a[1] 4 1 1 a[2] 5 1 6 b 7 8 ................ Προγραμματισμός Ι lalis@inf.uth.gr

διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 2 1 1 1 1 3 1 1 1 1 4 1 1 5 1 6 … char a[]={'a','b','c'}; char *b=a; b[0]++; b[1]++; 1 1 1 1 1 1 1 1 2 1 1 1 1 a[0] 3 1 1 1 1 a[1] 4 1 1 a[2] 5 1 6 b 7 8 ................ Προγραμματισμός Ι lalis@inf.uth.gr

διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 2 1 1 1 1 3 1 1 1 4 1 1 5 1 6 7 … char a[]={'a','b','c'}; char *b=a; b[0]++; b[1]++; b[2]++; 1 1 1 1 1 1 1 1 2 1 1 1 1 a[0] 3 1 1 1 a[1] 4 1 1 a[2] 5 1 6 b 7 8 ................ Προγραμματισμός Ι lalis@inf.uth.gr

διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 1 2 1 1 1 1 3 1 1 1 4 1 1 1 5 1 … char a[]={'a','b','c'}; char *b=a; b[0]++; b[1]++; b[2]++; *b=*b+1; 1 1 1 1 1 1 1 1 1 2 1 1 1 1 a[0] 3 1 1 1 a[1] 4 1 1 1 a[2] 5 1 6 b 7 8 ................ Προγραμματισμός Ι lalis@inf.uth.gr

διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 1 2 1 1 1 1 3 1 1 1 4 1 1 1 5 1 … char a[]={'a','b','c'}; char *b=a; b[0]++; b[1]++; b[2]++; *b=*b+1; b++; 1 1 1 1 1 1 1 1 1 2 1 1 1 1 a[0] 3 1 1 1 a[1] 4 1 1 1 a[2] 5 1 6 b 7 8 ................ Προγραμματισμός Ι lalis@inf.uth.gr

διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 1 2 1 1 1 3 1 1 1 4 1 1 1 5 1 6 … char a[]={'a','b','c'}; char *b=a; b[0]++; b[1]++; b[2]++; *b=*b+1; b++; 1 1 1 1 1 1 1 1 1 2 1 1 1 a[0] 3 1 1 1 a[1] 4 1 1 1 a[2] 5 1 6 b 7 8 ................ Προγραμματισμός Ι lalis@inf.uth.gr

διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 1 2 1 1 1 3 1 1 1 4 1 1 1 5 1 1 … char a[]={'a','b','c'}; char *b=a; b[0]++; b[1]++; b[2]++; *b=*b+1; b++; 1 1 1 1 1 1 1 1 1 2 1 1 1 a[0] 3 1 1 1 a[1] 4 1 1 1 a[2] 5 1 1 6 b 7 8 ................ Προγραμματισμός Ι lalis@inf.uth.gr

διεύθυνση περιεχόμενα 1 1 1 1 1 1 1 1 1 2 1 1 1 3 1 1 1 1 4 1 1 1 5 1 … char a[]={'a','b','c'}; char *b=a; b[0]++; b[1]++; b[2]++; *b=*b+1; b++; 1 1 1 1 1 1 1 1 1 2 1 1 1 a[0] 3 1 1 1 1 a[1] 4 1 1 1 a[2] 5 1 1 6 b 7 8 ................ Προγραμματισμός Ι lalis@inf.uth.gr

/* εκτύπωση strings αποθηκευμένων σε ένα πίνακα */ char s[]= {'o','n','e','\0','t','w','o','\0','x'}; char *p; printf("%s\n", s); /* εκτυπώνει "one" */ printf("%s\n", &s[0]); /* εκτυπώνει "one" */ p = s; printf("%s\n", p); /* εκτυπώνει "one" */ printf("%s\n", &s[4]); /* εκτυπώνει "two" */ p = p + 4; printf("%s\n", p); /* εκτυπώνει "two" */ printf("%s\n", p + 1); /* εκτυπώνει "wo" */ Προγραμματισμός Ι lalis@inf.uth.gr

Σχόλιο Η πρόσβαση σε στοιχεία του πίνακα με δείκτη μπορεί να είναι πιο γρήγορη από την συμβατική πρόσβαση μέσω θέσης στον πίνακα – γιατί; Δεν είναι καλή ιδέα να χρησιμοποιείται, εκτός και αν υπάρχει σοβαρός λόγος, π.χ. η συγκεκριμένη πρόσβαση αποτελεί όντως σημείο συμφόρησης ενός ιδιαίτερα κρίσιμου κώδικα. Σε γενικές γραμμές, η συμβατική πρόσβαση στα στοιχεία ενός πίνακα βελτιώνει την αναγνωσιμότητα του κώδικα. Η πρόσβαση με δείκτες είναι συνήθης τακτική ιδίως για προγραμματισμό σε «χαμηλό» επίπεδο συστήματος π.χ. λειτουργικό σύστημα. Προγραμματισμός Ι lalis@inf.uth.gr

/* διέλευση (εκτύπωση) πίνακα ακεραίων */ int i,a[N]; for (i=0; i<N; i++) { printf("%d ",a[i]); } printf("\n"); /* διέλευση (εκτύπωση) πίνακα ακεραίων */ int i,*p,a[N]; p=a; for (i=0; i<N; i++) { printf("%d ",p[i]); } printf("\n"); /* διέλευση (εκτύπωση) πίνακα ακεραίων */ int *p,a[N]; for (p=a; p<a+N; p++) { printf("%d ",*p); } printf("\n"); Προγραμματισμός Ι lalis@inf.uth.gr

Πίνακες από δείκτες Οι πίνακες από δείκτες (π.χ. *b[Ν]) «μοιάζουν» με 2-διάστατους πίνακες (π.χ. a[Ν][Μ]), όμως: Κάθε σειρά a[i] του 2-διάστατου πίνακα a έχει ακριβώς τον ίδιο αριθμό στοιχείων (Μ). Οι σειρές του πίνακα a αποθηκεύονται πάντα σε συνεχόμενες θέσεις μνήμης, η μία μετά την άλλη. Κάθε δείκτης b[i] του πίνακα b μπορεί να δείχνει σε εντελώς διαφορετική περιοχή μνήμης, η οποία να μην έχει καμία σχέση με τις περιοχές μνήμης όπου δείχνουν οι υπόλοιποι δείκτες του πίνακα b. Τα δεδομένα που βρίσκονται αποθηκευμένα εκεί όπου δείχνουν τα στοιχεία του b, μπορεί να «ανήκουν» σε συμβατικές μεταβλητές του προγράμματος. Προγραμματισμός Ι lalis@inf.uth.gr

2-διάστατος πίνακας αντικειμένων τύπου Τ πίνακας από δείκτες σε αντικείμενα τύπου Τ T a[N][M]; T *b[N]; a b N … … … N … … … … … … NULL … M … δεδομένα τύπου Τ Προγραμματισμός Ι lalis@inf.uth.gr

Παράμετροι της main Συχνά είναι βολικό το πρόγραμμα να δέχεται κάποια δεδομένα ως παράμετρους εκκίνησης αντί να τα ζητά από τον χρήστη μέσω αντίστοιχου διαλόγου. Η συνάρτηση main δέχεται δύο παραμέτρους. 1. Τον αριθμό τον ορισμάτων argc (argument count) που περάστηκαν στο πρόγραμμα από το περιβάλλον εκτέλεσης, συμπεριλαμβανομένου του ονόματος του. 2. Τον πίνακα από δείκτες-σε-χαρακτήρα argv (argument vector), όπου το i-οστό στοιχείο του πίνακα περιέχει ένα δείκτη σε θέση μνήμης όπου βρίσκεται αποθηκευμένο το i-οστό αλαφαριθμητικό που δόθηκε ως όρισμα από την γραμμή εντολών. Προγραμματισμός Ι lalis@inf.uth.gr

>./myprog one 2 three 45 0x06 qkja<enter> int main (int argc, char *argv[]) { … } 7 o n e \0 4 5 \0 t h r e e \0 2 \0 x 6 \0 m y p r o g \0 q k j a \0 Προγραμματισμός Ι lalis@inf.uth.gr

/* εκτυπώνει τα ορίσματα εκκίνησης */ #include <stdio.h> int main(int argc, char *argv[]) { int i; for (i=0; i<argc; i++) { printf("%s ", argv[i]); } printf("\n"); >./myprog one 2 three 45 0x06 qkja<enter> myprog one 2 three 45 0x06 qkja > Προγραμματισμός Ι lalis@inf.uth.gr

/* ταξινόμηση αλφαριθμητικών με ευρετήριο */ #include <stdio.h> #include <string.h> #define N 7 #define MAXNAMELEN 7 int main(int argc, char *argv[]) { char names[Ν][MAXNAMELEN],*idx[N],*tmp; int i,j; for (i=0; i<N; i++) { printf("enter name: "); scanf("%6s", names[i]); } for (i=0; i<N; i++) { idx[i] = names[i]; } for (j=i; j<N; j++) { if (strcmp(idx[i],idx[j])>0) { tmp = idx[i]; idx[i] = idx[j]; idx[j] = tmp; for(i=0; i<N; i++) { printf("%s\n", idx[i]); } συνάρτηση σύγκρισης αλφαριθμητικών Προγραμματισμός Ι lalis@inf.uth.gr

πριν την ταξινόμηση του ευρετηρίου πίνακας από N δείκτες σε ονόματα στον πίνακα Πίνακας από 7 ονόματα (το πολύ 6 χαρακτήρων) char *idx[7]; char names[7][7]; d o n a l d k a t h y ? j o h n ? ? m a r i n a a l e x ? ? k o s t a s m a r y ? ? Προγραμματισμός Ι lalis@inf.uth.gr

μετά την ταξινόμηση του ευρετηρίου πίνακας από N δείκτες σε ονόματα στον πίνακα Πίνακας από 7 ονόματα (το πολύ 6 χαρακτήρων) char *idx[7]; char names[7][7]; d o n a l d k a t h y ? j o h n ? ? m a r i n a a l e x ? ? k o s t a s m a r y ? ? Προγραμματισμός Ι lalis@inf.uth.gr