Skip to content

C 标准库 - <complex.h>

概述

<complex.h> 头文件提供了复数类型和复数运算函数,支持复数的数学运算。这是 C99 标准引入的头文件,对于科学计算和工程应用非常重要。

复数类型

complex

复数类型关键字。

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

int main() {
    double complex z = 3.0 + 4.0 * I;
    
    printf("复数: %.2f + %.2fi\n", creal(z), cimag(z));
    
    return 0;
}

double complex

双精度复数类型。

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

int main() {
    double complex z = 3.0 + 4.0 * I;
    
    printf("复数: %.2f + %.2fi\n", creal(z), cimag(z));
    printf("模: %.2f\n", cabs(z));
    printf("幅角: %.2f 弧度\n", carg(z));
    
    return 0;
}

float complex

单精度复数类型。

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

int main() {
    float complex z = 3.0f + 4.0f * I;
    
    printf("复数: %.2f + %.2fi\n", crealf(z), cimagf(z));
    printf("模: %.2f\n", cabsf(z));
    
    return 0;
}

long double complex

扩展精度复数类型。

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

int main() {
    long double complex z = 3.0L + 4.0L * I;
    
    printf("复数: %.2Lf + %.2Lfi\n", creall(z), cimagl(z));
    printf("模: %.2Lf\n", cabsl(z));
    
    return 0;
}

复数常量

I

虚数单位。

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

int main() {
    double complex z1 = 3.0 + 4.0 * I;
    double complex z2 = 5.0 - 2.0 * I;
    
    printf("z1 = %.2f + %.2fi\n", creal(z1), cimag(z1));
    printf("z2 = %.2f + %.2fi\n", creal(z2), cimag(z2));
    
    return 0;
}

复数运算

creal()

c
double creal(double complex z);
float crealf(float complex z);
long double creall(long double complex z);

获取复数的实部。

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

int main() {
    double complex z = 3.0 + 4.0 * I;
    double real = creal(z);
    
    printf("复数: %.2f + %.2fi\n", creal(z), cimag(z));
    printf("实部: %.2f\n", real);
    
    return 0;
}

cimag()

c
double cimag(double complex z);
float cimagf(float complex z);
long double cimagl(long double complex z);

获取复数的虚部。

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

int main() {
    double complex z = 3.0 + 4.0 * I;
    double imag = cimag(z);
    
    printf("复数: %.2f + %.2fi\n", creal(z), cimag(z));
    printf("虚部: %.2f\n", imag);
    
    return 0;
}

cabs()

c
double cabs(double complex z);
float cabsf(float complex z);
long double cabsl(long double complex z);

计算复数的模。

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

int main() {
    double complex z = 3.0 + 4.0 * I;
    double abs = cabs(z);
    
    printf("复数: %.2f + %.2fi\n", creal(z), cimag(z));
    printf("模: %.2f\n", abs);
    
    return 0;
}

carg()

c
double carg(double complex z);
float cargf(float complex z);
long double cargl(long double complex z);

计算复数的幅角。

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

int main() {
    double complex z = 1.0 + 1.0 * I;
    double arg = carg(z);
    
    printf("复数: %.2f + %.2fi\n", creal(z), cimag(z));
    printf("幅角: %.2f 弧度\n", arg);
    printf("幅角: %.2f\n", arg * 180.0 / 3.14159265358979323846);
    
    return 0;
}

conj()

c
double complex conj(double complex z);
float complex conjf(float complex z);
long double complex conjl(long double complex z);

计算复数的共轭。

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

int main() {
    double complex z = 3.0 + 4.0 * I;
    double complex conj_z = conj(z);
    
    printf("复数: %.2f + %.2fi\n", creal(z), cimag(z));
    printf("共轭: %.2f + %.2fi\n", creal(conj_z), cimag(conj_z));
    
    return 0;
}

cproj()

c
double complex cproj(double complex z);
float complex cprojf(float complex z);
long double complex cprojl(long double complex z);

计算复数的投影。

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

int main() {
    double complex z = 1.0 + 2.0 * I;
    double complex proj_z = cproj(z);
    
    printf("复数: %.2f + %.2fi\n", creal(z), cimag(z));
    printf("投影: %.2f + %.2fi\n", creal(proj_z), cimag(proj_z));
    
    return 0;
}

复数数学函数

