据我所知,我可以定义一个函数类型:
typedef void (fn)(void);
我还可以定义一个函数指针类型:
typedef void (*pfn)(void);
有2个功能。第一个函数的参数类型是一个函数,另一个是函数指针:
void a(fn fn1)
{
fn1();
}
void b(pfn fn1)
{
fn1();
}
我实现了一个函数回调:
void callback(void)
{
printf("hello\n");
}
并将其作为参数传递给a和b:
int main(void) {
a(callback);
b(callback);
return 0;
}
a和b都运行良好,并打印"hello"
。
所以我想知道定义函数类型和函数指针类型有什么区别?或者实际上,它们是一样的?
答案 0 :(得分:2)
函数类型被视为参数列表中相应的函数指针类型。
(非指针)函数类型基本上有两个实际应用:
如果发现它太巴洛克式,请避免使用函数指针语法。
int apply(int (*f)(int), int x) {
return f(x);
}
int apply(int f(int), int x) {
return f(x);
}
声明相同类型的多个功能。
int add(int, int);
int subtract(int, int);
int multiply(int, int);
int divide(int, int);
typedef int arithmetic(int, int);
arithmetic add, subtract, multiply, divide;
后者对于避免重复非常有用。但请注意,函数类型不允许您使用const
来防止指针被重新分配。所以编译得很好:
#include <stdio.h>
int pred(int const i) { return i - 1; }
int succ(int const i) { return i + 1; }
int apply(int f(int), int const x) {
// Oops, didn’t really mean to reassign ‘f’ here.
f = pred;
return f(x);
}
int main() {
printf("%i\n", apply(succ, 1));
return 0;
}
您可以通过指针const
:
int apply(int (* const f)(int), int const x) {
// error: assignment of read-only parameter ‘f’
f = pred;
return f(x);
}
答案 1 :(得分:2)
fn fn2 = callback;
在标准C中是非法的。
void a(fn fn1)
的行为与void a(fn *fn1)
完全相同。它是仅在函数形式参数列表中允许的特殊语法,类似于void b(int x[])
实际上与void b(int *x)
完全相同的行为。如果你执行sizeof fn1
,你将获得函数指针的大小。
顺便说一句,你在fn
的定义中有多余的括号,这更简单:
typedef void fn(void);
指针版本需要使用括号来关联*
。
答案 2 :(得分:1)
鉴于滥用,您可以使用函数指针(&func
,func
,*func
,**func
,...所有最终都作为函数的相同值{{ 1}}),两者之间几乎没有实际差异。您可以使用func
来指示指向函数的指针,这不是一个简单的转换。
但是,这里使用类型为fn *
的非参数变量并尝试(未成功)使用类型为pfn
的非参数变量,对您的代码进行了温和调整。这不会编译,因此在文件范围(全局)或本地范围内使用时存在差异,而不是在参数列表中使用。
fn
pfn.c
typedef void (fn)(void);
typedef void (*pfn)(void);
static void callback(void)
{
printf("hello\n");
}
static void a(fn fn1)
{
fn fn2 = callback;
fn *fn3 = callback;
fn1();
fn2();
(*fn2)();
fn3();
(*fn3)();
}
static void b(pfn fn1)
{
pfn fn2 = callback;
fn1();
fn2();
}
int main(void)
{
a(callback);
b(callback);
return 0;
}
答案 3 :(得分:0)
查看最后一段Here
可以帮助您更好地理解fucntion和函数指针的typedef。