User Tools

Site Tools


cpp:pointers

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
cpp:pointers [2021/04/27 04:21] – [Δείκτες και πίνακες] gthanoscpp:pointers [2023/04/25 13:14] (current) – [Δείκτες null] gthanos
Line 86: Line 86:
  
 Θα πρέπει να έχετε υπόψη ότι όλοι οι δείκτες καταλαμβάνουν τον ίδιο χώρο στη μνήμη (4-byte για συστήματα 32-bit και 8-byte για συστήματα 64-bit) ανεξάρτητα από τον τύπο δεδομένων στον οποίο δείχνουν. Θα πρέπει να έχετε υπόψη ότι όλοι οι δείκτες καταλαμβάνουν τον ίδιο χώρο στη μνήμη (4-byte για συστήματα 32-bit και 8-byte για συστήματα 64-bit) ανεξάρτητα από τον τύπο δεδομένων στον οποίο δείχνουν.
 +
 ===== Δείκτες και πίνακες ===== ===== Δείκτες και πίνακες =====
  
Line 123: Line 124:
  
 <WRAP tip 80% center round> <WRAP tip 80% center round>
-Οι δείκτες οφείλουν να δείχνουν σε διευθύνσεις μνήμης που ανήκουν στην διεργασία που εκτελείται. Στην πραγματικότητα όμως οι δείκτες μπορούν να πάρουν οποιαδήποτε τιμή ακόμη και τιμές εκτός του εύρους διευθύνσεων που έχουν ανατεθεί από το λειτουργικό στην τρέχουσα διεργασία. Η ανάγνωση από διευθύνσεις ή η εγγραφή σε διευθύνσεις που δεν ανήκουν στη διεργασία δημιουργεί σφάλμα που τερματίζει το πρόγραμμα. Δείτε το παρακάτω παράδειγμα όπου ένας δείκτης αρχικοποιείται σε τιμή εκτός των ορίων του πίνακα //intArray//.+Οι δείκτες οφείλουν να δείχνουν σε διευθύνσεις μνήμης που ανήκουν στη διεργασία που εκτελείται. Στην πραγματικότητα όμως οι δείκτες μπορούν να πάρουν οποιαδήποτε τιμή ακόμη και τιμές εκτός του εύρους διευθύνσεων που έχουν ανατεθεί από το λειτουργικό σύστημα στην τρέχουσα διεργασία. Η ανάγνωση από διεύθυνση ή η εγγραφή σε διεύθυνση που δεν ανήκει στη διεργασία δημιουργεί σφάλμα που τερματίζει το πρόγραμμα. Δείτε το παρακάτω παράδειγμα όπου ένας δείκτης αρχικοποιείται σε τιμή εκτός των ορίων του πίνακα //intArray//.
  
 <code c++ intArrayPointer.cpp> <code c++ intArrayPointer.cpp>
Line 133: Line 134:
   *ptr = 10;   *ptr = 10;
 } }
-</code> 
-</WRAP> 
- 
-===== Δείκτες αμετάβλητου περιεχομένου και δείκτες αμετάβλητης διεύθυνσης (const) ===== 
- 
-Είδαμε ότι οι δείκτες είναι μεταβλητές που περιέχουν διευθύνσεις μνήμης στις οποίες αποθηκεύονται άλλες μεταβλητές. Μέσω των δεικτών μπορούμε να διαβάσουμε και να γράψουμε το περιεχόμενο μία διεύθυνσης μνήμης. Υπάρχουν όμως περιπτώσεις που ένας δείκτης είναι επιθυμητό να διαβάζει μόνο τα περιεχόμενα των διευθύνσεων μνήμης στα οποία δείχνει χωρίς να μπορεί να τα μεταβάλλει. Σε αυτή την περίπτωση αρκεί να δηλώσετε τον τύπο δεδομένων στον οποίο δείχνει ο δείκτης ως //const// ως εξής: 
- 
-<code c> 
-int x; 
-int y = 10; 
-const int * p = &y; 
-x = *p;   // μπορείτε να διαβάσετε το περιεχόμενο του δείκτη 
-*p = x;   // error: ΔΕΝ μπορείτε να μεταβάλλετε το περιεχόμενο του δείκτη.  
-</code> 
- 
-Η χρήση δεικτών σε δεδομένα τύπου //const// είναι ευρέως διαδεδομένη σε συναρτήσεις, όταν θέλουμε να χρησιμοποιήσουμε δείκτες μόνο για το διάβασμα των περιεχομένων αποκλείοντας το γράψιμο στη συγκεκριμένη περιοχή μνήμης. Δείτε το παρακάτω παράδειγμα: 
- 
-<code c 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; 
-} 
-</code> 
- 
-Από τον παραπάνω παράδειγμα παρατηρήστε ότι ο δείκτης //start// στη συνάρτηση //print_all// δεν μεταβάλλει τα δεδομένα στη μνήμη, όμως το περιεχόμενο του δεν παραμένει σταθερό, αλλά μεταβάλλεται. Στην περίπτωση που επιθυμείτε τη χρήση ενός δείκτη ο οποίος δεν μεταβάλλει τη διεύθυνση στην οποία δείχνει, αλλά είναι σε θέση να μεταβάλλει το περιεχόμενο της διεύθυνσης αυτής τότε μπορείτε να δηλώσετε ένα δείκτη της μορφή  
- 
-<code c> 
-char c = 'a';  
-char * const ptr = &c; 
-</code> 
- 
-όπως στο παρακάτω παράδειγμα: 
- 
-<code 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); 
-} 
-</code> 
- 
-Τέλος εάν επιθυμείτε να έχετε ένα δείκτη ο οποίος δεν μεταβάλλει τη διεύθυνση στην οποία δείχνει και δεν μπορεί να μεταβάλλει το περιεχόμενο της διεύθυνσης αυτής τότε μπορείτε να τον δηλώσετε ως εξής: 
- 
-<code c>char c = 'a'; const char * const ptr = &c;</code> 
- 
-Δείτε το παρακάτω παράδειγμα χρήσης ενός τέτοιου δείκτη 
- 
-<code 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; 
-} 
-</code> 
- 
- 
-<WRAP center round tip 80%> 
-Συμπερασματικά, η χρήση του προσδιοριστή //const// μπορεί να δημιουργήσει δείκτες της εκάστοτε κατηγορίας ως εξής: 
-<code c> 
-int x; 
-      int *       p1 = &x;  // non-const pointer to non-const int 
-const int *       p2 = &x;  // non-const pointer to const int 
-      int * const p3 = &x;  // const pointer to non-const int 
-const int * const p4 = &x;  // const pointer to const int  
 </code> </code>
 </WRAP> </WRAP>
