Question

typedef struct vs struct in C: What's the Difference?

cstructtypedef

Question

I'm a beginner in C programming and I want to understand the difference between defining a structure with typedef and defining it without typedef.

These two examples seem to achieve the same result:

struct myStruct {
    int one;
    int two;
};

and

typedef struct {
    int one;
    int two;
} myStruct;

What is the actual difference between these two forms in C, and when would you use one over the other?

Short Answer

By the end of this page, you'll understand what a struct tag is in C, what typedef does, and why these two declarations look similar but are not exactly the same. You'll also learn the syntax developers use in real C codebases and how to choose the right form for readability and maintainability.

Concept

In C, struct and typedef solve related but different problems.

  • struct defines a structure type.
  • typedef creates an alias name for an existing type.

That means these are not identical operations.

1. Defining a struct without typedef

struct myStruct {
    int one;
    int two;
};

This creates a structure type with the tag myStruct.

To declare variables of that type, you must write:

struct myStruct a;

Notice that in C, the word struct is part of the type name when you use the tag.

2. Defining a struct with typedef

typedef struct {
    int one;
    int two;
} myStruct;

This creates an anonymous struct (a struct with no tag) and then gives it a typedef alias called myStruct.

Now you can declare variables like this:

myStruct a;

You do not write struct myStruct a; here, because myStruct is now a typedef name, not a struct tag.

Why this matters

The main difference is how you refer to the type later.

  • With a plain struct tag: use struct myStruct
  • With a typedef alias: use myStruct

This matters in real programming because type names appear everywhere:

  • function parameters
  • return types
  • pointers
  • arrays
  • API definitions
  • header files

A shorter, cleaner type name can make code easier to read. But using plain struct is also common, especially in traditional C code and codebases that want to make it explicit that the type is a structure.

Important: these two forms are not exactly equivalent

Your two examples are close in purpose, but not the same in meaning.

First version

struct myStruct {
    int one;
    int two;
};
  • Defines a struct tag: myStruct
  • Usable as struct myStruct
  • Does not create a typedef alias

Second version

typedef struct {
    int one;
    int two;
} myStruct;
  • Defines an anonymous struct
  • Creates a typedef alias: myStruct
  • Usable as myStruct
  • There is no struct tag named myStruct

So this would be invalid for the second version:

struct myStruct x;  // error: no struct tag named myStruct

A very common combined form

In C, you will often see this:

typedef struct myStruct {
    int one;
    int two;
} myStruct;

This creates both:

  • a struct tag: struct myStruct
  • a typedef alias: myStruct

Then both of these work:

struct myStruct a;
myStruct b;

This pattern is common in headers and library code because it gives flexibility.

Why developers use typedef

Common reasons:

  • Less typing
  • Cleaner function signatures
  • More readable public APIs
  • Consistent style with other typedef-based types

Common reasons not to use it:

  • It can hide that a type is a struct
  • Some C programmers prefer explicitness
  • Traditional C style often keeps struct visible

So the choice is often partly about style, but the language-level difference is still real: one creates a tag, the other creates a type alias.

Mental Model

Think of struct and typedef like a person and a nickname.

  • struct myStruct is the person's full formal name.
  • typedef ... myStruct is giving that type a shorter nickname.

If you only create the formal name, you must always use the full name:

struct myStruct x;

If you only create the nickname, you use the nickname:

myStruct x;

If you create both, you can use either one.

Another way to think about it:

  • struct creates the actual structure type definition.
  • typedef creates a label you can use instead of the original type spelling.

typedef does not create a new kind of data by itself. It only gives an existing type another name.

Take Quiz

Syntax and Examples

Core syntax

Struct with a tag only

struct Point {
    int x;
    int y;
};

struct Point p1;

Here, Point is a struct tag. You must write struct Point when declaring variables.

Typedef with an anonymous struct

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

Point p1;

Here, Point is a typedef alias. You use Point directly.

Typedef with a tagged struct

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

Point p1;
struct Point p2;

This gives you both forms.

Beginner-friendly example

#include <stdio.h>

typedef struct {
    int one;
    int two;
} MyStruct;

int main(void) {
    MyStruct value;
    value.one = 10;
    value.two = 20;

    printf("%d %d\n", value.one, value.two);
    return 0;
}

