typedef
is a special feature in the C language, which is used to create new type names. You also can know from the name “type def(ine)”. typedef
is similar to alias
program in Unix, which adds another name to an object. typedef
also makes multiple names actually correspond to same objext, but the object of typedef
operation is a data type. It is to “give a nickname” to the data type. This nickname usually has the first letter capitalized and is used to indicate that it is not an underlying data type.
In C, typedef
is very similar to macro #define
. The difference between the two is put at the end, because you need to understand typedef
first before you can understand the difference between it and macros.
For example, in C language, there is the concept of string: an array of type char
using \0
to terminate string, and a char
array is actually equivalent to a pointer to char
. But there is no String
type in C language. Then you can use the following statements to achieve String
type:
//String is a pointer, *String is equal to char. In other words, String is equal to char *
typedef char *String
You can also find nickname is not after type, rather than after typedef
. (In C language, when declaring and defining variables, does variable is after type?)
At this time, you can use the following statements to declare, assign, and output “String” type data. As follows:
#include <stdio.h>
int main()
{
typedef char *String;
String p = "abc";
printf("%s\n", p);
return 0;
}
The output is:
abc
Again emphasizing, typedef
does not create a new type, it just gives it a “nickname”. The String here is also implemented using the mechanism of the C language itself.
This method is not very common. In most cases, we wouldn’t give nickname for basic type. The names of most basic data types are already very concise and easy to understand. String is an exception. The most common thing is to use typedef
to find a simpler or more understandable synonym when using a structure, and it can also make the code more concise and efficient.
For example, the following code is a very classic binary tree node structure:
struct tnode {
char *word;
int count;
struct tnode *left;
struct tnode *right;
};
If you create a new node and allocate space without typedef
:
struct tnode *talloc(void)
{
return (struct tnode *) malloc(sizeof(struct tnode));
}
如果使用typedef
的方法,也就是在声明结构体tnode
的同时,用typedef
给它起一个“外号”Treenode
,如下:
If you use typedef
, it means to use typedef
to give it a “nickname” Treenode
while declaring the structure tnode
:
typedef struct tnode {
char *word;
int count;
Treeptr left;
Treeptr right;
} Treenode;
Then use typedef
to define *Treeptr
:
typedef struct tnode *Treeptr;
In this case, creating and allocating memory is simple and can be written in a style without the pointer symbol *
, as follows:
Treenode talloc(void)
{
return (Treeptr) malloc(sizeof(struct Treenode));
}
Compared with the previous version, it is much easier to understand.
The main purpose of typedef
and #define
is to make the code more concise, and to make the code more beautiful.
In addition, typedef
has two other advantages:
typedef
, you only need to modify the typedef
part when develop for different platforms. size_t
and ptrdiff_t
in the standard library are two examples.typedef
. talloc
in the previous section is an example.Next, I will explain the difference between typedef
and #define
.
The main purpose of typedef
and #define
is to make the code more concise, so they both can replace text in source code. The difference is that typedef
text replacement is much more powerful than macros, because typedef
can be understood by the compiler.
Macros only can do simple text replacement, such as direct text replacement, simple calculations and operations. Here is a simple text replacement example:
#define MAXWORD 100
int a[MAXWORD];
When compiling, MAXWORD
will be directly replaced with 100
, then compile after text replacement. MAXWORD
will not be treated as a variable or constant. Therefore, the scope of macro is also called the preprocessor.
By using typedef
, you can implement some complex functions. For example, the following line of code creates a new type PFI
, which is a pointer to a function which has two char *
parameters and return value int
:
typedef int (*PFI)(char *, char *);
This is very convenient when declaring some functions, such as the following function:
int strcmp(char *s, char *t)
{
for ( ; *s == *t; s++, t++) {
if (*s == '\0') {
return 0;
}
}
return *s - *t;
}
You can declare it like following:
PFI strcmp;
Compared to original declaration:
int strcmp(char *, char *);
Isn’t it much more concise? If there are multiple functions like about, they can be written on one line. More concise.
I hope these will help someone in need~