typedef
It gets a bit cumbersome to use types called struct person
and enum grade
. It would be much nicer to be able to call
them just person
or grade
. With C’s typedef construct, we
can do just that.
The format of typedef is:
typedef oldType newType;
Here, we rename type oldType
to the new name newType
. We
can now create variables using the name newType
. For example:
typedef char letterGrade;
letterGrade g;
g = 'A';
Notice that we treat our new letterGrade
type just like it was a
char. The only difference is that when we declare the variable, we
can use letterGrade
as the type instead of char.
Typedef with Structs, Unions, and Enums
We can do a similar thing to rename structs, unions, and enums. For example, consider the following struct:
struct person {
char name[20];
int age;
};
The formal type of the struct is struct person
. Now, we
want to rename the type to be just person
:
//typedef oldType newType
typedef struct person person;
Alternatively, we can declare the struct and rename it with typedef all on the same line:
//typedef oldType newType
typedef struct person {
char name[20];
int age;
} person;
However, we don’t need to name the struct now, since we’re always going to be using the new type name when creating variables of this type:
typedef struct {
char name[20];
int age;
} person;
Now we can declare and use a person
variable:
person p;
strcpy(p.name, "Bill");
p.age = 22;
We can do a similar thing to rename unions and enums. Consider the following union:
union money {
double dollars;
int yen;
};
We can rename the union type to money
:
typedef union {
double dollars;
int yen;
} money;
Now we can use money
as the type name instead of union money
. Similarly, consider the following enum:
enum grade{freshman = 9, sophomore, junior, senior};
We can rename the enum type to grade
:
typedef enum {freshman = 9, sophomore, junior, senior} grade;
Now we can use grade
as the type name instead of enum grade
.
Typedef with Linked Lists
Consider the following structure for a node in a linked list:
struct node {
int data;
struct node *next;
};
We can try to rename the struct node
type to node
using
typedef:
typedef struct {
int data;
node *next;
} node;
However, this will give us a compiler error. The reason is that this
struct is self-referential. When we declare the field node *next
in the struct, the compiler hasn’t yet seen that we’re
renaming the type to node
. If instead we list the field as:
struct node *next;
we will also get a complaint, as we left off the name of the struct. If you’re using typedef on a self-referential struct, you need to include BOTH the name of the struct and the name of the renamed type. The fixed node struct looks like:
typedef struct node {
int data;
struct node *next;
} node;
Here’s how we’d use it:
node *head = malloc(sizeof(node));
head->data = 4;
head->next = malloc(sizeof(node));
head->next->data = 7;
head->next->next = NULL;
This creates the linked list 4->7.