typedef statement in C

The typedef is an advance feature in C language which allows us to create an alias or new name for an existing type or user defined type. The syntax of typedef is as follows:

Syntax: typedef data_type new_name;

typedef: It is a keyword.

data_type: It is the name of any existing type or user defined type created using structure/union.

new_name: alias or new name you want to give to any existing type or user defined type.

Let’s take an example:

Now myint is an alias of int. From now on we can declare new int variables using myint instead of int keyword.

This statement declares and initializes a variable i of type int.

We can even create more than one alias for the same type. For example:

This statement creates two aliases for type int namely myint and integer.

Here are some more examples:

After these two declarations, ulint is an alias of unsigned long int and real is an alias of float.

We can write typedef declaration anywhere other declarations are allowed. However, it is important to note that the scope of the declarations depends on the location of the typedef statement. If the definition is placed outside all functions then the scope is global and any function can use an alias instead of the original name. On the other hand, if the definition is declared inside a function then the scope is local and the only the function which contains the typedef statement can use an alias. Consider the following examples:

Example 1: Declaring a local alias using typedef

Expected Output:

Here typedef definition is inside main() function so we can use alias uchar only inside the main(). Try uncommenting the line 15 and compile the program you will get an error from compiler because alias uchar is not available in the foo() function.

Example 2: Declaring a global alias using typedef

Expected Output:

Here typedef declaration is above all functions so any function can use alias uchar to declare variables of type unsigned char.

We have seen how to declare aliases for simple types in the following sections we will learn how to define aliases for pointer, functions, structures and unions.

typedef with a pointer

After this statement iptr is an alias of a pointer to int or (int*). Here is how we can declare an integer pointer using iptr:

This declaration is same as:

Here are some more examples:

In the first declaration, a is a pointer to int and b is pointer to pointer to int. In the second declaration, arr is an array of 10 integer pointers.

Here is an example:

Expected Output:

typedef with an Array

After this declaration, iarr is an alias of array of 10 integer elements.

In this declaration, a and b are arrays of 10 integers and c is a 2-D array of dimension 10*5.

Here is an example:

Expected Output:

typedef with a Structure

After this declaration, Book is an alias of struct book. So instead of using struct book to declare new structure variables we can use just use Book.

We can also combine structure definition and typedef declaration. The syntax to so is:

Let’s rewrite structure book definition using this new syntax of typedef.

Here is the program to demonstrate how to use typedef with structures.

Expected Output:

Similarly, we can use typedef with unions.

typedef and #define

It is important to mention that typedef is not a preprocessor directive, so its interpretation is handled by the compiler, not by the preprocessor. Recall that #define directive allows us to define an expansion for any text on the other hand typedef is used to create alias for any data type.

However, there are some cases when #define and typedef yield the same result. The following is one such case:

#define directive typedef declaration
#define uchar unsigned char typedef unsigned char uchar;
statement to test uchar ch; uchar ch;
After translation unsigned char ch; unsigned char ch;

Here is the case when #define and typedef yield different results.

#define directive typedef declaration
#define fp float * typedef float * fp;
statement to test fp a, b, c; fp a, b, c;
After translation float *a, b, c; float *a, *b, *c;

In the second case, as soon as preprocessor sees the statement.

It replaces the occurrence of fp it replaces it with float *. So the above declaration becomes.

On the other hand, typedef has more semantic meaning so the compiler doesn’t just replace as preprocessor does.

The following program demonstrate the difference between #define and typedef.

Expected Output:

How it works:

When preprocessor goes through the program and sees the declaration:

It replaces ptr with int * , so that the above declaration becomes:

where only a is a pointer to int, b and c are just variable of type int.

On the contrary in the following declaration.

The compiler knows that iptr is an alias to a pointer to int, so p1, p2 and p3 are pointer variables of type int.

Advantages typedef

It makes the program more readable. Certainly, Book b1 is more readable and intuitive than writing struct book b1.

It makes the program portable. Let me explain how .Take a look at the prototypes of sizeof() operator and malloc() function.

As you can both prototypes uses type size_t and we have already told you to treat size_t as unsigned int, but that’s not entirely true. The C standard says sizeof() must return an integer but leaves it up to the implementation to determine which type to return. The reason for this is that C standards committee decided no choice is likely to be the best for every platform. So they created a new type such as size_t, time_t etc and let the implementation use a typedef to set the name to some specific type. So one system type of size_t can be unsigned int, on another, it can be unsigned long int.

Leave a Comment