ΕΙΣΑΓΩΓΗ ΣΤΟΝ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ Ενδεικτικές Απαντήσεις Εξετάσεων Β' Περιόδου 2011 Θέµα 1 (α') Η άποψη που εκφράζεται στην εν λόγω πρόταση είναι λανθασµένη. Η πιθανή βελτίωση της ταχύτητας εκτέλεσης των προγραµµάτων λόγω χρήσης εξωτερικών/καθολικών µεταβλητών, για τον περιορισµό των ορισµάτων των συναρτήσεων, είναι αµελητέα µπροστά στη βλάβη που προκαλείται στην αναγνωσιµότητα και συντηρησιµότητα των προγραµµάτων λόγω της χρήσης αυτής. (β') Η εντολή break τερµατίζει βιαίως τη δοµή επανάληψης µέσα στην οποία βρίσκεται, ενώ η εντολή continue τερµατίζει µόνο την τρέχουσα επανάληψη και ο έλεγχος προχωρά στην επόµενη. Ένα παράδειγµα τµήµατος κώδικα: x = 0; for (i = 0 ; i < 10 ; i++) { if (i % 2) continue; if (i > 6) break; x++; printf("%d\n", x); Το παραπάνω τµήµα κώδικα θα εκτυπώσει την τιµή 4. Για τα περιττά i, παρακάµπτεται η επανάληψη και για i από το 7 και µετά, διακόπτεται. Οπότε, η εντολή x++ θα εκτελεσθεί µόνο για i = 0, 2, 4, 6. (γ') Μπορούµε, εκµεταλλευόµενοι οδηγίες προς τον προεπεξεργαστή, να περικλείσουµε το τµήµα κώδικα που θέλουµε να σχολιάσουµε µέσα σε: #if 0... #endif (δ') #define square(n) ((n)*(n)) int bigmod(int b, int p, int m) { int bm; if (p == 0) else if (p % 2 == 0) { bm = bigmod(b, p/2, m); return square(bm) % m; else return ((b % m) * bigmod(b, p-1, m)) % m;
Θέµα 2 (α') void print_inorder(treeptr p) { if (p!= NULL) { print_inorder(p->left); printf("%d ", p->value); print_inorder(p->right); (β') void print_paths(treeptr p) { int path[1000]; print_paths_recur(p, path, 0); void print_paths_recur(treeptr p, int path[], int length) { if (p!= NULL) { path[length] = p->value; length++; if (p->left == NULL && p->right == NULL) print_a_path(path, length); else { print_paths_recur(p->left, path, length); print_paths_recur(p->right, path, length); void print_a_path(int path[], int length) { int i; for (i = 0 ; i < length ; i++) printf("%d ", path[i]);
Θέµα 3 #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { int i, j, n, maxnd, nd; if (argc == 1) n = atoi(argv[1]); maxnd = 0;/* Αρχικοποίηση µέχρι στιγµής µεγίστου αθροίσµατος διαιρετών */ for (i = 1 ; i <= n ; i++) { /* Επανάληψη για κάθε i από 1 έως n */ nd = 1; /* Αρχικοποίηση πλήθους διαιρετών του i (το i διαιρεί το i) */ for (j = 1 ; j <= i/2 ; j++) /* Επανάληψη για κάθε πιθανό διαιρέτη */ if (i % j == 0) nd++; /* Βρέθηκε νέος διαρέτης, αύξησε το πλήθος τους */ if (nd > maxnd) { /* Αν το τρέχον πλήθος διαιρετών είναι µεγαλύτερο */ printf("%d ", i); /* από το µέχρι στιγµής µέγιστο, εκτύπωσε το i */ maxnd = nd; /* και ενηµέρωσε το µέχρι στιγµής µέγιστο πλήθος */ return 0;
Θέµα 4 #include <stdio.h> #include <stdlib.h> /* Αποσχολιάστε την παρακάτω γραµµή για την έκδοση µε κατακόρυφη εκτύπωση */ /* #define VERT */ #ifndef VERT int main(int argc, char *argv[]) /* Έκδοση µε οριζόντια εκτύπωση */ { int i, j, k, n, m, g, aliven; char ch, ***grid; /* Ορίζουµε έναν 3-διάστατο πίνακα, αφού θα χρειαστούµε στο τέλος όλες τις καταστάσεις για να τις εκτυπώσουµε οριζόντια */ if (argc!= 4) n = atoi(argv[1]); m = atoi(argv[2]); g = atoi(argv[3]); if ((grid = malloc((g+1) * sizeof(char **))) == NULL) for (i = 0 ; i <= g ; i++) { if ((grid[i] = malloc(n * sizeof(char *))) == NULL) for (j = 0 ; j < n ; j++) if ((grid[i][j] = malloc(m * sizeof(char))) == NULL) printf("please, give initial state\n"); for (j = 0 ; j < n ; j++) { /* Είσοδος αρχικής κατάστασης από το stdin */ for (k = 0 ; k < m ; k++) { ch = getchar(); if (ch!= 'X' && ch!= '.') grid[0][j][k] = ch; getchar(); for (i = 1 ; i <= g ; i++) for (j = 0 ; j < n ; j++) for (k = 0 ; k < m ; k++) { aliven = 0; grid[i][j][k] = grid[i-1][j][k]; /* Αντιγραφή τρέχουσας κατάστασης στην επόµενη */ /* Μέτρησε τους ζωντανούς γείτονες του τρέχοντος κυττάρου */ if (k < m-1 && grid[i-1][j][k+1] == 'X') aliven++; if (j < n-1 && grid[i-1][j+1][k] == 'X') aliven++; if (k > 0 && grid[i-1][j][k-1] == 'X') aliven++; if (j > 0 && grid[i-1][j-1][k] == 'X') aliven++; if (k < m-1 && j < n-1 && grid[i-1][j+1][k+1] == 'X') aliven++; if (k < m-1 && j > 0 && grid[i-1][j-1][k+1] == 'X') aliven++; if (k > 0 && j < n-1 && grid[i-1][j+1][k-1] == 'X') aliven++; if (k > 0 && j > 0 && grid[i-1][j-1][k-1] == 'X') aliven++; if ((aliven < 2 aliven > 3) && grid[i-1][j][k] == 'X') grid[i][j][k] = '.'; /* Το τρέχον κύτταρο πεθαίνει */ if (aliven == 3 && grid[i-1][j][k] == '.') grid[i][j][k] = 'X'; /* Το τρέχον κύτταρο αναγεννάται */ for (i = 0 ; i <= g ; i++) { /* Εκτύπωση όλων των καταστάσεων */ printf("state %-2d", i); if (i < g) { printf(" --> "); for (k = 0 ; k <= m-13; k++) putchar(' ');
for (j = 0 ; j < n ; j++) { for (i = 0 ; i <= g ; i++) { if (i > 0) { putchar(' '); for (k = 0 ; k <= 11-m ; k++) putchar(' '); for (k = 0 ; k < m ; k++) putchar(grid[i][j][k]); for (i = 0 ; i < g ; i++) { for (j = 0 ; j < n ; j++) free(grid[i][j]); free(grid[i]); free(grid); return 0; #else int main(int argc, char *argv[]) /* Έκδοση µε κατακόρυφη εκτύπωση */ { int i, j, st, n, m, g, aliven; char ch, **grid, **newgrid, **temp; /* Ορίζουµε δύο 2-διάστατους πίνακες, για να κρατάµε την τρέχουσα κατάσταση και την επόµενή της */ if (argc!= 4) n = atoi(argv[1]); m = atoi(argv[2]); g = atoi(argv[3]); if ((grid = malloc(n * sizeof(char *))) == NULL) if ((newgrid = malloc(n * sizeof(char *))) == NULL) for (i = 0 ; i < n ; i++) { if ((grid[i] = malloc(m * sizeof(char))) == NULL) if ((newgrid[i] = malloc(m * sizeof(char))) == NULL) printf("please, give initial state\n"); for (i = 0 ; i < n ; i++) { /* Είσοδος αρχικής κατάστασης από το stdin */ for (j = 0 ; j < m ; j++) { ch = getchar(); if (ch!= 'X' && ch!= '.') grid[i][j] = ch; getchar(); for (st = 0 ; st <= g ; st++) { printf("\nstate %d\n", st); /* Εκτύπωση τρέχουσας κατάστασης */ for (i = 0 ; i < n ; i++) { for (j = 0 ; j < m ; j++) printf("%c", grid[i][j]); for (i = 0 ; i < n ; i++) for (j = 0 ; j < m ; j++) { aliven = 0; newgrid[i][j] = grid[i][j]; /* Αντιγραφή τρέχουσας κατάστασης στην επόµενη */ /* Μέτρησε τους ζωντανούς γείτονες του τρέχοντος κυττάρου */
if (j < m-1 && grid[i][j+1] == 'X') aliven++; if (i < n-1 && grid[i+1][j] == 'X') aliven++; if (j > 0 && grid[i][j-1] == 'X') aliven++; if (i > 0 && grid[i-1][j] == 'X') aliven++; if (j < m-1 && i < n-1 && grid[i+1][j+1] == 'X') aliven++; if (j < m-1 && i > 0 && grid[i-1][j+1] == 'X') aliven++; if (j > 0 && i < n-1 && grid[i+1][j-1] == 'X') aliven++; if (j > 0 && i > 0 && grid[i-1][j-1] == 'X') aliven++; if ((aliven < 2 aliven > 3) && grid[i][j] == 'X') newgrid[i][j] = '.'; /* Το τρέχον κύτταρο πεθαίνει */ if (aliven == 3 && grid[i][j] == '.') newgrid[i][j] = 'X'; /* Το τρέχον κύτταρο αναγεννάται */ temp = grid; /* Επόµενη κατάσταση είναι η τρέχουσα */ grid = newgrid; newgrid = temp; for (i = 0 ; i < n ; i++) { free(grid[i]); free(newgrid[i]); free(grid); free(newgrid); return 0; #endif