以下代码有效,我认为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 = □
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)
答案 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)
的变量永远不能是左值。在全球范围内,它们当然是功能。
&square
与square
相同,后者只是第一个的语法糖。
我没有使用cython的经验,但就C语义而言,它似乎并不合规。