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

C/C++ goto αντι για function


NewProject

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

Δημοσ.

θελω γνωμες για το αν ειναι καλυτερο να χρησιμοποιησω goto αντι για function :

 

με goto :

>
std::string s = "";
while(1){
  getline(s,file);
  goto CONTINUE;
  MANIPULATE :
     // manipulate string :
     s = s.sub_str(0,s.size()-2);
  CONTINUE :
  if(s.size()>=15) goto MANIPULATE;
  std::cout << s << "\n";
  }

 

mε ξεχωριστο function :

>
std::string s = "";
while(1){
  getline(s,file);
  manipulate(&s);
  std::cout << s << "\n";
  }

-------------------------------
void manipulate(std::string *string){
  // manipulate string :
  while(s.size()>=15)
     s = s.sub_str(0,s.size()-2);
  }

 

φυσικα , στο συγκεκριμενο παραδειγμα , θα χρησιμοποιουσα το 2 απλα ρωταω απο αποψη παραμετρων κλπ. γιατι στο 2ο χρησιμοποιω δεικτες και στο πραγματικο παραδειγμα χρειαζεται να δωσω οχι μονο εναν παραμετρο αλλα 5-6 και πιστευω οτι ειναι καλυτερα να το κανω με goto στο οποιο ο κωδικας θα ειναι στο ιδιο function και οχι σε ενα 2ο ...

  • Απαντ. 31
  • Δημ.
  • Τελ. απάντηση
Δημοσ.

Φυσικα ειναι καλυτερο να χρησιμοποιεις functions γενικοτερα και να μην βρισκεις "ειδικες λυσεις" για το προβλημα σου.Γενικοτερα οι goto θα πρεπει να αποφευγονται γιατι αν χρησιμοποιεις μεγαλο αριθμο ( και οχι μια οπως εσυ ) θα χαθει η μπαλα.

Δημοσ.

ναι αλλα στο προγραμμα μονο αυτο το σημειο χρειαστηκε να το γραψω με goto γιατι αλλοιως εχω 2 pinters για το αποτελεσμα και 6 αλλους παραμετρους , συνολο 8 ... ενω με το goto τα αποφευγω ολα αυτα και γραφω κατευθειαν τον κωδικα για να κανω edit το string

Δημοσ.

Τωρα τι να σου πω.Ολα εξαρτωνται απο το τι θελεις να κανεις.Αφου λες οτι πρεπει να στειλεις 8 παραμετρους στειλτες με pointers ετσι ωστε να μπορεσεις να χρησιμοποιησεις την συναρτηση αυτη και αλλου αν χρειαστει.Ειναι θεμα επεκτασιμοτητας και ευκολης συντηρησης του κωδικα σου.Απο εκει και περα δεν ξερω αν σε ενδιαφερουν αυτα η ο αριθμος των πορων που θα δεσμευτουν και του χρονου εκτελεσης του κωδικα σου.

 

Αν σε βοηθαει η goto και δεν λαμβανεις υποψην τα παραπανω τοτε καντο ετσι,

Δημοσ.

απουσια goto == καλυτερο στυλ προγραμματισμου...αυτο μου ειπε καποιος καποτε κ σκεφτηκα "παραξενιες κ βλακειες..." αλλα στην πορεια συμφωνησα :-) με functions ο κωδικα σου γινεται πιο ευαναγνωστος κ πιο κατανοητος γρηγοροτερα,οταν μετα (ισως απο πολυ καιρο εσυ- η καποιος αλλος-)ξαναδει/ς το κωδικα σου.α,μν μενεις στο παραδειγμα, σκεψου πιο πολυπλοκες καταστασεις,με πολλα GOTO ....ενα 'απλο μπερδεματακι' θα υπαρχει :fear:

Επισης,σε projects που δν ειναι ενα απλο αρχειο ,αλλα παιζουν libs κλπ..εγω προσωπικα δν ξερω τροπο να "μετακινηθω" με GOTO κ το κανω με χρηση functions.απλα καλω τη συναρτηση που εχω ορισει σε ενα "αλλο" αρχειο.

 

---------- Προσθήκη στις 03:50 ---------- Προηγούμενο μήνυμα στις 03:48 ----------

 

κ μην σε τρομαζουν οι pointers οσοι κ να ειναι :-D

Δημοσ.

κ μην σε τρομαζουν οι pointers οσοι κ να ειναι :-D

 

δεν με τρομαζει ο αριθμος αλλα τι οτι ειναι σαν να φτιαχνω ενα 2ο "υποπρογραμμα" ... :fear:

 

υγ... ευχαριστω για τις γρηγορες απαντησεις

