This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
|
cpp:functions [2017/05/06 08:44] gthanos [Κλήση με τιμή και κλήση με αναφορά] |
cpp:functions [2021/04/27 06:43] |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== Συναρτήσεις ====== | ||
| - | |||
| - | Στη C++ οι μέθοδοι συνηθίζεται να καλούνται συναρτήσεις. Η συγκεκριμένη ονοματολογία προέρχεται ως κληρονομιά από την γλώσσα C. Η βασική διαφορά σε σχέση με την Java είναι ότι μπορείτε να ορίσετε συναρτήσεις οι οποίες δεν ανήκουν σε κλάσεις, | ||
| - | <code c++> | ||
| - | #include < | ||
| - | using namespace std; | ||
| - | |||
| - | int addition (int a, int b) { return a+b; } | ||
| - | |||
| - | int main () { | ||
| - | int x=5; | ||
| - | x = 5 + addition(8, | ||
| - | cout << "x: " << x << endl; | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | ===== Ορίσματα και επιστρεφόμενη τιμή της συνάρτησης main ===== | ||
| - | |||
| - | Γνωρίζετε από τη C ότι η συνάρτηση //main// από την οποία εκκινεί το πρόγραμμα ορίζεται ως εξής: | ||
| - | <code c++> | ||
| - | int main(int argc, char *argv[]); | ||
| - | </ | ||
| - | |||
| - | Σε ένα πρόγραμμα C++ η main μπορεί να δηλωθεί χωρίς να λαμβάνει κανένα όρισμα, | ||
| - | <code c++> | ||
| - | int main(); | ||
| - | </ | ||
| - | |||
| - | Επίσης, | ||
| - | ===== Προκαθορισμένες τιμές παραμέτρων (default values) ===== | ||
| - | |||
| - | Κατά τον ορισμό μίας συνάρτησης είναι δυνατόν να ορίσετε προκαθορισμένες τιμές για συγκεκριμένες παραμέτρους. Με αυτό τον τρόπο η ίδια μέθοδος μπορεί να κληθεί με λιγότερα ορίσματα, | ||
| - | |||
| - | <code c++ powerOf.cpp> | ||
| - | #include < | ||
| - | using namespace std; | ||
| - | |||
| - | int powerOf(int base, int e=2) { | ||
| - | if(e==0) | ||
| - | return 1; | ||
| - | for(int i=1; i<e; i++) { | ||
| - | base = base * base; | ||
| - | } | ||
| - | return base; | ||
| - | } | ||
| - | |||
| - | int main() { | ||
| - | int a = 5, b; | ||
| - | b = powerOf(a); | ||
| - | cout << "a: " << a <<", | ||
| - | b = powerOf(a, | ||
| - | cout << "a: " << a <<", | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | ===== Inline συναρτήσεις ===== | ||
| - | |||
| - | Κάθε φορά που καλείται μια συνάρτηση συνεπάγεται μία μικρή καθυστέρηση προκειμένου να αποθηκευτούν οι παράμετροι κλήσης της συνάρτησης στη στοίβα και να αποθηκευθεί η επιστρεφόμενη τιμή σε μία μεταβλητή. Για μικρές σε έκταση συναρτήσεις που καλούνται συχνά το συγκεκριμένο κόστος μπορεί να μην είναι αμελητέο σε σχέση με τον συνολικό χρόνο εκτέλεσης τους. | ||
| - | |||
| - | Μπορείτε να αποφύγετε την κλήση μίας συνάρτησης δηλώνοντας τη ως //inline//. Σε αυτή την περίπτωση δεν γίνεται καμία κλήση συνάρτησης, | ||
| - | |||
| - | <code c++ inline.cpp> | ||
| - | #include < | ||
| - | using namespace std; | ||
| - | inline int add(int a, int b) { return a+b;} | ||
| - | int main() { | ||
| - | int sum = 0; | ||
| - | for(int i=1; i<=100; i++) { | ||
| - | sum = add(sum,i); | ||
| - | cout << i << " | ||
| - | } | ||
| - | cout << "sum: " << sum << endl; | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | <WRAP tip 80% center round> | ||
| - | Ο παραπάνω κώδικας δηλώνει τη σύσταση του προγραμματιστή προς τον μεταγλωττιστή ο κώδικας της συνάρτησης //add// να ενσωματωθεί στον κώδικα που την καλεί. Σημειώστε ότι ο μεταγλωττιστής μπορεί να επιλέξει να ενσωματώσει μία συνάρτηση στον κώδικα που την καλεί ακόμη και εάν δεν έχει δηλωθεί //inline//. Αντίστοιχα, | ||
| - | </ | ||
| - | |||
| - | ===== Κλήση με τιμή και κλήση με αναφορά ===== | ||
| - | |||
| - | Κατά την κλήση μίας συνάρτησης οι παράμετροι της συνάρτησης αντιγράφονται στο //stack// πριν από την εκτέλεσης της. Μετά την ολοκλήρωση εκτέλεσης οι παράμετροι διαγράφονται από το //stack// και οποιεσδήποτε αλλαγές έγιναν στις παραμέτρους κατά τη κλήσης της συνάρτησης είναι αδύνατο να διατηρηθούν μετά την κλήση. | ||
| - | |||
| - | Εάν θέλουμε οι αλλαγές στα ορίσματα της συνάρτησης να διατηρηθούν και μετά την κλήση της θα πρέπει να περάσουμε τις διευθύνσεις των εμπλεκόμενων μεταβλητών και όχι τις μεταβλητές αυτές καθ' | ||
| - | |||
| - | <code c++ powerOf2.cpp> | ||
| - | #include < | ||
| - | using namespace std; | ||
| - | |||
| - | int powerOf2(int x) { | ||
| - | x = x*x; | ||
| - | return x; | ||
| - | } | ||
| - | |||
| - | int powerOf2Ref(int &x) { | ||
| - | x = x*x; | ||
| - | return x; | ||
| - | } | ||
| - | |||
| - | int powerOf2Ptr(int *x) { | ||
| - | *x = (*x)*(*x); | ||
| - | return *x; | ||
| - | } | ||
| - | |||
| - | int main() { | ||
| - | int a = 5, b; | ||
| - | b = powerOf2(a); | ||
| - | cout << "a: " << a <<", | ||
| - | a = 5; | ||
| - | b = powerOf2Ref(a); | ||
| - | cout << "a: " << a <<", | ||
| - | a = 5; | ||
| - | b = powerOf2Ptr(& | ||
| - | cout << "a: " << a <<", | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | Το αποτέλεσμα της εκτέλεσης του παραπάνω προγράμματος έχει ως εξής: | ||
| - | < | ||
| - | a: 5, b: 25 | ||
| - | a: 25, b: 25 | ||
| - | a: 25, b: 25 | ||
| - | </ | ||
| - | |||
| - | Παρατηρήστε ότι μετά την έξοδο από τις μεθόδους // | ||
| - | |||
| - | ===== Υπερφόρτωση συναρτήσεων ===== | ||
| - | |||
| - | Η C++ (όπως και η Java) επιτρέπει δύο συναρτήσεις να έχουν το ίδιο όνομα αλλά διαφορετικό αριθμό ή τύπο παραμέτρων. Αυτό συμβαίνει διότι η συνάρτηση δεν ορίζεται μόνο από το όνομα της, αλλά από το όνομα της σε συνδυασμό με τις τυπικές παραμέτρους που λαμβάνει. Δείτε το προηγούμενο παράδειγμα προσαρμοσμένο, | ||
| - | |||
| - | <code c++ powerOf2.cpp> | ||
| - | #include < | ||
| - | using namespace std; | ||
| - | |||
| - | int powerOf2(int &x) { | ||
| - | x = x*x; | ||
| - | return x; | ||
| - | } | ||
| - | |||
| - | int powerOf2(int *x) { | ||
| - | *x = (*x)*(*x); | ||
| - | return *x; | ||
| - | } | ||
| - | |||
| - | double powerOf2(double *x) { | ||
| - | *x = (*x)*(*x); | ||
| - | return *x; | ||
| - | } | ||
| - | |||
| - | int main() { | ||
| - | int a = 5, b; | ||
| - | double d = 5.0, e; | ||
| - | b = powerOf2(a); | ||
| - | cout << "a: " << a <<", | ||
| - | a = 5; | ||
| - | b = powerOf2(& | ||
| - | cout << "a: " << a <<", | ||
| - | e = powerOf2(& | ||
| - | cout << "d: " << d <<", | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | Παρατηρήστε ότι οι συνάρτηση // | ||
| - | |||
| - | <WRAP center round info 80%> | ||
| - | Όταν θέλουμε να περάσουμε σε μία συνάρτηση μεγάλα αντικείμενα που περιέχουν πολύ πληροφορία είναι προτιμότερο να τα περάσουμε με αναφορά ακόμη και εάν δεν επιθυμούμε οι πιθανές αλλαγές στις τυπικές παραμέτρους να είναι ορατές μετά την κλήση της συνάρτησης. Ο λόγος είναι ότι η κλήση με αναφορά έχει σταθερό κόστος αντιγραφής ισοδύναμο με το μήκος μίας διεύθυνσης μνήμης, | ||
| - | |||
| - | Για βασικούς τύπους δεδομένων η κλήση με αναφορά δεν έχει καμία επίπτωση στην ταχύτητα εκτέλεσης του προγράμματος. | ||
| - | </ | ||
| - | |||
| - | ===== Template συναρτήσεων ===== | ||
| - | |||
| - | Υπερφορτωμένες συναρτήσεις συχνά έχουν τον ίδιο αριθμό και τύπο ορισμάτων, | ||
| - | <code c++> | ||
| - | int sum (int a, int b) { return a+b; } | ||
| - | double sum (double a, double b) { return a+b; } | ||
| - | </ | ||
| - | |||
| - | Παρατηρούμε ότι οι παραπάνω συναρτήσεις έχουν το ίδιο διαφορετικούς τύπου παραμέτρων, | ||
| - | |||
| - | <code c++> | ||
| - | template <class T> | ||
| - | T sum (T a, T b) { | ||
| - | return a+b; | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | η δεσμευμένη λέξη //class// (''< | ||
| - | |||
| - | <code c++> | ||
| - | int s = sum< | ||
| - | </ | ||
| - | |||
| - | Δείτε το παραπάνω παράδειγμα που περιέχει επιμέρους κλήσεις για την // | ||
| - | |||
| - | <code sumUsage.cpp> | ||
| - | #include < | ||
| - | using namespace std; | ||
| - | |||
| - | template < | ||
| - | T sum (T a, T b) { | ||
| - | return a+b; | ||
| - | } | ||
| - | |||
| - | int main() { | ||
| - | cout << "10 + 20 = " << sum< | ||
| - | cout << "10.5 + 20.5 = " << sum< | ||
| - | cout << "1.5 + 2 = " << sum<> | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | <WRAP center round tip 80%> | ||
| - | Παρατηρήστε ότι κατά την τελευταία κλήση ο // | ||
| - | </ | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||