Line 287: Line 169:
  
 {{ :cpp:pointer2pointer.png | Οι μεταβλητές a,b,c,d }} {{ :cpp:pointer2pointer.png | Οι μεταβλητές a,b,c,d }}
 +
 ===== Δείκτες τύπου void ===== ===== Δείκτες τύπου void =====
  
-Ο δείκτης τύπου //void// είναι ένας ειδικός τύπος δείκτη ο οποίος έχει το πλεονέκτημα ότι μπορεί να μετατραπεί σε οποιονδήποτε τύπο δείκτη. Επίσης οποιοσδήποτε τύπος δείκτη μπορεί να μετατραπεί σε δείκτη τύπου //void//. Ο περιορισμός των δεικτών τύπου void είναι ότι δεν υπάρχει τρόπος να προσπελάσουμε το περιεχόμενο ενός ''void*'' δείκτη χωρίς προηγουμένως να τον μετατρέψουμε σε ένα διαφορετικό τύπο δείκτη. Δείτε το παρακάτω παράδειγμα που   χρησιμοποιεί ένα δείκτη ''void*'' για να προσπελάσει τα δεδομένα του.+Ο δείκτης τύπου //void// είναι ένας ειδικός τύπος δείκτη ο οποίος έχει το πλεονέκτημα ότι μπορεί να μετατραπεί σε οποιονδήποτε τύπο δείκτη. Επίσης οποιοσδήποτε τύπος δείκτη μπορεί να μετατραπεί σε δείκτη τύπου //void//. Ο περιορισμός των δεικτών τύπου void είναι ότι δεν υπάρχει τρόπος να προσπελάσουμε άμεσα το περιεχόμενο τους. Για την προσπέλαση τους θα πρέπει προηγούμενα να μετατραπούν σε ένα διαφορετικό τύπο δείκτη. Δείτε το παρακάτω παράδειγμα που χρησιμοποιεί ένα δείκτη ''void*'' για να προσπελάσει τα δεδομένα του.
  
 <code c void_ptr.cpp> <code c void_ptr.cpp>
Line 317: Line 200:
  
 <WRAP center round tip 80%> <WRAP center round tip 80%>
-Δεν επιτρέπεται η αριθμητική δεικτών σε δείκτες τύπου ''void*''.+Δεν υφίσταται η αριθμητική δεικτών σε δείκτες τύπου ''void*''.
 </WRAP> </WRAP>
  
-===== null pointers =====+===== Δείκτες με τιμή NULL =====
  
 Δείκτες που δεν είναι αρχικοποιημένοι συχνά αρχικοποιούνται στην τιμή 0 ή NULL. Η C++ εκτός από τις τιμές 0 και null παρέχει και την δεσμευμένη λέξη **nullptr** που αντιπροσωπεύει και αυτή την τιμή 0 για ένα δείκτη. Οι παρακάτω ορισμοί είναι ισοδύναμοι. Δείκτες που δεν είναι αρχικοποιημένοι συχνά αρχικοποιούνται στην τιμή 0 ή NULL. Η C++ εκτός από τις τιμές 0 και null παρέχει και την δεσμευμένη λέξη **nullptr** που αντιπροσωπεύει και αυτή την τιμή 0 για ένα δείκτη. Οι παρακάτω ορισμοί είναι ισοδύναμοι.
Line 326: Line 209:
 <code c++ nullptr.cpp> <code c++ nullptr.cpp>
 #include <iostream> #include <iostream>
 +
 char *p = 0; char *p = 0;
 char *q = NULL; char *q = NULL;
cpp/pointers.1619497296.txt.gz · Last modified: 2021/04/27 03:21 (external edit)