Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Εστω ότι έχουμε

 

>
int repeats = 0;
int MyFunction(int x)
{
 repeats += 2;
 
 sum = MyFunction(x) + MyFunction(x+1);
 
 printf("MyFaction: %d \n", sum);
}

 

Πόσες φορές θα κληθεί η συνάρτηση?

αφού την καλώ 2 φορές με μιας, λογικά πάει repeats += 2;

 

Θα σκάσω...

Καμια ιδέα;;

Δημοσ.

Πρώτον, γιατί δεν τρέχεις μόνος σου τον κώδικα να δεις;

 

Δεύτερον, αυτή η συνάρτηση αν κληθεί θα κάνει το πρόγραμμά σου να κρασάρει με stack overflow. Ακόμα κι αν δε συνέβαινε αυτό, κατ' ελάχιστον δε θα τερμάτιζε ποτέ γιατί θα καλέσει τη συνάρτηση άπειρες φορές. Πράγμα που δεν είναι δύσκολο να καταλάβεις αφού η κλήση MyFunction(n) προκαλεί ξανά την κλήση MyFunction(n) (η οποία ξανά καλεί την ίδια κλπ).

 

Για να μη συμβαίνει αυτό πρέπει να διορθώσεις 2 πράγματα: α) δεν επιτρέπεται μια αναδρομική συνάρτηση να καλεί τον εαυτό της με τα ίδια ορίσματα που κλήθηκε η ίδια, και β) πρέπει να υπάρχει κάποια συνθήκη τερματισμού ώστε όταν η κλήση γίνει με κάποια συγκεκριμένα ορίσματα να σταματήσει η αναδρομή.

 

Τρίτον, ακόμα κι αν δε γινόταν τίποτα από τα παραπάνω, αφού την καλείς 2 φορές αναδρομικά τότε κατ' ελάχιστον δε θα έπρεπε να πάει repeats += 4?

 

Νομίζω πρέπει να ξεμπερδέψεις μερικά πράγματα στο μυαλό σου.

Δημοσ.

Εστω ότι έχουμε

 

>
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 ως όρισμα στην συνάρτηση. Δοκίμασε να τον αυξάνεις πριν και μετά την αναδρομική κλήση, για να συγκρίνεις διαφορές.

 

 

 

Τις μισώ τις αναδρομές!

 

 

Δημοσ.

Πρώτον, γιατί δεν τρέχεις μόνος σου τον κώδικα να δεις;

 

Δεύτερον, αυτή η συνάρτηση αν κληθεί θα κάνει το πρόγραμμά σου να κρασάρει με stack overflow. Ακόμα κι αν δε συνέβαινε αυτό, κατ' ελάχιστον δε θα τερμάτιζε ποτέ γιατί θα καλέσει τη συνάρτηση άπειρες φορές. Πράγμα που δεν είναι δύσκολο να καταλάβεις αφού η κλήση MyFunction(n) προκαλεί ξανά την κλήση MyFunction(n) (η οποία ξανά καλεί την ίδια κλπ).

 

το ξέρω, δεν είναι κάτι συγκεκριμένο, ένα απλό παράδειγμα έφερα.

 

2ον, εχω την εντύπωη ότι είναι +=1 :/ ε γαμώτο.

 

>if (x = 0)
 break;
else
 return (Myf(x) + Myf(x-1))

 

απλά όσες περισσότερες φορές την καλώ ταυχτόχρονα τόσες πιο πολλές φορές θα μπει στην else, άρα γιατι x2?

 

νομίζω δηλαδή.

Δημοσ.

>if (x = 0)
 break;
else
 return (Myf(x) + Myf(x-1))

 

Το μόνο σίγουρο είναι αυτό που είπε και ο defacer, ότι αν καλείς την ίδια συνάρτηση με το ίδιο ακριβώς όρισμα (Myf(x)), δεν πρόκειται να τελειώσει ποτέ.

Για τον μετρητή πιστεύω ότι θέλει repeats++ αφού η repeats είναι global μεταβλητή.

Δημοσ.

Αν και δεν μου αρέσει το 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 κλήσεις της συνάρτησης.

