4.4 Οι δείκτες (Pointers) στην γλώσσα C++

Οι δείκτες είναι ένα σημαντικό χαρακτηριστικό της γλώσσας C++. Οι δείκτες επιτρέπουν την αναφορά σε διευθύνσεις μνήμης, παρέχοντας έτσι τη δυνατότητα πρόσβασης και επεξεργασίας των δεδομένων που αποθηκεύονται σε αυτές τις διευθύνσεις.

Στην C++, οι δείκτες μπορούν να χρησιμοποιηθούν για να δείξουν σε μεταβλητές, αντικείμενα και συναρτήσεις. Μπορούν να χρησιμοποιηθούν για να περάσουν αναφορές σε μεταβλητές σε συναρτήσεις, για δυναμική δέσμευση μνήμης και για την αποθήκευση διευθύνσεων αντικειμένων.

Η διαχείριση των δεικτών απαιτεί προσοχή, καθώς μπορούν να προκαλέσουν προβλήματα όπως δείκτες NULL, ανεπιθύμητη πρόσβαση σε μνήμη και διαρροές μνήμης. Ωστόσο, η σωστή χρήση των δεικτών μπορεί να παρέχει αποδοτικότητα και ευελιξία στον προγραμματισμό.

Οι δείκτες στην C++ είναι ένα σημαντικό εργαλείο που μπορεί να επεκτείνει τις δυνατότητες της γλώσσας και να βοηθήσει στην ανάπτυξη προηγμένων προγραμμάτων.

Παρακάτω παρουσιάζετε ένα αναλυτικό παράδειγμα χρήσης δεικτών στην C++:

#include <iostream>
using namespace std;

int main() {
    int num = 10; // Ορίζουμε μια μεταβλητή num με τιμή 10
    int* ptr; // Δηλώνουμε έναν δείκτη ptr

    ptr = &num; // Ο δείκτης ptr δείχνει στη διεύθυνση μνήμης της μεταβλητής num

    cout << "Περιεχόμενο μεταβλητής num: " << num << endl;
    cout << "Διεύθυνση μνήμης της μεταβλητής num: " << &num << endl;
    cout << "Περιεχόμενο δείκτη ptr: " << ptr << endl;
    cout << "Περιεχόμενο της μεταβλητής που δείχνει ο δείκτης ptr: " << *ptr << endl;

    return 0;
}

Σε αυτό το παράδειγμα, ορίζουμε μια μεταβλητή num με τιμή 10. Στη συνέχεια, δηλώνουμε έναν δείκτη ptr, ο οποίος μπορεί να δείχνει σε μια μεταβλητή τύπου int. Χρησιμοποιούμε τον τελεστή & για να αναθέσουμε στον δείκτη ptr τη διεύθυνση μνήμης της μεταβλητής num.

Έπειτα, εκτυπώνουμε την τιμή της μεταβλητής num, τη διεύθυνση μνήμης της μεταβλητής num, την τιμή του δείκτη ptr, καθώς και την τιμή της μεταβλητής που δείχνει ο δείκτης ptr. Χρησιμοποιούμε τον τελεστή * για να αναφερθούμε στην τιμή της μεταβλητής που δείχνει ο δείκτης.

Η έξοδος του προγράμματος θα είναι:

Περιεχόμενο μεταβλητής num: 10
Διεύθυνση μνήμης της μεταβλητής num: 0x7ffee2e687a8
Περιεχόμενο δείκτη ptr: 0x7ffee2e687a8
Περιεχόμενο της μεταβλητής που δείχνει ο δείκτης ptr: 10

Από την έξοδο, παρατηρούμε ότι η διεύθυνση μνήμης της μεταβλητής num και η τιμή του δείκτη ptr είναι ίδιες, καθώς ο δείκτης ptr δείχνει ακριβώς στη μνήμη όπου βρίσκεται η μεταβλητή num. Επίσης, η τιμή της μεταβλητής που δείχνει ο δείκτης ptr είναι ίση με την τιμή της μεταβλητής num.

Προσοχή: Οι δείκτες είναι πολύ ισχυροί, αλλά μπορούν να κάνουν τον κώδικα δυσανάγνωστο και ευάλωτο σε σφάλματα αν δεν χρησιμοποιούνται σωστά.

Δείτε παρακάτω ένα ακόμα παράδειγμα χρήσης των δεικτών:

#include <iostream>
using namespace std;

int main() {
  int myNum = 100;  // Δήλωση μιας μεταβλητής int
  int *myPointer;    // Δήλωση μιας μεταβλητής δείκτη

  myPointer = &myNum; // Αποθήκευση της διεύθυνσης της μεταβλητής myNum στον δείκτη

  cout << "Value of myNum: " << myNum << endl; // Εκτύπωση της τιμής της μεταβλητής myNum
  cout << "Address of myNum: " << &myNum << endl; // Εκτύπωση της διεύθυνσης της μεταβλητής myNum
  cout << "Value of myPointer: " << myPointer << endl; // Εκτύπωση της τιμής του δείκτη myPointer
  cout << "Value of the variable pointed to by myPointer: " << *myPointer << endl; // Εκτύπωση της τιμής της μεταβλητής στην οποία δείχνει ο δείκτης myPointer

  return 0;
}

