在旧C中,这是什么意思?双(*窗口)(双)

时间:2017-07-20 22:09:52

标签: java c

我正在尝试将一些用C编写的旧DSP​​代码转换为Java,然后转换为C#。我不明白参数“double(* Window)(double)”是什么意思以及如何在Java代码中引用它。以下功能让我不确定该怎么做。

void WinFirI(float LowOmega, float UppOmega,
       float *Shape, int Len, double (*Window)(double), float shift)
{ int i; double time,phase,shape;
// printf("WinFirI: %5.3f %5.3f %d\n",LowOmega,UppOmega,Len);
  for(i=0; i<Len; i++)
  { time=i+(1.0-shift)-(float)Len/2; phase=2*M_PI*time/Len;
    if(time==0) shape=UppOmega-LowOmega;
       else shape=(sin(UppOmega*time)-sin(LowOmega*time))/time;
// printf("%2d %5.1f %5.2f %7.4f %7.4f\n",i,time,phase,shape,(*Window)     (phase));
    Shape[i]=shape*(*Window)(phase)/M_PI; }
}

到目前为止,我已经写过:

public void WinFirI(float LowOmega, float UppOmega,
       float[] Shape, int Len, double[] Window, float shift) {
        double time;
        double phase;
        double shape;
//      printf("WinFirI: %5.3f %5.3f %d\n",LowOmega,UppOmega,Len);
        for(int i=0; i<Len; i++) {
            time = i +(1.0-shift) - (float)Len/2;
            phase = 2 * Math.PI * time / Len;
            if(time==0) {
                shape = UppOmega - LowOmega;
            }
       else {
                shape=(Math.sin(UppOmega*time) - Math.sin(LowOmega*time))    / time;
            }
//          printf("%2d %5.1f %5.2f %7.4f %7.4f\n",i,time,phase,shape,    (*Window)(phase));
            //Shape[i]=shape*(*Window)(phase)/M_PI; 
            Shape[i] = shape * Window[phase]/Math.PI;
        }
    }

3 个答案:

答案 0 :(得分:6)

使用参数double返回double的函数指针。

答案 1 :(得分:4)

作为补充说明,在Java中实现此函数指针行为将通过匿名类/接口完成。

double Window(double param);

在Java中将是:

interface WindowFnWrapper {
    double Window(double param);
}

然后函数签名将是:

public void WinFirI(float LowOmega, float UppOmega,
   float[] Shape, int Len, WindowFnWrapper WindowWrapper, float shift)

每次拨打Window()时,都会将其替换为WindowWrapper.Window()

答案 2 :(得分:1)

声明double (*Window)(double)声明参数Window,其值是指向函数的指针。该函数必须是一个以double为参数的函数,并返回double

在你的C代码中,(好吧,实际上是已注释掉的部分),该指针被取消引用,并调用该函数,传递phase作为其参数。也就是说,表达式(*Window) (phase)的值只是调用传入其地址的函数的结果。

如果您使用的是Java 8或更高版本,则最近的可用等效项是来自Function包的java.util.function泛型类。所以,如果你写

import java.util.function.Function;

然后您可以将参数声明为

Function<Double,Double> window

并将其用作

window.apply(phase);

这与C代码之间唯一真正的区别是Java泛型的类型参数不能是基本类型,例如double

Double是一种类似double的引用类型,但Double可以为空,而double则不能。实际上,这应该对您的代码没有任何影响,除了您可能想要添加一些错误处理来处理window.apply(phase)求值为null的情况。