csqrt()

c
double complex csqrt(double complex z);
float complex csqrtf(float complex z);
long double complex csqrtl(long double complex z);

计算复数的平方根。

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

int main() {
    double complex z = -1.0 + 0.0 * I;
    double complex sqrt_z = csqrt(z);
    
    printf("复数: %.2f + %.2fi\n", creal(z), cimag(z));
    printf("平方根: %.2f + %.2fi\n", creal(sqrt_z), cimag(sqrt_z));
    
    return 0;
}

cexp()

c
double complex cexp(double complex z);
float complex cexpf(float complex z);
long double complex cexpl(long double complex z);

计算复数的指数。

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

int main() {
    double complex z = 1.0 + 1.0 * I;
    double complex exp_z = cexp(z);
    
    printf("复数: %.2f + %.2fi\n", creal(z), cimag(z));
    printf("指数: %.2f + %.2fi\n", creal(exp_z), cimag(exp_z));
    
    return 0;
}

clog()

c
double complex clog(double complex z);
float complex clogf(float complex z);
long double complex clogl(long double complex z);

计算复数的自然对数。

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

int main() {
    double complex z = 1.0 + 1.0 * I;
    double complex log_z = clog(z);
    
    printf("复数: %.2f + %.2fi\n", creal(z), cimag(z));
    printf("自然对数: %.2f + %.2fi\n", creal(log_z), cimag(log_z));
    
    return 0;
}

cpow()

c
double complex cpow(double complex x, double complex y);
float complex cpowf(float complex x, float complex y);
long double complex cpowl(long double complex x, long double complex y);

计算复数的幂。

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

int main() {
    double complex x = 2.0 + 0.0 * I;
    double complex y = 3.0 + 0.0 * I;
    double complex result = cpow(x, y);
    
    printf("x = %.2f + %.2fi\n", creal(x), cimag(x));
    printf("y = %.2f + %.2fi\n", creal(y), cimag(y));
    printf("x^y = %.2f + %.2fi\n", creal(result), cimag(result));
    
    return 0;
}

csin()

c
double complex csin(double complex z);
float complex csinf(float complex z);
long double complex csinl(long double complex z);

计算复数的正弦。

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

int main() {
    double complex z = 1.0 + 1.0 * I;
    double complex sin_z = csin(z);
    
    printf("复数: %.2f + %.2fi\n", creal(z), cimag(z));
    printf("正弦: %.2f + %.2fi\n", creal(sin_z), cimag(sin_z));
    
    return 0;
}

ccos()

c
double complex ccos(double complex z);
float complex ccosf(float complex z);
long double complex ccosl(long double complex z);

计算复数的余弦。

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

int main() {
    double complex z = 1.0 + 1.0 * I;
    double complex cos_z = ccos(z);
    
    printf("复数: %.2f + %.2fi\n", creal(z), cimag(z));
    printf("余弦: %.2f + %.2fi\n", creal(cos_z), cimag(cos_z));
    
    return 0;
}

ctan()

c
double complex ctan(double complex z);
float complex ctanf(float complex z);
long double complex ctanl(long double complex z);

计算复数的正切。

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

int main() {
    double complex z = 1.0 + 1.0 * I;
    double complex tan_z = ctan(z);
    
    printf("复数: %.2f + %.2fi\n", creal(z), cimag(z));
    printf("正切: %.2f + %.2fi\n", creal(tan_z), cimag(tan_z));
    
    return 0;
}

casin()

c
double complex casin(double complex z);
float complex casinf(float complex z);
long double complex casinl(long double complex z);

计算复数的反正弦。

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

int main() {
    double complex z = 0.5 + 0.5 * I;
    double complex asin_z = casin(z);
    
    printf("复数: %.2f + %.2fi\n", creal(z), cimag(z));
    printf("反正弦: %.2f + %.2fi\n", creal(asin_z), cimag(asin_z));
    
    return 0;
}

cacos()

c
double complex cacos(double complex z);
float complex cacosf(float complex z);
long double complex cacosl(long double complex z);

计算复数的反余弦。

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

int main() {
    double complex z = 0.5 + 0.5 * I;
    double complex acos_z = cacos(z);
    
    printf("复数: %.2f + %.2fi\n", creal(z), cimag(z));
    printf("反余弦: %.2f + %.2fi\n", creal(acos_z), cimag(acos_z));
    
    return 0;
}

