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

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

Δημοσ.

Λοιπόν προσωπικά γνωρίζω 3 τρόπους για να δηλώσουμε σταθερές

1)const int x=10;

2)#define x=10

3)emu boolen {x=10};

 

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

Δημοσ.

Το #define ειναι preprocessor command και αντικαθιστα τη σταθερα με την τιμη που εχεις ορισει.

(Αυτο γινετε σε καποιο απ τα βηματα της μεταγλωττισης του κωδικα) δεν χρειαζεται το =

παραδειγμα:

πριν τη μεταγλωττιση

>#define N 9
printf("%d", N);

μετα την φαση αντικαταστασης

>printf("%d", 9);

Δημοσ.

Λοιπόν προσωπικά γνωρίζω 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;
...

Δημοσ.

Λοιπόν προσωπικά γνωρίζω 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.

 

 

Δημοσ.

Το "#define Χ 10" όπως είπε ο nilosgr είναι εντολή του preprocessor. Η αντικατάσταση γίνεται λεξικογραφικά δηλαδή όπου υπάρχει στον κώδικα το X, θα ήταν σαν να είχες γράψει 10. Ο compiler θα δει μόνο το 10 χωρίς να ξέρει αν το έγραψες εσύ απευθείας ή αν μεσολάβησε ο preprocessor. Επίσης, αν κάνεις debug θα δεις μόνο την τιμή 10 χωρίς να μπορείς να δεις τι συμβολίζει αυτή.

...

Ο gdb κάνει macro handling αν στον gcc περάσουμε το flag -g3 (αντί για σκέτο -g). ;)

Δημοσ.

Ο 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 και μπορεί να μας προειδοποιήσει για μ..κίες που μπορεί να γίνουν.

Δημοσ.

Δεν διαφωνώ φίλε ημίθεε στα υπέρ και κατά των 3 τρόπων, άλλωστε αν παρατηρήσεις τα είχα ήδη απαριθμήσει κι εγώ πριν το αρχικό σου ποστ. Η τελευταία μου παράθεση του μηνύματός σου αφορούσε τα περί debugging...

 

Με:

>
gcc -g3 myprog.c
gdb a.out

βλέπεις κανονικά τα ονόματα των #define σταθερών σου μέσα στον gdb.

Δημοσ.

Επισης να δωσεις σε gcc το flag -E μπορεις να δεις το παραγωμενο αρχειο μετα την αντικατασταση των #define (και των αλλων preprocessor commands)

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

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

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

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

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

Σύνδεση

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

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