Δείκτεσ Διαχείριςθ Μνιμθσ Βαγγζλθσ Οικονόμου Διάλεξθ 8
Δείκτεσ Κάκε μεταβλθτι ςχετίηεται με μία κζςθ ςτθν κφρια μνιμθ του υπολογιςτι. Κάκε κζςθ ςτθ μνιμθ ζχει τθ δικι τθσ ξεχωριςτι διεφκυνςθ. Με άμεςθ χριςθ αυτισ τθσ διεφκυνςθσ γίνεται, ςτθ γλϊςςα μθχανισ, θ αναφορά ςτα δεδομζνα είτε για αποκικευςθ είτε για ανάκλθςι τουσ. Στισ γλϊςςεσ υψθλοφ επιπζδου ο προγραμματιςτισ, όπωσ ιδθ ζχουμε αναφζρει, δε βλζπει διευκφνςεισ αλλά αναφζρεται ςτα δεδομζνα με τθ χριςθ ςυμβολικϊν ονομάτων, τα οποία το ςφςτθμα αντιςτοιχεί ςτισ πραγματικζσδιευκφνςεισ.
Δείκτεσ οριςμζνεσ γλϊςςεσ υψθλοφ επιπζδου, κζλοντασ να δϊςουν ςτον προγραμματιςτι τθ δυνατότθτα δθμιουργίασ πολφ αποδοτικοφ κϊδικα, ειςιγαγαν τθν ζννοια του δείκτθ. Ο δείκτθσ δεν είναι τίποτε παραπάνω παρά μία μεταβλθτι θ οποία χρθςιμοποιείται για τθν αποκικευςθ μιασ διεφκυνςθσ τθσ κφριασ μνιμθσ του υπολογιςτι.
Διλωςθ Δείκτθ Για τθ διλωςθ μιασ μεταβλθτισ δείκτθ πρζπει να γνωςτοποιιςουμε ςτον μεταγλωττιςτι ότι θ μεταβλθτι είναι τφπου δείκτθ, κακϊσ και τον τφπο του αντικειμζνου που μπορεί να δείχνει θ μεταβλθτι. Η διλωςθ μιασ μεταβλθτισ δείκτθ για τθ γλϊςςα C ζχει τθν παρακάτω μορφι: <όνομα τφπου> *<όνομα δείκτθ>;
Διλωςθ Δείκτθ
Διλωςθ Δείκτθ Το ςφμβολο * είναι ο τελεςτισ περιεχομζνου και μπορεί να ερμθνευκεί ςτθ διλωςθ int *num_ptr; Κατά δφο τρόπουσ: α) θ μεταβλθτι num_ptr είναι δείκτθσ ςε int ι β) το περιεχόμενο τθσ κζςθσ μνιμθσ που δείχνει ο num_ptr είναι int. Παρατθριςτε τθ χριςθ του αναγνωριςτικοφ _ptr ςτο τζλοσ του ονόματοσ τθσ μεταβλθτισ δείκτθ. Δεν είναι υποχρεωτικό ωςτόςο βελτιϊνει τθν αναγνωςιμότθτα του κϊδικα. Ο προγραμματιςτισ δεν χρειάηεται να ανατρζξει ςτθ διλωςθ τθσ μεταβλθτισ για να δει αν αυτι είναι δείκτθσ ι όχι.
Αρχικοποίθςθ Δείκτθ Μετά τθ διλωςι του, ζνασ δείκτθσ πρζπει να δείχνει ςε μια κζςθ μνιμθσ που ανικει ςτο πρόγραμμα. Για το λόγο αυτό δίνουμε ςυνικωσ τιμι ςτο δείκτθ ταυτόχρονα με τθ διλωςι του. Στθν περίπτωςθ αυτι, θ διλωςθ δείκτθ παίρνει τθ μορφι: <όνομα τφπου> *<όνομα δείκτθ> = <διεφκυνςθ>;
Αρχικοποίθςθ Δείκτθ όπου <διεφκυνςθ> μπορεί να είναι: α) μία άμεςθ διεφκυνςθ Παράδειγμα: int *num_ptr = 1000; β) θ διεφκυνςθ μιασ μεταβλθτισ ακζραιου τφπου τθν οποία παίρνουμε εφαρμόηοντασ μπροςτά από μια μεταβλθτι τον τελεςτι διεφκυνςθσ & Παράδειγμα: int *num_ptr = #
Ανάκεςθ Τιμισ ςε Δείκτθ Αν ζνασ δείκτθσ δεν αρχικοποιθκεί, κα πρζπει ςφντομα και οπωςδιποτε πριν από τθ χριςθ του, να του ανατεκεί τιμι με μια πρόταςθ ανάκεςθσ τθσ μορφισ <όνομα δείκτη> = <διεφθυνση>; Παράδειγμα: num_ptr = 1000; ι num_ptr = # Αποφφγετε αρχικοποιιςεισ με άμεςθ διεφκυνςθ. Είναι πολφ επικίνδυνεσ και χρθςιμοποιοφνται, ςυνικωσ, μόνο για άμεςθ πρόςβαςθ ςτο υλικό.
Τελεςτζσ Δεικτϊν Τελεςτισ Ερμθνεία = ο τελεςτισ ανάκεςθσ χρθςιμοποιείται για ανάκεςθ τιμισ ςε δείκτθ * ο τελεςτισ περιεχομζνου εφαρμόηεται μόνο ςε δείκτθ και ζχει ςαν αποτζλεςμα το περιεχόμενο τθσ διεφκυνςθσ που δείχνει ο δείκτθσ & ο τελεςτισ διεφκυνςθσ δίνει τθ διεφκυνςθ τθσ μεταβλθτισ ςτθν οποία εφαρμόηεται
Δείκτεσ Τι ςθμαίνουν οι παρακάτω ςυμβολιςμοί: *a_ptr a_ptr &a_ptr Περιεχόμενο που δείχνει ο δείκτθσ Περιεχόμενο του δείκτθ Διεφκυνςθ του δεικτθ
Δείκτεσ και Πίνακεσ Οποιαδιποτε λειτουργία ςτθ C γίνεται με πίνακεσ μπορεί να γίνει και με δείκτεσ Γιατί; το όνομα του πίνακα είναι θ διεφκυνςθ του πρϊτου ςτοιχείου του Πϊσ; Δφο τρόποι
Δείκτεσ και Πίνακεσ αν arr είναι πίνακασ δζκα ακεραίων int arr[10]; και ο p δείκτθσ ςε ακζραιο int *p; μποροφμε να ανακζςουμε ςτον p να δείχνει ςτο πρϊτο ςτοιχείο του arr με τθν πρόταςθ p = &arr[0]; εκμεταλλευόμενοι το γεγονόσ ότι το όνομα του πίνακα είναι θ διεφκυνςθ του πρϊτου ςτοιχείου του, μποροφμε να γράψουμε p = arr;
Δείκτεσ και Πίνακεσ Αν εφαρμόςω τον τελεςτι ++ ςτο δείκτθ p αυτόσ κα δείχνει, μετά τθν εφαρμογι, ςτο επόμενο ςτοιχείο του πίνακα. Προςζξτε ότι δεν μπορϊ να γράψω arr++ γιατί το arr είναι ςτακερά διεφκυνςθ
Δείκτεσ και Πίνακεσ μποροφμε να αναφερκοφμε ςτο ςτοιχείο arr[n] χρθςιμοποιϊντασ τθν ζκφραςθ *(arr+n). Ιςχφουν δθλαδι οι ιςοδυναμίεσ: *(arr + n) < > arr[n] arr + n < > &arr[n]
Κλιςθ με Αναφορά Ζχουμε δεί πωσ γίνεται θ μεταβίβαςθ παραμζτρων με τιμι όπου ςτθν ςυνάρτθςθ μεταβιβάηονταν θ τιμι μιασ παραμζτρου και όχι θ ίδια θ παράμετροσ Η μεταβίβαςθ με αναφορά δουλεφει πάνω ςτισ πραγματικζσ παραμζτρουσ και ωσ ορίςματα ςτθν ςυνάρτθςθ δε μεταβιβάηονται οι τιμζσ των παραμζτρων αλλά οι διευκφνςεισ των παραμζτρων
Παράδειγμα swap Είδαμε, ςε προθγοφμενο μάκθμα, τθν ςυνάρτθςθ swap θ οποία είχε ωσ ςκοπό τθν ανταλλαγι των τιμϊν μεταξφ 2 μεταβλθτϊν Ωςτόςο, κάνοντασ χριςθ τθσ τεχνικισ μεταβίβαςθ με τιμι παρατθριςαμε ότι θ ανταλλαγι των τιμϊν δε ζγινε. Αυτό ζγινε γιατί θ μεταβίβαςθ με τιμι δθμιουργεί αντίγραφα των πραγματικϊν τιμϊν.
Παράδειγμα swap Διλωςθ: void swap(int *a, int *b); Οριςμόσ ςυνάρτθςθσ: void swap(int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; } Κλιςθ: swap(&num1,&num2);
Παράδειγμα swap Οι διευκφνςεισ των num1 και num2 είναι αντίςτοιχα 1000 και 1002. Με τθν κλιςθ τθσ swap δθμιουργοφνται δφο νζα κελιά ςτθ μνιμθ για τισ μεταβλθτζσ δείκτθ a και b. Τα κελιά αυτά παίρνουν ςαν τιμζσ τισ διευκφνςεισ των μεταβλθτϊν num1 και num2, δθλαδι τα 1000 και 1002. Ζτςι, θ ςυνάρτθςθ swap ζχοντασ τισ διευκφνςεισ των num1 και num2 αλλάηει τισ τιμζσ του.