提问人:uvero 提问时间:12/21/2022 更新时间:12/21/2022 访问量:177
C 函数指针:从函数 [duplicate] 返回函数指针
C function pointer: returning a function pointer from a function [duplicate]
问:
我目前正在学习 C,并试图使我的代码更具可读性和更易于编写,我发现自己需要在函数中创建一个函数(闭包),并返回该函数。这是我要做的:
#typedef int (int_predicate*)(int);
int_predicate equals(int x) {
int ret(int y) { return x == y; }
return ret;
}
现在,这个不起作用,我明白了:我正在一个函数中创建这个闭包 (ret),所以一旦这个函数返回,指针就不再相关,因为它是在堆栈上定义的。这类似于我为更简单类型的指针执行此操作:
int* bad_int_ptr_function() {
int intOnTheStack;
int* ptr = &intOnTheStack;
return ptr;
}
那么,我怎样才能实现我想要的 - 在函数中创建一个闭包并对其进行重构?如果所指向的类型的大小是已知的,我可以使用,如果我想,我可以用 .但是,我只能假设函数的大小不能用 sizeof
找到,因为函数可以有任意数量的行。malloc
memcpy
这是 C,我不能使用特定于 C++ 的语法或库(我听说 C++ 最近得到了 lambda 表达式 - 如果我能使用 C++,但我不能,如果用于特定于 C 的课程)。
答:
在 C 语言中没有(简单、健壮的)方法来创建闭包。
但有一种方法可以稍微接近:你可以返回一个包含函数指针的函数指针,该指针可以将 or 的地址作为参数:struct
struct
typedef int ( *intClosureFuncPtr )( struct intClosure * );
struct intClosure
{
int tag // can be used to differentiate multiple struct
// types in a union
intClosureFuncPtr func;
.
.
// fields as necessary
};
闭合功能:
int closureFunc0( struct intClosure *c )
{
.
.
.
return( 0 );
}
int closureFunc42( struct intClosure *c )
{
.
.
.
return( 42 );
}
调用创建闭包并返回 :struct
struct intClosure someFunc( ... )
{
struct intClosureInstance = { 0 };
intClosure.tag = 7;
intClosure.func = closureFunc42;
// fill in rest of the struct fields as needed
return( intClosureInstance );
}
用法:
struct intClosure closureInstance = someFunc(...);
.
.
.
// call the closure:
int result = closureInstance.func( &closureInstance );
也可以按地址返回它,但这需要调用者。您需要评估“闭包”的大小,并且必须按值传递它,以应对要求调用者的额外复杂性。malloc()
struct
free()
struct
free()
请注意,此“闭包”的返回类型是固定的。有些黑客可能允许在 POSIX 和 Windows 系统上动态选择返回类型,因为它们都有一个由所有变量和函数共享的平面地址空间(当前 Windows 共享),但这些黑客将深入研究 C 标准未定义的行为。
* - 如果您愿意将 C“闭包”限制为仅从创建它们的线程中调用,并且每个线程在任何时刻都只能调用一个未完成的“闭包”,则可以使用特定于线程的数据将信息传递给生成闭包时由函数指针返回的实际函数,然后可以通过上述方法直接调用该函数,而无需任何间接调用。可能有一些方法可以允许更复杂的使用模式,但我目前无法想出任何方法。struct
在标准 C 中,不能将闭包定义为函数,但可以使用数据结构模拟它们:
#include <stdio.h>
typedef struct int_predicate_t {
int (*func)(struct int_predicate_t *s, int x);
int y, z;
} int_predicate_t;
#define APPLY(p, x) ((p).func(&(p), x))
int equal_func(struct int_predicate_t *s, int x) {
return x == s->y;
}
int greater_func(struct int_predicate_t *s, int x) {
return x > s->y;
}
int between_func(struct int_predicate_t *s, int x) {
return x >= s->y && x <= s->z;
}
int_predicate_t equals(int y) {
int_predicate_t s = { equal_func, y, 0 };
return s;
}
int_predicate_t greater(int y) {
int_predicate_t s = { greater_func, y, 0 };
return s;
}
int_predicate_t between(int y, int z) {
int_predicate_t s = { between_func, y, z };
return s;
}
int main() {
int_predicate_t p1 = equals(42);
int_predicate_t p2 = greater(10);
int_predicate_t p3 = between(1, 100);
printf("p1(42) = %d\n", APPLY(p1, 42));
printf("p2(42) = %d\n", APPLY(p2, 42));
printf("p3(42) = %d\n", APPLY(p3, 42));
printf("p1(0) = %d\n", APPLY(p1, 0));
printf("p2(0) = %d\n", APPLY(p2, 0));
printf("p3(0) = %d\n", APPLY(p3, 0));
return 0;
}
上一个:谁能解释一下这段代码的输出?
评论
write
write