学习 c++ 的道路是曲折,学多内容让人 confusing,我想原因很多,首先 c++ 是一门接近机器底层的语言,而非对开发人员友好的高级编程语言。这是也是他高效的原因吧。可能还有就是他更多的是操作计算机硬件和内存,如果对于硬件或内存结构并不了解的开发人员这里可能会有许多难理解的内容。
void HelloWorld()
{
std::cout << "Hello world" << std::endl;
}
int main(int argc, char const *argv[])
{
HelloWorld();
std::cin.get();
}
这是一个极其普通的函数,运行在控制台输出Hello World
。我是 web 前端出身,接触的最多就是 javascript 这样函数是一等公民的动态语言。
函数可以作为指针来使用,我们想一想函数是什么,编译后的函数又是什么。函数在代码组织的最小单元,编译以后一组 CPU 指令集保存在内存某个地方等待执行。所以我们可以用一个指针变量指向一个内存地址。执行这部分内存地址中指令不就等同于调用函数一样吗。
这里 auto 类型定义变量function
来接收HelloWorld
函数。对函数变量调用和普通函数没有任何区别。
void HelloWorld()
{
std::cout << "Hello world" << std::endl;
}
int main(int argc, char const *argv[])
{
auto function = HelloWorld;
function();
function();
// HelloWorld();
std::cin.get();
}
那么 function 这个变量具体又是什么类型呢,将鼠标移动到function
给我们提示function
是void (*function)()
。好既然我们知道了 function 具体是什么类型就可以对上面代码进行适当的修改。
int main(int argc, char const *argv[])
{
void (*function)() = HelloWorld;
function();
function();
std::cin.get();
}
这样写,运行没有任何问题,不过总是感觉怪怪。我们还是用 typedef 来指定一种类型作为函数指针的类型。
HelloWorldFunc func = HelloWorld;
创建该类型(HelloWorldFunc)函数指针接受函数作为值。这样处理起来符合我们开发的习惯,其实习惯挺重要的。
int main(int argc, char const *argv[])
{
typedef void (*HelloWorldFunc)();
HelloWorldFunc func = HelloWorld;
func();
func();
std::cin.get();
}
如果函数有参数例如HelloWorld(int a)
,我们就需要修改为typedef void (*HelloWorldFunc)(int);
。
void HelloWorld(int a)
{
std::cout << "Hello World " << a << std::endl;
}
int main(int argc, char const *argv[])
{
typedef void (*HelloWorldFunc)(int);
HelloWorldFunc func = HelloWorld;
func(1);
func(2);
func(3);
std::cin.get();
}
既然函数指针可以赋值给变量,我们就也可以将函数做参数传入函数进行使用从而实现高阶函数。这部分代码怎么看怎么像 underscore 的方法呢。
void PrintNum(int num)
{
std::cout << "number: " << num << std::endl;
}
void ForEach(const std::vector<int> &nums, void (*func)(int))
{
for (int num : nums)
func(num);
}
int main(int argc, char const *argv[])
{
std::vector<int> values = {1, 2, 3, 5, 6};
ForEach(values, PrintNum);
std::cin.get();
}
网友评论