迷惑很久的问题了,今天正好又遇到这个问题,就抽了个时间研究总结了一下把它记录下来。
和同学讨论一个typedef的问题,实验过程中偶然发现VS2005的行为:
int fun(){
cout << "fun()" <<endl;
return 43;
}
int (*callback())(){//对
return fun; //returns function pointer
}
int (callback())(){//不对,报错:function returns function
return fun; //returns function
}
C99中的一个例子:
typedef int F(void); // type F is "function with no parameters
// returning int"
F f, g; // fand g both have type compatible with F
F f { /* ... */ } // WRONG: syntax/constraint error
F g() { /* ... */ } // WRONG: declares that g returns a function
int f(void) { /* ... */ } // RIGHT: f has type compatible with F
int g() { /* ... */ } // RIGHT: g has type compatible with F
F *e(void) { /* ... */ } // e returns a pointer to a function
F *((e))(void) { /* ... */ } // same: parentheses irrelevant
int (*fp)(void); // fp points to a function that has type F
F*Fp; //Fp points to a function that has type F
typedef int F(void);和typedef int (*F)(void);含义是不同的。
还可以这样int (*G)(void);这是声明了一个函数变量G,它不是个类型只是个对象。
因此可以对它赋值但不能用它定义变量。
int f(int);
int (*pf)(int) = &f;
初始化表达式中的&操作符是可选的,因为函数名在被使用前总是由编译器把它转换为函数指针,&操作符只是显式地说明了编译器将隐式执行的任务。
在函数指针被声明并且被初始化之后,我们就可以使用一种方式调用函数:
int ans;
ans = f(25);
ans = (*pf)(25);
ans = pf(25);
第一条语句简单地使用名字调用函数f,但他的执行过程可能和你想像的不太一样。函数名f首先被转换为一个函数指针,该指针制定函数在内存中的位置。然后,函数调用操作符调用该函数,执行开始与这个地址的代码。
第二条语句对pf执行间接访问操作,它把函数指针转换为一个函数名。这个转换并不是真正需要的,因为编译器在执行函数调用操作符之前又会把它转换回去,不过,这条语句的效果和第一条完全一样。
第三条语句和前两条的效果一样。间接访问操作并非必须,因为编译器需要的是一个函数指针。这个例子显示了函数指针通常是如何使用的。
评论