Linux内核中的typedef用法

来源:互联网 发布:php技术总监招聘 编辑:程序博客网 时间:2024/06/04 18:52


原文出自:http://blog.163.com/njut_wangjian/blog/static/165796425201232510265243/

在C和C++编程语言中,typedef是一个关键字,它用来对一个类型起一个新名字,也用来声明自定义数据类型,其实给一个类型起新名字的作用也包含在声明自定义数据类型这个功能中。

      1.给一个类型起一个新名字

       给一个类型其新名字,有时候可以帮助我们更好地记忆。

       例子:typedef int inter;

       此声明定义了一个 int 的同义字,名字为 inter。注意 在这里typedef 并不创建新的类型。它仅仅为现有类型添加一个同义字。你可以在任何需要 int 的上下文中使用 inter,即可以用inter来代替int进行整数变量的定义。

       这个功能是最常用的,而且相对来说是比较简单的。

 

       2.定义新的类型

       定义新的类型有多种形式,下面简单的列一些。

      1>typedef  BaseType NewType [arrSize]

       这种类型可以掩饰一些符合类型,其中BaseType是基本类型,NewType是我们所定义的新类型,这个新定义的NewType可以像其他的基本类型那样使用。下面举个例子:

      typedef char Array[10]; 

       这里的char就是基本的类型,而Array是我们新定义的类型。这里Array是一个字符型的数组类型,这个数组类型的长度为10。下面我们就可以用Array来进行一些定义了。

       Array array1,array2;

       这里我就定义了两个Array型的数组,这两个数组都是字符型的有10个元素的数组;如果我们没有用typedef定义,那么我么就要进行下面这样的定义:

      char array1[10];char array2[10]。

      这种形式可以应用到指针等。

     这里引入typedef一个陷阱:

     typedef char * pstr;
  int mystrcmp(pstr, pstr);

      我们知道,标准函数 strcmp()有两个"const char *"类型的参数。因此,它可能会误导人们象下面这样声明 mystrcmp(): 
  int mystrcmp(const pstr, const pstr); 
  用GNU的gcc和g++编译器,是会出现警告的,按照顺序,"const pstr"被解释为"char* const"(一个指向 char 的常量指针),两者表达的并非同一意思。应该按以下方式定义:

       typedef const char* pstr;

 

       2>typedef int  (*PF) (const char *, const char *)这种类似的形式

      这个声明引入了 PF 类型作为函数指针的同义字,该函数有两个 const char * 类型的参数以及一个 int 类型的返回值。这种定义的用途过会在下面以例子的形式给出。

       typedef 就像 auto,extern,mutable,static,和 register 一样,是一个存储类关键字。这并不是说 typedef 会真正影响对象的存储特性;它只是说在语句构成上,typedef 声明看起来象 static,extern 等类型的变量声明。这一点对于我们理解typedef定义新类型的功能很有用。

       这里引入typedef另外一个陷阱:

       typedef register int FAST_COUNTER;

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

 

      3>typedef与结构体结合使用

      struct var {
                    int data1;
                     int data2;
                     char data3;
       };
       这里定义一个类型var,而要定义这种类型的变量,必须这样写:struct var a;若添加typedef struct var newtype;则定义变量只需这样即可:newtype a;

       typedef和结构体一般不这样使用,而是按下面这样子:

       typedef struct var {
                    int data1;
                     int data2;
                     char data3;
       } newtype;

       newtype a;

     在链表中更一般的形式:

   typedef struct tagNode 
  { 
  char *pItem; 
  struct tagNode *pNext; //这里不能写为*pNode *pNext;
  } *pNode;

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

      typedef 有另外一个重要的用途,那就是定义机器无关的类型,例如,你可以定义一个叫 REAL 的浮点类型,在目标机器上它可以获得最高的精度: 
  typedef long double REAL; 
  在不支持 long double 的机器上,该 typedef 看起来会是下面这样: 
  typedef double REAL; 
  并且,在连 double 都不支持的机器上,该 typedef 看起来会是这样:、 
  typedef float REAL; 

        linux内核中typedef的例子:

        前面提到的"2>typedef int  (*PF) (const char *, const char *)"这种类似的形式是可以简化函数的,而且便于理解。举linux内核中信号处理函数这个例子:

       void (*signal (int signr,void (*handler)(int))) (int)

       其用typedef定义如下:

       typedef void sigfunc(int);

       sigfunc *signal(int signr,sigfunc *handler);

       其中typedef定义了一个有一个整型参数无返回值的函数类型。void (*handler)(int)表示一个有一个整型参数无返回值的函数指针,这个指针名为handler,所以其可以用sigfunc进行说明,此时sigfunc就相当于前面的int signr中int的作用;同理这个函数也是这样。

       注:对复杂变量建立一个类型别名的方法很简单,你只要在传统的变量声明表达式里用类型名替代变量名,然后把关键字typedef加在该语句的开头就行了。 

  int *(*a[5])(int, char*); 
  //pFun是我们建的一个类型别名 
  typedef int *(*pFun)(int, char*); 
  //使用定义的新类型来声明对象,等价于int* (*a[5])(int, char*); 
  pFun a[5]; 

0 0
原创粉丝点击