转自: C中typedef 函数指针的使用

1. 常用用法

点击(此处)折叠或打开

  1. int integer; //整型变量
  2. int *pointer; //整型指针变量
  3. int array [5]; //整型数组变量
  4. int *p_array [5]; //整型指针的数组的变量
  5. int (*array_pointer) [5];//整型数组的指针的变量
  6. int function (int param);//函数定义,也可将函数名看作函数的变量
  7. int *function (int param);//仍然是函数,但返回值是整型指针
  8. int (*function) (int param);//现在就是指向函数的指针了
若要定义相应类型,即为类型来起名字,就是下面的形式:

点击(此处)折叠或打开

  1. typedef int integer_t; //整型类型
  2. typedef int *pointer_t; //整型指针类型
  3. typedef int array_t [5]; //整型数组类型
  4. typedef int *p_array_t [5]; //整型指针的数组的类型
  5. typedef int (*array_pointer_t) [5]; //整型数组的指针的类型
  6. typedef int function_t (int param); //函数类型
  7. typedef int *function_t (int param); //函数类型
  8. typedef int (*function_t) (int param); //指向函数的指针的类型
注意:上面的函数类型在C中可能会出错,因为C中并没有函数类型,它的函数变量会自动退化成函数指针;在C++中好像是可以的。在这里主要说明的是形式上的相似性。
记住如下两种模式,再复杂的typedef也能解读。

点击(此处)折叠或打开

  1. typedef (*)(....) 函数指针。
  2. typedef (*)[] 数组指针

2. 缺点(常遇陷阱)
2.1 “typedef是定义了一种类型的新别名,不同于宏,它不是简单的字符串替换”

点击(此处)折叠或打开

  1. typedef char* PSTR;
  2. int mystrcmp(const PSTR, const PSTR);
const PSTR实际上相当于const char*吗?不是的,它实际上相当于char* const。 原因在于const给予了整个指针本身以常量性,也就是形成了常量指针char* const。
2.2 "typedef在语法上是一个存储类的关键字(auto,extern,static,register,mutable,volatile,restrict以及typedef),虽然它并不真正影响对象的存储特性"

点击(此处)折叠或打开

  1. typedef static int i;
是非法的。因为,对于编译器来说,多个存储类关键字不能同时用,因为每个变量只能有一种存储类型。
    关于存储类型指示符(storage-class-specifier),其包括:auto,extern,static,register,mutable,volatile,restrict以及typedef。
    在不指定存储类型指示符的时候,编译器会根据约定自动取缺省值。
    存储类型指示符的位置也是任意的(但要求在变量名和指针*之前),也就是说以下几行代码是等价的:

点击(此处)折叠或打开

  1. static const int i;
  2. const static int i;
  3. int const static i;
  4. const int static i;
    对于typedef,只是在语句构成上,typedef 声明看起来像 static,extern 等类型的变量声明,它不会影响对象的存储特性。

3. 优点
“3.1 通常讲,typedef要比#define要好,特别是在有指针的场合”

点击(此处)折叠或打开

  1. typedef char *pStr1;
  2. #define pStr2 char *;
  3. pStr1 s1, s2;
  4. pStr2 s3, s4;
在上述的变量定义中,s1、s2、s3都被定义为char *,而s4则定义成了char,不是我们所预期的指针变量,根本原因就在于#define只是简单的字符串替换而typedef则是为一个类型起新名字。

4.
QA: #define和typedef有什么关系?
AN:
4.1 #define是在编译前(编译预处理阶段)做简单的字符替换。 typedef是在编译时被解释。
4.2 二者看起来都是替换,但实际使用要注意,见上“2.1” 和 “3.1”。
12-16 19:06