Αναφορά (υπολογιστές)

Στην πληροφορική και συγκεκριμένα στον προγραμματισμό, **αναφορά** είναι μια τιμή η οποία επιτρέπει στον προγραμματιστή έμμεση πρόσβαση σε ένα συγκεκριμένο στοιχείο δεδομένων (όπως μια μεταβλητή/variable ή μια εγγραφή/record η οποία βρίσκεται στην μνήμη του υπολογιστή ή σε κάποια άλλη μονάδα αποθήκευσης). Η *αναφορά* λέμε ότι αναφέρεται σε ένα συγκεκριμένο στοιχείο δεδομένων και η πρόσβαση στα δεδομένα ονομάζεται *έμμεση αναφορά* (dereferencing the reference).

Η αναφορά είναι διαφορετική από τα δεδομένα που αναφέρεται. Η αναφορά είναι μια διεύθυνση φυσικής μνήμης στην οποία τα δεδομένα είναι αποθηκευμένα (ή μνήμη αυτή μπορεί να είναι η μνήμη του υπολογιστή ή κάποια μονάδα αποθήκευσης). Για αυτό το λόγο η αναφορά ονομάζεται δείκτης ή διεύθυνση η οποία δείχνει τα δεδομένα. Η αναφορά μπορεί επίσης να αναφέρεται στην διαφορά μεταξύ μιας διεύθυνσης βάσης με την διεύθυνση ενός στοιχείου δεδομένων (όπως για παράδειγμα σε ένα πίνακα όπου η διαφορά αυτή μπορεί να αναφέρεται στην διαφορά της διεύθυνσης ενός στοιχείου από το πρώτο στοιχείο του πίνακα).

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

Η έννοια της αναφοράς μπορεί να συγκριθεί με την έννοια μιας ταχυδρομικής διεύθυνσης στην καθημερινή ζωή. Για παράδειγμα η διεύθυνση "Καποδιστρίου 12" μπορεί αναφέρεται στο ότι από την αρχή της οδού Καποδιστρίου αν κατέβεις το δρόμο το σπίτι βρίσκεται 3 σπίτια κάτω στην αριστερή πλευρά. Πηγαίνοντας στο κτήριο στο οποίο αναφέρεται η ταχυδρομική διεύθυνση είναι ανάλογο με την λειτουργία έμμεσης αναφοράς (dereferencing). Το όνομα "Το συνεργείο του Μανόλη" μπορεί να είναι μοναδικό αναγνωριστικό για το κτήριο αλλά δεν μπορεί να συγκριθεί με την αναφορά σε δεδομένα, γιατί για να βρεθεί το κτήριο με το όνομα αυτό θέλει αναζήτηση σε κάποιο οδηγό (π.χ. χρυσό οδηγό) και δεν είναι αυτονόητα ξεκάθαρο. Μια αναφορά δεδομένων μπορεί να συγκριθεί με την ταμπέλα του καταστήματος που λέει "Για συνεργείο λάστιχων να πάτε στη οδό Δημοκρατίας 23". Περνώντας μια αναφορά ως παράμετρο σε μια υπορουτίνα και όχι τα δεδομένα είναι σαν να δίνει σε ένα φίλο την διεύθυνση του συνεργείου αντί να φέρνεις τον Μανόλη και όλα τα εργαλεία του συνεργείου στο σπίτι του φίλου.

## Παραδείγματα

### Αναφορές στη C++

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


```cpp
/* int &top;     // ΛΑΘΟΣ - πρέπει να αρχικοποιηθεί  */

int buf[5] = {1, 2, 3, 4, 5};

int &first = buf[0];            // int *p = &buf[0];
int &last = buf[4];             // int *q = &buf[4];

first = -1;                     // *p = -1;
last = -5;                      // *q = -5;
```


### C++ και πέρασμα τιμών σε συνάρτηση
Στο παρακάτω παράδειγμα C++ βλέπουμε πέρασμα τιμής (παραμέτρου) σε μια συνάρτηση με δύο τρόπους: με αναφορά και με τιμή. Όταν γίνεται πέρασμα της παραμέτρου με τιμή αντιγράφεται η μεταβλητή ενώ όταν γίνεται πέρασμα της παραμέτρου με αναφορά περνάει η διεύθυνση της μεταβλητής και δεν είναι γρηγορότερο. Αλλαγές στο πέρασμα με τιμή δεν επηρεάζουν την εξωτερική μεταβλητή ενώ στο πέρασμα με διεύθυνση, επηρεάζουν την εξωτερική μεταβλητή. 


```cpp
#include <iostream>      // για την βιβλιοθήκη εισόδου/εξόδου και το cout

using namespace std;    // η cout βρίσκεται κάτω από το χώρο ονομάτων std

int greater_of_VALUE(int a, int b) {
  if (a > b) 
     return a;
  else
    return b;
} 

int greater_of_REFERENCE(int &a, int &b) {
  if (a > b) 
     return a;
  else
    return b;
} 

void add_one_VALUE(int a) {
   a++;
}

void add_one_REFERENCE(int &a) {
   a++;
}

int main() {
   int x = 8;
   int y = 10;
   
   // Η κλήση είναι η ίδια όπως και το αποτέλεσμα 
   // (εμφανίζεται ο αριθμός 10 - σε κάθε κλήση παρακάτω)   
   cout << greater_of_REFERENCE(x,y) << endl;
   cout << greater_of_VALUE(x,y) << endl;

   // κλήση της συνάρτησης με πέρασμα τιμής
   // δεν έχουμε μεταβολή της μεταβλητής x
   add_one_VALUE(x);
   cout << x << endl;      // εμφανίζει 8

   // κλήση της συνάρτησης με πέρασμα διεύθυνσης
   // έχουμε μεταβολή της μεταβλητής x
   add_one_REFERENCE(x);
   cout << x << endl;      // εμφανίζει 9

   return 1;
}
```


## Παραπομπές


Κατηγορία:Τύποι δεδομένων
Κατηγορία:Έννοιες γλωσσών προγραμματισμού