Constants in C (const, enum, macro)

In previous articles we have seen how to declare variables and all the data types that we have available in the C language. In this post you will see a very special type that in programming we call constants. You will see what they are, how to create them and how to use them.
What is a constant?
In programming, a constant is a value that cannot be altered during the execution of a program. More specifically, what cannot be changed is the value in memory of an assignment (where a variable points to) - for example, an integer.
This means that if we have defined a variable with a value, this value cannot be changed at any point of the program.
Const
In C, we can define constants with the reserved keyword const
. See the following example where we define a decimal constant and print it to the screen.
#include <stdio.h>
int main()
{
const float pi = 3.1416;
printf("The value of PI is %.4f\n", pi);
}
If we tried to change the value of pi just before we print it, we would get a compiler error. It is for this same reason that constants must be initialized at the same time they are declared - because their value cannot be changed throughout the program.
Macros
Another way to define a constant (this applies more when you are going to use it in several files around your project) is with the preprocessor instruction DEFINE
, which allows you to use macros in C.
#include <stdio.h>
#define PI 3.1416
int main()
{
printf("The value of PI is %.4f\n", PI);
}
In this last case, the preprocessor will replace the defined value in each part of the file before passing the code to the compiler. Note that it is not necessary to place a semicolon at the end of the line with the preprocessor instruction.
Enum
Enumerated variables allow you to define grouped constants. Each constant belongs to a set called an "enumeration set". See the following definition where the YEAR type is defined.
enum YEAR {JAN=1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC };
When we use enum in this way, we are actually defining a data type that in our case is YEAR. The first value of the enumeration set will always be zero unless initialized with a different value. In our case, JAN was initialized with one. The other values will follow the sequence - FEB=2, and so on. See the following example.
#include <stdio.h>
#define MES_HASTA 5
int main()
{
enum YEAR {JAN=1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC};
for (int i = JAN; i <= DEC; i++) {
printf("Month No: %d\n", i);
if (i == MES_HASTA)
break;
}
return(0);
}
Note the use of the constants JAN and DEC to iterate through the months of the year. Since MES_HASTA is 5, the output in the console will be the following:
Month No: 1
Month No: 2
Month No: 3
Month No: 4
Month No: 5
We can also define variables of an enum type created by us. See the following example:
#include <stdio.h>
int main()
{
/* ESTADO data type is defined and the process variable of this type */
enum ESTADO { EXIT, OK } proceso;
int numero;
proceso = OK; /* constant OK is assigned to process */
while (proceso)
{
printf("Enter an even number:\n");
scanf("%d", &numero);
if (numero % 2 != 0)
proceso = EXIT;
}
printf("The number you entered is not even, GAME OVER!\n");
return(0);
}
For the C standard, an enumerated type is of type int. However, for C++, they are a different user-defined data type. If we wanted to change the assignment of the variable proceso to the following:
proceso = 1; // supposedly OK
We would get a compiler error similar to the following:
error: invalid conversion from ‘int’
In this last example, we could also declare and initialize a variable in the same statement, like this:
enum ESTADO proc2 = EXIT;