Ο παραπάνω κώδικας σε C πραγματοποιεί τα εξής:

  1. Δηλώνει μια μεταβλητή myNum τύπου int και την αρχικοποιεί με την τιμή 100.
  2. Δηλώνει μια μεταβλητή δείκτη myPointer τύπου int.
  3. Αναθέτει στον myPointer τη διεύθυνση της μεταβλητής myNum μέσω του χρήσης του τελεστή αναφοράς &.
  4. Χρησιμοποιεί την εντολή cout για να εκτυπώσει την τιμή της μεταβλητής myNum, τη διεύθυνση της μεταβλητής myNum, την τιμή του myPointer και την τιμή της μεταβλητής στην οποία δείχνει ο myPointer.
  5. Επιστρέφει την τιμή 0, υποδηλώνοντας ότι το πρόγραμμα ολοκληρώθηκε με επιτυχία.

Ουσιαστικά, ο κώδικας δημιουργεί μια μεταβλητή και έναν δείκτη που δείχνει σε αυτήν τη μεταβλητή. Στη συνέχεια, εκτυπώνει την τιμή της μεταβλητής, τη διεύθυνση της μεταβλητής, την τιμή του δείκτη και την τιμή της μεταβλητής στην οποία δείχνει ο δείκτης.

[adinserter block=”2″]

Στην C++, μπορούμε να λάβουμε τη διεύθυνση μνήμης ενός αντικειμένου χρησιμοποιώντας τον τελεστή &. Για παράδειγμα, αν έχουμε μια μεταβλητή με όνομα x, μπορούμε να λάβουμε τη διεύθυνση μνήμης της με την παρακάτω εντολή:

int x = 10;
int *ptr = &x;

Στο παραπάνω παράδειγμα, ο δείκτης ptr δείχνει στη διεύθυνση μνήμης της μεταβλητής x. Μπορούμε επίσης να αποκτήσουμε πρόσβαση στην τιμή που βρίσκεται σε αυτήν τη διεύθυνση μνήμης χρησιμοποιώντας τον τελεστή αναφοράς *:

int value = *ptr;

Στο παραπάνω παράδειγμα, η μεταβλητή value περιέχει την τιμή που βρίσκεται στη διεύθυνση μνήμης που δείχνει ο δείκτης ptr, δηλαδή την τιμή της μεταβλητής x.

Με αυτόν τον τρόπο, μπορούμε να λάβουμε τη διεύθυνση μνήμης και την τιμή ενός αντικειμένου στην C++.

Παράδειγμα:

#include <iostream>
using namespace std;

int main() {
  int myNum = 100;  // Δήλωση μιας μεταβλητής int
  int *myPointer = &myNum; // Δήλωση μιας μεταβλητής δείκτη, και ανάθεση της διεύθυνσης της μεταβλητής myNum σε αυτήν

  cout << "Value of myNum: " << myNum << endl; // Εμφάνιση της τιμής της μεταβλητής myNum: 100
  cout << "Address of myNum: " << &myNum << endl; // Εμφάνιση της διεύθυνσης μνήμης της μεταβλητής myNum
  cout << "Value of myPointer: " << myPointer << endl; // Εμφάνιση της διεύθυνσης μνήμης της μεταβλητής myNum
  cout << "Value of the variable pointed to by myPointer: " << *myPointer << endl; // Εμφάνιση της τιμής της μεταβλητής στην οποία δείχνει ο δείκτης myPointer: 100

  // Αλλαγή της τιμής της μεταβλητής myNum
  myNum = 200;

  cout << "Value of myNum: " << myNum << endl; // Εμφάνιση της νέας τιμής της μεταβλητής myNum: 200
  cout << "Value of the variable pointed to by myPointer: " << *myPointer << endl; // Εμφάνιση της νέας τιμής της μεταβλητής στην οποία δείχνει ο δείκτης myPointer: 200

  // Αλλαγή της τιμής της μεταβλητής στην οποία δείχνει ο δείκτης myPointer
  *myPointer = 300;

  cout << "Value of myNum: " << myNum << endl; // Εμφάνιση της νέας τιμής της μεταβλητής myNum: 300
  cout << "Value of the variable pointed to by myPointer: " << *myPointer << endl; // Εμφάνιση της νέας τιμής της μεταβλητής στην οποία δείχνει ο δείκτης myPointer: 300

  return 0;
}

