/**********************************************************************

Exemplo de ponteiros para complexos.  Neste programa, a declaracao

  Complexo z;

declara z como ponteiro para um complexo.  Desta forma, a sua parte 
real 'e

  z->Re

e sua parte imaginaria 'e

  z->Im

O uso de ponteiros para estruturas, ao inves de variaveis do tipo da
estrutura, 'e muitas vezes mais eficiente.  

Este programa tambem ilustra o uso de malloc().

**********************************************************************/
#include <stdio.h>
#include <stdlib.h>

typedef struct {
  double Re;
  double Im;
} sComplexo, *Complexo; /* Note que agora Complexo 'e um tipo ponteiro. */ 

void imprima_complexo(Complexo z)
{
  printf("Parte real = %.5lf\n", z->Re);
  printf("Parte imaginaria = %.5lf\n", z->Im);
}

Complexo complexo_aleatorio()
{
  Complexo z;

  /* Alocamos memoria para a estrutura a ser apontada por z. */
  z=(Complexo)malloc(sizeof(sComplexo)); 

  z->Re=(double)rand()/RAND_MAX; 
  z->Im=(double)rand()/RAND_MAX; 
  /* RAND_MAX e o maior valor que rand() */
  /* pode devolver. */

  if (rand()%2) z->Re=-z->Re;
  if (rand()%2) z->Im=-z->Im;

  return z;
}

void troca_complexos(Complexo *w, Complexo *z)
{
  Complexo tmp;

  tmp=*w;
  *w=*z;
  *z=tmp;
}

main()
{
  unsigned int s;
  Complexo z1, z2;

  printf("Entre a semente para o gerador aleatorio: ");
  scanf("%ud", &s);
  srand(s); /* Inicializa o gerador de numeros aleatorios */

  z1=complexo_aleatorio();
  z2=complexo_aleatorio();

  printf("z1: \n");
  imprima_complexo(z1);
  printf("z2: \n");
  imprima_complexo(z2);

  troca_complexos(&z1, &z2);
  
  printf("z1: \n");
  imprima_complexo(z1);
  printf("z2: \n");
  imprima_complexo(z2);

  return 0;
}