What this does

  • Defines a struct type with two integer fields
  • Creates the alias MyStruct
  • Declares a variable named value
  • Assigns values to the fields
  • Prints them

Equivalent idea without typedef

#include <stdio.h>

struct MyStruct {
    int one;
    int two;
};

int main(void) {
    struct MyStruct value;
    value.one = 10;
    value.two = 20;

    printf("%d %d\n", value.one, value.two);
    return 0;
}

This works the same at runtime. The difference is only in how the type is named in source code.

Step by Step Execution

Consider this example:

#include <stdio.h>

typedef struct {
    int one;
    int two;
} MyStruct;

int main(void) {
    MyStruct a;
    a.one = 5;
    a.two = 7;

    int total = a.one + a.two;
    printf("%d\n", total);
    return 0;
}

Step by step

1. The struct type is defined

typedef struct {
    int one;
    int two;
} MyStruct;
  • A struct is defined with two members: one and two
  • MyStruct becomes a typedef alias for that struct type

2. A variable is declared

MyStruct a;
  • Memory is reserved for one struct variable named a
  • It contains space for two int fields

3. Field values are assigned

a.one = 5;
a.two = 7;
  • a.one stores 5
  • a.two stores 7

4. The values are used

int total = a.one + a.two;
  • Reads a.one → 5
  • Reads a.two → 7
  • Adds them to get 12
  • Stores 12 in total

5. Output is printed

printf("%d\n", total);
  • Prints 12

Same logic without typedef

The only source-code difference is the type name:

struct MyStruct {
    int one;
    int two;
};

int main(void) {
    struct MyStruct a;
    a.one = 5;
    a.two = 7;

    int total = a.one + a.two;
    return 0;
}

Execution is effectively the same. The compiler just sees a different spelling of the type.

Real World Use Cases

Structures are used whenever you need to group related data together.

Common examples

User records

typedef struct {
    int id;
    char name[50];
} User;

Used in:

  • command-line tools
  • file parsing
  • database-like records in memory

2D points or geometry

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

Used in:

  • graphics programs
  • games
  • coordinate calculations

Configuration data

typedef struct {
    int port;
    int debug;
} Config;

Used in:

  • application settings
  • server startup options
  • embedded systems

API response models

typedef struct {
    int status;
    char message[100];
} Response;

Used in:

  • networking code
  • protocol handling
  • library interfaces

Where typedef helps in practice

If a type appears frequently in function signatures, a typedef can improve readability:

void print_user(User user);
int save_config(Config config);

Without typedef:

void print_user(struct User user);
int save_config(struct Config config);

Both are valid, but many programmers find the typedef form cleaner.

Take Quiz

Real Codebase Usage

In real C projects, the choice between struct X and typedef struct ... X often depends on team style, API design, and compatibility needs.

Common patterns

1. Public data models in header files

Libraries often use typedefs so users of the library get simple names:

typedef struct {
    int code;
    char text[64];
} ErrorInfo;

This keeps function signatures short:

ErrorInfo get_last_error(void);

2. Opaque structs for encapsulation

A common C pattern is to expose only a forward declaration in a header:

typedef struct FileHandle FileHandle;

The full struct definition is hidden in a .c file. This lets developers use pointers without seeing internal fields:

FileHandle *open_file(const char *path);

This is very common in libraries.

3. Self-referential structs

When a struct needs to refer to itself, a tag is useful:

typedef struct Node {
    int value;
    struct Node *next;
} Node;

Inside the definition, struct Node *next; uses the tag.

4. Validation and function boundaries

Structs are commonly passed to helper functions:

int is_valid_user(const User *user);
void print_user(const User *user);

Using typedef can make these signatures easier to scan.

5. Error handling and configuration objects

Large C programs often group related settings or status data into structs instead of passing many separate parameters.

int start_server(const Config *config);

This improves maintainability when requirements grow.

Common Mistakes

1. Thinking typedef creates a new struct kind

typedef does not create a brand new data structure. It only creates another name for a type.

typedef int Number;

Number is still just int.

The same idea applies to structs.

2. Mixing up tag names and typedef names

Broken example:

typedef struct {
    int one;
    int two;
} MyStruct;

struct MyStruct a;  // wrong

