博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《编写高质量代码:改善c程序代码的125个建议》——建议6-1:掌握typedef的4种应用形式...
阅读量:5808 次
发布时间:2019-06-18

本文共 2663 字,大约阅读时间需要 8 分钟。

本节书摘来自华章计算机《编写高质量代码:改善c程序代码的125个建议》一书中的第1章,建议6-1,作者:马 伟 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

建议6-1:掌握typedef的4种应用形式

在实际使用中,typedef 的应用主要有如下4种形式。

1.为基本数据类型定义新的类型名
也就是说,系统默认的所有基本类型都可以利用typedef关键字来重新定义类型名,示例代码如下所示:

typedef unsigned int COUNT;

而且,我们还可以使用这种方法来定义与平台无关的类型。比如,要定义一个叫REAL的浮点类型,在目标平台一上,让它表示最高精度的类型,即:

typedef long double REAL;

在不支持 long double 的平台二上

,改为:

typedef double REAL;

甚至还可以在连double 都不支持的平台三上,改为:

typedef float REAL;

这样,当跨平台移植程序时,我们只需要修改一下 typedef 的定义即可,而不用对其他源代码做任何修改。其实,标准库中广泛地使用了这个技巧,比如size_t在VC++ 2010的crtdefs.h文件中的定义如下所示:

#ifndef _SIZE_T_DEFINED#ifdef  _WIN64typedef unsigned __int64    size_t;#elsetypedef _W64 unsigned int   size_t;#endif#define _SIZE_T_DEFINED#endif

2.为自定义数据类型(结构体、共用体和枚举类型)定义简洁的类型名称

以结构体为例,下面我们定义一个名为Point的结构体:

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

在调用这个结构体时,我们必须像下面的代码这样来调用这个结构体:

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

在这里,结构体struct Point为新的数据类型,在定义变量的时候均要向上面的调用方法一样有保留字struct,而不能像int和double那样直接使用Point来定义变量。现在,我们利用typedef定义这个结构体,如下面的代码所示:

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

在上面的代码中,实际上完成了两个操作:

定义了一个新的结构类型,代码如下所示:

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

其中,struct 关键字和tagPoint一起构成了这个结构类型,无论是否存在typedef关键字,这个结构都存在。

使用 typedef为这个新的结构起了一个别名,叫Point,即:

typedef struct tagPoint Point

因此,现在你就可以像int和double那样直接使用Point定义变量,如下面的代码所示:

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

为了加深对typedef的理解,我们再来看一个结构体例子,如下面的代码所

示:

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

从表面上看,上面的示例代码与前面的定义方法相同,所以应该没有什么问题。但是编译器却报了一个错误,为什么呢?莫非C语言不允许在结构中包含指向它自己的指针?

其实问题并非在于struct定义的本身,大家应该都知道,C语言是允许在结构中包含指向它自己的指针的,我们可以在建立链表等数据结构的实现上看到很多这类例子。那问题在哪里呢?其实,根本问题还是在于typedef的应用。
在上面的代码中,新结构建立的过程中遇到了pNext声明,其类型是pNode。这里要特别注意的是,pNode表示的是该结构体的新别名。于是问题出现了,在结构体类型本身还没有建立完成的时候,编译器根本就不认识pNode,因为这个结构体类型的新别名还不存在,所以自然就会报错。因此,我们要做一些适当的调整,比如将结构体中的pNext声明修改成如下方式:

typedef struct tagNode{    char *pItem;    struct tagNode *pNext;} *pNode;或者将struct与typedef分开定义,如下面的代码所示:typedef struct tagNode *pNode;struct tagNode{    char *pItem;    pNode pNext;};

在上面的代码中,我们同样使用typedef给一个还未完全声明的类型tagNode起了一个新别名。不过,虽然C语言编译器完全支持这种做法,但不推荐这样做。建议还是使用如下规范定义方法:

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];**

转载地址:http://txybx.baihongyu.com/

你可能感兴趣的文章
NLP自然语言处理学习笔记一(环境准备)
查看>>
李开复:中国第四波创业浪潮来临
查看>>
数组中连续重复数据删选且记下所在索引-demo
查看>>
管道和多路复用器
查看>>
第六周作业 百词斩对比可可英语
查看>>
李天平老师回复:如何稳步提高自己的技术?
查看>>
SQL Server 计算汉字笔画函数
查看>>
【算法】LeetCode算法题-Merge Two Sorted List
查看>>
子查询注意这几点, 就可以写出好的sql语句
查看>>
在项目中用run as java aplication调试类
查看>>
python-建造者模式
查看>>
常用模块
查看>>
RadioButtonList中的默认项(Selected)不触发OnSelectedIndexChanged
查看>>
Javascript选择checkbox
查看>>
jQuery系列:Ajax
查看>>
Ruiy自我识人做事领悟录ing
查看>>
shell数组
查看>>
hadoop测试环境主配置简例
查看>>
为PyCharm自动配置作者信息
查看>>
hdu4685 n个男生m个女生问男生可以娶哪些女生使最大匹配数不改变:二分图匹配/tarjan...
查看>>