使用typedef语句定义函数类型和函数指针

首先我们要先明白一个概念,函数名是不是指针?也就是说一个函数名可不可以代表一个地址?以及什么是函数类型?

经过查找,函数名就是一个指针,但是意义是不一样的,如同于数组a[],a和&a其实都是一样的。当调用一个函数时,我们都是直接用函数名调用,或者说通过指针调用。

函数类型,在我理解,就是定义了一个函数应该返回什么样的类型,int?void?以及它的参数形式。

那么:

1,tpyedef自定义函数指针类型:

看一个例子:

01 #include <stdio.h>
02  
03 typedef int (*fp_t)(char c);
04  
05 int f0(char c) { printf("f0, c = %c\n", c); return 0;}
06 int f1(char c) { printf("f1, c = %c\n", c); return 1;}
07  
08 int main()
09 {
10 int ret;
11 fp_t fp;//fp是一个指向一个函数类型(返回的是int,参数是char)的函数指针
12  
13 fp = f0;
14 ret = fp('a');通过函数指针调用函数
15  
16 fp = f1;
17 ret = fp('x');
18 return 0;
19 }

2,typedef自定义函数类型:

例子:

01 #include <stdio.h>
02  
03 typedef int f_t(char c);
04  
05 int f0(char c) { printf("f0, c = %c\n", c); return 0;}
06 int f1(char c) { printf("f1, c = %c\n", c); return 1;}
07  
08 int main()
09 {
10 int ret;
11 f_t *fp;//f_t是函数类型,所以fp是指向此函数类型的指针
12  
13 fp = f0;
14 ret = fp('a');
15  
16 fp = f1;
17 ret = fp('x');//函数指针调用此函数
18 return 0;
19 }
3.在看一个例子
#include "include/apue.h"
typedef int mf(void);
int test1(void);
int test(mf *fp)
{
        return fp();
}
int main(int argc,char * argv[])
{
        printf("%d\n",test(test1));
        exit(0);
}
int test1(void)
{
        return 3;
}

这里typedef定义了一种函数类型mf,此时并没有此类型真正的函数。
在test函数的定义中,我们发现它需要一个参数,此参数是指向mf类型的函数的指针,而test1函数正好是mf类型的函数,而test1正好是这种函数的地址(函数名即是函数地址),故而可以把test1传递给test函数。


4.typedef 与#define的异同
首先要理解typedef和#define宏的区别,typedef是给已有的类型取别名,而#define只是简单的字符替换。

【typedef与#define】

  【案例】

  typedef int* Tpi;

  #define int* Dpi;

  Tpi p1,p2;

  Dpi p3,p4;

  问上述代码中定义的四个变量分别为什么类型?

【分析】

  区分p1,p2,p3,p4四个变量的类型,首先要理解typedef和#define宏的区别,typedef是给已有的类型取别名,而#define只是简单的字符替换。于是上述代码等同于

  int *p1,*p2;//typedef的作用

  int *p3,p4;//#define的作用

  也就是说p3被定义为了一个整型指针,而p4则只是整型。

5.typedef之const指针

【案例】

  typedef string * pstr;

  const pstr cpstr;

  问上述代码中cpstr是一个怎样的指针?

【分析】

  很多朋友,包括我自己在刚接触到时,第一反应是:cpstr被定义为一个指向const string对象的普通指针,原因很简单,置换一下string*与pstr的位置就得到

  //这显然就是一个指向const string对象的普通指针

  const string * cpstr;

  然而,事不如人愿,cpstr的确切定义为:一个指向string类型的const指针。

  看到这个答案,相比不少朋友稍显惊讶,我也如此,其中内因,且听我慢慢道来。

  之所以出错,在于我们“置换一下就好了”,“置换”这个词不应该用在typedef,而该用在#define宏身上,typedef是定义了一个类型别名,定义的结果遵循任何正常定义的标准。那么这个typedef到底是怎么定义了一个const指针呢?

  首先分析

  const pstr cpstr;

  这段代码定义了一个pstr类型的const cpstr,实际上就是

  pstr const cpstr;

  为了便于理解,就拿int定义来说

  //二者等价,前者是习惯用法,后者是标准规定

  const int ival = 0;

  int const ival = 0;

  既然理解了cpstr是一个const的pstr类型的对象,pstr是什么呢?pstr是string*,因此这样一来,就成了cpstr是一个const的string*类型的对象,也即cpstr是一个指向普通string的const指针。

  【总结】

  本次误解主要源于大家认为typedef等同于#define宏定义,以为简单替换字符就可以了。实则不然。以后见到这样的定义,最简单的办法就是从定义该变量的地方入手

  typedef string * pstr;

  const pstr cpstr;

  按步骤(熟练了就很快了)思考:

  ①cpstr是一个类型为 pstr 的常量

  ②pstr 是什么?

  ③pstr 是 string*

  ④所以,cpstr是一个类型为 string* 的常量,也即 string *const cpstr



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值