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

typedef  struct complex{
  double Re,Im;
}Complex;

Complex InitComplex(double a, double b);
Complex ReadComplex();
void PrintComplex(Complex z);
Complex axpbyComplex(double lambda,Complex z1,double mu, Complex z2);
double modulusComplex(Complex z);
void permut(double *x, double *y);
void PermutComplex(Complex *z1,Complex *z2);

void Print3Complex(Complex z1,Complex z2, Complex z3);

int main(){
  Complex z1={1.,M_PI},z2,z3; 
  z2.Re=2*M_PI;z2.Im=-1.;
  z3=InitComplex(-2.,1.);
  printf("\n(0) Initial values of z1,z2,z3\n");
  Print3Complex(z1,z2,z3);
  
  printf("\n(1) permutation of z1 and z2\n");
  PermutComplex(&z1,&z2);
  Print3Complex(z1,z2,z3);
  
  printf("\n(2) z3<- z1-z2\n");
  z3=axpbyComplex(1.,z1,-1.,z2);
  Print3Complex(z1,z2,z3);
  
  printf("\n(2) |z3|\n");
  printf("  |z3|=%.6f\n",modulusComplex(z3));
  printf("\n");
}

Complex InitComplex(double a, double b){
  return (Complex){a,b};
}

/* Version plus "classique" */
Complex InitComplexV2(double a, double b){
  Complex z;
  z.Re=a;z.Im=b;
  return z;
}

Complex ReadComplex(){
  Complex z;
  printf("Enter complex number a+ib :\n  a=");
  scanf("%lf",&z.Re);
  printf("  b=");
  scanf("%lf",&z.Im);
  return z;
}

void PrintComplex(Complex z){
  printf("(%.6f,%.6f)",z.Re,z.Im);
}

Complex axpbyComplex(double lambda,Complex z1,double mu, Complex z2){
  Complex z;
  z.Re=lambda*z1.Re+mu*z2.Re;
  z.Im=lambda*z1.Im+mu*z2.Im;
  return z;
}

double modulusComplex(Complex z){
  return sqrt( z.Re*z.Re + z.Im*z.Im);
}

void permut(double *x, double *y){
  double tmp;
  tmp=*x;*x=*y;*y=tmp;
}

void PermutComplex(Complex *z1,Complex *z2){
  permut(&(z1->Re),&(z2->Re));
  permut(&(z1->Im),&(z2->Im));
}

void Print3Complex(Complex z1,Complex z2, Complex z3){
  printf("  z1=");PrintComplex(z1);
  printf(", z2=");PrintComplex(z2);
  printf(", z3=");PrintComplex(z3);
}
  