在c语言中,typedef的意思是将一个自己命名的类型用已经有的类型来代替。

C语言允许用户使用 typedef 关键字来定义自己习惯的数据类型名称,来替代系统默认的基本类型名称、数组类型名称、指针类型名称与用户自定义的结构型名称、共用型名称、枚举型名称等。

一旦用户在程序中定义了自己的数据类型名称,就可以在该程序中用自己的数据类型名称来定义变量的类型、数组的类型、指针变量的类型与函数的类型等。

例如,C 语言在 C99 之前并未提供布尔类型,但我们可以使用 typedef 关键字来定义一个简单的布尔类型,如下面的代码所示:typedef int BOOL;

#define TRUE 1

#define FALSE 0

定义好之后,就可以像使用基本类型数据一样使用它了,如下面的代码所示:BOOL bflag=TRUE;

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 _WIN64

typedef unsigned __int64 size_t;

#else

typedef _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;

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

1)、定义了一个新的结构类型,代码如下所示:struct tagPoint

{

double x;

double y;

double z;

} ;

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

2)、使用 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];

更多web开发知识,请查阅 HTML中文网 !!

c语言中文定义什么类型,typedef在c语言中是什么意思?相关推荐

  1. 关于C语言static定义函数类型的具体解释

    内部函数和外部函数 函数一旦定义后就可被其它函数调用.   但当一个源程序由多个源文件组成时,   在一个源文件中定义的函数能否被其它源文件中的函数调用呢?为此,C语言又把函数分为两类: 一.内部函数 ...

  2. c语言怎么用枚举类型的字符串,c语言枚举类型的用法

    枚举类型就相当于助记符,帮助程序员记忆的.比如现在要画一张地图,用到红黄蓝绿四种颜色.为了存储方便,我们规定0=红,1=黄,2=蓝,3=绿.但是当编程到某一阶段时,程序员可能忘记了哪个数字具体对应哪种 ...

  3. C语言 define 定义函数(多行书写) - C语言零基础入门教程

    目录 一.define 简介 二.define 定义多行函数 1.简单使用 2.经典案例 三.猜你喜欢 零基础 C/C++ 学习路线推荐 : C/C++ 学习目录 >> C 语言基础入门 ...

  4. c语言宏定义技巧和用法,关于C语言宏定义的技巧:'#'和'##'

    关于C语言宏定义的技巧:'#'和'##' '#'和'##' '#'和'##'是两个预处理运算符,只能在预处理的过程中使用.在带参数的宏定义中, '#'运算符后面应该跟一个参数,预处理器会把这个参数转换 ...

  5. c语言怎么定义字符串类型,求解答,在C语言里怎样定义string类型

    #include "string.h" //这个是 #define TRIM_LEFT 1 #define TRIM_RIGHT 2 #define TRIM_BOTH 0 cla ...

  6. c语言如何定义比较大的数组_C语言:数据结构-数组的定义、逻辑结构和特点

    一维数组 (1)定义 一维数组是属于同一种数据类型的元素(变量)的有限序列,其元素称为数组元素,每个元素有统一的名称(数组名),有按序编号的唯一的下标.序列中元素的个数称为数组的长度. 例:a=a0, ...

  7. c语言宏定义比较三个数大小,C语言中两个宏进行大小对比,其中一个没有定义,这种行为如何定义。...

    1.C语言中两个宏进行大小对比,其中一个没有定义,这种行为如何定义呢? 在学习U-boot的过程中遇到这么一个定义: # if (CONFIG_ENV_ADDR >= CONFIG_SYS_MO ...

  8. python语言中文社区-Python 之父谈 Python-Go语言中文社区

    在宣传海报上,Python 之父 Guido van Rossum 在 EuroPython 2015 会议的发言分为讲话稿和现场问答部分,但是他上台后将全程改为现场问答的形式.他在回答现场观众的问题 ...

  9. R语言中文社区2018年终文章整理(作者篇)

    欢迎关注天善智能,我们是专注于商业智能BI,人工智能AI,大数据分析与挖掘领域的垂直社区,学习,问答.求职一站式搞定! 对商业智能BI.大数据分析挖掘.机器学习,python,R等数据领域感兴趣的同学 ...

最新文章

  1. CPaintDC和CClientDC的区别
  2. centos transmission 无法开启登录验证
  3. vue配置文件读取_Vue+Spring Boot简单用户登录Demo实现
  4. SharePoint 2013 搭建负载均衡(NLB)
  5. 概率密度函数与分布函数的几何含义
  6. ML之catboost:基于自定义数据集利用catboost 算法实现回归预测(训练采用CPU和GPU两种方式)
  7. 基于Xilinx FPGA生态,加速提升视频处理质量
  8. day14(xml 编写及解析)
  9. php通过数组存取mysql查询语句的返回值
  10. GitLab 8.9 新增文件锁 和 U2F硬件支持
  11. linux 使用秘钥认证,linux 密钥验证登录
  12. 视频捕获增加color space converter + Transform Filter
  13. 软件测试教程第2版(宫云战主编)
  14. excel 第5讲:分类汇总与数据有效性
  15. ★SMILES数据处理+评价指标所有的代码
  16. SliceM与SliceL
  17. DWR 一些注意的地方
  18. java初学求一个数的绝对值
  19. 微软sql服务器可以关闭吗,停止Microsoft SQL server的几种方式
  20. 百度地图setMapStyle

热门文章

  1. duolingo 多邻国 安卓版无法使用口语功能
  2. biopython:基因genbank格式转核酸或氨基酸fasta格式
  3. 7大子论坛回顾 | PGConf.Asia亚洲技术大会DAY2精彩继续
  4. mysql数据库一些常用操作
  5. 中国红客联盟、编程爱好者、中国站长网等追加
  6. 算法---程序的灵魂,没错就是灵魂!
  7. 51单片机四位数码管的使用方法
  8. 树莓派4B开机自启动Python程序,发送WIFI-IP至指定邮箱
  9. 抖音二面:为什么模块循环依赖不会死循环?CommonJS和ES Module的处理不同?
  10. 诺基亚升级Android10,诺基亚发布第五次Android 10更新 ,诺基亚7+可升级