函数指针
原始函数指针类型:
void HelloHUAN() {
std::cout << "Hello Huan" << std::endl;
}
int main()
{
void (*voidfunc)() = nullptr;
voidfunc = HelloHUAN;
voidfunc();
std::cout << "Hello world" << std::endl;
std::cout << voidfunc << std::endl;
std::cout << &voidfunc << std::endl;
std::cout << sizeof(voidfunc) << std::endl;
std::cout << HelloHUAN << std::endl;
std::cout << &HelloHUAN << std::endl;
return 0;
}
这样看来,HelloHUAN本身就是一个指针吗,内部存储的是函数的入口地址吗? 既然这样我cout他一下
等等那么HelloHUAN和voidfunc中存储的是相同的函数地址吗? ———— 是的
还有一个问题是 那么函数指针和普通指针有什么区别,为什么能够通过funptr()的形式调用函数呢
———— 没什么区别,大小相同,当调用voidfunc时,编译器生成机器指令,跳转到该地址执行函数代码 PS: 重载过operaror()的类可以像函数一样调用诶
等等既然 指针位数和电脑位数相关,那么我的电脑难道是32位的吗?
在64位Windows系统中,如果在VS中打印指针变量的大小为4字节,是因为项目被编译为32位(X86)平台,而非64位(X64平台)
可以在工具栏中的解决方案平台中下拉更换为X64平台
cmd命令行中执行下面的代码就可以查看到电脑位数了
echo %PROCESSOR_ARCHITECTURE%
使用using定义类型别名:
using HelloFunc = void(*)();
HelloFunc SayHello(HelloFunc func = nullptr) {
if (func)
{
func();
return func;
}
else
{
cout << "No function is provided" << endl;
return nullptr;
}
}
void HelloHuan() {
cout << "hello HUAN!" << endl;
}
int main()
{
SayHello();
HelloFunc helloHuan = nullptr;
SayHello(HelloHuan);
}
有了类型别名,就可以将其作为一种基本数据类型使用啦,例如做函数入参、函数返回值、建立容器存储函数指针等等操作
但是如果不定义别名 应该如何写的超复杂呢?
- 作为参数好接受一点
void SayHello(void(*HelloFunc)() = nullptr) {}
-
作为返回值怎么搞呢
Deepseek大将军告诉我应该这么写:
返回类型 (函数名(参数列表))(函数指针的参数列表){
// 函数体
}
OK,这相比于使用别名不是复杂了一星半点,所以一个返回void()()类型函数指针的,名字叫做BENBEN的,没有参数的函数应该这么写void (*BENBEN())(){}
a. OK ,在函数中能构造一个void (*)()类型的函数并返回吗,这里是不是可以使用大佬的lambda表达式了
b. 等等,首先那么函数体内能否访问到自己的函数指针并返回自己呢?稍等,如果我想返回自己的指针,那么返回值类型就需要是我自己的类型,而我的类型同时也包含返回值类型,别动,是不是绕不出来了
c. 首先在函数中,可以访问取到自己的函数指针,通过函数名就可以,像不像类对象中的this指针
void CIRCLE() { void(*ptr)() = CIRCLE; cout << "ptr" << ptr << endl; cout << "CIRCLE" << CIRCLE << endl; // 这两个东西是一样的 }
d. 那我们就可以递归了,那还取什么指针直接CIRCLE中CIRCLE
void CIRCLE(int n = 5) { if (!n--) return; cout << n << endl; CIRCLE(n); }
如果没有终止条件,会一直递归导致栈溢出,栈溢出了怎么样,很严重吗,能把公司服务器干出不可逆损伤吗?试试
VS里面的黑窗好像有自动限制,那么将无限递归程序输出成exe文件,之后用cmd管理员权限执行呢
或者在linux系统中写个脚本,这个应该会更直接,想到了一首歌 “重复重复” -
如果参数和返回值都是函数指针呢
这是返回值的
void (*BENBEN())(){}
这是参数的
void SayHello(void(*HelloFunc)() = nullptr) {}
嗯,结合一下就是超级无敌笨笨了
void (*BENBEN(void(*HelloFunc)()))()
理解一下,现在BENBEN是一个接受void(*ptr)()类型函数指针,返回void(*ptr)()类型函数指针的函数
```
void(*BENBEN(void(*HelloFunc)()))(){
return HelloFunc;
}
void CIRCLE() {
cout << "I am CIRCLE" << endl;
}
int main()
{
BENBEN(CIRCLE)();
}
```
OK ,就是这样,我可以出面试题了,请写一个返回值为 double()()类型函数指针的,参数为int()(double,void(*)())类型函数指针的函数声明