Προγραμματισμός Ι Παράδειγμα: Παράδειγμα:Να γραφεί πρόγραμμα που να δέχεται ως είσοδο κείμενο, να απαριθμεί τις εμφανίσεις των ψηφίων 0-9, τα λευκά διαστήματα και τους υπόλοιπους χαρακτήρες και στη συνέχεια να τυπώνει τα αποτελέσματα. Το πρόγραμμα ολοκληρώνεται όταν δοθεί ο χαρακτήρας τελεία ‘.’.Λύση: δομημένα Ελληνικά Το παραπάνω πρόβλημα μπορεί να μορφοποιηθεί σε δομημένα Ελληνικά ως εξής: Για κάθε χαρακτήρα του κειμένου που είναι διάφορος τής ‘.’ έλεγξε τον τύπο του χαρακτήρα έλεγξε τον τύπο του χαρακτήρα αν είναι ένας από τους ’ ’, ’\t’, ’\n’ αν είναι ένας από τους ’ ’, ’\t’, ’\n’ αύξησε τον απαριθμητή των διαστημάτων αύξησε τον απαριθμητή των διαστημάτων αν είναι ψηφίο αν είναι ψηφίο αύξησε τον απαριθμητή που αντιστοιχεί στο ψηφίο αύξησε τον απαριθμητή που αντιστοιχεί στο ψηφίο σε κάθε άλλη περίπτωση σε κάθε άλλη περίπτωση αύξησε τον απαριθμητή των υπόλοιπων χαρακτήρων αύξησε τον απαριθμητή των υπόλοιπων χαρακτήρων
Προγραμματισμός Ι Αναπαράσταση δεδομένων: Όσον αφορά τις μεταβλητές απαιτείται: n_white 1) Ένας απαριθμητής για τα διαστήματα, τον οποίο ονομάζουμε n_white. n_other 2) Ένας απαριθμητής για τους λοιπούς χαρακτήρες, ο n_other, και δέκα απαριθμητές για τα ψηφία. Για την τελευταία περίπτωση μπορούμε να δηλώσουμε δέκα ανεξάρτητες μεταβλητές αλλά είναι προτιμότερο να επιλεχθεί ένας πίνακας δέκα θέσεων, όπως int n_digit[10]; o οποίος οδηγεί σε πιο συμπαγή και δομημένο κώδικα.
Προγραμματισμός Ι Αναπαράσταση δεδομένων: Για την εκτύπωση των αριθμών των εμφανίσεων των δέκα ψηφίων, στην περίπτωση του πίνακα απαριθμητών, ο αντίστοιχος κώδικας θα έχει τη μορφή for (i=0;i<10;i++) for (i=0;i<10;i++) printf(“To ψηφίο %d εμφανίσθηκε \t %d \t φορές\n”,i,n_digit[i]); printf(“To ψηφίο %d εμφανίσθηκε \t %d \t φορές\n”,i,n_digit[i]); Αναλογιστείτε τον κώδικα για την περίπτωση 10 ανεξάρτητων μεταβλητών!!!
Προγραμματισμός Ι Αναπαράσταση διεργασιών: getchar() Για τη διεργασία πάρε χαρακτήρα χρησιμοποιείται η συνάρτηση getchar(), η οποία επιστρέφει το χαρακτήρα που διαβάζει από την κύρια είσοδο. Αυτός ο χαρακτήρας πρέπει να αποθηκευθεί σε μία μεταβλητή τύπου χαρακτήρα για παραπέρα επεξεργασία. Τα παραπάνω οδηγούν στη δήλωση char ch; και στην έκφρασηch=getchar(); η τιμή της οποίας είναι η τιμή του αριστερού τελεστέου της έκφρασης.
Προγραμματισμός Ι Αναπαράσταση διεργασιών: != Για την ανίχνευση του τέλους του αρχείου χρησιμοποιούμε το συσχετιστικό τελεστή != οδηγούμαστε στην έκφραση (ch=getchar())!=‘.’ (ch=getchar())!=‘.’ while Η έκφραση γίνεται ψευδής όταν αναγνωσθεί ‘.’. Μπορεί επομένως να χρησιμοποιηθεί ως έκφραση μίας πρότασης while, που θα οδηγεί στην επανάληψη του συνόλου των ενεργειών που το πρόγραμμα πρέπει να εκτελεί για κάθε χαρακτήρα.
Προγραμματισμός Ι Διαμόρφωση της ροής ελέγχου: Με βάση τα προηγούμενα, η περιγραφή διαμορφώνεται ως εξής: while ((ch=getchar())!=‘.’) { έλεγξε τον τύπο του χαρακτήρα έλεγξε τον τύπο του χαρακτήρα αν είναι ένας από τους ’ ’, ’\t’, ’\n’ αν είναι ένας από τους ’ ’, ’\t’, ’\n’ αύξησε τον απαριθμητή των διαστημάτων αύξησε τον απαριθμητή των διαστημάτων αν είναι ψηφίο αν είναι ψηφίο αύξησε τον απαριθμητή που αντιστοιχεί στο ψηφίο αύξησε τον απαριθμητή που αντιστοιχεί στο ψηφίο σε κάθε άλλη περίπτωση σε κάθε άλλη περίπτωση αύξησε τον απαριθμητή των υπόλοιπων χαρακτήρων αύξησε τον απαριθμητή των υπόλοιπων χαρακτήρων} while switch ch Το σώμα της while αποτελεί κλασική περίπτωση επιλογής από αμοιβαία αποκλειόμενες ενέργειες, γεγονός που οδηγεί στη χρήση της πρότασης switch. Η έκφραση ανάλογα με την τιμή της οποίας θα γίνει η επιλογή της κατάλληλης ενέργειας είναι η απλή έκφραση ch.
Προγραμματισμός Ι Α) εάν είναι ένας από τους ’ ’, ’\t’, ’\n’ αύξησε τον απαριθμητή n_white αύξησε τον απαριθμητή n_white ή εκφρασμένη στη C case ‘ ’: case ‘\t’: case ‘\n’: n_white++; n_white++; break; break; Β) εάν ο χαρακτήρας είναι ψηφίο αύξησε τον απαριθμητή που αντιστοιχεί στο ψηφίο αύξησε τον απαριθμητή που αντιστοιχεί στο ψηφίο μία πρώτη μορφή του κώδικα είναι η παρακάτω case ‘0’: n_digit++; break; n_digit++; break; case ‘9’: n_white++; break; n_white++; break; Κοινή έξοδος για τις τρεις case
Προγραμματισμός Ι case O κώδικας αυτός δεν εκμεταλλεύεται τη δήλωση των απαριθμητών των ψηφίων ως πίνακα χαρακτήρων. Για το λόγο αυτό, θα προσπαθήσουμε να ενοποιήσουμε τα case ώστε να έχουν μία παραμετρική πρόταση, που σε κάθε περίπτωση θα οδηγεί στην αύξηση του κατάλληλου απαριθμητή. Θεωρούμε την έκφρασηch-’o’ ch{‘0’, ‘1’, …, ‘9’} ch‘0’ 0 και εξετάζουμε την τιμή της για τιμές τής ch από το σύνολο {‘0’, ‘1’, …, ‘9’}. Είναι προφανές ότι, εάν το ch είναι ‘0’, η έκφραση έχει τιμή 0 οπότε και η πρότασηn_digit[ch-’0’]++; ‘0’ έχει ως αποτέλεσμα την αύξηση του απαριθμητή που αντιστοιχεί στο ψηφίο ‘0’. ch=‘8’ ‘0’ Αντίστοιχα, η παραπάνω πρόταση για ch=‘8’ θα αυξήσει τον απαριθμητή που νατιστοιχεί στο ‘0’. Κατά αυτόν τον τρόπο οδηγούμαστε στον ακόλουθο συμπαγή κώδικα:
Προγραμματισμός Ι case ‘0’: case ‘1’: …… case ‘9’: n_digit[ch-’0’]++; n_digit[ch-’0’]++; break; break; Γ) Γ) Για τα υπόλοιπα στοιχεία έχουμε την κλασική περίπτωση χρήσης της εντολής default, οπότε προκύπτει:default: n_other++; n_other++; break; break; Το τελευταίο σημείο που πρέπει να προσεχθεί είναι η αρχικοποίηση των μεταβλητών. Κοινή έξοδος για τις δέκα case
Προγραμματισμός Ι Oλοκληρώστε τον πηγαίο κώδικα και εκτελέστε το πρόγραμμα για έλεγχο της λειτουργίας του.
Προγραμματισμός Ι Παράδειγμα: Παράδειγμα:Να βρεθούν τα σφάλματα του ακόλουθου προγράμματος καθώς και τα σημεία στα οποία θα μπορούσαν να γίνουν βελτιώσεις. #include #include main () { int a, b; int a, b; do do { printf (“Correspond the integers 1-5 to letters A-E\n"); printf (“Correspond the integers 1-5 to letters A-E\n"); printf (“Give an integer within [1 5] "); scanf ("%i",&b); printf (“Give an integer within [1 5] "); scanf ("%i",&b); switch (b) switch (b) { case (1): case (1): printf ("A\n"); printf ("A\n"); break; break; case (2): case (2): printf ("B"); printf ("B"); break; break; printf ("\nCorrespond …"); Έτσι όπως είναι δομημένο χρειάζεται printf ("\nCorrespond …"); printf()switch \n σε όλες τις printf() της switch χρειάζεται \n για καλύτερο αισθητικό αποτέλεσμα
Προγραμματισμός Ι case (3): printf ("C"); printf ("C"); break; break; case (4): case (4): printf ("D"); printf ("D"); break; break; case (5): case (5): printf ("E"); printf ("E"); break; break; default: default: printf ("Ektos orion"); printf ("Ektos orion"); } } // τέλος της switch printf (“Press 1 to continue"); printf (“Press 1 to continue"); scanf ("%i",&a); scanf ("%i",&a); } while (a!='1'); } while (a!='1'); // τέλος της do-while } } // τέλος της main() break Να μπει break, είναι καλύτερη προγραμματιστική τακτική Σφάλμα πρώτο Σφάλμα δεύτερο
Προγραμματισμός Ι Σφάλματα: 1‘1’ 1) Έπρεπε να μπει 1 κι όχι ‘1’, γιατί η μεταβλητή είναι τύπου ακεραίου. while (a= = 1)while (a! = 1) 2) Η συνθήκη είναι while (a= = 1) κι όχι while (a! = 1), εφόσον η πληκτρολόγηση του 1 συνεπάγεται εκτέλεση εκ νέου του βρόχου.