Why it fails:

  • MyStruct here is a typedef alias
  • There is no struct tag named MyStruct

Correct:

MyStruct a;

Or define both:

typedef struct MyStruct {
    int one;
    int two;
} MyStruct;

struct MyStruct a;
MyStruct b;

3. Forgetting struct when no typedef exists

Broken example:

struct Point {
    int x;
    int y;
};

Point p;  // wrong in C

Correct:

struct Point p;

4. Confusing C with C++

In C++, you can usually write:

Point p;

after defining a struct. In C, that only works if you used typedef.

5. Using lowercase names that look like variables

This is valid:

typedef struct {
    int one;
    int two;
} myStruct;

But beginners may confuse myStruct the type with myStruct a variable. Many codebases use names like MyStruct or my_struct_t to make type names clearer.

6. Anonymous struct limitations

If you use an anonymous struct with typedef, you cannot refer to it later by a tag name because it has no tag.

typedef struct {
    int value;
} Item;

This is fine unless you specifically need a struct tag, such as in some forward declaration or self-referential cases.

Comparisons

FormWhat it createsHow you declare a variableNotes
struct Point { ... };Struct tag Pointstruct Point p;Traditional C style
typedef struct { ... } Point;Typedef alias PointPoint p;Anonymous struct with alias
typedef struct Point { ... } Point;Tag Point and typedef alias Pointstruct Point p; or Point p;Very common in real projects

struct tag vs typedef alias

FeatureStruct tagTypedef alias
PurposeNames a struct type in the tag namespaceCreates an alternate type name
Requires struct keyword when usedYesNo
Can exist without typedefYesNo
Useful for self-referential structsYesIndirectly, but tag is usually needed

Which should you choose?

SituationCommon choice
Learning basic C syntaxstruct Name
Cleaner API namestypedef
Opaque library handlestypedef struct Name Name;
Linked lists or treesTagged struct, often with typedef too
Strictly explicit code stylePlain struct
Take Quiz

Cheat Sheet

Quick rules

  • struct X { ... }; defines a struct tag named X
  • Use it as struct X variable;
  • typedef struct { ... } X; creates a typedef alias named X
  • Use it as X variable;
  • typedef struct X { ... } X; gives you both forms

Common patterns

Tag only

struct Person {
    int age;
};

struct Person p;

Typedef only

typedef struct {
    int age;
} Person;

Person p;

Tag + typedef

typedef struct Person {
    int age;
} Person;

Person p1;
struct Person p2;

Important edge case

This does not create a struct tag:

typedef struct {
    int x;
} Point;

So this is invalid:

struct Point p;

Good rule of thumb

  • Want explicit traditional C? Use struct Name
  • Want shorter type names? Use typedef
  • Want flexibility? Use both

FAQ

What is the difference between struct and typedef struct in C?

struct defines a structure type with a tag, while typedef gives a type another name. A plain struct must be used as struct Name, but a typedef alias can be used as Name.

Does typedef struct create a new type?

Not in the same sense as defining a new kind of data. It creates an alias for a type. The underlying struct type is still the same.

Why do C programmers often use typedef with structs?

Mostly for convenience and readability. It removes the need to write struct every time the type is used.

Can I use struct MyType after typedef struct { ... } MyType;?

No. That form creates a typedef alias but no struct tag named MyType.

When should I use typedef struct Name { ... } Name;?

Use it when you want both a struct tag and a short alias. This is common in larger C projects and libraries.

Is this different in C++?

Yes. In C++, struct type names can usually be used directly without typedef. In C, you need typedef if you want that shorter form.

Which style is more correct?

Both are correct. The best choice depends on your codebase style, readability goals, and whether you need a struct tag.

Take Quiz

Mini Project

Description

Build a small C program that stores and prints information about a book. The goal is to practice defining a struct both conceptually and syntactically, and to see how a typedef makes declarations shorter in normal code.

Goal

Create a program that defines a Book structure, stores one book's data, and prints it using a function.

Requirements

  • Define a structure with fields for title, author, and year.
  • Use typedef so the type can be written without the struct keyword.
  • Create one variable of that type in main.
  • Assign values to all fields.
  • Write a function that accepts the struct and prints its contents.
Take Quiz

Keep learning

Related questions

View more