将指针传递给 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
的其他问题
我无法在任何地方找到以下问题的答案:
- 可以在函数和参数中交替使用
double complex foo
和 double _Complex foo
吗?
- 可以在函数和参数中交替使用
double complex *foo
和 double _Complex *foo
吗?
- 可以在函数和参数中交替使用
double complex (*foo)[3]
和 double _Complex (*foo)[3]
吗?
- 更一般地说,
double complex
、double _Complex
和complex double
之间有什么区别吗?
测试 1
两个问题。
foo
是局部变量。当你分配它时,它只会在函数范围内有效。
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
类型
我正在尝试运行一个函数,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
.
当我使用 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
的其他问题
我无法在任何地方找到以下问题的答案:
- 可以在函数和参数中交替使用
double complex foo
和double _Complex foo
吗? - 可以在函数和参数中交替使用
double complex *foo
和double _Complex *foo
吗? - 可以在函数和参数中交替使用
double complex (*foo)[3]
和double _Complex (*foo)[3]
吗? - 更一般地说,
double complex
、double _Complex
和complex double
之间有什么区别吗?
测试 1
两个问题。
foo
是局部变量。当你分配它时,它只会在函数范围内有效。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
类型