Εμφάνιση 1-5 από 5
  1. #1
    Εγγραφή
    04-02-2009
    Ηλικία
    33
    Μηνύματα
    1.486
    Downloads
    4
    Uploads
    0
    Τύπος
    ADSL
    Ταχύτητα
    2048/256
    ISP
    Cyta Hellas
    Διαβάζω για τους function pointers και ότι είναι χρήσιμοι λέει όταν θες callback. Μετά από αυτό το παράδειγμα μπερδεύτηκα ακόμα παραπανω.

    Κώδικας:
    #include <iostream>
    
    // An example of a callback function
    bool update_progress( int pct )
    {
    	std::cout << pct << "% complete...\n";
    	return true;
    }
    
    // A function that runs for a while
    void some_long_operation( bool (*update_progress)(int) )
    {
    	for ( long l = 0; l < 100000000; l++ )
    	{
    		if ( l % 10000000 == 0 )
    		{
    			update_progress( l / 1000000 );
    		}
    	}
    }
    
    void some_long_operation2()
    {
    	for ( long l = 0; l < 100000000; l++ )
    	{
    		if ( l % 10000000 == 0 )
    		{
    			update_progress( l / 1000000 );
    		}
    	}
    }
    
    int main( int argc, char **argv )
    {
    	some_long_operation( update_progress );                    // ok
    	some_long_operation2();
    }
    Και οι 2 συναρτήσεις τρέχουν και παράγουν το ίδιο αποτέλεσμα. Με ποιον τρόπο διαφέρει η μία από την άλλη και που χρησιμεύουν σε απλά ελληνικά;
    Με ΜΑΤ και βία δεν βγαίνει πανδημία, Μιχαλάκη και Κούλη.

  2. #2
    Εγγραφή
    13-11-2011
    Περιοχή
    Χολαργός
    Ηλικία
    37
    Μηνύματα
    1.451
    Downloads
    1
    Uploads
    0
    Τύπος
    VDSL2
    Ταχύτητα
    24000 / 4500
    ISP
    Wind
    DSLAM
    Wind - ΧΟΛΑΡΓΟΣ
    Path Level
    Interleaved
    Ενα απλό παράδειγμα είναι οταν θέλεις να τρέξεις κατι σε διαφορετικό thread και να σε ενημερώσει ότι τελειωσε. Όταν γράφεις εσυ τον κώδικα και έχεις ενα αποτέλεσμα ειναι εύκολο να γράψεις ποια συνάρτηση θα καλέσει στο τέλος.
    Όταν χρησιμοποιείς μια βιβλιοθήκη όμως και τρέξει κατι σε άλλο thread, πώς θα σε ενημερώσει ότι αυτό που έκανε τελείωσε; εκει του περνάς σαν παράμετρο τη συνάρτηση που θέλεις να καλέσει οταν τελειώσει (callback). Έτσι και το προγραμμα σου συνεχίζει να λειτουργεί κανονικά (πχ ένα gui παραμένει responsive) και ξέρεις πότε τελείωσε αυτό που έκανες.

    Στο παράδειγμα που έχεις χρησιμοποιεί την callback για να ενημερώσει για το ποσοστό ολοκλήρωσης. Μπορεί να έχεις μια συνάρτηση που ειναι "βαριά" και 2 συναρτήσεις που ενημερώνουν για το ποσοστό ολοκληρωσης (πχ console και gui). Ανάλογα με το ποια θέλεις να χρησιμοποιήσεις την περνάς στη συνάρτηση ώστε να ενημερώνει τη σωστή.

    - - - Updated - - -

    Ίσως σε μπερδεύει ότι και στις δύο περιπτώσεις καλεί την update_progress.
    Κώδικας:
    #include <iostream>
    
    // An example of a callback function
    bool update_progress( int pct )
    {
    	std::cout << pct << "% complete...\n";
    	return true;
    }
    
    // A function that runs for a while
    void some_long_operation( bool (*update_function)(int) )
    {
    	for ( long l = 0; l < 100000000; l++ )
    	{
    		if ( l % 10000000 == 0 )
    		{
    			update_function( l / 1000000 );
    		}
    	}
    }
    
    void some_long_operation2()
    {
    	for ( long l = 0; l < 100000000; l++ )
    	{
    		if ( l % 10000000 == 0 )
    		{
    			update_progress( l / 1000000 );
    		}
    	}
    }
    
    int main( int argc, char **argv )
    {
    	some_long_operation( update_progress );                    // ok
    	some_long_operation2();
    }
    Και στο δικό σου και σε αυτό το παράδειγμα, οι συναρτήσεις some_long_operation καλούν την update_progress αλλά με διαφορετικό τρόπο.
    Η some_long_operation2 την καλεί με το όνομά της, ενώ η some_long_operation καλεί την συνάρτηση που κάποιος του δίνει σαν παράμετρο. Δηλαδή το void some_long_operation( bool (*update_function)(int) ) δηλώνει μία συνάρτηση που παίρνει σαν παράμετρο μία συνάρτηση που επιστρέφει bool και δέχεται σαν παράμετρο ένα int.

    Κώδικας:
    #include <iostream>
    
    // An example of a callback function
    bool update_progress( int pct )
    {
    	std::cout << pct << "% complete...\n";
    	return true;
    }
    
    bool update_progress2( int pct )
    {
            for(int i=0; i< pct; ++i)
                     std::cout << '.';
            std::cout << endl;
    	return true;
    }
    
    // A function that runs for a while
    void some_long_operation( bool (*update_function)(int) )
    {
    	for ( long l = 0; l < 100000000; l++ )
    	{
    		if ( l % 10000000 == 0 )
    		{
    			update_function( l / 1000000 );
    		}
    	}
    }
    
    void some_long_operation2()
    {
    	for ( long l = 0; l < 100000000; l++ )
    	{
    		if ( l % 10000000 == 0 )
    		{
    			update_progress( l / 1000000 );
    		}
    	}
    }
    
    int main( int argc, char **argv )
    {
    	some_long_operation( update_progress );
            some_long_operation( update_progress2 );
    	some_long_operation2();
    }
    Σε αυτό το παράδειγμα αλλάζουμε το τρόπο που απεικονίζεται το ποσοστό και μία το κάνουμε με λεκτικό ("5% complete...") και μία με τελείες ("....").
    Με το some_long_operation2 δεν μπορείς να το πετύχεις χωρίς να αλλάξεις τον κώδικά του.

  3. #3
    Εγγραφή
    04-02-2009
    Ηλικία
    33
    Μηνύματα
    1.486
    Downloads
    4
    Uploads
    0
    Τύπος
    ADSL
    Ταχύτητα
    2048/256
    ISP
    Cyta Hellas
    Στο πρώτο παράδειγμα χρησιμοποίησες την update_function και όχι *_progress. Ψάχνοντας το γιατί, βρήκα ότι δεν χρειάζεται να γνωρίζει ποια συνάρτηση (όνομα) θα καλέσει. Έχεις όμως στο δευτερο παράδειγμα, μια δεύτερη συνάρτηση με την ίδια υπογραφή. Πως αποφασίζει ποια συνάρτηση θα καλέσει με βάση τον function pointer;
    Με ΜΑΤ και βία δεν βγαίνει πανδημία, Μιχαλάκη και Κούλη.

  4. #4
    Εγγραφή
    13-11-2011
    Περιοχή
    Χολαργός
    Ηλικία
    37
    Μηνύματα
    1.451
    Downloads
    1
    Uploads
    0
    Τύπος
    VDSL2
    Ταχύτητα
    24000 / 4500
    ISP
    Wind
    DSLAM
    Wind - ΧΟΛΑΡΓΟΣ
    Path Level
    Interleaved
    Αν δεις στην main, όταν καλούμε την some_long_operation του περνάμε σαν παράμετρο τη συνάρτηση που θα καλέσει όταν φτάσει στο update_function( l / 1000000 );. Οπότε την πρώτη φορά του δίνουμε το update_progress ενώ την δεύτερη το update_progress2. Δεν βρίσκει μόνο του μία συνάρτηση με αυτή την υπογραφή. Όποιος τον καλεί είναι υποχρεωμένος να του δώσει σαν παράμετρο μία συνάρτηση με αυτή την υπογραφή.

    Είναι σαν να είχες μία συνάρτηση bool test(int x){, όποιος την καλεί πρέπει να περάσει σαν παράμετρο μία int μεταβλητή. Αν δεν την περάσει θα σκάσει στο compile. Μέσα στη συνάρτηση χρησιμοποιείς την μεταβλητή x σαν int.
    Αντίστοιχα στην some_long_operation όποιος την καλέσει πρέπει να περάσει μία μεταβλητή με αυτή την υπογραφή (function ουσιαστικά). Αν δεν την περάσει θα σκάσει στο compile. Μέσα στη συνάρτηση χρησιμοποιείς την μεταβλητή update_function σαν (ένα δείκτη σε) μία συνάρτηση που παίρνει έναν ακέραιο και επιστρέφει ένα bool.

  5. #5
    Εγγραφή
    04-02-2009
    Ηλικία
    33
    Μηνύματα
    1.486
    Downloads
    4
    Uploads
    0
    Τύπος
    ADSL
    Ταχύτητα
    2048/256
    ISP
    Cyta Hellas
    Παράθεση Αρχικό μήνυμα από MitsakosGR Εμφάνιση μηνυμάτων
    Αν δεις στην main, όταν καλούμε την some_long_operation του περνάμε σαν παράμετρο τη συνάρτηση που θα καλέσει όταν φτάσει στο update_function( l / 1000000 );. Οπότε την πρώτη φορά του δίνουμε το update_progress ενώ την δεύτερη το update_progress2
    Έβγαζε μάτι τώρα που το λες

    Αύριο θα μελετήσω και πως στο 1.2 αντικαθιστά την κλήση διαφορετικών συναρτήσεων με switch/multiple ifs, με την χρήση function pointers και ίσως επανέλθω. Ευχαριστώ για τον χρόνο σου
    Με ΜΑΤ και βία δεν βγαίνει πανδημία, Μιχαλάκη και Κούλη.

Παρόμοια Θέματα

  1. Μηνύματα: 31
    Τελευταίο Μήνυμα: 24-11-20, 12:37
  2. Πώς να συνδέσω μια ISDN γραμμή σε Freepbx κέντρο;
    Από mechpanos στο φόρουμ Voice over IP (VoIP) Sip/Iax Hardware
    Μηνύματα: 44
    Τελευταίο Μήνυμα: 11-01-18, 19:25
  3. Μηνύματα: 30
    Τελευταίο Μήνυμα: 21-12-17, 18:16

Tags για αυτό το Θέμα

Bookmarks

Bookmarks

Δικαιώματα - Επιλογές

  • Δεν μπορείτε να δημοσιεύσετε νέα θέματα
  • Δεν μπορείτε να δημοσιεύσετε νέα μηνύματα
  • Δεν μπορείτε να αναρτήσετε συνημμένα
  • Δεν μπορείτε να επεξεργαστείτε τα μηνύματα σας
  •  
  • Τα BB code είναι σε λειτουργία
  • Τα Smilies είναι σε λειτουργία
  • Το [IMG] είναι σε λειτουργία
  • Το [VIDEO] είναι σε λειτουργία
  • Το HTML είναι εκτός λειτουργίας