3. Έλεγχος ροής προγράμματος: if – while – for – goto

Οι εντολές ελέγχου ροής ορίζουν τη σειρά με την οποία εκτελούνται οι εντολές ενός προγράμματος στη γλώσσα C. Ας σημειώσουμε ότι κάθε εντολή θα πρέπει να τερματίζεται με το ελληνικό ερωτηματικό και ότι οι αγκύλες { και } χρησιμοποιούνται για να ορίσουν ένα μπλοκ εντολών ισοδύναμα σαν να ήταν μια απλή εντολή.

Οι εντολές ελέγχου εκτέλεσης ενός προγράμματος, σε γλώσσα C, είναι οι if, while, for και switch οι οποίες παίρνουν απόφαση για την κατεύθυνση της εκτέλεσης του προγράμματος, βασιζόμενες σε μια συνθήκη ελέγχου. Η συνθήκη μπορεί να είναι μια λογική μεταβλητή με τιμή true ή false, ή επίσης μια λογική έκφραση οι οποία μπορεί να πάρει μια από τις λογικές τιμές true(αληθής) ή false(ψευδής).

Μπορούμε να σχηματίσουμε λογικές εκφράσεις με τους λογικούς τελεστές && (λογικό ΚΑΙ), || (λογικό ‘Η), ^ (αποκλειστικό Η), ! (λογικό ΝΟΤ). Επίσης με τους σχεσιακούς τελεστές < > <= >= == != που εφαρμόζονται σε αριθμητικές τιμές, μπορούμε να σχηματίσουμε απλές ή σύνθετες λογικές εκφράσεις. Τέλος η συνθήκη ελέγχου μπορεί να είναι μια σκέτη ακέραια τιμή με την τιμή 0 να αντιπροσωπεύει την ψευδή λογική τιμή και μια ακέραια τιμή διάφορη του 0 να αντιπροσωπεύει την αληθή λογική τιμή.

Η εντολή if

Η if ορίζει μια εντολή υπό συνθήκη. Εάν η συνθήκη της if είναι αληθής ή έχει μη μηδενική τιμή, εκτελείται το μπλοκ κώδικα που συνοδεύει την if. Αν είναι ψευδής ή έχει τιμή μηδέν παρακάμπτεται το μπλοκ κώδικα. Η σύνταξη της εντολής if είναι η ακόλουθη:

if(συνθήκη)
     μπλοκ_κώδικα;

Ένα παράδειγμα της εντολής if είναι το ακόλουθο:

if(a > b)
      sum+=2;

Η τιμή της μεταβλητής sum αυξάνει κατά 2 εάν η τιμή της μεταβλητής a είναι μεγαλύτερη από την τιμή της μεταβλητής b.

Η εντολή if – else

Η if – else μεταχειρίζεται συνθήκες με τέτοιο τρόπο, ώστε ένα πρόγραμμα να εκτελεί μια εντολή όταν η συνθήκη της if είναι αληθής (έχει μια μη μηδενική τιμή) και μια διαφορετική εντολή εάν η συνθήκη είναι ψευδής (έχει μηδενική τιμή).

Η σύνταξη της εντολής if – else είναι:

if(συνθήκη)
     μπλόκ_εντολών_1;
else
     μπλοκ_εντολών_2;

Η συνθήκη εκτιμάται και εάν είναι αληθής (έχει μη μηδενική τιμή) τότε εκτελείται το μπλοκ_εντολών_1. Εάν είναι ψευδής (έχει μηδενική τιμή)  τότε εκτελείται το μπλοκ_εντολών_2 . Ακολουθεί ένα παράδειγμα της if – else:

if(a!=0)
    r=b;
else
    r=c;

Η εντολή if – else του προηγούμενου παραδείγματος μπορεί να αντικατασταθεί από τον τελεστή ?: Η εντολή  r = (a != 0) ? b : c;   είναι ισοδύναμη με την εντολή if – else του προηγούμενου παραδείγματος.

Ένθετη εντολή if

Μια ένθετη if μπορεί να εκφραστεί από διαδοχικές εντολές if –else, όπως παρακάτω:

if(συνθήκη_1)
     μπλοκ_εντολών_1;
else if(συνθήκη_2)
     μπλοκ_εντολών_2;
else if(συνθήκη_3)
     μπλοκ_εντολών_3;
.
.
else
     μπλοκ_εντολών_n;
εντολή εξόδου;

Εάν η πρώτη συνθήκη είναι αληθείς εκτελείται το μπλοκ_εντολών_1 και το πρόγραμμα συνεχίζει με την εντολή εξόδου. Εάν η πρώτη συνθήκη είναι ψευδής, ελέγχεται η δεύτερη συνθήκη. Αν η πρώτη συνθήκη είναι ψευδής και η δεύτερη συνθήκη είναι αληθής, εκτελείται το μπλοκ_εντολών_2 και στη συνέχεια η ροή εκτέλεσης πάει στην εντολή εξόδου.

Όμοια αν φτάσουμε στο τελευταίο else και καμία από τις προηγούμενες συνθήκες δεν είναι αληθής, εκτελείται το τελευταίο μπλοκ_κώδικα_n και μετά η ροή του προγράμματος βγαίνει στην εντολή_εξόδου.

Η εντολή switch

