首先发布在这里
我一直在研究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的基本信息,因为我似乎无法在这里或通过谷歌找到它
答案 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
相同。您可以使用大括号来执行索引,也可以使用指针算法。