Ελληνικά

Δομή της Επανάληψης

 

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

Επανάληψη όσο η συνθήκη είναι αληθής.

while (this_is_true)
{
    /* Keep executing me */
}

Ίδιο με το παραπάνω, αλλά ο κώδικας εκτελείται τουλάχιστον μια φορά.

do
{
    /* Keep executing me */
}while (this_is_true);

Διαφορετικό από τα παραπάνω, αυτή η δομή συνήθως χρησιμοποιείται σαν "ΓΙΑ χ ΑΠΟ κάπου ΜΕΧΡΙ κάπου ΜΕ_ΒΗΜΑ κάτι", αλλά είναι πολύ ευέλικτη. To initialization είναι η ανάθεση αρχικής τιμής, το condition είναι η συνθήκη επανάληψης και το operation είναι κάποια πράξη, συνήθως το "βήμα".

for (initialization ; condition ; operation)
{
    /* Keep executing me */
}

Παρακάτω δίνονται 3 παραδείγματα, τα οποία είναι το ίδιο πρόβλημα( το άθροισμα 1+2+3+...+n ) λυμένο με τους 3 διαφορετικούς τρόπους:

#include <stdio.h>

int main(void)
{
    int N, i;
    int sum;
   
    printf("Give a positive integer: ");
    scanf("%d", &N);
   
    /* Εδώ μπορεί να πάει οποιοδήποτε από τα παρακάτω 3 παραδείγματα */
   
    printf("Adding all integers from 1 to %d gives %d.\n", N, sum);
   
    /* Μήπως αρχίζει να βγάζει νόημα αυτή η γραμμή? Μην απελπίζεστε, θα εξηγηθεί σε επόμενα άρθρα */
    while (getchar() != '\n');
    getchar();
   
    return 0;
}
    /* Παράδειγμα με while */
    i = 1;
    sum = 0;
    while (i <= N)
    {
        sum += i;
        ++i;
    }
    /* Παράδειγμα με do-while */
    i = 1;
    sum = 0;
    do
    {
        sum += i;
        ++i;
    }while (i <= N);
    /* Παράδειγμα με for */
    sum = 0;
    for (i = 1; i <= N; i++)
    {
        sum += i;
    }
}

Δομή Επιλογής

Η δομή της Επιλογής

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

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

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

Το κύριο χαρακτηριστικό της άλγεβρας Boole είναι ότι οι τιμές που χρησιμοποιεί περιορίζονται σε δύο καταστάσεις: το 0 και το 1 (ή αλλιώς "ψευδές" και "αληθές"). Επιπλέον, περιλαμβάνει τελεστές που εκτελούν συγκεκριμένες λογικές πράξεις. Οι βασικοί τελεστές είναι:

  • OR (|| στη γλώσσα C),
  • AND (&& στη γλώσσα C),
  • NOT (! στη γλώσσα C).

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

 

α || β

α β  αποτέλεσμα
0 0  0
0 1  1
1 0  1
1 1  1

α && β

α β  αποτέλεσμα
0 0  0
0 1  0
1 0  0
1 1  1

α  αποτέλεσμα
0  1
1  0

Κάθε λογικός τελεστής έχει τη δική του προτεραιότητα. Πρώτο εκτελείται το NOT, ακολουθεί το AND, και τελευταίο το OR. Αλλά πώς υπολογίζονται αυτές οι λογικές τιμές; Η απάντηση βρίσκεται στους τελεστές σύγκρισης.

Η C περιλαμβάνει τελεστές ισότητας (==), ανισότητας (!=), καθώς και όλους τους γνωστούς τελεστές σύγκρισης: >, >=, <, <=. Όταν συγκρίνονται δύο τιμές, το αποτέλεσμα της σύγκρισης είναι πάντα είτε ψευδές (0) είτε αληθές (1).

Πώς όμως αυτές οι λογικές τιμές επηρεάζουν τη ροή ενός προγράμματος; Η C παρέχει εντολές που αξιολογούν λογικές εκφράσεις και, ανάλογα με το αν το αποτέλεσμα είναι αληθές ή ψευδές, καθορίζουν ποιο μέρος του κώδικα θα εκτελεστεί. Η γενική μορφή αυτών των εντολών παρουσιάζεται παρακάτω:

if (this_is_true)
{
    /* Τρέξε με */
}/* Μπορεί να σταματάει εδώ */
else if (that_is_true)
{
    /* Τρέξε εμένα! */
}
/* Όσες "else if" θέλετε ενδιάμεσα */
/* Μπορεί να σταματάει κι εδώ */
else
{
    /* Τίποτα δεν ήταν αληθές, άρα εκτέλεσε εμένα */
}

Να σημειωθεί ότι αν ο κώδικας που πρόκειται να εκτελεστεί είναι μόνο μια γραμμή (μια έκφραση ), τότε δεν χρειάζονται τα "{ }".
Θα κλείσω με το παρακάτω παράδειγμα, που εκτυπώνει κάτι διαφορετικό ανάλογα τι τιμή του έδωσε ο χρήστης.

#include <stdio.h>

int main(void)
{
    int age = 0;
   
    printf("Please input your age: ");
    scanf("%d", &age);
   
    if (age > 0 && age < 18)
        printf("So you're a minor. Oh, I miss those days...\n");
    else if (age >= 18 && age < 30)
        printf("Good thing to be young and full of energy.\n");
    else if (age >= 30 && age < 60)
        printf("It's ok, learning never stops. :)\n");
    else if (age >= 60 && age < 120)
        printf("Well... I guess it's never too late!...\n");
    else
        printf("Nah, you're just messing with me!\n");
   
    /* Αγνοήστε την παρακάτω γραμμή, προστέθηκε ώστε να μην είναι ελλιπές το παράδειγμα, θα αποκτήσει νόημα σε επόμενα άρθρα... */
    while (getchar() != '\n');
    getchar();
   
    return 0;
}

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

switch (variable)
{
    case value1: /* if (variable == value1) */
        /* Τρέχε εμένα */
    break;
    case value2: /* else if (variable == value2) */
        /* Τρέχε εμένα! */
    break;
    /* Όσα cases θέλετε βάζετε */
    default: /* else */
        /* Εκτέλεσε εμένα. */
}

Τα "break" υπάρχουν για να "πετάξουν" τη ροή εκτέλεσης έξω από τη switch. Αν κάποιο δεν υπήρχε, ο αμέσως επόμενος κώδικας θα εκτελούταν!! Μπορούν να κάνουν κάτι αντίστοιχο στις δομές επανάληψης, αλλά θα επανέλθω σ`αυτό σε άλλο άρθρο.

Κλείνοντας, μη ξεχνάτε να πειραματίζεστε με το κώδικα και να προσπαθείτε να φτιάξετε να δικά σας προγράμματα. Μερικά παραδείγματα σαν τα δικά μου δεν είναι αρκετά για να μάθετε τη γλώσσα, πρέπει να προσπαθήσετε! 🙂