Η switch είναι μια πολλαπλής απόφασης εντολή που βασίζεται στην τιμή μιας έκφρασης ελέγχου. Η έκφραση ελέγχου μπορεί να είναι μια ακέραια αριθμητική παράσταση. Κατά την εκτέλεση της εντολής switch υπολογίζεται η τιμή της αριθμητικής έκφρασης, και η εκτέλεση του προγράμματος πάει στο σημείο με τη λέξη – κλειδί case σε αυτή, που η ετικέτα της να ταιριάζει με εκείνη την τιμή της έκφρασης ελέγχου. Αν η ροή εκτέλεσης συναντήσει την εντολή break η εκτέλεση βγαίνει από την switch και εκτελείται η επόμενη εντολή. Διαφορετικά η εκτέλεση πάει στο επόμενο μπλοκ της case και αυτός ο κύκλος συνεχίζεται μέχρι την επόμενη break. Αν η αριθμητική τιμή της έκφρασης switch δεν αντιστοιχεί σε καμία ετικέτα της λέξης case εκτελείται το μπλοκ της ετικέτας default και στο τέλος της εκτέλεσης της η ροή του προγράμματος πάει στην εντολή μετά την switch. Η σύνταξη της εντολής switch είναι η εξής:

switch(έκφραση) {
        case περίπτωση_1:
                 μπλοκ_εντολών_1;
                  break;
        case περίπτωση_2:
                 μπλοκ_εντολών_2;
                 break;
        ....
         default:
                 μπλοκ_εντολών_n;
}

Για παράδειγμα θεωρούμε το ακόλουθο απόσπασμα κώδικα:

switch(level) {
      case 1:
          pay = 10;
          break;
      case 2:
          pay = 20;
          break;
      case 3:
          pay = 30;
          break;
      case 4:
          pay = 40;
          break;
      default:
          pay=0;
}

Η μεταβλητή pay παίρνει τιμή ίση με level x 10. Η λέξη κλειδί break τραβά την εκτέλεση ροής έξω από την εντολή switch έτσι ώστε μόνο το αντίστοιχο μπλοκ της break να εκτελείται. Αν κάποια εντολή break λείπει τότε όλες οι εντολές από εκείνη την case μέχρι την επόμενη break, μέσα στο ίδιο μπλοκ της switch, εκτελούνται.

Η εντολή for

Η εντολή for στην ουσία είναι ένας βρόγχος που εκτελείται ξανά και ξανά εφόσον μια συνθήκη είναι αληθής. Η σύνταξη της εντολής for είναι:

for(εκχ1; συνθ; εκχ3)
         μπλοκ_εντολών;

Όπου εκχ1 και εκχ3 είναι εκχωρήσεις και η συνθ είναι μια συνθήκη. Μόλις η ροή του προγράμματος φτάσει στην for εκτελείται η έκφραση εκχώρησης εκχ1. Στη συνέχεια εκτιμάται η συνθήκη συνθ και εάν είναι αληθής εκτελείται το μπλοκ_εντολών και μετά εκτελείται η εκχ3. Ακολουθεί η εκ νέου εκτίμηση της συνθήκης συνθ και εάν είναι αληθής εκτελείται το μπλοκ_εντολών και πάλι ο ίδιος κύκλος.

Αν η συνθήκη είναι ψευδής η ροή εκτέλεσης του κώδικα βγαίνει έξω από τη for. Για παράδειγμα η ακόλουθη for υπολογίζει το άθροισμα των τετραγώνων των ακεραίων από το 1 έως το 9.

int i, sum;
sum = 0;
for(i=1; i<10; i++)
         sum = sum + i*i;

Η εντολή while

while(συνθήκη)
         μπλοκ εντολών;

Όταν η συνθήκη της while έχει μια μη μηδενική τιμή (αληθής) ο βρόγχος της while εκτελείται. Η τιμή της συνθήκης εκτιμάται ξανά και αν είναι αληθής εκτελείται πάλι το μπλόκ_εντολών. Εκτελείται συνεχώς αυτός ο κύκλος έως ότου η συνθήκη να πάρει μηδενική τιμή (ψευδής). Αν η συνθήκη γίνει ψευδής η ροή εκτέλεσης βγαίνει έξω από το βρόγχο της while.

Το μπλοκ εντολών μπορεί να είναι μια NULL εντολή. Η εντολή NULL δεν κάνει τίποτα και παριστάνεται με το ελληνικό ερωτηματικό. Θεωρήστε το παρακάτω απόσπασμα κώδικα:

intCnt = 5;
while(intCnt);

H CPU θα παραμείνει στο βρόγχο while μέχρι η μεταβλητή intCnt πάρει τιμή μηδέν. Στις εφαρμογές μικροελεγκτών η μείωση της intCnt γίνεται με εξωτερικά γεγονότα όπως οι διακοπές.

Η εντολή Do – While

Οι εντολές βρόγχου while και for ελέγχουν πρώτα τη συνθήκη εκτέλεσης του βρόγχου. Αντίθετα η εντολή do – while ελέγχει την συνθήκη για να επιτραπεί η εκτέλεση του βρόγχου μετά την εκτέλεση των εντολών που βρίσκονται μέσα στο βρόγχο. Έτσι το μπλοκ εντολών της εντολής do – while εκτελείται τουλάχιστον μια φορά. Η σύνταξη της εντολής είναι:

do {
      μπλοκ_εντολών;
} while(συνθήκη);

Η εντολή goto

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

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

Η σύνταξη της εντολής goto είναι

goto label;

Ένα παράδειγμα χρήσης της goto είναι το ακόλουθο:

char e[ ];
if(x<0 || x>100)
          goto error;
…
error: e[ ] = “variable x is out of bound”;