Constants
Some values should never change: the number of days in a week, a tax rate, the size of a buffer. C gives you three ways to name them — const variables, #define macros and enum constants — and each has its place.
const variables
const makes a variable read-only. The compiler rejects any attempt to change it:
#include <stdio.h> int main(void) { const double VAT_RATE = 0.20; VAT_RATE = 0.25; printf("%.2f\n", VAT_RATE); return 0; }
main.c:5:14: error: cannot assign to variable 'VAT_RATE' with const-qualified type 'const double'
A const variable has a type, follows normal scope rules and shows up in the debugger — the safest choice for most constants.
#include <stdio.h> int main(void) { const double VAT_RATE = 0.20; const int DAYS_PER_WEEK = 7; double net = 50.0; printf("Gross: %.2f\n", net * (1 + VAT_RATE)); printf("Weeks in 365 days: %d\n", 365 / DAYS_PER_WEEK); return 0; }
Gross: 60.00 Weeks in 365 days: 52
#define macros
The preprocessor replaces a macro name with its text before compiling (lesson 4). Macros have no type and no scope, but they work anywhere a literal value is needed, such as array sizes in older C:
#include <stdio.h> #define MAX_NAME 32 #define PI 3.14159265358979 int main(void) { char name[MAX_NAME] = "Ada"; double r = 2.0; printf("%s: room for %d characters\n", name, MAX_NAME); printf("Circle area: %.3f\n", PI * r * r); return 0; }
Ada: room for 32 characters Circle area: 12.566
No = and no semicolon in a #define: #define MAX_NAME = 32; would paste = 32; everywhere. By convention macro names are all capitals.
enum constants
An enum defines a set of named integer constants. They're ideal for related values and are real constant expressions:
#include <stdio.h> enum { BOARD_SIZE = 8, MAX_PLAYERS = 4 }; enum weekday { MONDAY = 1, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY }; int main(void) { int board[BOARD_SIZE]; printf("%zu squares in a row\n", sizeof board / sizeof board[0]); printf("Wednesday is day %d\n", WEDNESDAY); printf("Up to %d players\n", MAX_PLAYERS); return 0; }
8 squares in a row Wednesday is day 3 Up to 4 players
Values count up from the previous one, so TUESDAY is 2. Lesson 43 covers enums fully.
Which to use
const | #define | enum | |
|---|---|---|---|
| Has a type | Yes | No | int |
| Respects scope | Yes | No — applies to the rest of the file | Yes |
Usable as an array size at file scope / in case labels | No (before C23's constexpr) | Yes | Yes |
| Non-integer values | Yes | Yes | No |
| Best for | Typed values, especially double and strings | Conditional compilation, values shared through headers | Integer constants and sets of choices |
C23 adds constexpr, which combines the advantages of const and true constant expressions (lesson 55).
Literals
A value written directly in code is a literal: 42, 3.5, 'x', "hello". Numbers with no explanation are called magic numbers — if (temp > 37.5) is clearer as if (temp > FEVER_THRESHOLD). Name the constant once, and changing it later means editing one line.
Try it yourself
Replace the magic numbers with named constants.
2 days, 7 hours, 33 minutes, 20 seconds