Copyright © 2003 Pearson Education, Inc. Slide 1
Copyright © 2003 Pearson Education, Inc. Slide 2 Κεφάλαιο 12 Pointers και Δυναμικοί Πίνακες
Copyright © 2003 Pearson Education, Inc. Slide 3 Παράδειγμα με Pointers v1 = 0; p1 = &v1; *p1 = 42; cout << v1 << endl; cout << *p1 << endl; output: v1 και *p1 αναφέρονται στην ίδια μεταβλητή
Copyright © 2003 Pearson Education, Inc. Slide 4 Ανάθεση Δεικτών Ο τελεστής ανάθεσης = χρησιμοποιείται για την ανάθεση της τιμής ενός δείκτη σε άλλον Παράδειγμα:Αν ο p1 δείχνει στο v1 (προηγ. slide) τότε με την εντολή p2 = p1; οι *p2, *p1, και v1 αναφέρονται στην ίδια μεταβλητή
Copyright © 2003 Pearson Education, Inc. Slide 5 Προσοχή! Αναθέσεις Δεικτών Απαιτείται προσοχή όταν πραγματοποιούνται αναθέσεις δεικτών p1= p3; // αλλάζει η θέση προς την οποία “δείχνει’’ ο p1 *p1 = *p3; // αλλάζει η τιμή της θέσης προς την // οποία δείχνει ο p1 Display 12.1
Copyright © 2003 Pearson Education, Inc. Slide 6 O τελεστής new Χρησιμοποιώντας δείκτες, ο χειρισμός μεταβλητών πραγματοποιείται ακόμα και αν δεν υπάρχει αναγνωριστικό Για τη δημιουργία ενός δείκτη προς μία νέα «ανώνυμη» μεταβλητή τύπου int: p1 = new int; Στη νέα μεταβλητή αναφερόμαστε ως *p1 Η *p1 μπορεί να χρησιμοποιηθεί οπουδήποτε χρησιμοποιείται μία μεταβλητή τύπου int cin >> *p1; *p1 = *p1 + 7;
Copyright © 2003 Pearson Education, Inc. Slide 7 Δυναμικές Μεταβλητές Οι μεταβλητές που δημιουργούνται με τον τελεστή new καλούνται δυναμικές μεταβλητές (dynamic variables) Οι δυναμικές μεταβλητές δημιουργούνται και καταστρέφονται όσο το πρόγραμμα εκτελείται Επιπλέον παράδειγμα για δείκτες και δυναμικές μεταβλητές Γραφική απεικόνιση: Χώρος για τις δυναμικές μεταβλητές δεσμεύεται στο σωρό (heap) Display 12.2 Display 12.3
Copyright © 2003 Pearson Education, Inc. Slide 8 new και Κλάσεις Η χρήστη του τελεστή new με τύπους κλάσεων δεσμεύει χώρο και καλεί τον constructor Αν MyType είναι κλάση MyType *myPtr; // δημιουργεί δείκτη προς // μεταβλητή τύπου MyType myPtr = new MyType; // καλεί τον εξ’ορισμού constructor myPtr = new MyType (32.0, 17); //καλεί τον Mytype(double, int);
Copyright © 2003 Pearson Education, Inc. Slide 9 Διαχείριση Μνήμης Η περιοχή της μνήμης που χρησιμοποιείται για τις δυναμικές μεταβλητές καλείται και freestore (heap) Νέες δυναμικές μεταβλητές χρησιμοποιούν το σωρό Αν εξαντληθεί ο σωρός, κλήσεις του new αποτυγχάνουν Μη χρησιμοποιούμενη μνήμη, ανακυκλώνεται Όταν οι μεταβλητές δεν χρησιμοποιούνται πλέον, μπορούν (και πρέπει) να διαγράφονται και η μνήμη που χρησιμοποιούσαν επιστρέφεται στο σωρό
Copyright © 2003 Pearson Education, Inc. Slide 10 Ο τελεστής delete Όταν οι δυναμικές μεταβλητές δεν χρειάζονται, μπορείτε να τις διαγράψετε (delete): Παράδειγμα: delete p; Η τιμή του p είναι πλέον απροσδιόριστη και η μνήμη που χρησιμοποιούνταν από τη μεταβλητή προς την οποία έδειχνε ο p επιστρέφεται στο σωρό
Copyright © 2003 Pearson Education, Inc. Slide 11 Αιωρούμενοι Δείκτες delete σε ένα δείκτη καταστρέφει τη δυναμική μεταβλητή προς την οποία έδειχνε Αν ένας άλλος δείκτης έδειχνε προς την ίδια δυν. μεταβλητή, και εκείνος είναι απροσδιόριστος Απροσδιόριστοι δείκτες ονομάζονται dangling pointers (αιωρούμενοι δείκτες) Έμμεση αναφορά σε έναν αιωρούμενο δείκτη (*p) είναι συνήθως καταστροφική
Copyright © 2003 Pearson Education, Inc. Slide 12 Αυτόματες Μεταβλητές Οι μεταβλητές που δηλώνονται σε μία συνάρτηση δημιουργούνται από την C++ και καταστρέφονται όταν τερματιστεί η συνάρτηση Αυτές ονομάζονται αυτόματες (automatic) μεταβλητές καθώς η δημιουργία και καταστροφή τους ελέγχεται αυτόματα
Copyright © 2003 Pearson Education, Inc. Slide 13 Δυναμικοί Πίνακες Ένας δυναμικός πίνακας (dynamic array) είναι ένας πίνακας του οποίου το μέγεθος μπορεί να καθοριστεί κατά τη διάρκεια εκτέλεσης του προγράμματος 12.2
Copyright © 2003 Pearson Education, Inc. Slide 14 Μεταβλητές δείκτη και μεταβλητές πίνακα Οι μεταβλητές πίνακα είναι στην ουσία δείκτες προς το πρώτο στοιχείο του πίνακα Παράδειγμα: int a[10]; int* p; Οι μεταβλητές a και p είναι το ίδιο είδος μεταβλητής Καθώς ο a είναι δείκτης που δείχνει προς το a[0], p = a; θέτει τον p ώστε να δείχνει στην ίδια θέση με τον a
Copyright © 2003 Pearson Education, Inc. Slide 15 Δείκτες ως Πίνακες Σε συνέχεια του προηγούμενου παραδείγματος: Ο δείκτης p μπορεί να χρησιμοποιηθεί ως να ήταν μεταβλητή πίνακα Παράδειγμα: p[0], p[1], …p[9] είναι έγκυροι τρόποι χρήσης του p Η μεταβλητή a μπορεί να χρησιμοποιηθεί ως δείκτης αλλά η τιμή a δεν μπορεί να τροποποιηθεί Display 12.4
Copyright © 2003 Pearson Education, Inc. Slide 16 Δημιουργία Δυναμικών Πινάκων Οι κανονικοί πίνακες απαιτούν από τον προγραμματιστή να καθορίσει το μέγεθος του πίνακα κατά την δήλωσή του Αν η εκτίμηση του προγραμματιστή είναι μεγάλη? Σπαταλάται μνήμη Αν η εκτίμηση είναι μικρή? Το πρόγραμμα δεν θα λειτουργεί σε ορισμένες περιπτώσεις Το μέγεθος των δυναμικών πινάκων μπορεί να καθοριστεί κατά την εκτέλεση του προγράμματος
Copyright © 2003 Pearson Education, Inc. Slide 17 Δημιουργία Δυναμικών Πινάκων Οι δυναμικοί πίνακες δημιουργούνται χρησιμοποιώντας τον τελεστή new Παράδειγμα: Δημιουργία ενός πίνακα 10 στοιχείων τύπου double: double* d; d = new double[10]; Ο d μπορεί πλέον να χρησιμοποιηθεί ως κανονικός πίνακας Θα μπορούσε να είναι int μεταβλητή!
Copyright © 2003 Pearson Education, Inc. Slide 18 Δυναμικοί Πίνακες (cont.) Ο δείκτης d δείχνει στο d[0] Μετά το τέλος χρήσης του πίνακα, θα πρέπει να διαγραφεί ώστε να επιστραφεί η μνήμη στο σωρό Παράδειγμα: delete [ ] d; Οι αγκύλες λένε στην C++ ότι διαγράφεται ένας δυναμικός πίνακας ώστε να ελεγχθεί το μέγεθος του πίνακα και να διαγραφούν όλα τα στοιχεία του Η παράλειψη των αγκυλών δεν είναι έγκυρη (θα διαγράφονταν μόνο ένα στοιχείο) Display 12.5 (1) Display 12.5 (2)
Copyright © 2003 Pearson Education, Inc. Slide 19 Αριθμητική Δεικτών Βασικές αριθμητικές πράξεις μπορούν να εφαρμοστούν σε διευθύνσεις που περιέχονται σε δείκτες Για τον δυναμικό πίνακα d που δηλώθηκε, ο d είναι δείκτης που δείχνει στο d[0] Η παράσταση d+1 αναφέρεται στη διεύθυνση του d[1] και η d+2 αναφέρεται στη διεύθυνση του d[2]
Copyright © 2003 Pearson Education, Inc. Slide 20 Αριθμητική Δεικτών Πρόσθεση και αφαίρεση σε δείκτες Οι τελεστές ++ και - - μπορούν να χρησιμοποιηθούν Δύο δείκτες ιδίου τύπου μπορούν να αφαιρεθούν για να ληφθεί ο αριθμός των στοιχείων μεταξύ τους Οι δείκτες θα πρέπει να βρίσκονται στον ίδιο πίνακα! Μία χρήση αριθμητικής δεικτών: for (int i = 0; i < array_size; i++) cout << *(d + i) << " " ; // same as cout << d[i] << " " ;
Copyright © 2003 Pearson Education, Inc. Slide 21 Display 12.1 Back Next
Copyright © 2003 Pearson Education, Inc. Slide 22 Display 12.2 Back Next
Copyright © 2003 Pearson Education, Inc. Slide 23 Display 12.3 Back Next
Copyright © 2003 Pearson Education, Inc. Slide 24 Display 12.4 Back Next
Copyright © 2003 Pearson Education, Inc. Slide 25 Display 12.5 (1/2) Back Next
Copyright © 2003 Pearson Education, Inc. Slide 26 Display 12.5 (2/2) Back Next