C/C++ 之 typedef的用法

2017-04-22     浏览次数:

我们都知道typedef是类型重定义,既然是重定义就不可能出现新的数据类型,只是将已有的数据类型进行换个名字而已,但是这有什么用呢?可能我们学的时候,给的例子都是:typedef int INT; 然后再用INT去定义一些变量,例如:INT a;

  这个就等于int a; 我们当时感觉不出来有什么用,当学到结构体的时候,可能觉得会减少数据类型的写法,像struct student这样一个结构体定义变量的时候如果不用typedef就只能struct student(当然这是在C语言中,在C++中可以省略掉struct直接写student),这样感觉很麻烦,所以才想到用typedef,但是这是他的用法之一,却不是为唯一的用法。

typedef的用法主要我总结了一下三点:

用法一:可以减少代码的书写量

就像我们经常能考虑到的,结构体这样“新的”数据类型,用typedef可以简化,而且不容易出错.例如:

struct student{

  int data;

  char name[10];

}; 

当我们定义学生结构体的时候要这么定义struct student s1,s2,s3; 如果想定义结构体指针,我们可以这么定义,struct student *ps1, ps2; 显然ps2不是指针类型,但是好多初学者对指针不熟悉,所以容易出错,但是当我们用typedef的时候,就不会出现这样的错误了,

typedef struct student{

  int data;

  char name[10];

}stu, *pstu; 

我们定义的时候可以这么定义

stu s1, s2, s3;

定义结构体指针的时候,可以这么定义,

pstu ps1, ps2;

这样ps1, ps2都是指针类型的变量 这是typedef的用法之一,也是比较常用的。

用法二:可以实现代码的复用性和可扩展性

如果一段代码没有扩展性和复用性,那么这段代码就不能算得上是一段特别规范的代码,就像我们为了实现代码的复用性,提高程序可读性的时候,用函数一样,提高代码的复用性和可扩展性是作为软件开发者必备的本领。一段好的代码,如果在别的项目中引用的话,如果功能类似,基本上改不了几行,这就是规范性的重要性(这里先不谈规范性,但是这个typedef的用法也涉及规范性,嘿嘿,所以规范是避免不了的)。就这么来说吧,假如我们定义了一个结构体

struct student{

  int score;

  char name[10];

};

我们想把成绩改成double类型的,应为int的精度太低了,但是下面用到的地方可能都要改掉,但是,我们要是用typedef一下, 问题就变得简单多了,

typedef int typeitem;

struct student{

  typeitem score;

  char name[10];

};

  这样直接改typedef就行了,其他的代码根本不用动,这就是分层的原因,我们只改变最底层的,上层的东西根本不用变(就像在链表中,我们可以把它分为三层,纯数据层、节点层、head指针层,也就是整条链)这样分层处理问题会变得简单得多。
  还有就是平台不同可以兼容,就像有的平台不支持 long double类型,但是你如果定义了long double 直接不能用,但是如果这么

typedef long double typeitem;

直接改成可以支持的类型就行啦,根本不用那么麻烦改下面的代码,这也是比较重要的用途。

用途三:简化,提高可读性

  想必大家觉得,这个用途不是包含在上面的用途之中了吗,为什么还要再说一遍呢,其实我举个例子你也就明白了,

typedef int array[10];

这个代表什么意思,这可不是平时那种array[10】是个int了吧,这个代表,array是个重定义的类型

array a; 

就代表a是一个含有10个int型元素的数组,这么定义可能觉得简化不了多少,还不如直接int a[10];看着明白呢,好! 继续往下看,这个呢

typedef array Array[5]; 

如果我这么定义一个变量

Array arr[2]; 

这个又是什么意思呢?

这个就是定义个Array类型数组,其中这个“一维”数组有两个元素,但是每个元素又都是Array类型的,每个Array又是一个5行10列二维数组,所以arr就是一个三维数组,他就等于int arr[2][5][10];

  是不是看的有点蒙了, 其实在C语言中根本不存在多维数组,全部都是一维数组,只是一维数组里面又含一维数组,所以才构成了所谓的“多维”数组, 如果这样理解的话,是不是觉得多维数组也就不那么“神奇”了,变得简单了,没有那么晕了,这样定义的好处就是可以讲一个多维的数组转化成我们比较熟悉的一维数组,这样操作起来就比较容易了,可读性自然也会增强。所以这就是他的“简化”的作用。
  其实我们还可以在函数指针上体现,想定义个函数指针int (*p)(); 我们可以定义为
  

typedef int (*POWER)(); 

  接下来可以直接定义

POWER p1, p2; 

  他就等价于

  int (*p1)(), int (*p2)();

  这样也非常易懂。

定义方法:

  下面来谈一下他的定义过程,说了这么多,还没讲到怎么定义,其实也就三步:
  
  第一步: 按照定义变量的方法先写出定义体(想必这么都比较熟悉吧), 例如: int a;
  
  第二步: 将变量名换成想要重定义的名字 例如: int INT;
  
  第三步:在最前面加上typedef
  
  例如:

typedef int INT; 

  整个步骤就完成了,下面就可以用重定义的类型定义变量了:
  例如:

   INT a; 

   就是这么简单,不要想那么复杂。

  还有就是与宏定义区分开来,宏定义是在编译预处理的时候直接进行的替换,而typedef却不是,宏定义特别是写那个表达式的时候新手容易出错就是不能真正理解宏替换,就像这么例子:
  

 #define mul(a, b) a * b

  如果这么写
  

mul(2, 3)

  那么恭喜,你对了, 但是如果这么写,

mul(2 + 1, 3 + 4);

  你的出来的结果一定是错的,它只是简单地替换, 不会像函数那样会先计算出来2 + 1 等于 3 然后在进行计算, 它只能替换为2 + 1 * 3 + 4 所以结果当然错了……新手注意点就好了,这东西挺简单的。

参考:
详谈typedef的用法

C++ typename的起源与用法

*转载请注明出处,更多资料尽在 吾爱编程
返回吾爱编程首页