Skip to Content
Course content
Click on the "Edit" button in the top corner of the screen to edit your slide content.

Up until now, we've been hard-coding values or using variables for everything. But as you start building larger projects, you'll find yourself repeating the same magic numbers or writing the same tiny, one-line formulas over and over. That's where the preprocessor comes in, specifically with #define.

Think of a macro not as a variable, but as a "find and replace" instruction for the compiler. Before your code is even compiled into machine instructions, the preprocessor scans your file and swaps every instance of your macro name with the value you defined. It's fast, it's lightweight, and it can be dangerous if you aren't careful.

Setting up our physics constants

Let's imagine we're writing a small physics module for a 2D game. We need the value of PI and a gravity constant. I could use a const float, but in C, using #define for global constants is a standard pattern because it doesn't occupy any memory at runtime.

#include <stdio.h>

#define PI 3.14159
#define GRAVITY 9.81

int main() {
    float radius = 5.0;
    float area = PI * radius * radius;
    printf("The area of the circle is: %f\n", area);
    return 0;
}

Simple enough. The compiler just sees 3.14159 * radius * radius. No variable lookup is required.

Adding a shortcut for squaring

Since we're doing physics, we're going to be squaring numbers constantly. Writing x * x is fine, but I want something that looks cleaner. I'll create a function-like macro for this. I'll call it SQUARE.

#define SQUARE(x) x * x

Now, I can just write SQUARE(radius). It feels like a function, but it's actually just the preprocessor pasting code. I'll try to calculate the area of a circle where the radius is a small calculation, like (2 + 3).

float area = PI * SQUARE(2 + 3);

I'm expecting the radius to be 5, so the square should be 25. But when I run this, I get a weird result. The area comes out way too low. Why? Because I forgot that macros are literal text replacement. The preprocessor expanded my code to this:

float area = 3.14159 * 2 + 3 * 2 + 3;

Order of operations ruined me. The multiplication happened before the addition, and I ended up with something entirely different from 5 * 5.

Protecting the macro with parentheses

This is the classic "gotcha" with C macros. Whenever you're writing a macro that takes arguments, you have to wrap everything in parentheses. You wrap the individual arguments and the entire expression. It looks a bit cluttered, but it's the only way to ensure the math stays correct regardless of what the user passes in.

#define SQUARE(x) ((x) * (x))

Now, if I call SQUARE(2 + 3), it expands to ((2 + 3) * (2 + 3)). That's exactly what we want. Here is the corrected version of our physics snippet:

#include <stdio.h>

#define PI 3.14159
#define GRAVITY 9.81
#define SQUARE(x) ((x) * (x))

int main() {
    float radius = 2 + 3;
    float area = PI * SQUARE(radius);
    
    printf("Radius: %.2f\n", radius);
    printf("Area: %.2f\n", area);
    
    return 0;
}

One last tip: you'll notice I used uppercase for PI and SQUARE. This is a convention in C. Since macros don't follow the same scoping rules as variables and can change your code in unexpected ways, we use all-caps to scream to other developers: "Heads up! This is a macro, not a variable!"




📋 Practical Task

Building a Cylinder Volume Calculator

Create a program that calculates the volume of a cylinder. You must use #define for the following:

  • A constant for PI (3.14159).
  • A macro called CUBE that takes one argument and returns its cube (the value multiplied by itself three times). Ensure you use parentheses to prevent the order-of-operations bug we discussed.

In your main function, prompt the user to enter a radius and a height. Calculate the volume using the formula: Volume = PI * (radius squared) * height. To make it interesting, try to use your CUBE macro to calculate the volume of a "perfect cylinder" (where height equals radius) as a second output.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.