Skip to Content
Course content

65: typedef for Cleaner Code

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

By now, you've probably spent a fair amount of time writing struct definitions. You've also likely noticed that C can be a bit repetitive. That's where typedef comes in. It isn't creating a new type—it's just giving an existing type a nickname.

Why do I have to keep writing the word "struct" every time I declare a variable?

If you've defined a struct for something like a 2D coordinate, you've probably realized that writing struct Point p1; and struct Point p2; gets tedious. It feels like redundant noise. I hate that noise too.

You can use typedef to tell the compiler, "From now on, whenever I say Point, I actually mean struct Point." You can even do this in one shot during the definition:

typedef struct {
    float x;
    float y;
} Point;

// Now you can just do this:
Point p1 = {10.0f, 20.0f};
Point p2 = {5.0f, -2.0f};

Now your code looks much cleaner, and it reads more like a modern language. You're treating Point as a first-class type rather than a "structure of type Point."

Can't I just use a #define to do the same thing?

This is a classic question. On the surface, #define POINT struct Point looks like it does the same thing. But remember: the preprocessor is just a find-and-replace tool. It doesn't understand C syntax; it just swaps text before the compiler ever sees it.

The danger becomes obvious when you deal with pointers. Look at this comparison:

typedef int* int_ptr;
#define INT_PTR int*

int_ptr a, b; // Both a and b are pointers to integers.
INT_PTR c, d; // c is a pointer, but d is just a regular integer!

In the #define example, the preprocessor turns INT_PTR c, d; into int* c, d;. In C, the asterisk binds to the variable name, not the type. This is a subtle bug that can haunt you for hours. typedef creates a real type alias that the compiler understands, so it treats the entire alias as a single unit. Always use typedef for types.

Does it actually make sense to typedef basic types like ints or floats?

At first glance, typedef float Distance; seems useless. Why rename a float? But as your projects grow, it's less about the computer and more about the human reading your code. This is what I call "semantic labeling."

Imagine you're writing a physics engine. If I see a function signature like this:

void move_entity(float x, float y, float speed);

It's fine, but it's generic. Now look at this:

typedef float Coordinate;
typedef float Velocity;

void move_entity(Coordinate x, Coordinate y, Velocity speed);

Suddenly, the code tells a story. If you ever decide that Coordinate needs to be a double for higher precision, you only have to change one line of code instead of searching and replacing every float in your entire project. It gives you a single point of control.




📋 Practical Task

Implementing a 2D Vector Math Library

Create a small program that manages 2D vectors for a game. Your task is to:

  • Use typedef struct to create a Vec2 type containing two floats (x and y).
  • Use typedef to create a semantic type called Scalar (based on float) to represent scaling factors.
  • Write a function Vec2 scale_vector(Vec2 v, Scalar s) that multiplies the vector's components by the scalar and returns a new Vec2.
  • In main, initialize a Vec2, scale it by a Scalar, and print the results.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.