Lesson content
Read, practise, then check your understanding
A literal writes a value directly in source code. A constant expression can be evaluated where the language requires a compile-time value. A const-qualified object cannot be modified through that qualified lvalue, but it is not automatically a compile-time constant in every C context.
Integer literals
Decimal literals begin normally, octal literals begin with 0, and hexadecimal literals begin with 0x or 0X. Binary literals are standardized in C23 and supported earlier by some compilers.
int decimal = 42;
int octal = 052; // also 42; avoid accidental leading zeroes
int hexadecimal = 0x2A;
unsigned long limit = 1000UL;
Suffixes influence type: U means unsigned, L means long, and LL means long long. The compiler otherwise chooses the first type in a standard candidate list that can represent the value.
Floating, character, and string literals
An unsuffixed floating literal such as 3.14 is double; 3.14f is float, and 3.14L is long double. Scientific notation is useful for scale: 6.022e23.
Escape sequences represent special characters:
char newline = '\n';
char quote = '\'';
const char *message = "first line\nsecond line";
Adjacent string literals concatenate during translation, which helps format long messages.
Named constants
Use names to explain meaning and centralize change:
enum { MAX_RETRIES = 4, BUFFER_SIZE = 256 };
static const double tax_rate = 0.18;
Enumeration constants are integer constant expressions and work for array bounds in ordinary declarations. A file-scope static const object has internal linkage but is still an object with storage.
Macros can define constants, but they have no C type and obey textual substitution:
#define SECONDS_PER_MINUTE 60
Prefer enum or typed const objects when their semantics fit. Use a macro when conditional preprocessing or token substitution is actually needed.
const and pointers
Read declarations from the identifier outward:
const int *read_only_value; // pointer to const int
int *const fixed_pointer = &count; // const pointer to int
const int *const both_fixed = &count;
const makes interfaces clearer and helps the compiler reject accidental writes. It does not make a casted write safe: modifying an object originally defined as const produces undefined behavior.
Knowledge check
Answer every question correctly to complete this chapter.
0 of 10 checks passed
Your progress is saved on this device.