Ο παραπάνω κώδικας σε C πραγματοποιεί τις παρακάτω ενέργειες:

  1. Πρώτα, δηλώνονται μια μεταβλητή myNum τύπου int με αρχική τιμή 100 και ένας δείκτης myPointer τύπου int που αναθέτει τη διεύθυνση της μεταβλητής myNum.
  2. Στη συνέχεια, εκτυπώνονται η τιμή της μεταβλητής myNum, η διεύθυνση της μεταβλητής myNum, η διεύθυνση που αποθηκεύεται στον δείκτη myPointer και η τιμή της μεταβλητής στην οποία δείχνει ο δείκτης myPointer. Οι τιμές αυτές εμφανίζονται στην οθόνη.
  3. Μετά, η τιμή της μεταβλητής myNum αλλάζει σε 200 και εκτυπώνεται η νέα τιμή της myNum καθώς και η τιμή της μεταβλητής που δείχνει ο δείκτης myPointer. Είναι εμφανές ότι η αλλαγή της τιμής της myNum επηρέασε επίσης την τιμή που δείχνει ο δείκτης myPointer.
  4. Τέλος, η τιμή της μεταβλητής στην οποία δείχνει ο δείκτης myPointer αλλάζει σε 300 και εκτυπώνονται η νέα τιμή της myNum και η νέα τιμή της μεταβλητής που δείχνει ο δείκτης myPointer. Και πάλι, η αλλαγή της μεταβλητής που δείχνει ο δείκτης myPointer επηρέασε επίσης την τιμή της myNum.

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

Παράδειγμα:

#include <iostream>
using namespace std;

int main() {
  int myNum = 10; // Δημιουργία μιας μεταβλητής myNum και αρχικοποίησή της με την τιμή 10
  int *myPointer = &myNum; // Δημιουργία ενός δείκτη myPointer και ανάθεση της διεύθυνσης μνήμης της μεταβλητής myNum

  cout << "Value of myNum: " << myNum << endl; // Εκτύπωση της τιμής της μεταβλητής myNum: 10
  cout << "Address of myNum: " << &myNum << endl; // Εκτύπωση της διεύθυνσης μνήμης της μεταβλητής myNum
  cout << "Value of myPointer: " << myPointer << endl; // Εκτύπωση της διεύθυνσης μνήμης που δείχνει ο δείκτης myPointer (διεύθυνση της myNum)
  cout << "Value of the variable pointed to by myPointer: " << *myPointer << endl; // Εκτύπωση της τιμής της μεταβλητής στην οποία δείχνει ο δείκτης myPointer: 10

  *myPointer = 20; // Αλλαγή της τιμής της μεταβλητής στην οποία δείχνει ο δείκτης myPointer σε 20

  cout << "Value of myNum: " << myNum << endl; // Εκτύπωση της τιμής της μεταβλητής myNum: 20
  cout << "Value of the variable pointed to by myPointer: " << *myPointer << endl; // Εκτύπωση της τιμής της μεταβλητής στην οποία δείχνει ο δείκτης myPointer: 20

  return 0;
}

Ο παραπάνω κώδικας περιέχει τη συνάρτηση main(), η οποία είναι η κύρια συνάρτηση ενός προγράμματος C++. Ας εξετάσουμε τι κάνει ο κώδικας σε κάθε τμήμα του:

  1. Αρχικά, δημιουργείται μια μεταβλητή myNum με τιμή 10 και ένας δείκτης myPointer ο οποίος δείχνει στη διεύθυνση μνήμης της myNum.
  2. Στη συνέχεια, χρησιμοποιώντας την εντολή cout, εκτυπώνονται οι τιμές και οι διευθύνσεις μνήμης στην οθόνη. Συγκεκριμένα, εκτυπώνονται η τιμή της myNum, η διεύθυνση μνήμης της myNum, η διεύθυνση μνήμης που δείχνει ο δείκτης myPointer (δηλαδή η διεύθυνση της myNum) και η τιμή της μεταβλητής που δείχνει ο δείκτης myPointer.
  3. Στη συνέχεια, γίνεται αλλαγή της τιμής της μεταβλητής στην οποία δείχνει ο δείκτης myPointer. Αυτό γίνεται με τη γραμμή κώδικα *myPointer = 20;, η οποία αλλάζει την τιμή της myNum σε 20.
  4. Τέλος, χρησιμοποιώντας ξανά την εντολή cout, εκτυπώνονται οι νέες τιμές της myNum και της μεταβλητής που δείχνει ο δείκτης `myPointer`.

Έτσι, ο κώδικας εκτυπώνει τιμές και διευθύνσεις μνήμης, αλλάζει την τιμή της myNum μέσω του δείκτη myPointer και εκτυπώνει τις νέες τιμές.

26 Ιουνίου, 2023
top
error: Content is protected !!
Μετάβαση σε γραμμή εργαλείων