关键字typedef

来源:互联网 发布:圆形画框软件 编辑:程序博客网 时间:2024/06/05 17:13

对这个东西的探讨始于一道趋势科技的笔试题目,网上找到:
1.Please define a member function pointer of A::print()
class A
{
  public:
  void print()
  {
   
  }
};
(a) typedef void(*pf_type)(A*);
(b) typedef void(A::*pf_type)();
(c) typedef void(*)(A*) pf_type;
(d) typedef void(A::*)() pf_type;

给出我的理解前(在最最后面)先来看下几个别的关于类型的问题,从简单开始

void (*func)()
这个比较简单,是一个函数指针,没有参数,返回类型也为void;
void my(void); //函数声明。也可也是void my(),好的习惯是写上void。
func = my; //OK,但是必须有个前提,这个函数已经定义了,光声明是不行的

void (*func[2])()
这个func就是一个函数指针的数组了。
void my(void);
func[0] = my;//OK

还有几种常见的情况:
int (*a)[10]
a为一个指针,这个指针指向一个数组,所以a也叫数组指针。
int *a[10]
a为一个数组,这个数组里面元素的类型为int *,即全部为整型的指针。注意:这里[]的优先级比*的优先级高~
int (**a)[10]
a为一个二级指针,它指向的是一个一维的数组的指针,数组的类型元素为int,a为一个指向数组指针的指针

void (*func[10]) (void (*)())
这里的func也是一个函数指针的数组,数组中的元素为一个函数指针,这个函数指针对应函数类型为,输入参数为一个函数指针(void (*)()),注意这里的void(*)()里面的*不要丢失!否则编译器会给你隐式转化的。

这里有个“右左法则”是分析复杂的声明时候用的,为了使声明看的简单,经常会用typedef关键字,这里先不用typedef关键字,看两个复杂的声明,其实在复杂的声明无非就是几种比较容易搞混的东西复杂的嵌套,函数指针,指针数组,数组指针,能看透这几种形式就简单了。说下什么是“右左法则”,就是先看变量名字,一般是一个吧,当你碰到一个括号时就调转阅读的方向。括号内的所有内容都分析完毕就跳出括号的范围。这样继续,直到整个声明都被分析完毕。

int (*(*func)())()
先找变量func,向右看,),向左看,为一个*说明func为一个指针,在继续向左看为一个(,跳出括号,向右看为一个()说明func为一个函数指针,且指向的函数没有参数。在向右看,为一个),向左看,看到一个*,说明这个函数指针返回的为一个指针,向左看为(,跳出括号,向右看为一个(),说明返回的为一个函数指针,向左看为一个int 说明这个函数指针的返回类型为int

int (*(*fp) (int))[10];
这个fp为一个函数指针,指向的函数的参数为int,返回类型为一个指针,而这个指针指向的是一个int [10]指针数组。
int* (*(*fp) (int))[10];
这个fp为一个函数指针,指向的函数的参数为int,返回类型为一个指针,而这个指针指向的是一个int *[10]指针数组。
int(*)() (*a)[10];
a为一个数组指针,数组大小为10,每个元素的类型为int (*)(),即一个函数指针。

下面在说下typedef,这个东西可以让你的复杂类型看的简单,而且很容易编码。

1)与define的区别

一个经典的题目:

typedef char *pStr1;
#define pStr2 char *//没有分号注意
pStr1 s1, s2;
pStr2 s3, s4;
s1,s2,s3为一个char *的类型,而s4为char,因为define只是简单的替换,并不是像tpyedef那样定义了一个“新类型”

还有一个题目
typedef char * pStr;
char string[4] = "abc";
const char *p1 = string;
const pStr p2 = string;
p1++;
p2++;
第二p2++编译器会报错“increment of read-only variable ‘p2’”,这里比较特殊,第一个const修饰的是p1指向的内容,第二修饰的是p2,这个时候的pStr 相当于一个新的类型,可以看成因为是指针就比较特殊,第二种情况相当于char * const p2;理解么可以解释成编译器解释的时候,第一种为(const char) *p,一个指针,指向的内容为const char,第二种为(const pStr) p2,因为编译器肯定是要先做出pStr这种类型,并定义成“新类型”, 所以这个时候p2为一个 const pStr的类型,为一个const (char *)即一个常指针的类型,当然不能直接写成 cosnt (char *) p1 编译器是不识别的。

2)定义一个函数指针类型

这只是typedef的一个特殊用法而已,这样可以简化定义。

typedef <返回类型> (*<函数类型名>)(参数表)
typedef <返回类型> (<类名>::*<函数类型名>)(参数表)

上面提到的声明:void (*func[10]) (void (*)())可以按照如下声明:
typedef void (*PF)(void (*)());
PF func[10];
也可以
tpyedef void (*pFunParam)();
typedef void (*pF)(pFunParam);
pF func[10];
这样就可以看的更清楚一些了。

最最后,那个题目,按照这个格式typedef <返回类型> (<类名>::*<函数类型名>)(参数表),应该是选b的。