现场计算是如何在C中进行的

现场计算是如何在C中进行的,c,io,in-place,C,Io,In Place,我正在研究一种简单的就地傅里叶变换。但我不知道这是怎么发生的。例如,以下代码段取自 由于函数声明void fft(cplx buf[],int n),在没有任何输出的情况下,子函数中buf的变化如何转移回主函数 #include <stdio.h> #include <math.h> #include <complex.h> double PI; typedef double complex cplx; void _fft(cplx buf[], cplx

我正在研究一种简单的就地傅里叶变换。但我不知道这是怎么发生的。例如,以下代码段取自

由于函数声明
void fft(cplx buf[],int n)
,在没有任何输出的情况下,子函数中
buf
的变化如何转移回主函数

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

double PI;
typedef double complex cplx;

void _fft(cplx buf[], cplx out[], int n, int step)
{
if (step < n) {
    _fft(out, buf, n, step * 2);
    _fft(out + step, buf + step, n, step * 2);

    for (int i = 0; i < n; i += 2 * step) {
        cplx t = cexp(-I * PI * i / n) * out[i + step];
        buf[i / 2]     = out[i] + t;
        buf[(i + n)/2] = out[i] - t;
    }
}
}

void fft(cplx buf[], int n)
{
cplx out[n];
for (int i = 0; i < n; i++) out[i] = buf[i];

_fft(buf, out, n, 1);
}


void show(const char * s, cplx buf[]) {
printf("%s", s);
for (int i = 0; i < 8; i++)
    if (!cimag(buf[i]))
        printf("%g ", creal(buf[i]));
    else
        printf("(%g, %g) ", creal(buf[i]), cimag(buf[i]));
}

int main()
{
PI = atan2(1, 1) * 4;
cplx buf[] = {1, 1, 1, 1, 0, 0, 0, 0};

show("Data: ", buf);
fft(buf, 8);
show("\nFFT : ", buf);

return 0;
}
#包括
#包括
#包括
双PI;
typedef双复数cplx;
void _fft(cplx buf[],cplx out[],整数n,整数步长)
{
如果(步骤
我不确定我是否已经把问题说清楚了。我在下面写了一个片段,其结构与上面的相同。然而,它在就地模式下不工作,我的意思是,子函数中变量的值变化没有转移到主函数中

#include <stdio.h>

void _sumab(int a, int b, int c)
{
printf("2: %d, %d, %d\n", a, b, c );
a = 2*a + b+c;
b = 12;
// if(a<800) _sumab(a, b, c);
printf("3: %d, %d, %d\n", a, b, c );
}

void sumab(int a, int b, int c)
{
printf("1: %d, %d, %d\n", a, b, c );
_sumab(a, b, c);
a = a*4;
printf("4: %d, %d, %d\n", a, b, c);
}


int main()
{
int out1 = 0;
int out2 = 1;
int out3 = 2;
sumab(out1+100, out2, out3);
printf("5: %d, %d, %d\n", out1, out2, out3);
return 0; 
}
#包括
void_sumab(内部a、内部b、内部c)
{
printf(“2:%d,%d,%d\n”,a、b、c);
a=2*a+b+c;
b=12;

//如果(a问题的关键是在C中,不能将数组传递给函数

当你写这篇文章时:

void fft(cplx buf[], int n)
该声明中的类型根据C11标准第6.7.6.3节第7页中定义的规则进行了调整(此处引用最新的公开草案n1570):

将参数声明为“类型数组”应调整为“指向 类型“”,其中类型限定符(如果有)是在 数组类型派生。[…]

这意味着,真正的声明如下所示:

void fft(cplx *buf, int n)
char a[5];
void foo(char x[]);
因此,实际上您正在传递一个指针,函数可以通过该指针操纵原始数组


*)人们常说数组作为指针衰减。这不是标准的官方措辞,但被广泛理解。如果您有这样一个数组:

void fft(cplx *buf, int n)
char a[5];
void foo(char x[]);
您只需编写
a
,它将作为指向
a
的第一个元素的指针进行计算,类型为
char*
。因此,函数声明如下:

void fft(cplx *buf, int n)
char a[5];
void foo(char x[]);
你可以这样称呼它

foo(a);

真正被传递的是指向
a
的第一个元素的指针,因此,
a
作为指针“衰减”。

问题的关键是,在C中,不能将数组传递给函数

当你写这篇文章时:

void fft(cplx buf[], int n)
该声明中的类型根据C11标准第6.7.6.3节第7页中定义的规则进行了调整(此处引用最新的公开草案n1570):

将参数声明为“类型数组”应调整为“指向 类型“”,其中类型限定符(如果有)是在 数组类型派生。[…]

这意味着,真正的声明如下所示:

void fft(cplx *buf, int n)
char a[5];
void foo(char x[]);
因此,实际上您正在传递一个指针,函数可以通过该指针操纵原始数组


*)人们常说数组作为指针衰减。这不是标准的官方措辞,但被广泛理解。如果您有这样一个数组:

void fft(cplx *buf, int n)
char a[5];
void foo(char x[]);
您只需编写
a
,它将作为指向
a
的第一个元素的指针进行计算,类型为
char*
。因此,函数声明如下:

void fft(cplx *buf, int n)
char a[5];
void foo(char x[]);
你可以这样称呼它

foo(a);

真正传递的是指向
a
的第一个元素的指针,因此,
a
会“衰减”作为指针。

主题外,但以下划线开头的文件作用域标识符保留给实现以供任何使用。您不应该这样命名函数,否则可能会导致UB.Array通过引用、内部类型(如int)传递是通过value.Off-topic传递的,但以下划线开头的文件作用域标识符保留给实现以供任何使用。您不应该这样命名函数,否则可能会有这样的风险。数组是通过引用传递的,内部类型(如int)是通过值传递的。哦,我得到了它。那么
fft(buf+2,8)是如何实现的呢
work?这里,数字
2
被添加到指针或值上?@RoyLiao
buf
作为指针计算,因此
buf+2
也是指针(指向第三个元素)。@RoyLiao C中只有3个运算符接受数组操作数(因此数组不作为指针计算):
sizeof
\u Alignof
&
。哦,我知道了。那么
fft(buf+2,8)
是如何工作的呢?那么这里,数字
2
被添加到指针或值上?@RoyLiao
buf
作为指针计算,所以
buf+2
也是指针(指向第三个元素)@RoyLiao在C语言中只有3个运算符接受数组操作数(因此数组不会作为指针计算):
sizeof
\u Alignof
&