typedef定义的函数指针
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
int *p; 这样的代码是 C 语言中最最基础的一个语句了,大家都知道这个语句声明了一个变量 p,其类型是指向整型的指针(pointer to int);如果在这个声明的前面加上一个 typedef 后, 整个语义(semantics)又会是如何改变的呢?
typedef int *p; 我们先来看看 C99 标准中关于 typedef 是如何诠释的?C99 标准中这样一小段精辟的 描述:"In a declaration whose storage-class specifier is typedef, each declarator defines an identifier to be a typedef name that denotes the type specified for the identifier in the way described in xx"。
再比对一下两个声明:
int *p;
typedef int *p;
是不是有点"茅舍顿开"的感觉,int *p 中, p 是一个变量,其类型为 pointer to int;在 int *p 前面增加一个 typedef 后,p 变为一个 typedef-name,这个 typedef-name 所表示的类型 就是 int *p 声明式中 p 的类型(int*)。说句白话,typedef 让 p 去除了普通变量的身份,摇身 一变,变成了 p 的类型的一个 typedef-name 了。
typedef double *Dp; 分析: 去掉 typedef ,得到正常变量声明=> double *Dp; 变量 Dp 的类型为 double*,即 pointer to double; => "typedef double *Dp"中 Dp 是类型 double*的一个 typedef-name。 Dp dptr; <=> dptr 是一个 pointer to double 的变量 [例 3]
为了巩固上面的理解,我们再来看看"C 语言参考手册(C: A Reference Manual)"中的说 法:任何 declarator(如 typedef int *p)中的 indentifier(如 p)定义为 typedef-name, 其(指 代 p)表示的类型是 declarator 为正常变量声明(指代 int *p)的那个标识符(指代 p)的类型 (int*)。有些绕嘴,不过有例子支撑:
#includபைடு நூலகம் "iostream"
using namespace std;
int add(int a,int b){ return (a+b); }
typedef int (* func)(int ,int ) ;
void main(){ func f = add; int n = f(1,2); cout << n << endl; }
[例 1]
typedef double MYDOUBLE; 分析: 去掉 typedef ,得到正常变量声明=> double MYDOUBLE; 变量 MYDOUBLE 的类型为 double; => "typedef double MYDOUBLE"中 MYDOUBLE 是类型 double 的一个 typedef-name。 MYDOUBLE d; <=> d 是一个 double 类型的变量 [例 2]
Func *fptr; <=> fptr 是一个 pointer to function with one int parameter, returning a pointer to int
Func f; 这样的声明意义就不大了。 [例 4]
typedef int (*PFunc)(int); 分析: 去掉 typedef ,得到正常变量声明=> int (*PFunc)(int); 变量 PFunc 的类型为一个函数指针,指向的返回值类型为 int,参数类型为 int 的函数 原型; => "typedef int (*PFunc)(int)"中 PFunc 是函数指针类型(该指针类型指向返回值类型为 int,参数类型为 int 的函数)的一个 typedef-name。 PFunc fptr; <=> fptr 是一个 pointer to function with one int parameter, returning int
参照这段描述,并拿 typedef int *p 作为例子来理解:在一个声明中,如果有存储 类说明符 typedef 的修饰,标识符 p 将被定义为了一个 typedef name,这个 typedef name 表示(denotes)一个类型,什么类型呢?就是 int *p 这个声明(declarator)中标识符 (indentifier)p 的类型(int*)。
[例 5]
typedef int A[5]; 分析: 去掉 typedef ,得到正常变量声明 => int A[5];
变量 A 的类型为一个含有 5 个元素的整型数组; => "typedef int A[5]"中 A 是含有 5 个元素的数组类型的一个 typedef-name。 A a = {3, 4, 5, 7, 8}; A b = { 3, 4, 5, 7, 8, 9}; /* 会给出 Warning: excess elements in array initializer */ [例 6] typedef int (*A)[5]; (注意与 typedef int* A[5]; 区分) 分析: 去掉 typedef ,得到正常变量声明 => int (*A)[5]; 变量 A 的类型为 pointer to an array with 5 int elements; => "typedef int (*A)[5]"中 A 是"pointer to an array with 5 int elements"的一个 typedef-name。 int c[5] = {3, 4, 5, 7, 8}; A a = &c; printf("%d\n", (*a)[0]); /* output: 3 */ 如果这样赋值: int c[6] = {3, 4, 5, 7, 8, 9}; A a = &c; /* 会有 Warning: initialization from incompatible pointer type */ [例 7] typedef struct _Foo_t Foo_t; 分析: 去掉 typedef ,得到正常变量声明 => struct _Foo_t Foo_t; 变量 Foo_t 的类型为 struct _Foo_t; => "typedef struct _Foo_t Foo_t"中 Foo_t 是"struct _Foo_t"的一个 typedef-name。 [例 8] typedef struct { ... // } Foo_t; 分析: 去掉 typedef ,得到正常变量声明 => struct { ... // } Foo_t;
再谈 typedef(重点为函数指针)
有种很方便的写法。
typedef int *p; p pointer; 这时直接把 pointer 带入原式中,取代 p 然后去掉 typedef,得到的结果就是 int * pointer; 哈哈,这样直接替换就很直观多了。
C 语言语法简单,但内涵却博大精深;如果在学习时只是止步于表面,那么往往后期 会遇到很多困难。typedef 是 C 语言中一个很好用的工具,大量存在于已有代码中,特别值 得一提的是:C++标准库实现中更是对 typedef 有着大量的使用。但很多初学者对其的理解 仅局限于:typedef 用来定义一个已有类型的"别名(alias)"。正是因为有了这样的理解,才有 了后来初学者在 typedef int myint 和 typedef myint int 之间的犹豫不决。很多国内大学的 C 语言课之授课老师也都是如是说的,或者老师讲的不够透彻,导致学生们都是如是理解的。 我这里想结合 C 语言标准文档以及一些代码实例,也说说 typedef。
typedef int* Func(int); 分析: 去掉 typedef ,得到正常变量声明=> int* Func(int); 变量 Func 的类型为一个函数标识符,该函数返回值类型为 int*,参数类型为 int;
=> "typedef int* Func(int)"中 Func 是函数类型(函数返回值类型为 int*,参数类型为 int) 的一个 typedef-name。
变量 Foo_t 的类型为 struct { ... // } ;
=> "typedef struct { ... // } Foo_t "中 Foo_t 是"struct { ... // }"的一个 typedef-name。 这里 struct {...//}是一个无"标志名称(tag name)"的结构体声明。
typedef int *p; 我们先来看看 C99 标准中关于 typedef 是如何诠释的?C99 标准中这样一小段精辟的 描述:"In a declaration whose storage-class specifier is typedef, each declarator defines an identifier to be a typedef name that denotes the type specified for the identifier in the way described in xx"。
再比对一下两个声明:
int *p;
typedef int *p;
是不是有点"茅舍顿开"的感觉,int *p 中, p 是一个变量,其类型为 pointer to int;在 int *p 前面增加一个 typedef 后,p 变为一个 typedef-name,这个 typedef-name 所表示的类型 就是 int *p 声明式中 p 的类型(int*)。说句白话,typedef 让 p 去除了普通变量的身份,摇身 一变,变成了 p 的类型的一个 typedef-name 了。
typedef double *Dp; 分析: 去掉 typedef ,得到正常变量声明=> double *Dp; 变量 Dp 的类型为 double*,即 pointer to double; => "typedef double *Dp"中 Dp 是类型 double*的一个 typedef-name。 Dp dptr; <=> dptr 是一个 pointer to double 的变量 [例 3]
为了巩固上面的理解,我们再来看看"C 语言参考手册(C: A Reference Manual)"中的说 法:任何 declarator(如 typedef int *p)中的 indentifier(如 p)定义为 typedef-name, 其(指 代 p)表示的类型是 declarator 为正常变量声明(指代 int *p)的那个标识符(指代 p)的类型 (int*)。有些绕嘴,不过有例子支撑:
#includபைடு நூலகம் "iostream"
using namespace std;
int add(int a,int b){ return (a+b); }
typedef int (* func)(int ,int ) ;
void main(){ func f = add; int n = f(1,2); cout << n << endl; }
[例 1]
typedef double MYDOUBLE; 分析: 去掉 typedef ,得到正常变量声明=> double MYDOUBLE; 变量 MYDOUBLE 的类型为 double; => "typedef double MYDOUBLE"中 MYDOUBLE 是类型 double 的一个 typedef-name。 MYDOUBLE d; <=> d 是一个 double 类型的变量 [例 2]
Func *fptr; <=> fptr 是一个 pointer to function with one int parameter, returning a pointer to int
Func f; 这样的声明意义就不大了。 [例 4]
typedef int (*PFunc)(int); 分析: 去掉 typedef ,得到正常变量声明=> int (*PFunc)(int); 变量 PFunc 的类型为一个函数指针,指向的返回值类型为 int,参数类型为 int 的函数 原型; => "typedef int (*PFunc)(int)"中 PFunc 是函数指针类型(该指针类型指向返回值类型为 int,参数类型为 int 的函数)的一个 typedef-name。 PFunc fptr; <=> fptr 是一个 pointer to function with one int parameter, returning int
参照这段描述,并拿 typedef int *p 作为例子来理解:在一个声明中,如果有存储 类说明符 typedef 的修饰,标识符 p 将被定义为了一个 typedef name,这个 typedef name 表示(denotes)一个类型,什么类型呢?就是 int *p 这个声明(declarator)中标识符 (indentifier)p 的类型(int*)。
[例 5]
typedef int A[5]; 分析: 去掉 typedef ,得到正常变量声明 => int A[5];
变量 A 的类型为一个含有 5 个元素的整型数组; => "typedef int A[5]"中 A 是含有 5 个元素的数组类型的一个 typedef-name。 A a = {3, 4, 5, 7, 8}; A b = { 3, 4, 5, 7, 8, 9}; /* 会给出 Warning: excess elements in array initializer */ [例 6] typedef int (*A)[5]; (注意与 typedef int* A[5]; 区分) 分析: 去掉 typedef ,得到正常变量声明 => int (*A)[5]; 变量 A 的类型为 pointer to an array with 5 int elements; => "typedef int (*A)[5]"中 A 是"pointer to an array with 5 int elements"的一个 typedef-name。 int c[5] = {3, 4, 5, 7, 8}; A a = &c; printf("%d\n", (*a)[0]); /* output: 3 */ 如果这样赋值: int c[6] = {3, 4, 5, 7, 8, 9}; A a = &c; /* 会有 Warning: initialization from incompatible pointer type */ [例 7] typedef struct _Foo_t Foo_t; 分析: 去掉 typedef ,得到正常变量声明 => struct _Foo_t Foo_t; 变量 Foo_t 的类型为 struct _Foo_t; => "typedef struct _Foo_t Foo_t"中 Foo_t 是"struct _Foo_t"的一个 typedef-name。 [例 8] typedef struct { ... // } Foo_t; 分析: 去掉 typedef ,得到正常变量声明 => struct { ... // } Foo_t;
再谈 typedef(重点为函数指针)
有种很方便的写法。
typedef int *p; p pointer; 这时直接把 pointer 带入原式中,取代 p 然后去掉 typedef,得到的结果就是 int * pointer; 哈哈,这样直接替换就很直观多了。
C 语言语法简单,但内涵却博大精深;如果在学习时只是止步于表面,那么往往后期 会遇到很多困难。typedef 是 C 语言中一个很好用的工具,大量存在于已有代码中,特别值 得一提的是:C++标准库实现中更是对 typedef 有着大量的使用。但很多初学者对其的理解 仅局限于:typedef 用来定义一个已有类型的"别名(alias)"。正是因为有了这样的理解,才有 了后来初学者在 typedef int myint 和 typedef myint int 之间的犹豫不决。很多国内大学的 C 语言课之授课老师也都是如是说的,或者老师讲的不够透彻,导致学生们都是如是理解的。 我这里想结合 C 语言标准文档以及一些代码实例,也说说 typedef。
typedef int* Func(int); 分析: 去掉 typedef ,得到正常变量声明=> int* Func(int); 变量 Func 的类型为一个函数标识符,该函数返回值类型为 int*,参数类型为 int;
=> "typedef int* Func(int)"中 Func 是函数类型(函数返回值类型为 int*,参数类型为 int) 的一个 typedef-name。
变量 Foo_t 的类型为 struct { ... // } ;
=> "typedef struct { ... // } Foo_t "中 Foo_t 是"struct { ... // }"的一个 typedef-name。 这里 struct {...//}是一个无"标志名称(tag name)"的结构体声明。