(1) typedef可以声明各种类型名,但不能用来定义变量。用typedef可以声明数组类型、字符串类型,使用比较方便。
优点:
1. 定义易于记忆的类型名
2.代码简化------申明复杂函数
3.促进跨平台开发
4.
注意:
typedef的作用是申明,不是替换。
声明一个变量只是将变量名标识符的有关信息告诉编译器,使编译器“认识”该标识符,
c语言的函数申明,只是告诉编译器,遇到这个符号应该怎样解释。和define 的完全替换不一样
所以:
typedef int (*PF) (const char *, const char *);
这个声明引入了 PF 类型作为函数指针的同义字,该函数有两个 const char * 类型的参数以及一个 int 类型的返回值。这里就不能用完全替换的方式来解释这个函数。
举例:
typedef char * pstr;
int mystrcmp(pstr, pstr);
这里将带我们到达第一个 typedef 陷阱。标准函数 strcmp()有两个‘const char *'类型的参数。因此,它可能会误导人们象下面这样声明 mystrcmp():
int mystrcmp(const pstr, const pstr);
这是错误的,按照顺序,‘const pstr'被解释为‘char * const'(一个指向 char 的常量指针),而不是‘const char *'(指向常量 char 的指针)。这个问题很容易解决:
typedef const char * cpstr;
int mystrcmp(cpstr, cpstr); // 现在是正确的
记住:不管什么时候,只要为指针声明 typedef ,那么都要在最终的 typedef 名称中加一个 const,以使得该指针本身是常量,而不是对象。(2)typedef 和存储类关键字(storage class specifier)
typedef 就像 auto,extern,mutable,static,和 register 一样,是一个存储类关键字。这并是说 typedef 会真正影响对象的存储特性;它只是说在语句构成上,typedef 声明看起来象 static,extern 等类型的变量声明。陷阱:
typedef register int FAST_COUNTER; // 错误
编译通不过。问题出在你不能在声明中有多个存储类关键字。因为符号 typedef 已经占据了存储类关键字的位置,在 typedef 声明中不能用 register(或任何其它存储类关键字)。
typedef struct tagNode
{
char *pItem;
pNode pNext;
} *pNode;
错误说明:
<span style="color:#FF0000;">pNode pNext; ------------还没有申明成功,编译器识别不了。</span>
<span style="color:#FF0000;"> </span><span style="font-size:14px;"><strong><span style="color:#FF0000;">在许多<span style="font-family:Times New Roman;">C</span>语言编程规范中提到使用<span style="font-family:Times New Roman;">#define</span></span><span style="color:black;"><span style="color:#FF0000;">定义时,如果定义中包含表达式,必须使用括号</span>,则上述定义应该如下定义才对:</span></strong></span><table style="BACKGROUND:#e6e4dd;" border="1" cellpadding="0" width="90%"><tbody><tr><td><p align="left"><span style="color:black;"><span style="font-family:Times New Roman;font-size:14px;">#define f(x) (x*x)</span></span></p></td></tr></tbody></table>
const pStr p2的含义是:char * const p2 限定数据类型为char *的变量p2为只读------指针常量,*p2=a,但是不能p2++
const char * p2 限定数据类型为char的变量 *p2为只读 常量指针-----p2++,但是不能*p2=a