catan()

c
double complex catan(double complex z);
float complex catanf(float complex z);
long double complex catanl(long double complex z);

计算复数的反正切。

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

int main() {
    double complex z = 0.5 + 0.5 * I;
    double complex atan_z = catan(z);
    
    printf("复数: %.2f + %.2fi\n", creal(z), cimag(z));
    printf("反正切: %.2f + %.2fi\n", creal(atan_z), cimag(atan_z));
    
    return 0;
}

csinh()

c
double complex csinh(double complex z);
float complex csinhf(float complex z);
long double complex csinhl(long double complex z);

计算复数的双曲正弦。

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

int main() {
    double complex z = 1.0 + 1.0 * I;
    double complex sinh_z = csinh(z);
    
    printf("复数: %.2f + %.2fi\n", creal(z), cimag(z));
    printf("双曲正弦: %.2f + %.2fi\n", creal(sinh_z), cimag(sinh_z));
    
    return 0;
}

ccosh()

c
double complex ccosh(double complex z);
float complex ccoshf(float complex z);
long double complex ccoshl(long double complex z);

计算复数的双曲余弦。

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

int main() {
    double complex z = 1.0 + 1.0 * I;
    double complex cosh_z = ccosh(z);
    
    printf("复数: %.2f + %.2fi\n", creal(z), cimag(z));
    printf("双曲余弦: %.2f + %.2fi\n", creal(cosh_z), cimag(cosh_z));
    
    return 0;
}

ctanh()

c
double complex ctanh(double complex z);
float complex ctanhf(float complex z);
long double complex ctanhl(long double complex z);

计算复数的双曲正切。

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

int main() {
    double complex z = 1.0 + 1.0 * I;
    double complex tanh_z = ctanh(z);
    
    printf("复数: %.2f + %.2fi\n", creal(z), cimag(z));
    printf("双曲正切: %.2f + %.2fi\n", creal(tanh_z), cimag(tanh_z));
    
    return 0;
}

实际应用示例

1. 复数基本运算

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

int main() {
    double complex z1 = 3.0 + 4.0 * I;
    double complex z2 = 1.0 + 2.0 * I;
    
    double complex sum = z1 + z2;
    double complex diff = z1 - z2;
    double complex product = z1 * z2;
    double complex quotient = z1 / z2;
    
    printf("z1 = %.2f + %.2fi\n", creal(z1), cimag(z1));
    printf("z2 = %.2f + %.2fi\n", creal(z2), cimag(z2));
    printf("z1 + z2 = %.2f + %.2fi\n", creal(sum), cimag(sum));
    printf("z1 - z2 = %.2f + %.2fi\n", creal(diff), cimag(diff));
    printf("z1 * z2 = %.2f + %.2fi\n", creal(product), cimag(product));
    printf("z1 / z2 = %.2f + %.2fi\n", creal(quotient), cimag(quotient));
    
    return 0;
}

2. 极坐标转换

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

int main() {
    double complex z = 3.0 + 4.0 * I;
    
    double r = cabs(z);
    double theta = carg(z);
    
    printf("直角坐标: %.2f + %.2fi\n", creal(z), cimag(z));
    printf("极坐标: r = %.2f, θ = %.2f 弧度\n", r, theta);
    printf("极坐标: r = %.2f, θ = %.2f\n", r, theta * 180.0 / M_PI);
    
    return 0;
}

3. 欧拉公式验证

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

int main() {
    double theta = M_PI;
    
    double complex result = cexp(theta * I);
    
    printf("e^(iπ) = %.2f + %.2fi\n", creal(result), cimag(result));
    printf("cos(π) + i*sin(π) = %.2f + %.2fi\n", cos(theta), sin(theta));
    
    return 0;
}

4. 复数方程求解

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

void solve_quadratic(double a, double b, double c) {
    double complex discriminant = b * b - 4 * a * c;
    double complex sqrt_discriminant = csqrt(discriminant);
    
    double complex z1 = (-b + sqrt_discriminant) / (2 * a);
    double complex z2 = (-b - sqrt_discriminant) / (2 * a);
    
    printf("方程: %.2fx² + %.2fx + %.2f = 0\n", a, b, c);
    printf("解1: %.2f + %.2fi\n", creal(z1), cimag(z1));
    printf("解2: %.2f + %.2fi\n", creal(z2), cimag(z2));
}

