有关下面 C++ 代码正确的是( )。
#include <iostream>
using namespace std;
bool isOdd(int N) {
return N % 2 == 1;
}
int Square(int N) {
return N * N;
}
bool checkNum(bool (*Fx)(int), int x) {
return Fx(x);
}
int main() {
cout << checkNum(isOdd, 10) << endl; // 输出行A
cout << checkNum(Square, 10) << endl; // 输出行B
return 0;
}这题考函数指针类型匹配。拿到题先别急着看选项,盯着checkNum的参数声明bool (*Fx)(int),脑子里过一遍isOdd和Square的返回类型,只要发现Square返回int,就能立刻锁定答案,因为C++编译器在编译期就会卡住这种类型不匹配。
学生最容易犯的错误是以为只要函数名字能传进去就行,忽略了C++函数指针是强类型的。很多人会误选A,觉得checkNum定义有问题,或者误选B,以为isOdd返回bool会被自动转换。还有的同学会想当然地认为程序能跑,只是输出不对,从而选D。这些坑本质上都是因为没把“编译期类型检查”这个概念刻在脑子里,觉得函数指针像普通参数一样灵活。
这道题考查的是C++中函数指针的类型匹配规则,属于GESP五级C++模块中非常核心的知识点。命题人专门在这里挖坑,就是要看看学生是否真正理解函数指针不是普通的变量,它的类型必须和所指向的函数完全一致,包括参数列表和返回类型,而且这种检查是在编译期进行的,一旦不匹配,代码甚至无法生成可执行文件。我们来一步步拆解。首先看checkNum函数的定义:bool checkNum(bool (*Fx)(int), int x)。这里Fx被声明为一个函数指针,它明确要求指向一个接受int参数、返回bool值的函数。接下来看main函数里的调用。第一行cout << checkNum(isOdd, 10),isOdd函数的定义是bool isOdd(int N),它的返回类型是bool,参数是int,和checkNum要求的类型严丝合缝,所以编译器会 happily 接受这个调用,程序运行后输出0(因为10是偶数)。第二行cout << checkNum(Square, 10),Square函数的定义是int Square(int N),它的返回类型是int。这时候编译器会进行严格的类型检查,发现传入的函数指针类型(要求返回bool)和实际函数类型(返回int)不匹配。在C++中,这种不匹配是无法隐式转换的,所以编译器会直接报错,提示类似“incompatible function pointer types”的错误。因此,输出行B会导致编译错误。再看选项A,说checkNum定义错误,这显然是不对的,参数声明完全合法。选项B说行A编译错,也不对,行A类型匹配。选项D说没有编译错误,那更不可能了。所以正确答案只能是C。这里有个反命题思维可以帮学生加深理解:如果把checkNum的参数改成int (*Fx)(int),那行A就会编译错,行B就能通了,答案就会反过来。这种“改一个参数类型,答案全反”的命题技巧,正是五级函数指针题的经典套路,出题人就是喜欢考这种细节。考频方面,从题库数据看,函数与函数指针是GESP五级的高频考点,2023年考了287题,2024年考了413题,2025年考了401题,五年加起来超过1000道题,占比极高。未来预测,只要GESP五级还在考C++,函数指针类型匹配这类题大概率还会以单选或填空的形式出现,尤其是结合lambda表达式或者模板函数的混合考察,难度会进一步升级。所以,记住这一条铁律:函数指针传参,类型必须严丝合缝,编译期不匹配直接炸,这是C++的脾气。