指向函数/函数表的指针
Pointers to functions / Function Tables
我正在学习函数指针,并遇到了以下代码:
#include <iostream>
using namespace std;
// A macro to define dummy functions:
#define DF(N) void N() {
cout << "function " #N " called ... " << endl; }
DF(a); DF(b); DF(c); DF(d); DF(e); DF(f); DF(g);
void (*func_table[])() = {a, b, c, d, e, f, g};
int main(){
while(1){
cout << "press a key from 'a' to 'g' "
"or q to quit"<< endl;
char c, cr;
cin.get(c); cin.get(cr); // second one for CR
if ( c == 'q')
break;
if (c < 'a' || c > 'g')
continue;
(*func_table[c-'a'])();
}
}
有人可以向我解释指向函数func_table的指针是如何工作的吗?特别是{}
内有a,b,c,d,e,f,g的效果是什么,整个表达式在做什么?
通常,当我看到指向函数的指针时,您可以通过分配函数名称来初始化指针,但在此示例中,它仅提供字符数组。那么它怎么知道调用DF(char(呢?
另外,我不确定为什么我需要这些语句:
DF(a); DF(b); DF(c); DF(d); DF(e); DF(f); DF(g);
另外,声明:(*func_table[c-'a'])();
我们减去"a"的原因是,这种不同将确定从数组中选择的正确字母{a,b,c,d,e,f,g}
?
这是一些丑陋的、混淆的代码,这并不丢人,它让你感到困惑。让我们一点一点地做:
// A macro to define dummy functions:
#define DF(N) void N() {
cout << "function " #N " called ... " << endl; }
DF(a);
如果展开该宏调用,则会得到:
void a() {
cout << "function a called ... " << endl; }
对于 b、c 等类似。因此,a
到g
都是打印自己名称的函数,仅此而已。
void (*func_table[])() = {a, b, c, d, e, f, g};
使用typedef更容易阅读:
typedef void (*FuncPtr)(); //FuncPtr is a function pointer to functions of type void X();
FuncPtr func_table[] = {a, b, c, d, e, f, g};
实际上,这是{&a, &b, &c, &d, &e, &f, &g}
- 作者使用了隐式函数到函数指针的转换。含义:func_table
是指向a
g
的函数指针数组
int main(){
while(1){
cout << "press a key from 'a' to 'g' "
"or q to quit"<< endl;
char c, cr;
cin.get(c); cin.get(cr); // second one for CR
if ( c == 'q')
break;
if (c < 'a' || c > 'g')
continue;
这应该很清楚。现在调用:
(*func_table[c-'a'])();
c-'a'
是与 'a'
的偏移量,表示 0 表示 'a',1 表示 'b' 等等。例如,如果 c 是 'd',则此行调用 (*func_table['d'-'a'])()
,wich 是 *(func_table[3])()
wich 只是 d
- 因此该行仅使用您刚刚键入的名称调用函数。
通常当我看到指向函数的指针时,您会初始化指针 通过分配函数名称,但在本例中它只是 提供字符数组。那么它怎么知道打电话 DF(字符(?
实际上,它不是给出一个字符数组,而是一个函数数组。 DF(a)
将定义一个命名为 a
的函数。
所以基本上,你最终会有一个指向你的函数的函数指针数组(即,a
、b
、c
、...(。
我们减去"a"的原因是,如果用户按下b
键,我们将需要调用b
函数。您的变量c
将以"b"作为值。"b" - "a" = 1。因此,它将调用数组的第二个函数指针(因为 array[1] 是第二个元素(,这实际上是命名为 b
的函数。
丑陋的丑陋...
DF(N)
创建一个输出"N"的 N 函数(在宏中使用 # 运算符(
所以:
DF(a);
是一种较短的写作方式
void a(){cout << "function Acalled" << endl;}
现在它们存储在一个数组中:
func_table[0]()
相当于
a()
使用字符c-'a'
会在两个字符之间产生差异:'a' - 'a' = 0
然后调用func_tables[c-'a']
将调用预期的函数。
这一行:
#define DF(N) void N() {
cout << "function " #N " called ... " << endl; }
定义一个名为 N
的新函数。这是有效的,因为宏只是创建一个文本替换,所以当编译器看到它时,它会看到一个名为 N
的完全有效的函数,就好像你键入了该函数一样
void a() {... }
这里有用上述宏声明的函数,名为a-g
DF(a); DF(b); DF(c); DF(d); DF(e); DF(f); DF(g);
这里:
void (*func_table[])() = {a, b, c, d, e, f, g};
上面声明的函数只是简单地分配。
减去字符的原因是将索引 0-n 放入函数数组中。
- QMetaObject invokeMethod的基于函数指针的语法
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- c++r值引用应用于函数指针
- 模板函数指针和lambda
- 是否可以将llvm::FunctionType转换为C/C++原始函数指针
- 带有类的函数指针
- () 函子后面的括号,而不是函数指针?
- 全局作用域中函数指针的赋值
- 使用"Task"函数指针队列定义作业管理器
- 将成员函数指针作为参数传递给模板方法
- 如何创建对象函数指针C++映射?
- 匹配函数指针作为模板参数?
- 通过函数指针定义类范围之外的方法
- 存储在类中的函数指针
- C++从函数指针数组调用函数
- 将返回值存储在函数指针数组的指针中是如何工作的?
- 整数键映射到头文件中的成员函数指针
- 从类成员函数到类 C 函数指针的转换
- 如何将内联匿名函数分配给C++函数指针
- 将字符缓冲区强制转换为函数指针