Δημοσ.

To goto είναι πολύ κακή τεχνική προγραμματισμού. Οδηγεί σε χαοτικό κώδικα και σε πολλά άλλα.

Επίσης, όντως κάθε συνάρτηση είναι στην ουσία ένα μικροπρόγραμμα που κάνει μια πολύ συγκεκριμένη δουλειά.

Τώρα από εκεί και πέρα είναι δική σου επιλογή...

Δημοσ.

Γιατί πρέπει να επιλέξεις μεταξύ function και goto; Με δομημένο τρόπο, το παράδειγμα στο opening post γράφεται ως εξής:

 

>
std::string s = "";

while(1)
{
   getline(s, file);

   if(s.size() >= 15)
   {
       s = s.sub_str(0, s.size() - 2);
   }

   std::cout << s + "\n";
}

 

Είναι τόσο περίπλοκος ο κώδικάς σου και τόσες πολλές οι παράμετροι σε αυτόν που δε μπορείς να τον προσαρμόσεις σε κάτι σαν το παραπάνω... ;

Δημοσ.

το θέμα είναι να μην μάθεις από τα απλά προγράμματα να χρησιμοποιείς goto γιατί όπως αναφέρθηκε κάνει χαοτικό τον κώδικα και εσύ ή κάποιος άλλο δεν θα μπορείτε μετά να τον διαβάσετε..

Δημοσ.

Η goto είναι πολύ χρήσιμη εντολή για να γράφεις πιο "elegant" κώδικα αν ξέρεις να την χρησιμοποιείς εκεί που πρέπει.

Π.χ. έστω ότι έχουμε εναν δυσδιάστατο πίνακα με ακέραιες τιμές και ψάχνουμε να βρούμε αν υπάρχει μέσα ο αριθμός 5 :

 

>[color="#008000"][i]//xoris goto[/i][/color]
[color="#8000ff"]bool[/color] found = [color="#ff8000"]0[/color];
[color="#0000ff"][b]for[/b][/color] ([color="#8000ff"]int[/color] i=[color="#ff8000"]0[/color]; i<lenX; i++)
{
[color="#0000ff"][b]for[/b][/color] ([color="#8000ff"]int[/color] j=[color="#ff8000"]0[/color]; j<lenY; j++)
{
	[color="#0000ff"][b]if[/b][/color] (array[i][j] == [color="#ff8000"]5[/color])
	{
		found = TRUE;
		[color="#0000ff"][b]break[/b][/color];
	}
}
[color="#0000ff"][b]if[/b][/color] (found)
	[color="#0000ff"][b]break[/b][/color];
}

[color="#0000ff"][b]if[/b][/color] (found)
[color="#0000ff"][b]return[/b][/color] [color="#ff8000"]1[/color];
[color="#0000ff"][b]else[/b][/color]
[color="#0000ff"][b]return[/b][/color] [color="#ff8000"]0[/color];

[color="#008000"][i]//me goto[/i][/color]
[color="#0000ff"][b]for[/b][/color] ([color="#8000ff"]int[/color] i=[color="#ff8000"]0[/color]; i<lenX; i++)
{
[color="#0000ff"][b]for[/b][/color] ([color="#8000ff"]int[/color] j=[color="#ff8000"]0[/color]; j<lenY; j++)
{
	[color="#0000ff"][b]if[/b][/color] (array[i][j] == [color="#ff8000"]5[/color])
	{
		[color="#0000ff"][b]goto[/b][/color] found;
	}
}
}

[color="#0000ff"][b]return[/b][/color] [color="#ff8000"]0[/color];
found:
printf([color="#a31515"]"vrethike"[/color]);
[color="#0000ff"][b]return[/b][/color] [color="#ff8000"]1[/color];

 

Το παράδειγμα είναι απλό μεν, αλλά δείχνει ότι με goto δεν χρειάζονται "flag" μεταβλητές και ανούσια if.

 

Το να μεταφέρεις την ροή εκτέλεσης με goto ενώ μπορείς να βάλεις συνάρτηση όμως είναι χαζό.

 

Υ.Γ. Μην μένετε στο ότι θα μπορούσε να γίνει return μέσα στο loop. Το έχω έξω για να δείξω ότι το πρόγραμμα συνεχίζει να κάνει κάτι.

Δημοσ.

Η όποια εμπειρία μου με C++ μου έχει δείξει ότι πάντα υπάρχει εναλλακτική στο goto η οποία είναι πολύ πιο κομψή, κατανοητή και δεν εισάγει "ανούσια" if. O έλεγχος για οποιοδήποτε flag ή τιμή μπορεί να πάει μέσα στη δήλωση ελέγχου της for

 

