Downloadpercent Δημοσ. 5 Ιουνίου 2012 Δημοσ. 5 Ιουνίου 2012 Εστω ότι έχουμε > int repeats = 0; int MyFunction(int x) { repeats += 2; sum = MyFunction(x) + MyFunction(x+1); printf("MyFaction: %d \n", sum); } Πόσες φορές θα κληθεί η συνάρτηση? αφού την καλώ 2 φορές με μιας, λογικά πάει repeats += 2; Θα σκάσω... Καμια ιδέα;;
defacer Δημοσ. 5 Ιουνίου 2012 Δημοσ. 5 Ιουνίου 2012 Πρώτον, γιατί δεν τρέχεις μόνος σου τον κώδικα να δεις; Δεύτερον, αυτή η συνάρτηση αν κληθεί θα κάνει το πρόγραμμά σου να κρασάρει με stack overflow. Ακόμα κι αν δε συνέβαινε αυτό, κατ' ελάχιστον δε θα τερμάτιζε ποτέ γιατί θα καλέσει τη συνάρτηση άπειρες φορές. Πράγμα που δεν είναι δύσκολο να καταλάβεις αφού η κλήση MyFunction(n) προκαλεί ξανά την κλήση MyFunction(n) (η οποία ξανά καλεί την ίδια κλπ). Για να μη συμβαίνει αυτό πρέπει να διορθώσεις 2 πράγματα: α) δεν επιτρέπεται μια αναδρομική συνάρτηση να καλεί τον εαυτό της με τα ίδια ορίσματα που κλήθηκε η ίδια, και β) πρέπει να υπάρχει κάποια συνθήκη τερματισμού ώστε όταν η κλήση γίνει με κάποια συγκεκριμένα ορίσματα να σταματήσει η αναδρομή. Τρίτον, ακόμα κι αν δε γινόταν τίποτα από τα παραπάνω, αφού την καλείς 2 φορές αναδρομικά τότε κατ' ελάχιστον δε θα έπρεπε να πάει repeats += 4? Νομίζω πρέπει να ξεμπερδέψεις μερικά πράγματα στο μυαλό σου.
migf1 Δημοσ. 5 Ιουνίου 2012 Δημοσ. 5 Ιουνίου 2012 Εστω ότι έχουμε > int repeats = 0; int MyFunction(int x) { repeats += 2; sum = MyFunction(x) + MyFunction(x+1); printf("MyFaction: %d \n", sum); } Πόσες φορές θα κληθεί η συνάρτηση? αφού την καλώ 2 φορές με μιας, λογικά πάει repeats += 2; Θα σκάσω... Καμια ιδέα;; Οι αναδρομές βασίζονται σε ένα base-case κατά το οποίο τερματίζουν (επιστρέφουν) πριν ή μετά την αναδρομική κλήση. Για να μετρήσεις το σύνολο κλήσεων (αν δεν θες δηλ να χρησιμοποιήσεις debugger) βάλε ένα base-case στον κώδικα της συνάρτησης και κατόπιν πέρνα τον μετρητή repeats ως όρισμα στην συνάρτηση. Δοκίμασε να τον αυξάνεις πριν και μετά την αναδρομική κλήση, για να συγκρίνεις διαφορές. Τις μισώ τις αναδρομές!
Downloadpercent Δημοσ. 5 Ιουνίου 2012 Μέλος Δημοσ. 5 Ιουνίου 2012 Πρώτον, γιατί δεν τρέχεις μόνος σου τον κώδικα να δεις; Δεύτερον, αυτή η συνάρτηση αν κληθεί θα κάνει το πρόγραμμά σου να κρασάρει με stack overflow. Ακόμα κι αν δε συνέβαινε αυτό, κατ' ελάχιστον δε θα τερμάτιζε ποτέ γιατί θα καλέσει τη συνάρτηση άπειρες φορές. Πράγμα που δεν είναι δύσκολο να καταλάβεις αφού η κλήση MyFunction(n) προκαλεί ξανά την κλήση MyFunction(n) (η οποία ξανά καλεί την ίδια κλπ). το ξέρω, δεν είναι κάτι συγκεκριμένο, ένα απλό παράδειγμα έφερα. 2ον, εχω την εντύπωη ότι είναι +=1 :/ ε γαμώτο. >if (x = 0) break; else return (Myf(x) + Myf(x-1)) απλά όσες περισσότερες φορές την καλώ ταυχτόχρονα τόσες πιο πολλές φορές θα μπει στην else, άρα γιατι x2? νομίζω δηλαδή.
pantpesl2 Δημοσ. 5 Ιουνίου 2012 Δημοσ. 5 Ιουνίου 2012 >if (x = 0) break; else return (Myf(x) + Myf(x-1)) Το μόνο σίγουρο είναι αυτό που είπε και ο defacer, ότι αν καλείς την ίδια συνάρτηση με το ίδιο ακριβώς όρισμα (Myf(x)), δεν πρόκειται να τελειώσει ποτέ. Για τον μετρητή πιστεύω ότι θέλει repeats++ αφού η repeats είναι global μεταβλητή.
Downloadpercent Δημοσ. 5 Ιουνίου 2012 Μέλος Δημοσ. 5 Ιουνίου 2012 Αν και δεν μου αρέσει το Debug, έκανα αυτό που είπε ο defactor και τελικά καλά το είχα repeats+=2; Για x = 4 ... > unsigned int Myf(unsigned int x) { if (x = 0) break; else return (Myf(x) + Myf(x-1)); } Είδα Call Stack και στο σύνολο έγιναν 9 κλήσεις της συνάρτησης.
migf1 Δημοσ. 5 Ιουνίου 2012 Δημοσ. 5 Ιουνίου 2012 ... 2ον, εχω την εντύπωη ότι είναι +=1 :/ ε γαμώτο. >if (x = 0) break; else return (Myf(x) + Myf(x-1)) ... Είμαι off-topic, αλλά μετά από break (και return) τα else είναι άχρηστα... > if ( 0 == x ) break; return Myf(x) + Myf(x-1); Είναι πιο... professional έτσι
Downloadpercent Δημοσ. 5 Ιουνίου 2012 Μέλος Δημοσ. 5 Ιουνίου 2012 Είμαι off-topic, αλλά μετά από break (και return) τα else είναι άχρηστα... > if ( 0 == x ) break; return Myf(x) + Myf(x-1); Είναι πιο... professional έτσι Είσαι "ανάποδος" αν και έχουν το ίδιο αποτέλεσμα στην συγκεκριμένη περίπτωση. x = 1; if (1 == 0) do... x = 0 if (0 = 0) do... hehe ;p Στο if σου θες == αντι για = btw πω, το ξέχασα. tragic! σχετικά με το else, ναι ;p απλά καμια φορά δεν θέλουμε να εκτελεστεί κάτι αν δεν ισχύει κάτι, σας είπα αυτο το παράδειγμα πάνω δεν είναι κάτι συγκεκριμένο...
migf1 Δημοσ. 5 Ιουνίου 2012 Δημοσ. 5 Ιουνίου 2012 Είσαι "ανάποδος" αν και έχουν το ίδιο αποτέλεσμα στην συγκεκριμένη περίπτωση. x = 1; if (1 == 0) do... x = 0 if (0 = 0) do... hehe ;p πω, το ξέχασα. tragic! Δεν είμαι ανάποδος τυχαία. Αν το είχες γράψει όπως το έχω εγώ, ο compiler θα σου είχε βρει το λάθος που είχες κάνει στο ίσον
Downloadpercent Δημοσ. 5 Ιουνίου 2012 Μέλος Δημοσ. 5 Ιουνίου 2012 Δεν είμαι ανάποδος τυχαία. Αν το είχες γράψει όπως το έχω εγώ, ο compiler θα σου είχε βρει το λάθος που είχες κάνει στο ίσον και πριν στις στοίβες είχες κάτι αντίστοιχο, δηλαδή if (NULL == (XYZ)) ε κοίτα τώρα, τι Μήτσος τι Δημήτρης... αλλά 1η φορά το βλέπω έτσι, ο κόσμος στο NET έχει συνηθίσει το ανάποδο
migf1 Δημοσ. 5 Ιουνίου 2012 Δημοσ. 5 Ιουνίου 2012 και πριν στις στοίβες είχες κάτι αντίστοιχο, δηλαδή if (NULL == (XYZ)) ε κοίτα τώρα, τι Μήτσος τι Δημήτρης... αλλά 1η φορά το βλέπω έτσι, ο κόσμος στο NET έχει συνηθίσει το ανάποδο Το θέμα είναι πως το... >(x = 0) δεν παράγει σφάλμα, γιατί ο compiler δεν μπορεί να ξέρει αν όντως θες να κάνεις ανάθεση αντί για σύγκριση. Βέβαια, αν είχες ενεργοποιημένα τα warnings του compiler θα σου έβγαζε προειδοποίηση Από την άλλη μεριά το... >(0 = x) παράγει σφάλμα (δηλαδή δεν βγαίνει καν το εκτελέσιμο) γιατί η γλώσσα δεν επιτρέπει να αναθέτεις μεταβλητές σε σταθερές. EDIT: σχετικά με το else, ναι ;p απλά καμια φορά δεν θέλουμε να εκτελεστεί κάτι αν δεν ισχύει κάτι, σας είπα αυτο το παράδειγμα πάνω δεν είναι κάτι συγκεκριμένο... Δεν χρειάζεται καθόλου το else. Αν ισχύει το if θα εκτελεστεί το break. Αν όχι ( το αχρείαστο else δηλαδή) δεν θα μπει καν στο σώμα της if, θα πάει στο αμέσως επόμενο statement είτε ξεκινάει με else είτε όχι.
defacer Δημοσ. 5 Ιουνίου 2012 Δημοσ. 5 Ιουνίου 2012 και πριν στις στοίβες είχες κάτι αντίστοιχο, δηλαδή if (NULL == (XYZ)) ε κοίτα τώρα, τι Μήτσος τι Δημήτρης... αλλά 1η φορά το βλέπω έτσι, ο κόσμος στο NET έχει συνηθίσει το ανάποδο Αυτό που λέει ο migf1 είναι πολύ γνωστό (βέβαια αυτό δε σημαίνει ότι η πλειοψηφία το εφαρμόζει) ως Yoda condition, και όσοι το χρησιμοποιούν το κάνουν για το λόγο που περιγράφει. Από την άλλη δε νομίζω πως σήμερα παίζει κάποιο ιδιαίτερο ρόλο καθώς οι καιροί και οι νοοτροπίες έχουν αλλάξει και πλέον οποιοσδήποτε compiler θα δώσει warning όταν δει ανάθεση τιμής μέσα σε συνθήκη (εννοείται πως όταν κάνεις δουλειά έχεις όλα τα warning στο τέρμα και επίσης treat warnings as errors).
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα