如何在 C 中使用 complex.h 读取复数?

How to read complex number using complex.h in C?

我想从文件中读取两个复数

(1.1,2) (1.7,3.14)

一开始我是这样做的

struct Num { double Re; 
                    double Im; 
                };

typedef struct Num zesp;

zesp readZ(FILE *wp)
{
    char c;
    zesp z;
    assert(fscanf(wp,"%c%lg%c%lg%c%c",&c,&z.Re,&c,&z.Im,&c,&c));

    return z;
}

但是现在我接到了一个新任务,我的老师说我应该使用complex.h来读、写等,而不是使用我的类型zesp

首先我初始化两个复数

    double complex c1;
    double complex c2;

然后我知道通常我会通过写这个来给他们价值

double complex z1 = 2.6 + 3.1*I

但是如何通过读取文件来做到这一点?

(1.1,2) (1.7,3.14)

编辑: 数字是这样存储的

(1.1,2) (1.7,3.14) (2.71,-15)
(4,3.21) (6,7.89)
(10,45)

括号和space复数之间

您可以使用变量代替 2.63.1,而不是 double complex z1 = 2.6 + 3.1*I。这应该有助于从文件中读取单个条目:

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

int main(void) 
{ 
    double real, imag;

    //assuming the wp variable is properly initialized
    fscanf(wp,"%c%lg%c%lg%c%c",&c,&real,&c,&imag,&c,&c);

    double complex z = CMPLX(real, imag); 

    printf("z = %.1f% + .1fi\n", creal(z), cimag(z)); 
} 
  • CMPLX()函数以实部和虚部为参数创建复数对象。此函数returns复数对象
  • creal() 函数returns 复数的实部
  • cimag()函数returns复数的虚部

cppreference.com 开始,支持以下宏来创建复数对象:

#define CMPLX(x, y) ((double complex)((double)(x) + _Imaginary_I * (double)(y)))
#define CMPLXF(x, y) ((float complex)((float)(x) + _Imaginary_I * (float)(y)))
#define CMPLXL(x, y) ((long double complex)((long double)(x) + \
                      _Imaginary_I * (long double)(y)))

complex.h 没有声明或定义:

  • 任何输入或输出设施,
  • 字符串和复数之间转换的任何工具,或
  • 任何访问复数部分左值的方法,这对于通过 scanf 或类似函数在这些部分中存储值是必要的。

因此,您的老师指导您使用 complex.h 阅读复数的含义并不明确。写的时候,我们可以用crealcimag来获取部分的值,这些值声明在complex.h.

有一些方法可以访问复数各部分的左值。 C 6.2.5 13 说“每个复数类型都具有与恰好包含相应实数类型的两个元素的数组类型相同的表示和对齐要求;第一个元素等于复数的实部,第二个元素等于复数的虚部。”虽然这个语句缺乏一些正式的细节,但我们可以通过类比标准中的其他措辞来判断,它打算告诉我们可以将指向 complex double 的指针转换为指向 double [2] 的指针并使用那访问的部分。因此,我们可以这样做:

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

int main(void)
{
    complex double x;
    double *y = * (double (*)[2]) &x;
    if (2 != scanf("(%lg,%lg)", &y[0], &y[1]))
    {
        fputs("Error, scanf failed.\n", stderr);
        exit(EXIT_FAILURE);
    }
    printf("Read %g + %g i.\n", creal(x), cimag(x));
}