User Tools

Site Tools


cpp:const_pointers

Δείκτες αμετάβλητου περιεχομένου και αμετάβλητης διεύθυνσης

Δείκτες αμετάβλητου περιεχομένου

Είδαμε ότι οι δείκτες είναι μεταβλητές που περιέχουν διευθύνσεις μνήμης στις οποίες αποθηκεύονται άλλες μεταβλητές. Μέσω των δεικτών μπορούμε να διαβάσουμε και να γράψουμε το περιεχόμενο μία διεύθυνσης μνήμης. Υπάρχουν όμως περιπτώσεις που ένας δείκτης είναι επιθυμητό να διαβάζει μόνο τα περιεχόμενα των διευθύνσεων μνήμης στα οποία δείχνει χωρίς να μπορεί να τα μεταβάλλει. Σε αυτή την περίπτωση αρκεί να δηλώσετε τον τύπο δεδομένων στον οποίο δείχνει ο δείκτης ως const ως εξής:

int x;
int y = 10;
const int * p = &y;
x = *p;   // μπορείτε να διαβάσετε το περιεχόμενο του δείκτη
*p = x;   // error: ΔΕΝ μπορείτε να μεταβάλλετε το περιεχόμενο του δείκτη. 

Η χρήση δεικτών σε δεδομένα τύπου const είναι ευρέως διαδεδομένη σε συναρτήσεις, όταν θέλουμε να χρησιμοποιήσουμε δείκτες μόνο για το διάβασμα των περιεχομένων αποκλείοντας το γράψιμο στη συγκεκριμένη περιοχή μνήμης. Δείτε το παρακάτω παράδειγμα:

const_content.cpp
#include <iostream>
using namespace std;
 
// stop pointer does not modify its contents
void increment_all (int* start, const int* stop) {
  while (start != stop) {
    ++(*start);  // increment value pointed
    ++start;     // increment pointer
  }
}
 
// start & stop pointers do not modify their contents
void print_all (const int* start, const int* stop)
{
  while (start != stop) {
    cout << *start << endl;
    ++start;     // increment pointer
  }
}
 
int main ()
{
  int numbers[] = {10,20,30};
  increment_all (numbers,numbers+3);
  print_all (numbers,numbers+3);
  return 0;
}

Από τον παραπάνω παράδειγμα παρατηρήστε ότι ο δείκτης start στη συνάρτηση print_all μεταβάλλει την τιμή του, αλλά δεν μεταβάλλει τα περιεχόμενα των διευθύσεων στα οποία δείχνει.

Δείκτες αμετάβλητης διεύθυνσης

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

char c = 'a'; 
char * const ptr = &c;

Το παρακάτω παράδειγμα είναι ενδεικτικό της χρήσης ενός τέτοιου δείκτη

const_address.cpp
#include <string.h>
typedef struct {
  char name[32];
  char age;
} person_t;
 
void set_age(person_t * const p, int age) {
  p->age = age;  // this is OK
  //p++;         // this is not allowed!
}
 
int main() {
  person_t peter;
  strcpy(peter.name, "Peter Smith");
  set_age(&peter, 25);
}

Δείκτες αμετάβλητης διεύθυνσης και αμετάβλητου περιεχομένου

Στην περίπτωση που είναι επιθυμητή η χρήση ενός δείκτη που δεν μεταβάλλει τη διεύθυνση στην οποία δείχνει ούτε το περιεχόμενο της, τότε μπορείτε να δηλώσετε τον δείκτη ως εξής:

char c = 'a'; const char * const ptr = &c;

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

const_address_const_ptr.cpp
#include <string.h>
#include <iostream>
using namespace std;
 
typedef struct {
  char name[32];
  char age;
} person_t;
 
void set_age(person_t * const p, int age) {
  p->age = age;  // this is OK
  //p++;         // this is not allowed!
}
 
int get_age(const person_t * const p) {
  //p->age++;  // this is not allowed!
  //p++;    // this is not allowed!
  return p->age;  // this is OK
}
 
int main() {
  person_t peter;
  strcpy(peter.name, "Peter Smith");
  set_age(&peter, 25);
  std::cout << "Age of" << peter.name << " is " << get_age(&peter) << endl;
}

Συμπερασματικά, η χρήση του προσδιοριστή const μπορεί να δημιουργήσει δείκτες της εκάστοτε κατηγορίας ως εξής:

int x;
      int *       p1 = &x;  // δείκτης χωρίς περιορισμούς
const int *       p2 = &x;  // δείκτης αμετάβλητου περιεχομένου
      int * const p3 = &x;  // δείκτης αμετάβλητης διεύθυνσης
const int * const p4 = &x;  // δείκτης αμετάβλητου περιεχομένου και αμετάβλητης διεύθυνσης
cpp/const_pointers.txt · Last modified: 2021/04/27 04:41 (external edit)