Typedef in C — Getting deep

Prashanth P
5 min readApr 8, 2021

Typedef is a keyword available in the C language which is used to assign alternative names to exist data types. It allows users to provide alternative names to primitive data types (e.g. int) and user-defined data types (e.g. struct).

The reason for using typedef is sometimes it becomes complicated while using or declaring a data type to write its name, again and again, so to make things easier we can provide an alias to the already existing data type which is easy to use.

And Typedefis also one of the most asked C interview questions that you’ve to be well prepared.

Syntax:

typedef <existing_name> <alias_name> ;

In the above syntax, ‘existing_name’ is the name of the already existing data type while alias_name is the alternative name we want to provide to this data type.

Example:

typedef pair<int,int> PI ;

Now instead of declaring pair<int,int> everywhere, we can just use PI to use the same data type.

PI a; // same as pair<int,int>a ;

By convention, Uppercase letters are preferred for these definitions to remind the user that the type name is really a symbolic abbreviation, but we can use lowercase as well.

e.g. typedef pair<int,int> pi ;

pi a;

Applications of Typedef :

1. Using Typedef with Basic Data Types

We can use typedef to rename primitive data types which are used again and again to save our keystrokes and increase speed.

Most of the Competitive Programmers rename data types like unsigned long, long to relatively shorter names to increase their speed during a contest.

Example:

typedef unsigned long ulong

Code:

#include <stdio.h>
typedef long long ll ;

ll gcd(ll n1, ll n2) {
if (n2 != 0)
return gcd(n2, n1 % n2);
else
return n1;
}

int main() {

ll x=83929284838209229;
ll y=93403490349883493;
ll z=gcd(x,y);

printf(“GCD of %lld and %lld is : %lld”,x,y,z);

}

Here, we can clearly see that we have saved a lot of keystrokes by renaming long to ll.

2. Using Typedef with user-defined data types:

We can use typedef to rename derived data types which are used again and again to save our keystrokes and increase speed.

Most of the Competitive Programmers rename data types like struct, pair<int,int>, etc. to relatively shorter names to increase their speed during a contest.

Example:

Code without using Typedef:

#include <stdio.h>

struct Student {
int roll;
char name[20];
float cgpa;
};

int main() {

struct Student a;

a.roll=1;
strcpy(a.name,”Ashish”);
a.cgpa=9.3;

struct Student b;

b.roll=2;
strcpy(b.name,”Garima”);
b.cgpa=8.4;
}

Code after using Typedef :

#include <stdio.h>

struct Student {
int roll;
char name[20];
float cgpa;
};

typedef struct Student st;

int main() {

// instead of writing struct Student a;
st a;

a.roll=1;
strcpy(a.name,”Ashish”);
a.cgpa=9.3;

st b;

b.roll=2;
strcpy(b.name,”Garima”);
b.cgpa=8.4;
}

Note that there is no longer any need to type struct Student every time to declare a new variable of type struct.

Also, we can use Typedef with Policy-Based Data Structure whose declaration type is very long :

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set.

3. Typedef With Pointers :

We can use typedef to give alias names to pointers as well.

We know that in pointers, the Indirection Operator (*) binds to the right and not to the left.

So, the declaration: int *x,y; will declare x as a pointer to int, while y will be declared as a plain int variable.

To avoid this confusion we can use typedef here: typedef int* ptr; and now can declare multiple pointers in a single line, ptr x,y, z; will declare all 3 x,y,z as a pointer to an integer.

Now, one doubt that arises is that we could have just used #define for defining the data type some other name. Then why introduce one more keyword for the same purpose.

So, now we will understand the difference between typedef and #define.

#define is a directive in C that is used to provide an alias.

Example:

#define pi pair<long,long>

will replace all ‘pi’ with ‘pair<long,long>’

Typedef vs #define:

1. Typedef is limited to giving symbolic names to different data types only, whereas #define can be used to provide an alias to values as well.

Example:

#define one 1 , #define PI 3.14 but ‘typedef 1 one’ will generate error :

2. typedef is processed by the compiler but #define statements are worked by preprocessors.

3. typedef is terminated with a semicolon but #define is not terminated with a semicolon.

4. #define just copy-pastes the values whereas typedef actually defines types.

Code Example:

#include <stdio.h>

typedef int* ptr1;
#define ptr2 int*

int main() {

ptr1 a,b,c;
ptr2 x,y,z;

printf(“sizeof a:%u\n” ,sizeof(a) );
printf(“sizeof b:%u\n” ,sizeof(b) );
printf(“sizeof c:%u\n” ,sizeof(c) );
printf(“sizeof x:%u\n” ,sizeof(x) );
printf(“sizeof y:%u\n” ,sizeof(y) );
printf(“sizeof z:%u\n” ,sizeof(z) );
}

Output:

Here, we can see that even though we expect all of them to have the same size but y and z have different sizes. This happens because, in the case of typedef, it effectively defines its type as int *a,*b,*c;

and thus each of a,b,c are pointers to integers.

But, in the case of #define it just copy its definition and paste it everywhere its alias is present, which makes our declaration as int *x,y,z;

Here, x is a Pointer to int but y and z are integer types now.

So, if we declare macros with pointers, if we define more than 1 identifier, the actual definition is given to the first identifier, and to the rest non-pointer definition is given.

5. Typedef follows the scope rule, that is, if a type is defined within a scope then it will be visible only till the scope is there.
But for #define, the preprocessor replaces all occurrences for alias after encountering #define. ( No scope rule is followed ).

Conclusion

Using typedef results in cleaner, more readable code, and saves the programmer keystrokes​. However, it also leads to a more cluttered global namespace which can be problematic for large programs.

And, for defining types and special pointers, we must always rely on typedef as others like #define can cause unexpected errors.

More Resources for you to learn about typedef

CProgramming

Wiki

Microsoft

Stackoverflow

--

--