函数指针正确声明为 int (*p)(int, double),星号必须紧邻变量名且括号不可省;int *p(int) 是返回指针的函数声明;调用用 p(1, 2.0) 或 (*p)(1, 2.0);仅无捕获 lambda 可转为函数指针。

函数指针声明语法为什么总写错
根本原因是把 int (*p)(int) 和 int *p(int) 搞混了——后者是函数声明,返回 int*,不是指针类型。C++ 里函数指针的星号必须和变量名紧挨着,括号不能省,否则编译器按函数声明解析。
常见错误现象:error: 'p' declared as function returning a function,就是括号位置错了。
- 正确写法:
int (*p)(int, double)—— 指向接受int和double、返回int的函数 - 别用
typedef隐藏问题,先手写三遍,再考虑封装;using fp_t = int(*)(int, double);是安全的替代 - 成员函数指针完全不同,不能用这个语法,会编译失败(
error: cannot declare pointer to member function)
调用函数指针时加不加括号
必须加括号,但不是给指针本身加,而是像调用普通函数一样用 (*p)(1, 2.0) 或更简洁的 p(1, 2.0)。C++ 允许省略解引用,但语义上仍是通过指针跳转。
使用场景:回调、策略切换、事件分发。比如注册一个日志处理函数:set_log_handler(&log_to_file),内部存的是 void (*)(const char*) 类型指针。
立即学习“C++免费学习笔记(深入)”;
-
p(1, 2.0)和(*p)(1, 2.0)完全等价,前者更常用 - 如果
p是空指针,调用直接崩溃,务必检查:if (p) p(x); - 传入函数名(如
&func或func)都行,C++ 中函数名自动转为地址,但显式写&更清晰
lambda 能赋给函数指针吗
只有无捕获的 lambda 才能隐式转换为函数指针;一旦用了 [&] 或 [=],就生成闭包类型,无法赋值,编译报错:error: cannot convert '<lambda>' to 'void(*)()' in assignment</lambda>。
性能影响:函数指针调用是直接跳转,零开销;而 std::function 有类型擦除开销,别为了图方便用它替代原生函数指针。
- 允许:
auto l = []{ return 42; }; int (*fp)() = l; - 禁止:
int x = 0; auto l2 = [&]{ return x; };—— 捕获了变量,类型不是纯函数指针 - 若需捕获,老实用
std::function,别硬转;函数指针不是万能接口
函数指针数组怎么初始化才不崩
声明时维度和类型必须严格匹配,漏写星号或括号顺序错,轻则类型不符,重则触发未定义行为。比如想存三个返回 void、接受 int 的函数指针,得写成:void (*handlers[3])(int),不是 void* handlers[3](int)(语法错误)。
常见错误现象:error: array of functions is not allowed,说明你把括号套在了数组名后面。
- 初始化要对齐参数和返回值:
void (*handlers[2])(int) = {func_a, func_b}; - 用
std::array包一层可提升类型安全:std::array<void> arr = {func_a, func_b};</void> - 数组长度写错(比如声明 3 个却只初始化 2 个),剩余元素自动为
nullptr,调用前仍需判空
函数指针本身不携带调用约定信息,Windows 上若混用 <strong>stdcall</strong> 和默认 cdecl,链接时可能静默失败或运行时栈错乱——这地方没报错,但结果不可靠。