int main() {
    solve_quadratic(1.0, -3.0, 2.0);
    solve_quadratic(1.0, 2.0, 5.0);
    
    return 0;
}

5. 傅里叶变换基础

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

double complex dft_term(const double* signal, int n, int k) {
    double complex sum = 0.0 + 0.0 * I;
    
    for (int m = 0; m < n; m++) {
        double angle = 2.0 * M_PI * k * m / n;
        sum += signal[m] * cexp(-angle * I);
    }
    
    return sum;
}

int main() {
    double signal[] = {1.0, 2.0, 3.0, 4.0};
    int n = sizeof(signal) / sizeof(signal[0]);
    
    printf("DFT 结果:\n");
    for (int k = 0; k < n; k++) {
        double complex Xk = dft_term(signal, n, k);
        printf("X[%d] = %.2f + %.2fi\n", k, creal(Xk), cimag(Xk));
    }
    
    return 0;
}

6. 复数矩阵运算

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

typedef struct {
    double complex a;
    double complex b;
    double complex c;
    double complex d;
} Matrix2x2;

Matrix2x2 multiply_matrices(const Matrix2x2* m1, const Matrix2x2* m2) {
    Matrix2x2 result;
    result.a = m1->a * m2->a + m1->b * m2->c;
    result.b = m1->a * m2->b + m1->b * m2->d;
    result.c = m1->c * m2->a + m1->d * m2->c;
    result.d = m1->c * m2->b + m1->d * m2->d;
    return result;
}

void print_matrix(const Matrix2x2* m) {
    printf("| %.2f + %.2fi  %.2f + %.2fi |\n", 
           creal(m->a), cimag(m->a), creal(m->b), cimag(m->b));
    printf("| %.2f + %.2fi  %.2f + %.2fi |\n", 
           creal(m->c), cimag(m->c), creal(m->d), cimag(m->d));
}

int main() {
    Matrix2x2 m1 = {
        .a = 1.0 + 1.0 * I,
        .b = 2.0 + 0.0 * I,
        .c = 0.0 + 1.0 * I,
        .d = 1.0 + 0.0 * I
    };
    
    Matrix2x2 m2 = {
        .a = 1.0 + 0.0 * I,
        .b = 1.0 + 1.0 * I,
        .c = 2.0 + 0.0 * I,
        .d = 0.0 + 1.0 * I
    };
    
    Matrix2x2 result = multiply_matrices(&m1, &m2);
    
    printf("矩阵1:\n");
    print_matrix(&m1);
    printf("\n矩阵2:\n");
    print_matrix(&m2);
    printf("\n乘积:\n");
    print_matrix(&result);
    
    return 0;
}

7. 复数序列

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

void print_complex_sequence(double complex* seq, int n) {
    for (int i = 0; i < n; i++) {
        printf("z[%d] = %.2f + %.2fi\n", i, creal(seq[i]), cimag(seq[i]));
    }
}

int main() {
    double complex sequence[5];
    
    for (int i = 0; i < 5; i++) {
        sequence[i] = (double)i + (double)i * I;
    }
    
    print_complex_sequence(sequence, 5);
    
    return 0;
}

8. 复数函数绘制

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

void plot_complex_function(double complex (*func)(double complex), 
                        double real_min, double real_max,
                        double imag_min, double imag_max,
                        int steps) {
    double real_step = (real_max - real_min) / steps;
    double imag_step = (imag_max - imag_min) / steps;
    
    for (int i = 0; i <= steps; i++) {
        double real = real_min + i * real_step;
        for (int j = 0; j <= steps; j++) {
            double imag = imag_min + j * imag_step;
            double complex z = real + imag * I;
            double complex w = func(z);
            
            printf("f(%.2f + %.2fi) = %.2f + %.2fi\n", 
                   real, imag, creal(w), cimag(w));
        }
    }
}

int main() {
    printf("f(z) = z²:\n");
    plot_complex_function(cpow, -2.0, 2.0, -2.0, 2.0, 2);
    
    return 0;
}

9. 复数根

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

