有人可以帮助解释这个fft代码片段中发生的事情

时间:2014-12-20 23:58:06

标签: c fft code-snippets

首先发布在这里

我一直在研究fft,特别是Rosetta Code C的实现 http://rosettacode.org/wiki/Fast_Fourier_transform#C

我一直在尝试真正理解代码,而不仅仅是复制它,但是我对某个特定行有一个问题,更具体地说是该行的一部分。

_fft(out+step, buf+step, n , step*2);

所以我们有一个

typedef double complex cplx;

然后声明一个cplx类型的数组

cplx buf[] = {1, 1, 1, 1, 0, 0, 0, 0};

我们有一步作为int 1

现在我理解的问题是将int添加到cplx时发生的事情

所以我写了一个测试程序

#include <stdio.h>
#include <math.h>
#include <complex.h>

typedef double complex cplx;

void test(cplx buff[]) 
{
    for(int a = 0; a < 8; a++) {
        printf("%g \n", creal(buff[a]));
    }
}

int main(int argc, char **argv)
{
    cplx buff[] = {1,1,1,1,0,0,0,0};

    int step = 1;

    test(buff);

    test(buff + step);

    getchar();

    return 0;
}

我得到的是:

1 1 1 1 0 0 0 0
1 1 1 0 0 0 0 2.1231e-314

我无法做出正面或反面,我可能会遗漏一些关于C99的基本信息,因为我似乎无法在这里或通过谷歌找到它

2 个答案:

答案 0 :(得分:1)

  

现在我理解的问题是将int添加到cplx时发生的事情

实际上,添加不是<int> + <cplx>而是<int> + <cplx>*(在单词中是整数加上指向复合体的指针)。所以你在这里处理的是指针算法。你问为什么指针?因为在C数组类型中,当在表达式中使用指针时,会降级为指向数组元素类型的指针。

那么什么是指针算术?

好吧,让&#39;假设我们得到了一个对象a,这是一个int数组(只要我们不能访问它的边界,长度就不重要了。)

int a[N];

然后定义了指针算术,以下三个表达式具有完全相同的含义:

*(a + i)
a[i]
i[a]

是的,最后一个是完全有效的C,继续,尝试一下。

对您的代码段意味着什么?好吧,有一件事,当您向缓冲区指针添加1并传递给test时,您需要添加一个偏移量。但由于缓冲区只有8个元素长,并且你的test函数从指针开始访问8个连续的元素,因为它执行一个越界访问,调用未定义的行为实际上任何东西可能合法地发生。

答案 1 :(得分:0)

在我看来,你正在考试两次。第一次使用buff[0]地址,第二次使用地址buff[step],其中变量step等于1,因此它与buff[1]相同。< / p>

这就是您使用

查看旋转输出的原因
1 1 1 1 0 0 0
1 1 1 0 0 0 0

我离开了最后一位数。第二行中的最后一位数字在数组结束后或数组的最后一个元素buff之后只是垃圾。

buff是一个数组,如果你只是指定名称buff,那么它就像一个指针。因此,在第二次测试调用中,您指定&buff[step]而不是&buff[0],这与buff相同。

所以buff[step]*(buff + step)相同,因为buff[0]*(buff + 0)*buff相同。您可以使用大括号来执行索引,也可以使用指针算法。