Κεφάλαιο 6: Συναρτήσεις IΙΙ Αρθρωτός Προγραμματισμός Δείκτες (Διάλεξη 14) 14-1
Παράδειγμα: Αλλαγή τιμής μεταβλητής μόνο τοπικά ΛΑΘΟΣ τρόπος να αυξήσουμε το num κατά 1 #include <stdio.h> void AddOne (int); void AddOne (int num) { num++; main () { printf ( In AddOne: ); int num = 5; printf ( num = %d\n, num); AddOne (num); } printf ( In main: ); printf ( num = %d\n, num); num } 6 num 5 To πρόγραμμα εκτυπώνει: In AddOne: num=6 In main: num= 5 14-2
Παράδειγμα (συνέχεια): Αλλαγή τιμής μεταβλητής με επιστροφή τιμής ΣΩΣΤΟΣ τρόπος να αυξήσουμε το num κατά 1 #include <stdio.h> int AddOne (int); int AddOne (int num) { main () num++; { printf ( In AddOne: ); int num = 5; printf ( num = %d\n, num); return num; num = AddOne (num); } printf ( In main: ); printf ( num = %d\n, num); num } 6 num 6 To πρόγραμμα εκτυπώνει: In AddOne: num=6 In main: num= 6 14-3
Συναρτήσεις Σήμεραθαδούμεσεπερισσότερο βάθος τις συναρτήσεις. Α) Συναρτήσεις με Παραμέτρους Με Επιστροφή Πολλών Τιμών Β) Εισαγωγή στους δείκτες Γ) Η έννοια και η χρήση του * Δ) Αποσφαλμάτωση - έλεγχος 14-4
Χρήση δεικτών ΝΕΟΣ ΣΩΣΤΟΣ τρόπος να αυξήσουμε το num κατά 1 #include <stdio.h> void AddOne (int*); void AddOne (int *nump) { main () *nump = *nump+1; { printf ( In AddOne: ); int num = 5; printf ( num = %d\n, *nump); AddOne (&num); } printf ( In main: ); printf ( num = %d\n, num); num } 6 num 6 To πρόγραμμα εκτυπώνει: In AddOne: num=6 In main: num= 6 14-5
int num = 5; AddOne (&num); Διευθύνσειςωςπαράμετροι num είναι μία μεταβλητή τύπου int &num είναι η διεύθυνσή του στη μνήμη 3643847 5 14-6
Συμβολίζονται με * Εισαγωγή στους δείκτες Ένα μέρος της μνήμης του οποίου το περιεχόμενο είναι διεύθυνση μνήμης 3643847 5 3643847 num nump To nump δείχνει δηλαδή στη μεταβλητή num 14-7
Χρήση * στις τυπικές μεταβλητές void AddOne (int *nump) To nump είναι ένας δείκτης σε μεταβλητές τύπου int. O τύπος εξόδου παραμένει void AΛΛΑ, το int *nump είναι παράμετρος όχι μόνο εισόδου αλλά και εξόδου ΔΕΔΟΜΕΝΟΥ ότι η συνάρτηση γνωρίζει την διεύθυνση που είναι αποθηκευμένη η μεταβλητή num, ώστε να αλλάξει την τιμή της. 14-8
Χρήση * στο σώμα συναρτήσεων *nump = *nump+1; 3643847 5 *nump 3643847 num nump Ερμηνεία: Ακολούθησε τον δείκτη και βρες την τιμή της μεταβλητής στην οποία δείχνει. nump: 3643847 num: 5 *nump == num 14-9
* : Ανακεφαλαίωση 3 χρήσεις/ερμηνείες: Πολλαπλασιασμός (δυαδικός τελεστής) 2 * a Τυπική Παράμετρος int *nump Σημαίνει «δείκτης σε» Μοναδιαίος (unary) τελεστής *nump = 5/num Σημαίνει «ακολούθησε τον δείκτη» 14-10
scanf με δείκτες int number; int *numberp; scanf( %d %d, &number, numberp); ΠΡΟΣΟΧΗ: Δεν βάζουμε το σύμβολο & καθώς η μεταβλητή numberp ήδη αναφέρεται σε διεύθυνση. 14-11
Παράδειγμα συνάρτησης που υπολογίζει πολλαπλές τιμές Δημιουργήστε μία συνάρτηση που διαχωρίζει έναν αριθμό σε ακέραιο και δεκαδικό μέρος void separate (double num, int *intp, double *fracp) { *intp = (int)num; *fracp = num (*intp); } int main () { double value, fractional_part; int integer_part; separate(value, &integer_part, & fractional_part); printf( The integer part of %.4f is %d and the fractional part is %.4f, value, integer_part, fractional_part); } 14-12
*p=5; *q=8; p 5 q 8 p=q; p 8 p 5 q 8 q 8 λάθος σωστό 14-13
*p=5; *q=8; p 5 q 8 *p=*q; p 8 p 5 q 8 q 8 σωστό λάθος 14-14
Έλεγχος προγράμματος με πολλές συναρτήσεις Ο έλεγχος πρέπει να αρχίσει πολύ πριν ολοκληρωθεί η ανάπτυξη όλων των συναρτήσεων. Χρήση σκελετών (stubs) Εκτυπώνουν προειδοποιητικά μηνύματα Εκτυπώνουν μηνύματα με τις τιμές εισόδου Δίνουν (ψεύτικες) τιμές στις παραμέτρου εξόδου 14-15
Π.χ., Σκελετός συνάρτησης που βρίσκει τον ΜΚΔ δύο ακεραίων int mkd(int a, int b) { printf( WARNING: THIS FUNCTION IS INCOMPLETE! ) printf( a= %d, b= %d, a,b); return a*b; } 14-16
Αποσφαλμάτωση Συμβουλές Σχόλια για κάθε συνάρτηση, τις παραμέτρους της και τις τοπικές μεταβλητές Εκτύπωση ενδείξεων για τη ροή του προγράμματος Όνομα συνάρτησης που καλείται Τιμή παραμέτρων κατά την κλίση Τιμή παραμέτρων εξόδου μετά την ολοκλήρωση 14-17