Define and macros in C: solved exercise

Define and macros in C: solved exercise

If you searched for a solved #define and macros exercise in C, here are the most common patterns: symbolic constants, function-like macros, and a safe SWAP macro using the do { } while (0) idiom.

Preprocessor macros are expanded before compilation: they generate no function call overhead and have no type, which makes them fast but also dangerous if used carelessly.

Problem statement

Implement and use the following macros:

  • PI: constant with the value of π.
  • SQUARE(x): returns x squared.
  • MAX(a, b): returns the greater of two values.
  • SWAP(T, a, b): swaps two variables of type T.

C solution

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>

#define PI            3.14159
#define SQUARE(x)     ((x) * (x))
#define MAX(a, b)     ((a) > (b) ? (a) : (b))
#define SWAP(T, a, b) do { T _tmp = (a); (a) = (b); (b) = _tmp; } while (0)

int main(void) {
    double r = 3.0;
    printf("Circle area (r=%.1f): %.5f\n", r, PI * SQUARE(r));
    printf("SQUARE(5)   = %d\n", SQUARE(5));
    printf("MAX(7, 3)   = %d\n", MAX(7, 3));

    int x = 10, y = 20;
    SWAP(int, x, y);
    printf("After SWAP: x=%d, y=%d\n", x, y);

    return 0;
}

Expected output

1
2
3
4
Circle area (r=3.0): 28.27431
SQUARE(5)   = 25
MAX(7, 3)   = 7
After SWAP: x=20, y=10

Common mistakes

  • Not wrapping macro parameters in parentheses: SQUARE(1+2) without them expands to 1+2 * 1+2 = 5 instead of 9.
  • Not using do { } while (0) for multi-statement macros: without it, a bare if may not execute all statements in the macro.
  • Passing expressions with ++ or function calls as macro arguments: MAX(f(), g()) evaluates each argument twice.
  • Confusing #define with const: const has a type and scope; #define is raw text with neither.

Practical use

#define is used for configuration constants (buffer sizes, bit masks), debug macros (DEBUG_PRINT), and minimal abstractions that avoid function call overhead on performance-critical paths.

Guided practice and full book

If you want a complete path with progressive difficulty:

FAQ

Why wrap macro parameters in parentheses?

Because macros are text substitution. Without parentheses, SQUARE(1+2) becomes 1+2 * 1+2 due to operator precedence, giving 5 instead of 9. With parentheses: ((1+2) * (1+2)) = 9.

What is the difference between #define PI 3.14 and const double PI = 3.14?

#define is typeless, scopeless text substitution that is invisible to the debugger. const double has a type, block scope, and shows up in the debugger. In modern C, prefer const or enum for named constants.

What is the do { } while (0) idiom for in multi-statement macros?

It lets you use the macro as a normal statement: if (cond) SWAP(int, a, b); else .... Without this wrapper, only the first statement of the macro would be under the if.