Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c blocks 当我在C中使用Y组合子和块时,我在参数值中遇到了一个奇怪的事情_Objective C Blocks_Y Combinator - Fatal编程技术网

Objective c blocks 当我在C中使用Y组合子和块时,我在参数值中遇到了一个奇怪的事情

Objective c blocks 当我在C中使用Y组合子和块时,我在参数值中遇到了一个奇怪的事情,objective-c-blocks,y-combinator,Objective C Blocks,Y Combinator,当我试图计算sinh时−1(x)使用功能: 在块中,在某个时间,当我通过buf=0.479167时,下一次打印它时,它仍然是0.500000。 我想知道为什么它是这样工作的,也许我在某个地方写了一些错误的代码…问题是,你的Y组合符只用于一个底层函数,它接受一个void*参数并返回一个void*。您可以在下面的行中看到: return f(^ (void * x) { return ((YCBlock)h(h))(x); }); 其中的块接受x(一个参数)并将x作为一个参数传递给另一个对象。要

当我试图计算sinh时−1(x)使用功能:

在块中,在某个时间,当我通过buf=0.479167时,下一次打印它时,它仍然是0.500000。
我想知道为什么它是这样工作的,也许我在某个地方写了一些错误的代码…

问题是,你的Y组合符只用于一个底层函数,它接受一个
void*
参数并返回一个
void*
。您可以在下面的行中看到:

return f(^ (void * x) { return ((YCBlock)h(h))(x); });
其中的块接受
x
(一个参数)并将
x
作为一个参数传递给另一个对象。要使用多个参数的递归函数,该函数必须接受这些多个参数并将它们全部传递(当然,类型也必须正确,因为不同类型的大小不同,传递和返回不同类型的对象的ABI也不同)。因此,您需要为每个函数签名使用不同的Y组合符

您有一个递归函数,它接受三个参数(两个
double
s和一个
unsigned long
),并返回一个
double
。通过更改Y combinator中的相关块并将其从错误类型强制为正确类型,可以(至少)使其工作:

return f(^ (double buf, double increment, unsigned long item_count) {
    return ((RECUR_BLK_TYPE)((YCBlock)h(h)))(buf, increment, item_count);
});
但是,要真正使其清洁并具有正确的类型安全性,而不使用这种不安全的铸造,需要仔细设置类型。大概是这样的:

typedef double (^Func)(double, double, unsigned long);
typedef Func (^FuncFunc)(Func);
typedef Func (^RecursiveFunc)(void *);
typedef Func (^YCBlock)(FuncFunc);

Y = ^(FuncFunc f) {
    return ^(RecursiveFunc g) {
        return g(g);
    }(
        ^(void *temp) {
            RecursiveFunc h = temp; // trick to hide the recursive typing
            return f(^(double buf, double increment, unsigned long item_count) {
                return h(h)(buf, increment, item_count);
            });
        }
    );
};

哇,这真是太复杂了。我相信它可以简化。是的,我认为你是对的,你是说像处理开始时的函数,还是静态块一样处理它?我们会做一些事情让它更容易理解。谢谢你的建议,我认为这是对的,但这只是尝试用块进行递归。。。这只是一次尝试,当我遇到奇怪的事情,我想知道发生了什么…谢谢!它的工作,并感谢您的详细解释!那么如果我想在Obj-C中使用Y-Combinator,我是否也应该设置块类型?我的意思是,如果我使用“id”而不是“void*”,并且递归块有多个参数,它会正常工作还是像我的源代码一样?当我尝试我在Obj-C中所说的时,“EXC_BAD_ACCESS”发生了。。。也许我应该在制作Y组合器时设置块类型。。。
return f(^ (void * x) { return ((YCBlock)h(h))(x); });
return f(^ (double buf, double increment, unsigned long item_count) {
    return ((RECUR_BLK_TYPE)((YCBlock)h(h)))(buf, increment, item_count);
});
typedef double (^Func)(double, double, unsigned long);
typedef Func (^FuncFunc)(Func);
typedef Func (^RecursiveFunc)(void *);
typedef Func (^YCBlock)(FuncFunc);

Y = ^(FuncFunc f) {
    return ^(RecursiveFunc g) {
        return g(g);
    }(
        ^(void *temp) {
            RecursiveFunc h = temp; // trick to hide the recursive typing
            return f(^(double buf, double increment, unsigned long item_count) {
                return h(h)(buf, increment, item_count);
            });
        }
    );
};