The real question is whether n
should be a declared const
object or a macro. (The question's title currently refers to "a variable or a symbolic constant".)
This:
const int myNumber = 12;
makes myNumber
const
but not constant. The const
keyword means that you're not allowed to modify the object it applies to, but it doesn't make it constant. Switch labels, for example, must be constant; you can't write:
switch (n) {
case myNumber:
...
}
So if you need to use myNumber
in a context that requires a constant expression, the above isn't going to work.
On the other hand, a macro:
#define MY_NUMBER 12
means that any use of MY_NUMBER
is replaced by a literal 12
, which is constant. A drawback of macros is that they're not scoped the way declared objects are; the name MY_NUMBER
is visible from the definition to the end of the source file, which can cause conflicts. (Note that macro names are conventionally written in all-caps, specifically to draw attention to them.) In effect, the preprocessor, which is where macros are handled is another language tacked onto C.
For constants of type int
, there's another trick you can use (I don't think K&R mention this):
enum { myNumber = 12 };
This creates an anonymous enumeration type, which you aren't actually going to use. myNumber
is actually of type int
, not of the enumeration type, and you can use it the same way you'd use the literal 12
. You can even use an expression to define its value, as long as the expression is constant:
enum { myNumber = 3 * 4 };
(C++ has different rules. In C++, const int myNumber = 12;
does make myNumber
a constant expression -- and enumeration constants are of the enumerated type, not of type int
.)