【问题标题】:Passing pointer to complex double in C (using complex.h)将指针传递给 C 中的复数双精度(使用 complex.h)
【发布时间】:2021-12-30 13:19:44
【问题描述】:

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

当我通过main 调用testfn 时,它没有返回分配的值1.0 + 0.5*I,而是返回0.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,然后分配@ 987654336@ 是 testarrayfn 内的特定 2x3 复数矩阵。

当我使用double _Complex toot[2][3];testarrayfn(toot);main 呼叫testarrayfn 时,我确实得到了正确的答案。 我不确定为什么这样做是正确的(我只是在谷歌上搜索并玩了很多关于数组和传递数组参数的操作)。

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 之间有什么区别吗?

【问题讨论】:

    标签: c pointers pass-by-reference complex.h


    【解决方案1】:

    测试1

    两个问题。

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

    你需要在函数返回后使foobar存在,并将引用传递给指针。

    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;
    }
    

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

    您可以将foo[i][j] = foobar; 写为*(*(foo + i) + j) = foobar;,它与我的第二个示例相同(您可以将toot 视为单元素数组)

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

    【讨论】:

      猜你喜欢
      • 2012-02-05
      • 2013-03-05
      • 2011-05-19
      • 2014-06-20
      • 2016-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多