将指针传递给 C 中的复数双精度数(使用 complex.h)

Passing pointer to complex double in C (using complex.h)

我正在尝试运行一个函数,int testfn下面,它应该将一个复数分配给指针(指向一个复数),double _Complex *foo下面,它是喂。最小(非工作)示例 .c 文件是下面的 test.c

当我通过main调用testfn时,它没有返回赋值1.0 + 0.5*I,而是returns0.0 + 0.0*I 我不明白为什么,也不知道如何解决。

test.c

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

int testfn(double _Complex *foo) {
    double _Complex foobar = 1.0 + 0.5*I;
    foo = &foobar;
    printf("foobar = %.8f + I %.8f \n",creal(foobar),cimag(foobar));
    printf("*foo = %.8f + I %.8f \n",creal(*foo),cimag(*foo));
    return 0;
}

int main() {
    double _Complex toot;
    testfn(&toot);
    printf("toot = %.8f + I %.8f \n",creal(toot),cimag(toot));
    return 0;
}

编译并运行与

cc -o test test.c -L. -lm -Wall
./test

终端输出给出错误答案

foobar = 1.00000000 + I 0.50000000 
*foo = 1.00000000 + I 0.50000000 
toot = 0.00000000 + I 0.00000000 

注意 toot 的实际答案应该是 toot = 1.00000000 + I 0.50000000.


另一方面,这个数组案例有效

在这里,在 test2.c 中,我正在输入 double _Complex (*foo)[3],即 一个指向复数的三维指针数组(对吗?) int testarrayfn,然后将 foo 指定为 testarrayfn.

内的特定 2x3 复数矩阵

当我使用 double _Complex toot[2][3];testarrayfn(toot);main 调用 testarrayfn 时,我得到了正确的答案。 我不确定为什么这样做是正确的(我只是用 google 搜索并大量使用数组,并传递数组参数)。

test2.c

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

int testarrayfn(double _Complex (*foo)[3]) {
    double _Complex foobar;
    int i,j;
    for (i=0;i<2;i++) {
        for (j=0;j<3;j++) {
            foobar = 1.*(i+1) + 0.5*(j+1)*I ;
            foo[i][j] = foobar;
            printf("[%d][%d]: foobar = %.8f + I %.8f \n",i,j,creal(foobar),cimag(foobar));
            printf("foo[%d][%d] = %.8f + I %.8f \n",i,j,creal(foo[i][j]),cimag(foo[i][j]));
            }
        }
    return 0;
}

int main() {
    double _Complex toot[2][3];
    testarrayfn(toot);
    int i,j;
    for (i=0;i<2;i++) {
        for (j=0;j<3;j++) {
            printf("toot[%d][%d] = %.8f + I %.8f \n",i,j,creal(toot[i][j]),cimag(toot[i][j]));
            }
        }
    return 0;
}

编译并运行与

cc -o test2 test2.c -L. -lm -Wall
./test2

终端输出给出了预期的答案

[0][0]: foobar = 1.00000000 + I 0.50000000 
foo[0][0] = 1.00000000 + I 0.50000000 
[0][1]: foobar = 1.00000000 + I 1.00000000 
foo[0][1] = 1.00000000 + I 1.00000000 
[0][2]: foobar = 1.00000000 + I 1.50000000 
foo[0][2] = 1.00000000 + I 1.50000000 
[1][0]: foobar = 2.00000000 + I 0.50000000 
foo[1][0] = 2.00000000 + I 0.50000000 
[1][1]: foobar = 2.00000000 + I 1.00000000 
foo[1][1] = 2.00000000 + I 1.00000000 
[1][2]: foobar = 2.00000000 + I 1.50000000 
foo[1][2] = 2.00000000 + I 1.50000000 
toot[0][0] = 1.00000000 + I 0.50000000 
toot[0][1] = 1.00000000 + I 1.00000000 
toot[0][2] = 1.00000000 + I 1.50000000 
toot[1][0] = 2.00000000 + I 0.50000000 
toot[1][1] = 2.00000000 + I 1.00000000 
toot[1][2] = 2.00000000 + I 1.50000000 

关于 complex.h

的其他问题

我无法在任何地方找到以下问题的答案:

  1. 可以在函数和参数中交替使用 double complex foodouble _Complex foo 吗?
  2. 可以在函数和参数中交替使用 double complex *foodouble _Complex *foo 吗?
  3. 可以在函数和参数中交替使用 double complex (*foo)[3]double _Complex (*foo)[3] 吗?
  4. 更一般地说,double complexdouble _Complexcomplex double之间有什么区别吗?

测试 1

两个问题。

  1. foo 是局部变量。当你分配它时,它只会在函数范围内有效。
  2. foobar 是一个局部变量,在函数 return 之后无法访问它(因为它不再存在)

你需要让foobar存在于函数return之后,并将引用传递给指针。

int testfn(double _Complex **foo) {
    static double _Complex foobar = 1.0 + 0.5*I;
    *foo = &foobar;
    printf("foobar = %.8f + I %.8f \n",creal(foobar),cimag(foobar));
    printf("*foo = %.8f + I %.8f \n",creal(**foo),cimag(**foo));
    return 0;
}

int main() {
    double _Complex *toot;
    testfn(&toot);
    printf("toot = %.8f + I %.8f \n",creal(*toot),cimag(*toot));
    return 0;
}

或者为底层对象赋值foobar(非引用)

int testfn(double _Complex *foo) {
    double _Complex foobar = 1.0 + 0.5*I;
    *foo = foobar;
    printf("foobar = %.8f + I %.8f \n",creal(foobar),cimag(foobar));
    printf("*foo = %.8f + I %.8f \n",creal(*foo),cimag(*foo));
    return 0;
}

int main() {
    double _Complex toot;
    testfn(&toot);
    printf("toot = %.8f + I %.8f \n",creal(toot),cimag(toot));
    return 0;
}

测试 2 有效,因为您将值分配给引用的对象,而不是尝试更改指向数组的指针。

你可以把 foo[i][j] = foobar; 写成 *(*(foo + i) + j) = foobar; 和我的第二个例子一样(你可以把 toot 当作单元素数组)

_Complex 是来自 C99(或 C99 之前的 GCC 扩展)的实际 C 关键字。 complex 是扩展到 _Complex 的简单定义。这样做是因为许多旧程序使用自己的 complex 类型