ΔΟΜΗΜΕΝΟΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Μάθημα 4ο Τμήμα Διοίκησης Επιχειρήσεων α εξάμηνο Β. Φερεντίνος
Συναρτήσεις (functions) 56 Τεμαχισμός του προγράμματος σε μικρότερα κομμάτια που είναι πιο κατανοητά, πιο εύκολα στην υλοποίηση και στην διαχείριση. Βοηθούν στη λογική σχεδίαση του προγράμματος. Επιτυγχάνουν επαναχρησιμοποίηση κώδικα. Είναι μαύρα κουτιά. Υπάρχουν συναρτήσεις βιβλιοθήκης και συναρτήσεις χρήστη.
57 Δομή συναρτήσεων (ορισμός και υλοποίηση) <τύπος> <όνομα_συνάρτησης>([παράμετροι εισόδου]) [δηλώσεις μεταβλητών] <εντολές> [return μεταβλητή ή έκφραση] float area(float width, float height) float a; a = width * height; return a;
Βήματα δημιουργίας και χρήσης συναρτήσεων Δήλωση συνάρτησης 58 1. Δήλωση των συναρτήσεων (των πρωτοτύπων τους) 2. Κλήση των συναρτήσεων (από άλλες συναρτήσεις ή από τη συνάρτηση main) 3. Ορισμοί των συναρτήσεων και υλοποίησή τους (προηγούμενη διαφάνεια) 1 2 3 ή [1] 3 2 Παράδειγμα δήλωσης: float area(float, float); ή ή float area(float width, float height); float area(float x, float y);
Κλήση των συναρτήσεων 59 για void συναρτήσεις: <όνομα_συνάρτησης>([ορίσματα εισόδου]); για συναρτήσεις που επιστρέφουν κάποια τιμή: <μεταβλητή> = <όνομα_συνάρτησης>([ορίσματα εισόδου]); Παράδειγμα κλήσης: float x = 10, y = 5.5, ar; ar = area(x, y);
Πλήρες παράδειγμα 60 #include <stdio.h> int power(int vasi, int ekthetis); void main() int i,j; printf("δώσε τη βάση και τον εκθέτη:\n"); scanf("%d %d", &i, &j); // ή int power(int, int); δήλωση συνάρτησης printf("το %d εις την %dη ισούται με %d.\n", i, j, power(i,j) ); // κλήση συνάρτησης int power(int vasi, int ekthetis) // ορισμός και // υλοποίηση συνάρτησης int p = 1; for (int i=1; i<=ekthetis; i++) p *= vasi; return p;
Να γραφεί συνάρτηση megistos που να δέχεται 3 ακέραιους και να επιστρέφει το μέγιστο. 61 int megistos(int n1, int n2, int n3) int max; if (n1>n2) max = n1; else max = n2; if (n3>max) max = n3; return max;
Να γραφεί πρόγραμμα που να βρίσκει το μέγιστο από 5 ακέραιους, χρησιμοποιώντας τη συνάρτηση megistos. 62 #include <stdio.h> int megistos(int n1, int n2, int n3); // δήλωση της συνάρτησης void main() int num1, num2, num3, num4, num5; int temp, max; printf("δώσε 5 ακέραιους αριθμούς:\n"); scanf("%d %d %d %d %d", &num1, &num2, &num3, &num4, &num5); temp = megistos(num1, num2, num3); max = megistos(num4, num5, temp); // ο μέγιστος των 3 πρώτων // ο μέγιστος όλων printf("ο μέγιστος είναι ο: %d\n", max);
Εσωτερικές και εξωτερικές μεταβλητές 63 Εσωτερικές ή τοπικές μεταβλητές (local variables) ονομάζονται οι μεταβλητές που ορίζονται μέσα σε μια συνάρτηση. Εξωτερικές ή γενικές μεταβλητές (global variables) ονομάζονται οι μεταβλητές που ορίζονται εκτός συναρτήσεων. Εμβέλεια: ο τμήμα του κώδικα στο οποίο μπορούν να χρησιμοποιηθούν οι μεταβλητές
Παράδειγμα εμβέλειας μεταβλητών 64 #include <stdio.h> int a, b, c; int foo() int x, y;... void main() a = 2*c; b = 2*x;... // εξωτερικές μεταβλητές // τοπικές μεταβλητές // σωστό // λάθος! Η main δεν έχει πρόσβαση στη μεταβλητή x
auto και static τοπικές μεταβλητές 65 auto: οι τιμές των μεταβλητών αυτών χάνονται μετά την ολοκλήρωση της κλήσης της συνάρτησής τους (όταν ξανακληθεί η συνάρτηση αρχικοποιούνται πάλι). static: οι τιμές των μεταβλητών αυτών παραμένουν και μετά την ολοκλήρωση της κλήσης της συνάρτησής τους (όταν ξανακληθεί η συνάρτηση θα έχουν τις τιμές που είχαν με το τέλος της προηγούμενης εκτέλεσης - η αρχικοποίσή τους δεν εκτελείται) Οι τοπικές μεταβλητές που δεν καθορίζονται, εξ ορισμού θεωρούνται auto.
Παράδειγμα auto και static μεταβλητών 66 #include <stdio.h> void foo() int x = 1; auto int y = 1; void main() foo(); foo(); foo(); static int z = 1; printf("x = %d, y = %d, z = %d\n", x, y, z); x++; y++; z++; θα εκτυπώσει: x = 1, y = 1, z = 1 x = 1, y = 1, z = 2 x = 1, y = 1, z = 3
67 Πέρασμα ορισμάτων (μεταβίβαση παραμέτρων) Έστω ότι η συνάρτηση Α καλεί τη συνάρτηση Β(x). Πέρασμα με τιμή (ο ήδη γνωστός τρόπος): Μεταδίδεται η τιμή της μεταβλητής x από τη συνάρτηση Α στη συνάρτηση Β. Αλλαγές στην τιμή του x μέσα στη Β δεν επιστρέφουν στην Α (η τιμή του x στην Α δεν μπορεί να αλλάξει εξ' αιτίας της Β). Πέρασμα με αναφορά: Μεταδίδεται στη Β η θέση μνήμης της μεταβλητής x. Το x αναφέρεται στην ίδια διεύθυνση μνήμης σε Α και Β, άρα αλλαγές στο x στη Β μεταφέρονται και στην Α.
Παράδειγμα μεταβίβασης με τιμή 68 void swap(int a, int b) int temp= a; printf("πριν το swap: a = %d, b = %d\n", a, b); a = b; b = temp; printf("μετά το swap: a = %d, b = %d\n", a, b); void main() int x = 1, y = 2; printf("πριν το swap: x = %d, y = %d\n", x, y); swap(x, y); printf("μετά το swap: x = %d, y = %d\n", x, y); Η swap θα εκτυπώσει: Πριν το swap: a = 1, b = 2 Μετά το swap: a = 2, b = 1 Αλλά η main θα εκτυπώσει: Πριν το swap: x = 1, y = 2 Μετά το swap: x = 1, y = 2
Παράδειγμα μεταβίβασης με αναφορά(1a) 69 void swap(int *a, int *b) int temp= *a; printf("πριν το swap: a = %d, b = %d\n", a, b); *a = *b; *b = temp; printf("μετά το swap: a = %d, b = %d\n", a, b); void main() int x = 1, y = 2; printf("πριν το swap: x = %d, y = %d\n", x, y); swap(&x, &y); printf("μετά το swap: x = %d, y = %d\n", x, y); Η swap θα εκτυπώσει: Πριν το swap: a = 1, b = 2 Μετά το swap: a = 2, b = 1 Τώρα η main θα εκτυπώσει: Πριν το swap: x = 1, y = 2 Μετά το swap: x = 2, y = 1
Παράδειγμα μεταβίβασης με αναφορά(1b) 70 Πλέον μεταβιβάζονται οι θέσεις μνήμης των μεταβλητών x και y στη swap (με τον τελεστή & μπροστά από το όνομά τους), οπότε οποιαδήποτε αλλαγή συμβαίνει στη swap, συμβαίνει στην ουσία στη θέση μνήμης των x και y, άρα μεταφέρεται και στη main. Οι τελεστές * που υπάρχουν πριν τα ονόματα μεταβλητών στη συνάρτηση swap αναφέρονται σε δείκτες και θα αναλυθούν στο αντίστοιχο κεφάλαιο για τους δείκτες στη συνέχεια του μαθήματος.
Παράδειγμα μεταβίβασης με αναφορά(2) 71 #include <stdio.h> void add2(int *x); void main() int a = 10; printf("η μεταβλητή στη main: %d\n", a); add2(&a); printf("η μεταβλητή στη main μετά την κλήση της add2: %d\n", a); void add2(int *x) *x+=2; // αλλιώς: *x = *x+2; printf("η μεταβλητή στην add2: %d\n", *x); θα εκτυπώσει: Η μεταβλητή στη main: 10 Η μεταβλητή στην add2: 12 Η μεταβλητή στη main μετά την κλήση της add2: 12
Μεταβίβαση με αναφορά 72 Για να γίνει πέρασμα με αναφορά σε μία συνάρτηση, η συνάρτηση πρέπει να χρησιμοποιεί δείκτες ως παραμέτρους εισόδου και κατά την κλήση της πρέπει να μεταβιβάζονται οι διευθύνσεις μνήμης των μεταβλητών (με τον τελεστή & πριν το όνομα των ορισμάτων). Δείκτες: θα αναλυθούν σε επόμενο κεφάλαιο προς το παρόν απλά χρησιμοποιείται ο τελεστής * πριν το όνομα των παραμέτρων εισόδου. Μία συνάρτηση μπορεί να επιστρέφει το πολύ μία τιμή. Με την ιδιότητα της μεταβίβασης με αναφορά, επιτυγχάνεται ουσιαστικά η επιστροφή περισσότερων από μία τιμών, αφού η συνάρτηση μπορεί να τροποποιήσει όσες μεταβλητές δέχεται ως παραμέτρους εισόδου.