For numbers, certainly, const <type>
is preferred. This is chiefly because it imposes a type (which would only be optional for a #define
), which can have a knock-on effect for mathematics.
That's not to say that you should always use const <type>
instead of #define
. #define
has its place.
One of the benefits of #define
over const <type>
is that it is a direct literal text replacement. The replacement is done before the compilation, so anything that is valid in your code can be put in a #define
, whereas only things which evaluate to the correct type at runtime can be placed in a const <type>
.
Take strings for example. Yes, you can use:
const char *foo = "This is text";
And you can use that wherever a const char *
is expected. However, if you use:
#define FOO "This is text"
you can use it anywhere a string literal is expected. That makes for useful things such as C's way of concatenating string literals at compile time:
Serial.println("I say: " FOO);
The two string literals "I say: "
and FOO
(which expands to "This is text"
) are concatenated into a singe string literal at compile time into:
Serial.println("I say: This is text");
You can't do that with const char *
.
Another big difference with const <type>
compared with #define
is when expressions are evaluated. Take for example:
const float sinpi = sinf(3.141592653);
That will calculate the sine of PI once at startup. However:
#define SINPI sinf(3.141592653);
will calculate the sine of PI every time it is used.
So in this instance const float
not only gives you an imposed type of float
for all calculations, it also reduces calculation overhead by only running the calculation once and saving the result.
So as you can see there are pros and cons to each. But in general, for numbers:
const <type>
is preferred for storing internal numerical data that doesn't change, and
#define
is most often used for user-configurable data, since it doesn't impose the ;
at the end of the line which often gets forgotten by (newer) users.