Exosouler Δημοσ. 10 Φεβρουαρίου 2012 Δημοσ. 10 Φεβρουαρίου 2012 Λοιπόν προσωπικά γνωρίζω 3 τρόπους για να δηλώσουμε σταθερές 1)const int x=10; 2)#define x=10 3)emu boolen {x=10}; Θέλω να ρωτήσω ποιά είναι η διαφορά μεταξύ τους και αν υπάρχει κι άλλος τρόπος να δηλώνουμε σταθερές.
nilosgr Δημοσ. 10 Φεβρουαρίου 2012 Δημοσ. 10 Φεβρουαρίου 2012 Το #define ειναι preprocessor command και αντικαθιστα τη σταθερα με την τιμη που εχεις ορισει. (Αυτο γινετε σε καποιο απ τα βηματα της μεταγλωττισης του κωδικα) δεν χρειαζεται το = παραδειγμα: πριν τη μεταγλωττιση >#define N 9 printf("%d", N); μετα την φαση αντικαταστασης >printf("%d", 9);
migf1 Δημοσ. 10 Φεβρουαρίου 2012 Δημοσ. 10 Φεβρουαρίου 2012 Λοιπόν προσωπικά γνωρίζω 3 τρόπους για να δηλώσουμε σταθερές 1)const int x=10; 2)#define x=10 3)emu boolen {x=10}; Θέλω να ρωτήσω ποιά είναι η διαφορά μεταξύ τους και αν υπάρχει κι άλλος τρόπος να δηλώνουμε σταθερές. Με #define είναι ο πιο ευέλικτος τρόπος από όλους, με const προσθέτεις type-checking μιας και ουσιαστικά ορίζεις μεταβλητή, αλλά χάνεις π.χ. τη δυνατότητα να την χρησιμοποιήσεις ως σταθερά για να ορίζεις μέγεθος στατικών πινάκων (αν το θυμάμαι καλά, βαριέμαι να το τσεκάρω τώρα με τα πρότυπα της γλώσσας), με enum μπορείς να προσθέσεις partial type-checking αν το συνδυάσεις με typdef (παρόλο που οι τιμές του θεωρούνται ισοδύναμες με int), π.χ... > typedef enum {FALSE=0, TRUE} boolean; ... boolean isenabled = FALSE; ...
imitheos Δημοσ. 10 Φεβρουαρίου 2012 Δημοσ. 10 Φεβρουαρίου 2012 Λοιπόν προσωπικά γνωρίζω 3 τρόπους για να δηλώσουμε σταθερές 1)const int x=10; 2)#define x=10 3)emu boolen {x=10}; Θέλω να ρωτήσω ποιά είναι η διαφορά μεταξύ τους και αν υπάρχει κι άλλος τρόπος να δηλώνουμε σταθερές. Το "#define Χ 10" όπως είπε ο nilosgr είναι εντολή του preprocessor. Η αντικατάσταση γίνεται λεξικογραφικά δηλαδή όπου υπάρχει στον κώδικα το X, θα ήταν σαν να είχες γράψει 10. Ο compiler θα δει μόνο το 10 χωρίς να ξέρει αν το έγραψες εσύ απευθείας ή αν μεσολάβησε ο preprocessor. Επίσης, αν κάνεις debug θα δεις μόνο την τιμή 10 χωρίς να μπορείς να δεις τι συμβολίζει αυτή. Η enum είναι λίγο καλύτερη από την άποψη ότι σου παρέχει ένα επίπεδο ελέγχου και μπορείς να δεις το όνομα κατά το debug. Με την const υπάρχει μια διαφοροποίηση στη συμπεριφορά της σε c και c++. > const int x = 10; int a[x]; Στην c δημιουργείς ένα "const object" και όχι μια μια σταθερά (constant). Το παραπάνω παράδειγμα δηλαδή είναι λάθος επειδή η x είναι κανονική μεταβλητή και δεν μπορεί να χρησιμοποιηθεί ως μέγεθος του array (ή να χρησιμοποιηθεί στην switch ή όπου αλλού χρειάζεται σταθερά). Αυτό που κάνεις με το const είναι να λες στον compiler ότι δεν σκοπεύεις να αλλάξεις την τιμή της μεταβλητής. Έτσι αυτός μπορεί να το λάβει υπόψην του και (αν γίνεται) να παράξει καλύτερο κώδικα. Edit: Να αναφέρω ότι το παράδειγμα που έγραψα παραπάνω λειτουργεί κανονικά σε C99. Αυτό όμως δεν γίνεται επειδή η x θεωρείται σταθερά αλλά λόγω στις Variable Length Arrays που παρέχει η C99.
migf1 Δημοσ. 10 Φεβρουαρίου 2012 Δημοσ. 10 Φεβρουαρίου 2012 Το "#define Χ 10" όπως είπε ο nilosgr είναι εντολή του preprocessor. Η αντικατάσταση γίνεται λεξικογραφικά δηλαδή όπου υπάρχει στον κώδικα το X, θα ήταν σαν να είχες γράψει 10. Ο compiler θα δει μόνο το 10 χωρίς να ξέρει αν το έγραψες εσύ απευθείας ή αν μεσολάβησε ο preprocessor. Επίσης, αν κάνεις debug θα δεις μόνο την τιμή 10 χωρίς να μπορείς να δεις τι συμβολίζει αυτή. ... Ο gdb κάνει macro handling αν στον gcc περάσουμε το flag -g3 (αντί για σκέτο -g).
imitheos Δημοσ. 10 Φεβρουαρίου 2012 Δημοσ. 10 Φεβρουαρίου 2012 Ο gdb κάνει macro handling αν στον gcc περάσουμε το flag -g3 (αντί για σκέτο -g). ΑΝ το περάσουμε και ακόμη και τότε το πρόβλημα της μη type-safety των #defines εξακολουθεί να υπάρχει ενώ με το enum το μόνο αρνητικό είναι ότι πρέπει να γράψεις πιο πολλά και έτσι είναι λίγο πιο άβολο αλλά πόσες φορές πια θα το γράψει κάποιος. > enum myenum { foo, bar, baz }; int main(void) { int k; enum myenum m; switch(m) { case foo: k = 3; case bar: k = 5; } return 0; } Εδώ παίρνουμε μήνυμα "enumeration value 'baz' not handled in switch". Χαζό παράδειγμα χωρίς νόημα φυσικά αλλά βλέπουμε ότι ο compiler γνωρίζει για το enum και μπορεί να μας προειδοποιήσει για μ..κίες που μπορεί να γίνουν.
migf1 Δημοσ. 10 Φεβρουαρίου 2012 Δημοσ. 10 Φεβρουαρίου 2012 Δεν διαφωνώ φίλε ημίθεε στα υπέρ και κατά των 3 τρόπων, άλλωστε αν παρατηρήσεις τα είχα ήδη απαριθμήσει κι εγώ πριν το αρχικό σου ποστ. Η τελευταία μου παράθεση του μηνύματός σου αφορούσε τα περί debugging... Με: > gcc -g3 myprog.c gdb a.out βλέπεις κανονικά τα ονόματα των #define σταθερών σου μέσα στον gdb.
nilosgr Δημοσ. 10 Φεβρουαρίου 2012 Δημοσ. 10 Φεβρουαρίου 2012 Επισης να δωσεις σε gcc το flag -E μπορεις να δεις το παραγωμενο αρχειο μετα την αντικατασταση των #define (και των αλλων preprocessor commands)
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα