Τμήμα:C/Μάθημα 5ο
Προηγούμενη Ενότητα |
Περιεχόμενα | Επόμενη Ενότητα |
Σε αυτό το μάθημα θα εξετάσουμε τις επαναληπτικές δηλώσεις (iterative statements). Επαναληπτικές δηλώσεις ονομάζονται μπλοκ κώδικα που εκτελούνται παραπάνω από μία φορές ανάλογα με την συνθήκη που τα έχουμε δηλώσει.
while
[επεξεργασία]Η while χρησιμοποιείται όταν δεν γνωρίζουμε τον αριθμό των επαναλήψεων ή υπάρχει περίπτωση οι εντολές να μην εκτελεστούν ούτε μία φορά. Εκτελούνται όσο η συνθήκη (expression) είναι αληθής(true).
Η γενική σύνταξη είναι η εξής:
while(expr)
{
statements;
}
Παράδειγμα
[επεξεργασία]Θυμάστε το τελευταίο παράδειγμα με την switch. Αν όχι ξαναρίξτε του μια ματιά και συγκρίνετέ το με το παρακάτω. Προσπαθείστε να καταλάβετε την διαφορά που θα έχει πριν το εκτελέσετε.
#include <stdio.h>
int main()
{
int choice,n1,n2;
char op;
printf("\nMake a choice:\n0.Exit\n1.Continue");
scanf("%i",&choice);
while(choice!=0) /*Αρχίζει η while*/
{
printf("Enter the first number:");
scanf("%i",&number1);
printf("\nEnter the second number:");
scanf("%i",&number2);
printf("\nEnter the operation you wish to make (+,-,*,/):");
scanf("%c",&op);
switch(op){
case '+':
printf("%i + %i:%i",n1,n2,n1+n2);
break;
case '-':
printf("%i - %i:%i",n1,n2,n1-n2);
break;
case '*':
printf("%i * %i:%i",n1,n2,n1*n2);
break;
case '/':
printf("%i + %i:%i,%i",n1,n2,n1/n2,n1%n2);
break;
default:
printf("Well, I could not understand what operation you wanted,
but the numbers that you gave are %s.",
((number1>0)&&(number2>0))?"both positive":
((number1<0)&&(number2<0))?"both negative":"...nothing special");
}
printf("Make a choice:\n0.Exit\n1.Continue");
scanf("%i",&choice);
} /*Τελειώνει η while*/
return 0;
}
do..while
[επεξεργασία]Η εντολή do..while, χρησιμοποιείτε όταν επίσης δεν γνωρίζουμε τον αριθμό των επαναλήψεων, αλλά θέλουμε το μπλοκ εντολών μας να εκτελεστεί τουλάχιστον μία φορά. Φυσικά ακόμα και αν γνωρίζουμε τον αριθμό των επαναλήψεων, και πάλι μπορούμε να προσαρμόσουμε τον κώδικά μας. Η γενική σύνταξη της είναι η εξής:
do
{
statements;
}while(expr);
Παράδειγμα
[επεξεργασία]Και πάλι θα χρησιμοποιήσουμε το ίδιο παράδειγμα, με την διαφορά της επαναληπτικής εντολής. Συγκρίνετε αυτό τον κώδικα με τον ανωτέρω και προσπαθείστε να βρείτε πιο από τα δύο είναι πιο ελαφρύ, και μας συμφέρει να χρησιμοποιήσουμε.
#include <stdio.h>
int main()
{
int choice,n1,n2;
char op;
do
{
printf("Make a choice:\n0.Exit\n1.Continue"); /*Εδώ είναι η διαφορά που μας ενδιαφέρει*/
scanf("%i",&choice); /*με το προηγούμενο παράδειγμα*/
printf("Enter the first number:");
scanf("%i",&number1);
printf("\nEnter the second number:");
scanf("%i",&number2);
printf("\nEnter the operation you wish to make (+,-,*,/):");
scanf("%c",&op);
switch(op){
case '+':
printf("%i + %i:%i",n1,n2,n1+n2);
break;
case '-':
printf("%i - %i:%i",n1,n2,n1-n2);
break;
case '*':
printf("%i * %i:%i",n1,n2,n1*n2);
break;
case '/':
printf("%i + %i:%i,%i",n1,n2,n1/n2,n1%n2);
break;
default:
printf("Well, I could not understand what operation you wanted,
but the numbers that you gave are %s.",
((number1>0)&&(number2>0))?"both positive":
((number1<0)&&(number2<0))?"both negative":"...nothing special");
}
}while(choice!=0);
return 0;
}
Τελικώς κανένα από τα δύο δεν είναι πιο βαρύ, αφού και οι δύο εντολες επανάληψης συγκρίνουν μόνο 1 μεταβλητή. Η διαφορά τους είναι στο ότι με την do..while είναι πιο κατανοητό αφού χρειάζεται μόνο μία φορά η εκτύπωση του κατάλογου επιλογών. Επίσης το 2ο είναι και πιο μικρό σε μέγεθος παρ'όλο που σε ταχύτητα προσπέλασης δεν διαφέρει.
for
[επεξεργασία]Η for συνήθως χρησιμοποιείται για έναν συγκεκριμένο αριθμό επαναλήψεων. Ωστόσο είναι δυνατό να αντικαταστήσει και τις δύο προηγούμενες με συγκεκριμένα expressions και εντολές (statements). Ακολουθεί η γενική σύνταξή της.
for(expr1;expr2;expr3)
statement; /*Μία εντολή*/
for(expr1;expr2;expr3)
{
statements; /*Πολλές εντολές*/
}
- Το expr1 εκτελείται μία φορά στην αρχή της for. Εδώ συνήθως κάνουμε αναθέσεις τιμών σε μεταβλητές γνωστές ως index variables.
- Το expr2 είναι η συνθήκη (if) σύμφωνα με την οποία το μπλοκ εντολών θα εκτελεστεί ή όχι. Όσο είναι true εκτελείται. Συνήθως, το expr2 χρησιμοποιεί την index variable για να καταλάβει αν έχει τρέξει ο αριθμός των επαναλήψεων που θέλουμε. Αν είναι κενό θεωρείται αληθές(true ή 1) οπότε το μπλοκ εκτελείται συνέχεια εκτός αν συναντήσει μία εντολή break ή κάποιο λάθος.
- Το expr3 είναι συνήθως μια τροποποίηση της τιμής της index variable. Αναφέρεται ως post expression, καθώς είναι το τελευταίο που θα εκτελεστεί με το πέρας της κάθε επανάληψης.
Όλα τα παραπάνω expressions μπορούν να μείνουν κενά. Ωστόσο τα semicolons (ερωτηματικά ";") θα πρέπει να παραμείνουν. Επιπλέον μπορείτε να προσθέσετε τον τελεστή comma (,) μέσα στα expressions. Με αυτό θα εκτελεστούν μεν όλες οι εντολές, αλλά μόνο η τελευταία θα δώσει το αποτέλεσμα του expression.
Προσοχή:Στα παραπάνω expressions θα προσέξατε την χρήση της λέξης "συνήθως". Κανείς δεν μας απαγορεύει την χρήση αυτών για άλλες χρήσεις, αρκεί να υπακούουν τους κανόνες της C για τα expressions.
Καλό θα ήταν να κατανοήσετε την σύνταξη της εντολής της for. Είναι πηγή πολλών προβλημάτων που σίγουρα θα αντιμετωπίσετε στο μέλλον. Η ευελιξία που μας δίνει η C είναι τεράστια, και μπορεί χωρίς να το καταλάβετε να δημιουργήσετε ένα infinite loop (ατέρμονη επανάληψη), που θα γονατίσει τον ηλεκτρονικό σας υπολογιστή, και θα χρειαστεί να την διακόψετε δια βίας, με ότι αυτό συνεπάγεται την δεδομένη στιγμή που θα γίνει (μην ξεχνάτε να αποθηκεύετε την εργασία σας, και να κρατάτε αντίγραφα διαφορετικών εκδόσεων).
Παράδειγμα
[επεξεργασία]#include <stdio.h>
int main()
{
int choice,n1,n2;
char op;
for(;choice!=0;)
{
printf("Make a choice:\n0.Exit\n1.Continue"); /*Εδώ είναι η διαφορά που μας ενδιαφέρει*/
scanf("%i",&choice); /*με το προηγούμενο παράδειγμα*/
printf("Enter the first number:");
scanf("%i",&number1);
printf("\nEnter the second number:");
scanf("%i",&number2);
printf("\nEnter the operation you wish to make (+,-,*,/):");
scanf("%c",&op);
switch(op){
case '+':
printf("%i + %i:%i",n1,n2,n1+n2);
break;
case '-':
printf("%i - %i:%i",n1,n2,n1-n2);
break;
case '*':
printf("%i * %i:%i",n1,n2,n1*n2);
break;
case '/':
printf("%i + %i:%i,%i",n1,n2,n1/n2,n1%n2);
break;
default:
printf("Well, I could not understand what operation you wanted,
but the numbers that you gave are %s.",
((number1>0)&&(number2>0))?"both positive":
((number1<0)&&(number2<0))?"both negative":"...nothing special");
}
}
return 0;
}
Περισσότερα παραδείγματα
[επεξεργασία]Ας δούμε μερικές ακόμα δυνατότητες της for. Όλα τα παρακάτω παραδείγματα εμφανίζουν το ίδιο αποτέλεσμα στην οθόνη.
1.
for(i=1;i<=5;i=i+1)
printf("%d\n",i);
|
2.
for(i=1;i<=5;i+=1)
printf("%d\n",i);
|
3.
for(i=1;i<=5;i++)
printf("%d\n",i);
|
4.
for(i=1;i<=5;)
{
printf("%d\n",i);
i++;
}
|
5.
for(i=1;i<=5;)
printf("%d\n",i++);
|
6.
i=1;
for(;i<=5;)
printf("%d\n",i++);
|
7.
for(i=1;i<=5;printf("%d\n",i++));
|
8.
for(i=1;i<=5;printf("%d\n",i),i++);
|
9.
for(i=1;(printf("%d\n",i),i++<5););/*Προσέξτε πως πρώτα γίνεται η σύγκριση i<5, και μετά το i++*/
Και υπάρχουν και άλλοι ακόμα τρόποι, αλλά αυτοί αρκούνε για να καταλάβετε πως ένας απλός κανονισμός δημιουργεί τόσες πολλές δυνατότητες.
Nested Loops
[επεξεργασία]Δεν θα είναι λίγες οι φορές που θα χρησιμοποιήσετε επαναληπτικές εντολές μέσα σε άλλες επαναληπτικές εντολές. Στην περίπτωση αυτή, για κάθε επανάληψη της εξωτερικής εντολής, η εσωτερική θα κάνει όλες τις τις επαναλήψεις. Ας το δούμε με ένα παράδειγμα.
Οθόνη | | | i | j | |
---|---|---|---|---|
1 | 1 | | | 1 | 1 |
1 | 2 | | | 1 | 2 |
| | 1 | 3 | ||
2 | 1 | | | 2 | 1 |
2 | 2 | | | 2 | 2 |
| | 2 | 3 | ||
3 | 1 | | | 3 | 1 |
3 | 2 | | | 3 | 2 |
| | 3 | 3 | ||
| | 4 | 1 |
for (i=1;i<=3;i++){
for(j=1;j<=2;j++){
printf("%d %d\n",i,j);
}
}
Είναι σημαντικό να κατανοήσετε το τι θα εμφανίζεται στην οθόνη, και τι τιμές θα έχουν οι μεταβλητές, αφού οι διαφορές είναι μεγάλες, και αν μας διαφύγει κάτι, η συνέχεια του προγράμματος δεν θα είναι η προσδοκώμενη.
Ασκήσεις
[επεξεργασία]- . Να δημιουργηθεί το εξής πρόγραμμα. Θα εκτυπώνει όλους τους αριθμούς της ακολουθίας Φιμπονάτσι, το έναν κάτω από τον άλλον, μέχρι το 1000.[1][2]
- . Να δημιουργηθεί το εξής πρόγραμμα. Το πρόγραμμα θα ζητάει τα ονόματα δύο παικτών και θα τους προσφωνεί με αυ΄τα. Ένας παίκτης θα δίνει έναν ακέραιο αριθμό από το 1 έως το 100, και αφού η οθόνη καθαριστεί ( clrscr() ), ένας δεύτερος παίκτης θα προσπαθεί να μαντέψει αυτόν τον αριθμό. Σε κάθε προσπάθεια του παίκτη2, το πρόγραμμα θα τον ενημερώνει αν ο αριθμός που έδωσε είναι μικρότερος ή μεγαλύτερος από τον ζητούμενο. Σε περίπτωση που ο παίκτης1 καθορίσει αριθμό εκτός του ορίου 1 έως 100, το πρόγραμμα να τον ενημερώνει, και να ξαναζητάει τιμές. Επίσης ο παίκτης1 θα καθορίζει τον μέγιστο αριθμό προσπαθειών. Τέλος το πρόγραμμα θα ρωτάει αν οι παίκτες θέλουν να ξαναπαίξουν (y/n).
Συμβουλή: Μην προσπαθείσετε να φτιάξετε όλο τον κώδικα μονομιάς. Αρχίστε με τα βασικά, όπως χωρίς να προσφονεί τους παίκτες, να δέχεται τον αριθμό, να καθαρίζει την οθόνη, και να απαντάει στις προσπάθειες του παίκτη2. Μετά αρχίστε να κάνετε τις παραμετροποιήσεις που χρειάζεστε.
Σημειώσεις
[επεξεργασία]Προηγούμενη Ενότητα |
Περιεχόμενα | Επόμενη Ενότητα |