一些“怪异”的C代码

时间:2012-12-10 22:35:27

标签: c

我有这个C代码,我在理解时遇到了问题:

int foo(int f(int,int), int g(int,int), int x) {

    int y = g(x,x);
    return f(y,y);
}

int sq(int x, int y) {
    if (x == 1) { return y; }
    return pl(y, sq(x-1, y));
}

int pl(int x, int y) {
    if (x == 0) { return y; }
    return pl(x-1, y+1);
}

int main (int argc, const char * argv[])
{
   printf("sq = %d\n", sq);
   printf("output=%d\n", foo(sq, pl, 1));
   return 0;
}

我知道f乘以两个变量而g是乘法,它们显然是内置的。函数foo有两个参数声明为函数声明 - > f(int,int)和g(int,int)。但是foo传递了两个参数 - sq和pl。这两个参数也有非常奇怪的值 - 3392和3488,是sq和pl函数的逻辑地址吗?如果它们是并且它们作为整数传递,foo如何接受它们?从foo开始,有函数声明来代替这些参数应该去的参数。

谢谢你, 编辑:很酷,谢谢你们,很多人,清理了一切!

4 个答案:

答案 0 :(得分:4)

fg不是内置的。正如您所见,它们只是函数foo()的参数。

此外,printf("sq = %d\n", sq);是未定义的行为,因为sq不是整数值,而是函数resp。它在这方面的地址。因此,您应该编写printf("sq = %p\n", sq);以便干净地输出函数的地址。

实际发生的是,您将foo()函数sq作为参数f,将函数pl作为参数gfoo使用参数x调用这些函数。

基本上foo调用pl(1,1)并将结果存储到y,然后将其用于sq(y,y)。因此它将工作委托给这些功能。这些函数可以看作是回调函数,因为foo()调用调用者给出的函数。

到目前为止,sq()pl()所做的事情超出了我的理解范围。

答案 1 :(得分:4)

这段代码绝对没有什么特别之处。这里没有涉及“内置”的东西。

这些是普通的函数指针。在C声明中

int foo(int f(int,int), int g(int,int), int x)

自动解释为

int foo(int (*f)(int,int), int (*g)(int,int), int x)

函数sqpl作为参数传递给foo

foo(sq, pl, 1); // same as foo(&sq, &pl, 1)

&运算符是可选的)并通过foo

中的这些指针调用
int y = g(x,x); // same as (*g)(x,x)
return f(y,y);  // same as (*f)(y,y)

(调用中的*运算符是可选的。)

在不知道您获得这些33923488值的位置。函数指针不是“作为整数传递”。如果您的调试器决定将指针值显示为33923488,则调试器必定存在问题。

答案 2 :(得分:2)

假设我理解你的问题并且能记住任何C,那么foo是一个将指针带到2个函数f和g加上一个int的函数,它返回一个int。

f和g都是2个int的函数并返回一个int。

您看到的数字是函数pl和sq的地址,所以它看起来很好

你需要阅读有关将函数指针作为参数传递的内容,以便更全面地解释正在发生的事情,这可能会有所帮助(即使它是C ++)http://www.oopweb.com/CPP/Documents/FunctionPointers/Volume/CCPP/FPT/em_fpt.html

答案 3 :(得分:2)

int foo(int f(int,int), int g(int,int), int x)

foo声明为带有三个参数的函数,前两个是(指向)函数,它们将两个int作为参数并返回int,第三个参数是int

sqpl是相应类型的函数,因此调用

foo(sq, pl, 1)

是对的。