C和C++中typedef的用法分析

 

   在代码之中使用typedef声明有助于创建与平台无关的类型,隐藏C和C++语言中复杂和难以理解的符合类型,创造更为美观的代码。

但是typedef的使用却有一些很容易混淆的地方,简单的用法还可以,稍微复杂一些的用法我就搞不懂了。在网上搜了一些资料,

看了看,自己总结了一下。

 

一、谭浩强版的用typedef定义已有的类型名的别名的步骤如下:

  (1)先按定义变量的方法写出定义体;

  (2)将变量名换成新类型名;

  (3)在最前面加typedef;

  (4)之后就可以用新类型名去定义变量。

二、typedef用法

  1、最简单的用法

  如:typedef int myint;

  myint  sn;  //相当于int  sn;

  是将myint作为int类型的同义词。

 

2、用typedef定义复合类型数组类型的同义词

  如例所示typedef char  WORD[20];

  WORD  w1, w2; //相当于char  w1[20]; char  w2[20];

  则WORD就成了包含20个元素的char数组类型的同义词。

 

3、用typedef定义简单的复合的指针类型同义词

  先看C和C++中指针类型纠结的定义。

  char*   pa,  pb;

  char    *pc, *pd;

  其中pa是char指针类型而pb不是,这多半不符合我们的常规理解方式,如果想要定义两个char指针,则必须像定义pc和pd那样;而且*的位置没有影响。

但是利用typedef我们却可以定义char*这种复合类型的同义词。如下所示:

  typedef char * chPointer;

  chPointer  pi, po;这样pi和po都是char指针类型了。

这里还有一些需要注意的地方。如下:

  有函数int myStrcmp(const  char*, const  char*) ;

  如果定义Typedef  char* pStr;而且声明myStrcmp()如下:

  int myStrcmp(const  pStr, const  pStr),那么这将是错误的。因为函数原型中的参数是指向char常量的指针,而声明的却是指向char的指针常量。

对于这一点我想必须要理解typedef不只是简单的宏替换。应该从它所表示的意义上去理解。Typedef  char* pStr定义的是一个指向char的指针,

所以const pStr中const修饰的是一个指针,也就是说const pStr 表示的是一个char型指针常量。

 

要解决不一致的问题可以这样:typedef const char*  pStr;这样声明函数就变成了:

int myStrcmp(pStr, pStr);

 

4、typedef用于struct的用法

  在旧的C的代码中声明struct新对象时,必须要带上struct,即形式为:

  struct 结构名 对象名,如:

  struct POINT

  {

  int  px;

  int  py;

  };

  struct POINT pot;

  而在C++中,则可以直接写:结构名 对象名,即:POINT pot;

  为了在C代码的结构体声明中少写一个struct是代码更为紧凑和简约,就有了如下的声明方法:

  typedef struct POINT

  {

  int px;

  int py;

  }POINT;

 

这样的一段代码实际上做了两件事情:

  (1)

  struct POINT

  {

  int px;

  int py;

  };

  (2)

  typedef struct POINT POINT;

以后就可以这样声明struct POINT类型的变量了:POINT pot;显得简约一点。

 

5、typedef隐藏复杂类型的用法

此种用法主要体现在定义函数型的指针上。关键点在于根据运算符的结合性,逐步理解其所代表的意义。

(1) 先看C语言中关于函数的声明

  int Function(int ,char);

  其对应的函数指针声明为:int (*Fp) (int,char);

  当进行赋值时可以有以下形式:

  Fp = &Function;函数调用时的形式为:(*Fp)(int, char)。

  Fp =  Function; 函数调用时的形式为:  Fp(int, char)。

 

(2)再看C语言中关于数组的声明

  int SN[6];

  其对应的数组指针声明为int (*pS)[6];注意括号的使用,因为[]的优先级大于*。

  使用方式为:pS = &SN; int a = (*pS)[0]。

 

(3)再看以下三个变量声明

  #1    int* (*A[6])(char*,int*);

  #2    void (*B[6])(int(*)());

  #3    int(*)() (*P)[6];

然后再来分析以上声明所代表的意义。

 

  #1

  int* (*A[6])(char*,int*);

  首先看变量名A,因为[]的结合性大于*,所以A首先是一个数组,然后每个数组元素都是一个指针;再看括号外边是一个函数的声明形式,所以A数组中的每一个元素都是指向函数的指针。这种函数返回值为int*型,参数形式为(char*,int*)。

  用typedef来简化此种类型声明:

  typedef  int* (*pA)(char*, int*);

  pA  A[6];同int* (*A[6])(char*,int*);

 

  #2

  void (*B[6])(int(*)());

  类似于#1,B是一个数组,每个元素是一个指针,这个指针指向一个函数,函数的返回值为void,参数为int(*)()(也就是一个函数,返回值为int无参数)。

用typedef来简化此种类型声明:

  typedef  void (*pB)(int (*)() );

  pB  B[6];同void (*B[6])(int(*)());

当然还可以逐步简化:

  typedef  int (*pi) ();简化指针指向的函数的参数;

  typedef  void (*pB)(pi);

  pB  B[6];同void (*B[6])(int(*)())。

 

#3

  int(*)() (*P)[6];

  首先P是一个指针,P指向了一个数组,这个数组的每一个元素为指向函数的指针,指向的函数类型是返回值为int无参数。

用typedef来简化此种类型声明:

  typedef int(*pi)();简化数组的元素定义;

  typedef pi (*PP)[6];

  PP  P;同int(*)() (*P)[6];

 

(4)2个模式:
  type (*)(....) 函数指针                     type (*)[]   数组指针

 

关键还在于根据运算符的结合性,理解typedef定义的类型的意义,C语言在很多类似的地方都让人纠结。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章