Αρχές Προγραμματισμού https://eclass.upatras.gr/courses/ee806/index.php Βασίλης Παλιουράς paliuras@ece.upatras.gr Μέχρι τώρα Μεθοδολογία Αυξητική ανάπτυξη Top-down Δομημένος προγραμματισμός Οργάνωση προγράμματος C Συναρτήσεις Δηλώσεις ονομάτων Έλεγχος ροής προγράμματος Βρόχοι επανάληψης Επιλογή if ( ) { { break, continue, goto 2 1
Διακλάδωση: if (συνθήκη) {εντολές1 {εντολές2 συνθήκη!=0 true συνθήκη συνθήκη = = 0 false εντολές1 εντολές2 3 if (/* */) /* */ /* */ if (έκφραση) (σύνθετη) εντολή 1; (σύνθετη) εντολή 2; if ( a == 5) { printf ("a is five.\n") ; printf("next line"); printf("a is not five.\n"); 4 2
Nested ifs int a = 5; int b = 6; if (a == 4) printf("a is four.\n"); if (b == 6) printf ("a is not four, but b is six.\n"); printf ("a is not four and b is not six.\n"); 5 int getinput(void); int b ; do { b = getinput(); if ( b > 2) continue; printf("b: %d", b); while (b>-1); int getinput(void); int b ; do { b = getinput(); if ( b <= 2) printf("b: %d", b); while (b>-1); int getinput(void) { int a; printf("enter integer:" ); scanf("%d", &a); return a; int getinput(void) { int a; printf("enter integer:" ); scanf("%d", &a); return a; 6 3
Τα { βοηθούν int a = 5; int b = 6; if (a == 4) printf("a is four.\n"); { if (b == 6) printf ("a is not four, but b is six.\n"); printf ("a is not four and b is not six.\n"); 7 Παράδειγμα #include <stdlib.h> int getuserresponse(void); void square(void); void triangle(void); int getuserresponse(void) { int a; printf("enter choice:\n"); scanf("%d", &a); int main(void) { int answer; return a; while((answer=getuserresponse())!=3){ if (answer==1) square (); if (answer==2) triangle(); void square(void) { printf("square\n"); void triangle(void) { printf("triangle\n"); 8 4
switch switch (έκφραση) { case τιμή1: εντολές; break; case τιμή1: λειτουργεί ως case τιμή2: εντολές; break; label case τιμή3: εντολές; break; /* */ default: εντολές; break; break: μεταφέρει τον έλεγχο τι γίνεται χωρίς break εκτός του switch () { 9 Παράδειγμα switch #include <stdlib.h> int getuserresponse(void); void square(void); void triangle(void); int getuserresponse(void) { int a; printf("enter choice:\n"); scanf("%d", &a); int main(void) { int answer; return a; while((answer=getuserresponse())!=3){ switch (answer) { case 1: square (); break; case 2: triangle(); break; void square(void) { printf("square\n"); void triangle(void) { printf("triangle\n"); 10 5
Εικασία του Collatz (1937) Ανεξάρτητα από ποιο θετικό ακέραιο n ξεκινήσει, η ακολουθία θα φθάσει στο 1. Μετά από πόσα βήματα; 11 Να κατασκευάσετε πρόγραμμα Να υπολογίζει το φυσικό αριθμό εκκίνησης ο οποίος είναι μικρότερος του 1000 και παρέχει τη μεγαλύτερη ακολουθία μέχρι να φτάσει στον αριθμό 1. Να τυπώνει τα στοιχεία της ακολουθίας μέγιστου μήκους, η οποία βρέθηκε. 12 6
Λύνουμε ένα μικρό παράδειγμα στο χαρτί. Εντοπίζουμε τα βήματα με τα οποία λύνουμε το πρόγραμμα στο χαρτί Γράφουμε μια δομημένη λεκτική περιγραφή. Γράφουμε κώδικα. 13 Για κάθε θετικό ακέραιο αριθμό μικρότερο του 1000: Υπολόγισε το μήκος της ακολουθίας που αντιστοιχεί στον αριθμό Είναι το μεγαλύτερο που έχεις βρει; Αν ναι: Σημείωσε τον αριθμό και το μήκος ακολουθίας Τύπωσε τον αριθμό που βρήκες Τύπωσε τα στοιχεία της ακολουθίας 14 7
int i j; int elems; int maxelems = 0; int maxi ; for (i=2; i<1000; i++) { j = i; elems = 0; while (j>1) { if (j%2==0) j =j /2; j = 3*j + 1; elems ++; if (elems>maxelems) { maxelems = elems; maxi = i; printf("max i: %d\n", maxi); j = maxi; while (j>1) { if (j%2==0) j =j /2; j = 3*j + 1; printf("%d\n", j); Για κάθε αριθμό i μικρότερο του 1000 Κατασκεύασε τα στοιχεία της ακολουθίας ξεκινώντας από το i μέχρις ότου φτάσεις στην τιμή 1, και μέτρα πλήθος στοιχείων Αν ο αριθμός i δίνει τα περισσότερα Στοιχεία, σημείωσε το πλήθος στοιχείων Και τον αριθμό i Κατασκεύασε τα στοιχεία της ακολουθίας ξεκινώντας από το maxi μέχρις ότου φτάσεις στην τιμή 1, και τύπωσε τα στοιχεία 15 int sequence(int ); Συνάρτηση που επιστρέφει το πλήθος των στοιχείων της ακολουθίας, ξεκινώντας από το όρισμά της int i,j; int elems; int maxelems = 0; int maxi ; for (i=2; i<1000; i++) { elems = sequence(i); if (elems>maxelems) { maxelems = elems; maxi = i; printf("max i: %d\n", maxi); j = maxi; while (j>1) { if (j%2==0) j =j /2; j = 3*j + 1; printf("%d\n", j); int sequence(int j) { int elems = 0; while (j>1) { if (j%2==0) j =j /2; j = 3*j + 1; elems ++; return elems; Παρόμοιος κώδικας: Στη μία περίπτωση υπολογίζει Πλήθος στοιχείων Στην άλλη περίπτωση τυπώνει τα στοιχεία 16 8
int sequence(int, int ); int i; int elems; int maxelems = 0; int maxi ; for (i=2; i<1000; i++) { elems = sequence(i, 0); if (elems>maxelems) { maxelems = elems; maxi = i; printf("max i: %d\n", maxi); int sequence(int j, int p) { int elems = 0; while (j>1) { if (j%2==0) j =j /2; j = 3*j + 1; if (p==1) printf("%d\n", j); elems ++; return elems; Αποφεύγω την επανάληψη κώδικα Όταν p==1 η συνάρτηση τυπώνει τα στοιχεία, αλλιώς όχι. sequence(maxi,1); 17 #define NOPRINT 0 #define PRINT 1 int sequence(int, int ); int i; int elems; int maxelems = 0; int maxi ; for (i=2; i<1000; i++) { elems = sequence(i, NOPRINT); if (elems>maxelems) { maxelems = elems; maxi = i; printf("max i: %d\n", maxi); sequence(maxi, PRINT); int sequence(int j, int p) { int elems = 0; while (j>1) { if (j%2==0) j = j /2; j = 3*j + 1; if (p == PRINT) printf("%d\n", j); elems ++; return elems; Ορίζοντας και χρησιμοποιώντας τα PRINT και NOPRINT Η λειτουργία του κώδικα τεκμηριώνεται σαφέστερα. 18 9
Αντιμετώπιση bottom-up int next_collatz(int n); printf("%d\n", next_collatz(3)); int next_collatz(int n) { if (n % 2==0) return n/2; return 3*n + 1; Πρώτα δοκιμάζουμε ότι Μπορούμε να υπολογίσουμε Σωστά επόμενα στοιχεία της ακολουθίας 19 int next_collatz(int n); int derivesequence(int n); derivesequence(10); int derivesequence(int n) { printf("%d\n", n); while (n>1) { n = next_collatz(n); printf("%d\n", n); int next_collatz(int n) { if (n % 2==0) return n/2; return 3*n + 1; Μετά τυπώνουμε τα Στοιχεία της ακολουθίας Από δοθέν n, μέχρι να Προκύψει στοιχείο με τιμή 1 Το εκτελούμε και βλέπουμε ότι Δουλεύει σωστά! 20 10
int next_collatz(int n); int derivesequence(int n); printf("length: %d\n", derivesequence(10)); int derivesequence(int n) { int count = 1; printf("%d\n", n); while (n>1) { n = next_collatz(n); count ++; printf("%d\n", n); return count; int next_collatz(int n) { if (n % 2==0) return n/2; return 3*n + 1; Τροποποιούμε την derivesequence ( ) ώστε Να επιστρέφει το πλήθος των στοιχείων από το δοθέν Μέχρι να φτάσει στο 1. Τρέχουμε, δοκιμάζουμε, βλέπουμε ότι δουλεύει. 21 int next_collatz(int n); int derivesequence(int n); int n, maxn, templen, maxlength=0; for (n=1; n<10; n++) { templen = derivesequence(n); if (templen>maxlength) { maxlength=templen; maxn = n; printf("maxn: %d\n", maxn); derivesequence(maxn); Χρησιμοποιούμε την derivesequence για να υπολογίσουμε Το μήκος της κάθε ακολουθίας και να βρούμε το μεγαλύτερο. Δοκιμάζουμε για τιμές που μπορούμε να ελέγξουμε. Παρατηρούμε ότι δεν θέλουμε να τυπώνονται τα στοιχεία όταν 22 Καλείται από το for αλλά θέλουμε στο τέλος 11
int next_collatz(int n); int derivesequence(int n, int verbose); int n, maxn, templen, maxlength=0; for (n=1; n<1000; n++) { templen = derivesequence(n, 0); if (templen>maxlength) { maxlength=templen; maxn = n; printf("maxlen: %d\n", derivesequence(maxn, 1)); printf("maxn: %d\n", maxn); int derivesequence(int n, int verbose) { int count = 1; if (verbose) printf("%d\n", n); while (n>1) { n = next_collatz(n); count ++; if (verbose) printf("%d\n", n); return count; 23 Να γραφεί ένα πρόγραμμα σε C το οποίο να τυπώνει στην οθόνη το σχήμα 24 12
Τύπωσε μια γραμμή από 10 αστέρια * και άλλαξε γραμμή Τύπωσε οκτώ γραμμές με πρώτο χαρακτήρα *, οκτώ κενά, και * και άλλαξε γραμμή Τύπωσε μια γραμμή από 10 αστέρια * και άλλαξε γραμμή 25 Ποιο είναι το ζήτημα με τον κώδικα αυτό; int main() { printf("**********\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("**********\n"); 26 13
int main() { int i; printf("**********\n"); for (i=0;i<8;i++) printf("* *\n"); printf("**********\n"); 27 Για 10 γραμμές { Αν είναι η πρώτη ή η τελευταία γραμμή Τύπωσε δέκα * και άλλαξε γραμμή Διαφορετικά Τύπωσε ένα *, οκτώ κενά, ένα * και άλλαξε γραμμή 28 14
void printline(char); int main() { int i; for (i=0;i<10;i++) { if (i==0 i ==9) printline('*'); printline(' '); void printline(char p) { int i ; printf("*"); for (i=0;i<8;i++) printf("%c",p); printf("*\n"); 29 Διάβασε πλήθος γραμμών, len Για len γραμμές { Αν είναι η πρώτη ή η len - 1 γραμμή Τύπωσε len * και άλλαξε γραμμή Διαφορετικά Τύπωσε ένα *, len - 2 κενά, ένα * και άλλαξε γραμμή 30 15
void printline(char, int); int main() { int i; int len; scanf("%d", &len); for (i=0;i<len;i++) { if (i==0 i ==len-1) printline('*', len); printline(' ', len); void printline(char p, int n) { int i ; printf("*"); for (i=0;i< n - 2;i++) printf("%c",p); printf("*\n"); 31 16