void complex_roots(double complex z, int n) {
    double r = cabs(z);
    double theta = carg(z);
    
    printf("%d 次方根:\n", n);
    for (int k = 0; k < n; k++) {
        double root_r = pow(r, 1.0 / n);
        double root_theta = (theta + 2 * M_PI * k) / n;
        
        double complex root = root_r * (cos(root_theta) + sin(root_theta) * I);
        printf("根 %d: %.2f + %.2fi\n", k, creal(root), cimag(root));
    }
}

int main() {
    double complex z = 1.0 + 0.0 * I;
    
    printf("复数: %.2f + %.2fi\n", creal(z), cimag(z));
    complex_roots(z, 3);
    
    return 0;
}

10. 复数滤波器

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

typedef struct {
    double complex a0;
    double complex a1;
    double complex b0;
    double complex b1;
} Filter;

double complex apply_filter(const Filter* filter, double complex input, 
                          double complex prev_input, double complex prev_output) {
    return (filter->b0 * input + filter->b1 * prev_input - 
            filter->a1 * prev_output) / filter->a0;
}

int main() {
    Filter filter = {
        .a0 = 1.0 + 0.0 * I,
        .a1 = -0.5 + 0.0 * I,
        .b0 = 0.5 + 0.0 * I,
        .b1 = 0.5 + 0.0 * I
    };
    
    double complex input = 1.0 + 0.0 * I;
    double complex prev_input = 0.0 + 0.0 * I;
    double complex prev_output = 0.0 + 0.0 * I;
    
    for (int i = 0; i < 5; i++) {
        double complex output = apply_filter(&filter, input, prev_input, prev_output);
        printf("输入: %.2f + %.2fi, 输出: %.2f + %.2fi\n", 
               creal(input), cimag(input), creal(output), cimag(output));
        
        prev_input = input;
        prev_output = output;
    }
    
    return 0;
}

注意事项

1. 虚数单位的使用

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

int main() {
    double complex z1 = 3.0 + 4.0 * I;
    double complex z2 = 3.0 + 4.0i;
    
    printf("z1 = %.2f + %.2fi\n", creal(z1), cimag(z1));
    printf("z2 = %.2f + %.2fi\n", creal(z2), cimag(z2));
    
    return 0;
}

2. 复数精度

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

int main() {
    float complex z_f = 3.0f + 4.0f * I;
    double complex z_d = 3.0 + 4.0 * I;
    long double complex z_ld = 3.0L + 4.0L * I;
    
    printf("float: %.2f + %.2fi\n", crealf(z_f), cimagf(z_f));
    printf("double: %.2f + %.2fi\n", creal(z_d), cimag(z_d));
    printf("long double: %.2Lf + %.2Lfi\n", creall(z_ld), cimagl(z_ld));
    
    return 0;
}

3. 复数比较

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

int complex_equal(double complex z1, double complex z2, double epsilon) {
    return fabs(creal(z1) - creal(z2)) < epsilon && 
           fabs(cimag(z1) - cimag(z2)) < epsilon;
}

int main() {
    double complex z1 = 1.0 + 1.0 * I;
    double complex z2 = 1.000001 + 1.000001 * I;
    
    if (complex_equal(z1, z2, 0.0001)) {
        printf("复数近似相等\n");
    } else {
        printf("复数不相等\n");
    }
    
    return 0;
}

4. 复数格式化输出

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

void print_complex(double complex z) {
    if (cimag(z) >= 0) {
        printf("%.2f + %.2fi", creal(z), cimag(z));
    } else {
        printf("%.2f - %.2fi", creal(z), -cimag(z));
    }
}

int main() {
    double complex z1 = 3.0 + 4.0 * I;
    double complex z2 = 3.0 - 4.0 * I;
    
    printf("z1 = ");
    print_complex(z1);
    printf("\n");
    
    printf("z2 = ");
    print_complex(z2);
    printf("\n");
    
    return 0;
}

总结

<complex.h> 提供的复数类型和函数对于科学计算和工程应用非常重要:

  1. 功能全面 - 涵盖复数的基本运算和数学函数
  2. 易于使用 - 提供了简单直观的接口
  3. 类型安全 - 支持不同精度的复数类型
  4. 广泛应用 - 适用于信号处理、控制系统、量子力学等领域

记住:

  • 使用 I 作为虚数单位
  • 注意复数的精度问题
  • 使用合适的函数变体(f, l 后缀)
  • 复数比较需要考虑浮点精度
  • 理解复数的极坐标表示