Δημοσ.

...

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 έτσι :)

 

 

Δημοσ.

 

 

Είμαι 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 απλά καμια φορά δεν θέλουμε να εκτελεστεί κάτι αν δεν ισχύει κάτι, σας είπα αυτο το παράδειγμα πάνω δεν είναι κάτι συγκεκριμένο...

Δημοσ.

Είσαι "ανάποδος" αν και έχουν το ίδιο αποτέλεσμα στην συγκεκριμένη περίπτωση.

 

 

x = 1;

if (1 == 0)

do...

 

x = 0

if (0 = 0)

do...

 

hehe ;p

 

 

πω, το ξέχασα. tragic!

 

Δεν είμαι ανάποδος τυχαία. Αν το είχες γράψει όπως το έχω εγώ, ο compiler θα σου είχε βρει το λάθος που είχες κάνει στο ίσον ;)

Δημοσ.

Δεν είμαι ανάποδος τυχαία. Αν το είχες γράψει όπως το έχω εγώ, ο compiler θα σου είχε βρει το λάθος που είχες κάνει στο ίσον ;)

 

και πριν στις στοίβες είχες κάτι αντίστοιχο, δηλαδή

if (NULL == (XYZ))

ε κοίτα τώρα, τι Μήτσος τι Δημήτρης...

αλλά 1η φορά το βλέπω έτσι, ο κόσμος στο NET έχει συνηθίσει το ανάποδο :P

Δημοσ.

και πριν στις στοίβες είχες κάτι αντίστοιχο, δηλαδή

if (NULL == (XYZ))

ε κοίτα τώρα, τι Μήτσος τι Δημήτρης...

αλλά 1η φορά το βλέπω έτσι, ο κόσμος στο NET έχει συνηθίσει το ανάποδο :P

 

Το θέμα είναι πως το...

 

>(x = 0)

δεν παράγει σφάλμα, γιατί ο compiler δεν μπορεί να ξέρει αν όντως θες να κάνεις ανάθεση αντί για σύγκριση. Βέβαια, αν είχες ενεργοποιημένα τα warnings του compiler θα σου έβγαζε προειδοποίηση ;)

 

Από την άλλη μεριά το...

 

>(0 = x)

παράγει σφάλμα (δηλαδή δεν βγαίνει καν το εκτελέσιμο) γιατί η γλώσσα δεν επιτρέπει να αναθέτεις μεταβλητές σε σταθερές.

 

EDIT:

 

σχετικά με το else, ναι ;p απλά καμια φορά δεν θέλουμε να εκτελεστεί κάτι αν δεν ισχύει κάτι, σας είπα αυτο το παράδειγμα πάνω δεν είναι κάτι συγκεκριμένο...

Δεν χρειάζεται καθόλου το else. Αν ισχύει το if θα εκτελεστεί το break. Αν όχι ( το αχρείαστο else δηλαδή) δεν θα μπει καν στο σώμα της if, θα πάει στο αμέσως επόμενο statement είτε ξεκινάει με else είτε όχι.

Δημοσ.

και πριν στις στοίβες είχες κάτι αντίστοιχο, δηλαδή

if (NULL == (XYZ))

ε κοίτα τώρα, τι Μήτσος τι Δημήτρης...

αλλά 1η φορά το βλέπω έτσι, ο κόσμος στο NET έχει συνηθίσει το ανάποδο :P

 

Αυτό που λέει ο migf1 είναι πολύ γνωστό (βέβαια αυτό δε σημαίνει ότι η πλειοψηφία το εφαρμόζει) ως Yoda condition, και όσοι το χρησιμοποιούν το κάνουν για το λόγο που περιγράφει.

 

Από την άλλη δε νομίζω πως σήμερα παίζει κάποιο ιδιαίτερο ρόλο καθώς οι καιροί και οι νοοτροπίες έχουν αλλάξει και πλέον οποιοσδήποτε compiler θα δώσει warning όταν δει ανάθεση τιμής μέσα σε συνθήκη (εννοείται πως όταν κάνεις δουλειά έχεις όλα τα warning στο τέρμα και επίσης treat warnings as errors).

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...