10. Εμβέλεια μεταβλητών

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

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

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

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

#include <avr/io.h>
uint8_t  add(uint8_t x, uint8_t y);
int main(void)
{
     DDRA=0x00; DDRB=0x00; DDRC=0xFF;
     uint8_t a, b, sum;
     a = PINA;  b = PINB;
     sum = add(a, b);
     PORTC = sum;
     while(1);

}
uint8_t  add(uint8_t x, uint8_t y)
{
     uint8_t ss;
     ss = x*y;
     return  ss;
}

Σε αυτό το πρόγραμμα ορίζεται το πρωτότυπο της συνάρτησης add() πριν από την main() διότι σε αντίθετη περίπτωση όταν ο μεταγλωττιστής θα την συναντούσε μέσα στην main(), δεν θα γνώριζε ούτε τον τύπο της συνάρτησης αλλά ούτε και τον τύπο των παραμέτρων της και θα εμφάνιζε μήνυμα σφάλματος.

Στην συνάρτηση  add() η ss είναι τοπική μεταβλητή και έχει ισχύ μόνο μέσα σε αυτή την συνάρτηση. Οι παράμετροι x και y αποτελούν και αυτές τοπικές μεταβλητές και έχουν ισχύ μόνο μέσα στη συνάρτηση.

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

int main(void)
{
     DDRC=0xFF;
     uint8_t a=16, b=32;
     if(a>=0 && b>=0)
     {
          uint8_t s;
          s = a+b;
          PORTC = s;
     }
     while(1);
}

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

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

int main(void)
{
      DDRC=0xFF;
      for(uint8_t k=0; k<=255; k++)
      {
            PORTC = k;
      }
      while(1);
}

Σε αυτόν τον κώδικα η μεταβλητή k γίνεται τοπική μεταβλητή του βρόγχου for και μπορεί να χρησιμοποιηθεί μόνο μέσα σε αυτόν.

Καθολικές μεταβλητές

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

#include <avr/io.h>
uint8_t count = 0  //Καθολική εμβέλεια
void increase_count()
{
    count++;  // Μπορούμε να προσπελάσουμε και να αλλάξουμε την καθολική μεταβλητή
    PORTC = count;
}
int main(void)
{
     DDRC = 0xFF;
     PORTC = count;
     increase_count();  // Αυξάνει το count κατά 1
     increase_count();  // Αυξάνει το count κατά 1 ακόμη
     while(1);
}

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

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

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

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

#include <avr/io.h>
void counter()
{
    static uint8_t count = 0; // Διατηρεί την τιμή της μεταξύ κλίσεων
    count++;
    PORTC = count;
}
int main(void)
{
     counter();  // Εκτυπώνει :  1
     counter();  // Εκτυπώνει :  2
     counter();  // Εκτυπώνει :  3
}