In the C language, <span>#define</span> and <span>const</span> can both be used to define constants, but they have significant differences in implementation mechanisms, usage, and characteristics.
1. <span>#define</span> Macro Definition
<span>#define</span> is a preprocessor directive used to define macro constants (or symbolic constants), which replaces all occurrences of the macro name in the code with the specified text during the preprocessing stage.
Basic Syntax:
#define macro_name replacement_text
Characteristics:
- No Type Checking Macro definitions are simple text replacements, and the compiler does not perform type checking, which may hide type errors.
- Processed During Preprocessing Stage Replacements are completed in the preprocessing stage before compilation, and no memory is allocated for macros in the code.
- Can Define “Function Fragments” In addition to constants,
<span>#define</span>can also define parameterized macros (similar to function functionality). - Scope From the definition to the end of the file, it can be terminated early with
<span>#undef</span>.
Example:
#include <stdio.h>
// Define numerical constants
#define PI 3.14159
#define MAX_SIZE 100
// Define parameterized macro (similar to function)
#define SQUARE(x) ((x) * (x))
int main() {
// Replaced with 3.14159
printf("PI = %f\n", PI);
// Replaced with ((5) * (5))
printf("5's square = %d\n", SQUARE(5));
int i = 5;
printf("5's square = %d\n", SQUARE(i++));
printf("%d \n", i);
return 0;
}
Running Result:
Notes:
- Do not add a semicolon at the end of the macro definition, otherwise it will cause syntax errors after replacement.
- Be cautious with parentheses in parameterized macros to avoid operator precedence issues (as in
<span>SQUARE(x)</span>).
2. <span>const</span> Modified Constants
<span>const</span> is a keyword in C language used to define read-only variables (constants), for which the compiler allocates memory and performs type checking during compilation.
Basic Syntax:
const data_type constant_name = initial_value;
Characteristics:
- Type Checking
<span>const</span>defined constants have a clear data type, and the compiler performs type validation, making it safer. - Processed During Compilation Stage
<span>const</span>constants are determined at compile time and occupy memory (similar to variables). - Cannot Be Modified
<span>const</span>modified variable values cannot be changed; otherwise, the compiler will report an error. - Scope Follows variable scope rules (such as block scope, file scope, etc.).
- Can Be Used as Array Length In the C99 standard,
<span>const</span>constants can be used to specify the length of variable-length arrays (VLA).
Example:
int arr1[size] error:error C2131: The result of the expression is not a constant
Notes:
<span>const</span>defined constants must be initialized, otherwise they cannot be assigned (as they cannot be modified later).<span>const</span>‘s “read-only” feature is a compile-time restriction, and indirect modification through pointers may bypass the check.
3. <span>#define</span> vs <span>const</span> Core Differences
| Feature | <span>#define</span> Macro Constant |
<span>const</span> Read-Only Variable |
|---|---|---|
| Processing Stage | Preprocessing Stage (Text Replacement) | Compilation Stage |
| Type Checking | No | Yes |
| Memory Allocation | No Memory Allocation | Allocates Memory (like Variables) |
| Scope | From Definition to <span>#undef</span> or End of File |
Follows Variable Scope Rules |
| Debugging Support | Cannot be recognized by the debugger (already replaced) | Can be recognized by the debugger |
| Applicable Scenarios | Simple Constants, Parameterized Macro Functions | Constants with Clear Types, Constants Requiring Memory |
4. How to Choose?
- Prefer using
<span>const</span>when you need to define constants with clear types (such as<span>int</span>,<span>float</span>), and want the compiler to perform type checking. - Use
<span>#define</span>when you need to define simple untyped constants or need to implement macro functionality similar to functions (such as<span>SQUARE(x)</span>).
For example, define the mathematical constant <span>PI</span> using <span>#define</span>, while using <span>const</span> is more appropriate for defining array lengths or configuration parameters.
Using both appropriately can improve code readability, safety, and efficiency.