>for(int i=0; i < lenx && found==FALSE; i++){

[indent]for(int j=0;j<lenY && found==FALSE; j++{[/indent]

Δημοσ.

Πάντα έχει να κάνει με τον κώδικα. Το παράδειγμά μου είναι απλό με στόχο να γίνει κατανοητή η χρησιμότητα της goto.

Θα μπορούσε π.χ. στο έξω loop να υπάρχει κώδικας και μετά το εσωτερικό loop δηλ :

 

for (...)

{

for (...)

{

}

entoles;

entoles;

}

 

Οπότε πάλι χρειάζεσαι if. Επίσης χωρίς goto πάλι χρησιμοποιείς flag μεταβλητές ακριβώς επειδή δεν χρησιμοποιείς goto.

Δημοσ.

Συμφωνώ με τον kagelo.

 

Γιατί τόση αποστροφή για την goto ; Εξάλλου αν ήταν τόσο επιβλαβής θα την έβγαζαν από το standard.

 

Yπάρχουν αρκετές περιπτώσεις όπου η ροή του προγράμματος εκφράζεται πιο διαισθητικά με την goto.

Επιπλέον, σε μερικές περιπτώσεις η χρήση της είναι σχεδόν αναπόφευκτη. Θυμάμαι χαρακτηριστικά

μια τεχνική για την μετατροπή αναδρομικών συναρτήσεων σε επαναληπτικές όπου χρησιμοποιούνταν

η goto και η αποφυγή της θα καθιστούσε πολύ στριφνότερη την γραφή του προγράμματος.

 

Για περίπτωση που συζητείται εδώ, το πρόβλημα οφείλεται στο ότι στην C++ δεν μπορεί να οριστεί/γραφεί μια συνάρτηση εντός μιας άλλης.

Έτσι θα υπήρχε μεν ξεχωριστή συνάρτηση (πράγμα που θέλει να αποφύγει ο φίλος) αλλά ΕΝΤΟΣ της αρχικής,

τοπικά, διατηρώντας την αυτοτέλεια της αρχικής σε σχέση με το υπόλοιπο πρόγραμμα.

 

Αυτό σε άλλες γλώσσες υποστηρίζεται μια χαρά και βολεύει.

Στην C++ δυστυχώς όχι.

Δημοσ.
Συμφωνώ με τον kagelo.

 

Γιατί τόση αποστροφή για την goto ; Εξάλλου αν ήταν τόσο επιβλαβής θα την έβγαζαν από το standard.

Yπάρχουν αρκετές περιπτώσεις όπου η ροή του προγράμματος εκφράζεται πιο διαισθητικά μ' αυτήν.

 

Στην συγκεκριμένη περίπτωση δεν συμβαίνει αυτό.

 

Εδώ το πρόβλημα οφείλεται στο ότι στην C++ δεν μπορεί να οριστεί/γραφεί μια συνάρτηση εντός μιας άλλης.

Έτσι θα υπήρχε μεν ξεχωριστή συνάρτηση (πράγμα που θέλει να αποφύγει ο φίλος) αλλά ΕΝΤΟΣ της αρχικής,

τοπικά, διατηρώντας την αυτοτέλεια της αρχικής σε σχέση με το υπόλοιπο πρόγραμμα.

 

Αυτό σε άλλες γλώσσες υποστηρίζεται μια χαρά και βολεύει.

Στην C++ δυστυχώς όχι.

 

Μπορει να φτιαξει μια struct που να έχει μέσα τη συνάρτηση:

 

>void foo ()
    struct foo_struct {
            static void bar() {} // δεν ειναι υποχρεωτικο να ειναι static
   };

    foo_struct::bar();
}

 

αν κάτι τέτοιο θα ήθελε...

Δημοσ.
Μπορει να φτιαξει μια struct που να έχει μέσα τη συνάρτηση:

 

αν κάτι τέτοιο θα ήθελε...

 

 

Ναι, αλλά έτσι πηγαίνει από την Αθήνα στον Πειραιά μέσω Λαμίας.

Και άντε εδώ εντάξει. Σε άλλες περιπτώσεις όπως αυτή που ανάφερα (μετατροπή

αναδρομικών συναρτήσεων σε επαναληπτικές) αυτό δεν εξυπηρετεί καθόλου την σαφήνεια - αν μπορεί να γίνει βέβαια...

 

Το θέμα είναι ότι στην C++ εμφωλιασμένες (nested) συναρτήσεις δεν υποστηρίζονται εγγενώς όπως αλλού.

"Ματζούνια" δεν αμφιβάλλω ότι μπορούν να γίνουν...

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...