Home  >  Article  >  Backend Development  >  What are the uses of typedef in C language?

What are the uses of typedef in C language?

青灯夜游
青灯夜游Original
2020-07-18 14:23:2934523browse

The usage of typedef is: 1. Define new type names for basic data types; 2. Define concise type names for custom data types (structures, unions and enumeration types); 3. Define concise type names for arrays; 4. Define concise names for pointers.

What are the uses of typedef in C language?

C language allows users to use the typedef keyword to define their own custom data type names to replace the system's default basic type names, array type names, and pointer types. Names and user-defined structural names, shared names, enumerated names, etc.

Once the user defines his own data type name in the program, he can use his own data type name in the program to define the type of variables, the type of arrays, the type of pointer variables, the type of functions, etc. .

For example, the C language did not provide a Boolean type before C99, but we can use the typedef keyword to define a simple Boolean type, as shown in the following code:

typedef int BOOL;
#define TRUE 1
#define FALSE 0

Definition After that, you can use it just like basic type data, as shown in the following code:

BOOL bflag=TRUE;

4 ways to use typedef

In actual use, there are mainly four types of applications of typedef.

1. Define new type names for basic data types

In other words, all basic types in the system by default can use the typedef keyword to redefine the type name. , the sample code is as follows:

typedef unsigned int COUNT;

Moreover, we can also use this method to define platform-independent types. For example, to define a floating point type called REAL, on target platform one, let it represent the highest precision type, that is:

typedef long double REAL;

On platform two that does not support long double, change it to:

typedef double REAL;

You can even change it to:

typedef float REAL;

On a platform that does not even support double, change it to:

#ifndef _SIZE_T_DEFINED
#ifdef  _WIN64
typedef unsigned __int64    size_t;
#else
typedef _W64 unsigned int   size_t;
#endif
#define _SIZE_T_DEFINED
#endif

In this way, when transplanting a program across platforms, we only need to modify the definition of typedef, and No modifications to other source code are required. In fact, this technique is widely used in the standard library. For example, the definition of size_t in the crtdefs.h file of VC 2010 is as follows:

struct Point
{
    double x;
    double y;
    double z;
};

2. It is a custom data type (structure, Unions and enumeration types) define concise type names

Take the structure as an example, below we define a structure named Point:

struct Point oPoint1={100,100,0};
struct Point oPoint2;

When calling this structure When, we must call this structure like the following code:

typedef struct tagPoint
{
    double x;
    double y;
    double z;
} Point;

Here, the structure struct Point is a new data type. When defining variables, we must have the same reservations as the above calling method. Word struct, rather than directly using Point to define variables like int and double. Now, we use typedef to define this structure, as shown in the following code:

struct tagPoint
{
    double x;
    double y;
    double z;
} ;

In the above code, two operations are actually completed:

1), define a The new structure type, the code is as follows:

typedef struct tagPoint Point

Among them, the struct keyword and tagPoint together constitute this structure type. This structure exists regardless of whether the typedef keyword exists or not.

2) Use typedef to give this new structure an alias called Point, that is:

Point oPoint1={100,100,0};
Point oPoint2;

Therefore, now you can directly use Point to define variables like int and double, As shown in the following code:

typedef struct tagNode
{
    char *pItem;
    pNode pNext;
} *pNode;

In order to deepen our understanding of typedef, let's look at a structure example, as shown in the following code:

typedef struct tagNode
{
    char *pItem;
    struct tagNode *pNext;
} *pNode;

On the surface, the above The sample code is defined in the same way as before, so there should be no problem. But the compiler reported an error, why? Could it be that the C language doesn't allow a structure to contain a pointer to itself?

In fact, the problem is not the struct definition itself. Everyone should know that the C language allows the structure to contain pointers to itself. We can see many of these in the implementation of data structures such as linked lists. class example. So what's the problem? In fact, the fundamental problem still lies in the application of typedef.

In the above code, the pNext declaration is encountered during the establishment of the new structure, and its type is pNode. It is important to note here that pNode represents the new alias of the structure. So the problem arises. When the structure type itself has not been created, the compiler does not know pNode at all, because the new alias of this structure type does not exist yet, so it will naturally report an error. Therefore, we need to make some appropriate adjustments, such as modifying the pNext declaration in the structure as follows:

typedef struct tagNode *pNode;
struct tagNode
{
    char *pItem;
    pNode pNext;
};

or defining struct and typedef separately, as shown in the following code:

struct tagNode
{
    char *pItem;
    struct tagNode *pNext;
};
typedef struct tagNode *pNode;
# ##In the above code, we also use typedef to give a new alias to a type tagNode that has not been fully declared. However, although this practice is fully supported by C compilers, it is not recommended. It is recommended to use the following standard definition method: ###
struct tagNode
{
    char *pItem;
    struct tagNode *pNext;
};
typedef struct tagNode *pNode;

3、为数组定义简洁的类型名称

它的定义方法很简单,与为基本数据类型定义新的别名方法一样,示例代码如下所示:

typedef int INT_ARRAY_100[100];
INT_ARRAY_100 arr;

4、为指针定义简洁的名称

对于指针,我们同样可以使用下面的方式来定义一个新的别名:

typedef char* PCHAR;
PCHAR pa;

对于上面这种简单的变量声明,使用 typedef 来定义一个新的别名或许会感觉意义不大,但在比较复杂的变量声明中,typedef 的优势马上就体现出来了,如下面的示例代码所示:

int *(*a[5])(int,char*);

对于上面变量的声明,如果我们使用 typdef 来给它定义一个别名,这会非常有意义,如下面的代码所示:

// PFun是我们创建的一个类型别名
typedef int *(*PFun)(int,char*);
// 使用定义的新类型来声明对象,等价于int*(*a[5])(int,char*);
PFun a[5];

小心使用 typedef 带来的陷阱

接下来看一个简单的 typedef 使用示例,如下面的代码所示:

typedef char* PCHAR;
int strcmp(const PCHAR,const PCHAR);

在上面的代码中,“const PCHAR” 是否相当于 “const char*” 呢?

答案是否定的,原因很简单,typedef 是用来定义一种类型的新别名的,它不同于宏,不是简单的字符串替换。因此,“const PCHAR”中的 const 给予了整个指针本身常量性,也就是形成了常量指针“char*const(一个指向char的常量指针)”。即它实际上相当于“char*const”,而不是“const char*(指向常量 char 的指针)”。当然,要想让 const PCHAR 相当于 const char* 也很容易,如下面的代码所示:

typedef const char* PCHAR;
int strcmp(PCHAR, PCHAR);

其实,无论什么时候,只要为指针声明 typedef,那么就应该在最终的 typedef 名称中加一个 const,以使得该指针本身是常量。

还需要特别注意的是,虽然 typedef 并不真正影响对象的存储特性,但在语法上它还是一个存储类的关键字,就像 auto、extern、static 和 register 等关键字一样。因此,像下面这种声明方式是不可行的:

typedef static int INT_STATIC;

不可行的原因是不能声明多个存储类关键字,由于 typedef 已经占据了存储类关键字的位置,因此,在 typedef 声明中就不能够再使用 static 或任何其他存储类关键字了。当然,编译器也会报错,如在 VC++2010 中的报错信息为“无法指定多个存储类”。

相关推荐:《c语言教程

The above is the detailed content of What are the uses of typedef in C language?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn