`double(double)`和`double(*)(double)`之间的区别是什么?

时间:2014-08-16 23:57:17

标签: c function-pointers cython

以下代码有效,我认为double(double)double (*)(double)square&square之间没有区别,我是对的吗?

#include <stdio.h>

double square(double x)
{
    return x*x;
}

void test1(double f(double), double x)
{
    printf("test1 %f\n", f(x));
}

void test2(double (*f)(double), double x)
{
    printf("test2 %f\n", f(x));
}

int main()
{
    double (*fp)(double);
    test1(square, 3);
    test2(square, 3);
    fp = square;
    test1(fp, 3);
    test2(fp, 3);
    fp = &square;
    test1(fp, 3);
    test2(fp, 3);
    return 0;
}

但是以下cython代码提升无法将类型'double(*)(double)'分配给'double(double)',这是一个错误还是我错过了什么?

from libc.stdio cimport printf

cdef double square(double x):
    return x*x

cdef void test1(double f(double), double x):
    printf("test1=%g\n", f(x))

cdef void test2(double (*f)(double), double x):
    printf("test2=%g\n", f(x))

def test():
    cdef double(*fp)(double)
    fp = square
    test1(fp, 3.0)
    test2(fp, 3.0)

3 个答案:

答案 0 :(得分:4)

特别是在功能参数列表中使用该表示法时,没有区别。

但在函数参数上下文之外,double(double)函数类型,double (*)(double)函数指针类型。这是两种不同的类型,具有非常不同的属性。

所以,第一段的答案是:在函数参数列表中是真的,只在函数参数列表中

换句话说,当在函数参数列表中使用时,函数类型的行为方式与数组类型非常相似:它立即衰减到指针类型。但是,正如数组和指针类型非常不同,函数类型和函数指针类型也非常不同。

在其他情况下,如果声明类型为double(double)的内容,则将其声明为函数。例如

typedef double D(double);

D foo;
double foo(double);

以上两个声明是有效且等效的。它们声明函数foo,它接受​​double类型的单个参数并返回double。此功能(通过typedef名称声明函数)通常不会在实际的C代码中使用,但它仍然在语言中。

答案 1 :(得分:2)

double(double)是一个函数的类型,它取一个double并返回一个double。

double(*)(double)是指向上述函数类型的指针。

实际上,如果你用力吸气,函数就会衰减到指向函数的指针。例如,您不能将函数作为另一个函数的参数。如果你尝试,那么类型&#34;衰变&#34;进入函数指针。类似地,如果您将函数by-name作为参数传递(或通常在表达式中),如果目标类型不是函数引用或其他类似类型,它可以自动衰减为函数指针。 / p>

数组也会发生类似的事情。

你也可以在指向函数的指针上调用operator (),它会自动解引用指针。

这些是从C继承的遗留功能。

在C ++中,您可以形成对函数的引用,有时您可以使用纯函数类型。 std::function< void(int) >采用纯函数类型。现在,它无法创建void(int)类型的变量,但它仍然可以操作类型。

cython可能没有实现自动转换衰减。

答案 2 :(得分:0)

double(double)在语义上与参数中的double (*)(double)完全等效:函数和数组是传递引用。但是,作为局部变量,类型double(double)的变量永远不能是左值。在全球范围内,它们当然是功能。

&squaresquare相同,后者只是第一个的语法糖。

我没有使用cython的经验,但就C语义而言,它似乎并不合规。