1.基本解释编程
typedef为C语言的关键字,做用是为一种数据类型定义一个新名字,这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等)。数据结构
在编程中使用typedef的目的通常有两个,一个是给变量一个易记且意义明确的新名字,另外一个是简化一些比较复杂的类型声明。至于typedef有什么微妙之处,我将具体根据如下几个问题展开阐述。函数
2. typedef和结构的问题spa
当使用下面的代码定义一个结构时,编译器会报告一个错误,为何呢?莫非C语言不容许在结构中包含指向它本身的指针吗?请看下文说明:指针
typedef struct tagNode { char *pItem; pNode pNext; } *pNode;
推理与分析:
(1) typedef的最简单使用:typedef long byte_4; 给一直数据类型long起个新名字,叫作byte_4;
(2) typedef与结构结合使用;
typedef struct tagMyStruct { int iNum; long lLength; } MyStruct;
这句话实际上完成了两个操做:
第一,定义了一个结构类型:
struct tagMyStruct { int iNum; long lLength; };
分析:tagMyStruct被称为“标签”(或结构标识符),是该结构体类型,struct关键字和tagMyStruct一块儿,构成了这个新的结构体。
第二,typedef为这个新的结构起了一个名字,叫作MyStruct,即typedef struct tagMyStruct MyStruct;
此时,MyStruct在功能上与struct tagMystruct等价。例如,当须要建立一个名称为varName,类型为tagMyStruct的结构体是,能够使用以下两种方法:
方法一:struct + 类型名称 + 结构体变量名称
struct tagMyStruct varName;
方法二:新名称 + 结构体变量名称
MyStruct varName;
答案与分析:
C语言固然容许在结构中包含指向它本身的指针,咱们能够在创建链表等数据结构的实现上看到无数这样的例子,上述代码的根本问题在于typedef的应用。根据咱们上面的阐述能够知道:新结构创建的过程当中遇到了pNext域的声明,类型是pNode,要知道pNode表示的是类型的新名字,那么在类型自己尚未创建完成的时候,这个类型的新名字还尚不存在,也就是说在这个时候,编译器根本就不认识pNode。那么,要解决这个问题的方法就有多种,以下:
// 方法1: typedef struct tagNode{ char *pItem; struct tagNode *pNext; } *pNode; // 方法2: typedef struct tagNode *pNode; struct tagNode{ char *pItem; pNode pNext; }; /* 注意:在这个例子中,你用typedef给一个还未彻底声明的结构类型起新名字,C语言编译器支持这种作法。*/
struct在代码中常见的形式有两种:
// 第一种: struct A { …… }; // 第二种: struct { …… } A;
这是两种彻底不一样的用法:
后者是定义结构体变量,意思是:定义一个名称为“A”的结构体变量。这里的结构体称之为匿名结构体,是没法被直接引用的。为了使该匿名结构体可以被引用,能够经过typedef为其建立一个别名,从而使得它能够被应用,实现方法以下:
typedef struct { //…… } A; //定义匿名结构体的别名为A
注意结构类型和结构变量名的区别:结构类型该结构体的类型,结构变量名是一个变量名称,但变量的类型是该结构体类型。对于结构类型已知的结构体,咱们可以经过“struct + 结构类型 + 结构变量名;”的方法来声明新的结构变量,而未定义类型的结构体则不能直接进行新的结构变量的定义。例如,如今我要在某函数中声明一个结构变量名为SHZ的结构体,若结构名已知,则可经过语句:struct + 结构类型 + SHZ;的形式来声明。对于结构类型未知的结构体,则须要经过使用typedef为该结构体起一个新的名字,而后才能利用该结构别名来声明一个结构变量名为SHZ的结构体,实现方法为“新名称 + 结构变量名”。