top of page

Magic Numbers: When to Use #define in C

Introduction


Say you're designing an online shopping app that allows a visitor to purchase up to 152 items at a time.


Or maybe you're creating some mathematical algorithm that predicts the logistic growth of a population using the constant e or 2.718281828459045…


P(t) = L / (1 + be⁻ᵏᵗ)

Wouldn't it be nice to store these independent, and seemingly random, values in one aptly-named place?


Perhaps the option we're most accustomed to use a variable. However, using magic numbers is another potential solution that has its own merits.


What are Magic Numbers?


  • preprocessor directive / macro

    • helps with creating symbolic constants

    • processes code before compilation

    • syntax for creating a "magic number"


#define MAX_PURCHASES 152

In this case, MAX_PURCHASES is the name and 152 is the value. So now, whenever you use MAX_PURCHASES in your code, it will get automatically treated as 152.


Wait a minute... isn't that what global variables do?


The difference here is that magic numbers are processed before the code compiles, meaning that all it effectively does is finds all instances of the magic number name in your code and replaces them with the assigned value before runtime. The advantage to this is that it takes up no memory space, unlike variables.


Further, magic numbers cannot be accidently modified (e.g. MAX_PURCHASES++ does not change the value to 153 because it is nothing more than a number in disguise).


Naming Convention


  • magic number names are almost always capitalized

    • differentiates them easily from variables

    • makes the code more readable

    • exceptions can be made:

      • #define e 2.718281828459045

      • here, you could argue that e is more easily recognized and readable in its lowercase form

  • doesn't require type declaration

    • can be an int, float, string (" "), etc.


#define vs. const


While the value of a const cannot be changed like a #define, there are a couple of advantages and disadvantages to both:


  • consts take up memory, while #defines are processed before compilation and don't

  • consts have type safety because the compiler knows the type of the variable, while #defines simply replace the name with the value


Final Thoughts


In summary, if you ever have a seemingly arbitrary constant lurking within your program, consider using a magic number (or string!) for better design and efficiency.



Thanks for reading!


Comments


bottom of page