C Typedef

typedef is a keyword in C that creates a new name (an alias) for an existing data type. It does not create a new data type — it simply gives an existing type a different, often shorter or more descriptive name. Using typedef makes your code easier to read, more portable, and simpler to maintain.

Why Use typedef?

Without typedef, some type declarations in C can become long and repetitive — especially for structures, pointers, and function pointers. typedef hides that complexity behind a clean, meaningful name.

// Without typedef — repetitive and verbose
struct Point { int x; int y; };
struct Point p1;
struct Point p2;

// With typedef — clean and short
typedef struct { int x; int y; } Point;
Point p1;
Point p2;

Basic Syntax

typedef existing_type new_name;

Simple Examples

typedef int Integer;
typedef float Decimal;
typedef char Letter;
typedef unsigned long ULong;

Integer age = 25;       // same as: int age = 25;
Decimal price = 9.99;   // same as: float price = 9.99;
Letter grade = 'A';     // same as: char grade = 'A';

typedef with Structures

The most common use of typedef in C is with structures. Without typedef, you must write struct StructName every time you declare a variable of that type. With typedef, you just write the alias.

Without typedef

#include <stdio.h>

struct Student {
    char name[50];
    int age;
    float marks;
};

int main()
{
    struct Student s1;   // must write 'struct' every time
    struct Student s2;
    return 0;
}

With typedef

#include <stdio.h>

typedef struct {
    char name[50];
    int age;
    float marks;
} Student;   // 'Student' is now the type name

int main()
{
    Student s1;   // no 'struct' keyword needed
    Student s2;

    s1.age = 20;
    s1.marks = 85.5;

    printf("Age: %d, Marks: %.1f\n", s1.age, s1.marks);

    return 0;
}

typedef with Pointers

typedef can simplify pointer declarations — especially when working with pointers that appear many times in a program.

typedef int* IntPtr;

IntPtr a, b;   // both a and b are int pointers
// Equivalent to: int *a, *b;

Caution: typedef int* IntPtr; IntPtr a, b; makes both a and b pointers. But int* a, b; only makes a a pointer — b would be a regular int. typedef avoids this ambiguity.

#include <stdio.h>

typedef int* IntPtr;

int main()
{
    int x = 10;
    IntPtr ptr = &x;

    printf("Value: %d\n", *ptr);   // Output: 10
    return 0;
}

typedef with Function Pointers

Function pointer syntax is notoriously complex. typedef makes it manageable.

// Without typedef — hard to read
int (*mathFunc)(int, int);

// With typedef — readable
typedef int (*MathFunc)(int, int);
MathFunc add;
MathFunc multiply;
#include <stdio.h>

typedef int (*Operation)(int, int);   // Operation is now an alias for this function pointer type

int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }

int main()
{
    Operation op;

    op = add;
    printf("Add: %d\n", op(10, 5));   // Output: Add: 15

    op = sub;
    printf("Sub: %d\n", op(10, 5));   // Output: Sub: 5

    return 0;
}

typedef with Arrays

typedef int Matrix[3][3];   // Matrix is a 3x3 int array type

Matrix identity = {
    {1, 0, 0},
    {0, 1, 0},
    {0, 0, 1}
};

typedef for Portability

On different platforms, the size of basic types like int may differ. typedef is used in system headers to define types with guaranteed sizes.

// From <stdint.h> (part of C99 standard)
typedef unsigned char  uint8_t;    // always 8 bits
typedef unsigned short uint16_t;   // always 16 bits
typedef unsigned int   uint32_t;   // always 32 bits
typedef unsigned long long uint64_t;  // always 64 bits

// Using these in code ensures consistent behavior across platforms
uint8_t  byte = 255;
uint32_t count = 1000000;

Practical Example: Building a Contact Book

#include <stdio.h>
#include <string.h>

typedef struct {
    char name[50];
    char phone[15];
    char city[30];
} Contact;

void printContact(Contact c)
{
    printf("Name : %s\n", c.name);
    printf("Phone: %s\n", c.phone);
    printf("City : %s\n", c.city);
    printf("---\n");
}

int main()
{
    Contact book[2];

    strcpy(book[0].name, "Alice");
    strcpy(book[0].phone, "9876543210");
    strcpy(book[0].city, "Delhi");

    strcpy(book[1].name, "Bob");
    strcpy(book[1].phone, "9123456789");
    strcpy(book[1].city, "Mumbai");

    for (int i = 0; i < 2; i++)
        printContact(book[i]);

    return 0;
}

Output:

Name : Alice
Phone: 9876543210
City : Delhi
---
Name : Bob
Phone: 9123456789
City : Mumbai
---

typedef vs #define

Featuretypedef#define
Processed byCompilerPreprocessor
Type checkingYes — respects type rulesNo — just text replacement
ScopeFollows C block scopingGlobal from definition point
Pointer alias clarityYes — all declared variables are pointersNo — only the first gets *
Works with structuresYes — creates clean aliasesLimited, no real type name

Common typedef Patterns

// Boolean type (before C99 _Bool)
typedef int bool;
#define true  1
#define false 0

// String alias
typedef char* String;
String message = "Hello, World!";

// Size type
typedef unsigned int size_t;

Summary

The typedef keyword creates an alias for an existing data type, making code more readable and maintainable. It does not create a new type — it only gives the existing type a new name. typedef shines when used with structures (removing the need to write struct repeatedly), pointers (clarifying that all declared variables are pointers), and function pointers (simplifying complex declarations). Standard C libraries use typedef extensively for portable types like uint8_t and size_t. Compared to #define, typedef is processed by the compiler with proper type checking, making it the safer and preferred choice for creating type aliases in C programs.

Leave a Comment

Your email address will not be published. Required fields are marked *