现在的位置: 首页 > 综合 > 正文

番外篇(1) typedef 采自百度百科 http://baike.baidu.com/view/1283800.htm

2013年10月07日 ⁄ 综合 ⁄ 共 1666字 ⁄ 字号 评论关闭

 

typedef用法小结(自己总结了一下)

 

1)      
 

typedef
int size;

 

此声明定义了一个 int 的同义字,名字为 size。注意 typedef 并不创建新的类型。它仅仅为现有类型添加一个同义字。你可以在任何需要 int 的上下文中使用 size

void
measure(size * psz);

 

2)

typedef
char Line[81];

 

定义一个 typedef,每当要用到相同类型和大小的数组时,可以这样:

typedef char
Line[81];

Line text,
secondline;

getline(text);

 

3)

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,以使得该指针本身是常量,而不是对象。

 

4)

链表中的大概应用

name 保存在结构体单元的name[20] 数组里;

typedef
struct node

{

char
name[20];

struct
node *link;

}stu;

 

这是前面定义的结构体变量,一个单元包含两个部分,一个用来存储name的数组name[20],一个用来存放下一个单元地址的指向结构体node的指针。假设该单元的地址是p,那么p->name 表示第一部分name[20]的地址,p->link表示第二部分,作用是存放下一个单元的地址。

 

5)

typedef
int (*PF) (const char *, const char *);

 

这个声明引入了 PF 类型作为函数指针的同义字,该函数有两个 const char * 类型的参数以及一个 int 类型的返回值。如果要使用下列形式的函数声明,那么上述这个 typedef 是不可或缺的:

PF Register(PF
pf);

Register() 的参数是一个 PF 类型的回调函数,返回某个函数的地址,其署名与先前注册的名字相同。做一次深呼吸。下面我展示一下如果不用 typedef,我们是如何实现这个声明的:

int (*Register
(int (*pf)(const char *, const char *)))

(const char *,
const char *);

很少有程序员理解它是什么意思,更不用说这种费解的代码所带来的出错风险了。显然,这里使用 typedef 不是一种特权,而是一种必需。持怀疑态度的人可能会问:"OK,有人还会写这样的代码吗?",快速浏览一下揭示 signal()函数的头文件 ,一个有同样接口的函数。

 

 

6)

typedef
register int FAST_COUNTER; //
错误

 

typedef 和存储类关键字(storage class specifier,这种说法是不是有点令人惊讶,typedef 就像 autoexternmutablestatic,和 register 一样,是一个存储类关键字。这并不是说 typedef 会真正影响对象的存储特性;它只是说在语句构成上,typedef 声明看起来象 staticextern 等类型的变量声明。下面将带到第二个陷阱:

typedef
register int FAST_COUNTER; //
错误

编译通不过。问题出在你不能在声明中有多个存储类关键字。因为符号 typedef 已经占据了存储类关键字的位置,在 typedef 声明中不能用 register(或任何其它存储类关键字)。

 

抱歉!评论已关闭.