--------------------------------------------------------------------
 MAC-115  - Turma T23 -  Outubro  -    Uso de funções
====================================================================

EXEMPLO 1
=========

/*
 * arquivo: mdc3_func.c
 *
 * Este programa recebe 3 numeros inteiros positivos a, b, c  e calcula o
 * maximo divisor comum (mdc) desses 3 numeros (usando o algoritmo de
 * Euclides). Para isso, define uma funcao chamada mdc que tem dois parametros 
 * inteiros m e n, e calcula o valor do mdc de m e n.
 */

#include <stdio.h>

/* prototipo da funcao *******************************/

int mdc(int m, int n);

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

int main()
{
    int a, b, c, resp1, resultado;
    printf("Entre com os valores de a, b e c : ");
    scanf("%d %d %d", &a, &b, &c);
    printf("a = %d,    b = %d,   c = %d \n ", a,b,c);
   
    resp1 = mdc(a, b); 
    resultado = mdc(resp1, c);                                 

    printf("O mdc de %d, %d, %d e' %d\n", a,b,c, resultado);
    
    return 0;
}

/* 
 * Funcao: mdc
 * Uso: mdc(m, n)
 * Esta funcao devolve o maximo divisor comum dos argumentos m e n
 */

int mdc(int m, int n)
{
    int resto;

    resto = m % n;
    while (resto != 0) {
	m = n;
	n = resto;
	resto = m % n;
    }
    return n;
}


/*
 * Exercício: mude este programa de modo a resolver o problema em 
 * que são dados n números inteiros positivos e deseja-se calcular
 * o mdc desses números.
 */


----------------------------------------------------------------
EXEMPLO 2
=========

/*
 * arquivo: pot_func.c
 *
 * Este programa recebe dois numeros reais x e y, dois inteiros a e b,  e calcula 
 * o valor da seguinte expressao:  x^a + (x-y)^5 + y^(a+b).
 * Para isso, define uma funcao chamada pot que tem dois parametros
 * x e n,  e devolve o valor de x elevado `a potencia n.
 */


#include <stdio.h>

/* prototipo da funcao **********************************/

double pot(double x, int n);
 /* Funcao que calcula o valor de x elevado `a potencia n  */

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

int main()
{
    double x, y, valor;
    int a, b;
    printf("Entre com os valores de x e y : ");
    scanf("%lf %lf", &x, &y);
    printf("x = %f  y = %f \n", x, y);
    printf("Entre com os valores de a e b : ");
    scanf("%d %d", &a, &b);
    printf("a = %d  b = %d \n", a, b);

    valor = pot(x, a) + pot(x - y, 5) + pot(y, a + b);

    printf("O valor da expressao x^a + (x-y)^5 + y^(a+b) e' %e\n", valor);

    return 0;

}
/* 
 * Funcao: pot
 * Uso: pot(x, n)
 * Esta funcao devolve o valor de x elevado `a potencia n.
 */

double pot(double x, int n)
{
    int i;
    double prod;

    prod = 1.0;
    for (i = 0; i < n; i++)
	prod = prod * x;
    return prod;
}

----------------------------------------------------------------
EXEMPLO 3
=========

/* 
 * arquivo: exp2_func.c
 * ----------------------
 * Dado x e epsilon (reais) e n, um inteiro, este programa calcula
 * exp(x) atraves da soma dos termos da serie 
 *
 * 1 + x + x^2/2! + x^3/3! + ...
 *
 * ate o valor absoluto do termo se tornar <= epsilon.
 */


#include <stdio.h>
#include <math.h>  // para usar a funcao exp(.)

double exp2 (double x, double epsilon); /* prototipo da funcao exp2 */


int main()
{
   double x, epsilon;

  printf("Forneca o valor de x: ");
  scanf("%lf", &x);

  printf("Forneca o valor de epsilon: ");
  scanf("%lf", &epsilon);
 
  printf("exp(%g) = %.20g [usando a serie]\n", x, exp2(x, epsilon)); 
  printf("exp(%g) = %.20g [biblioteca math]\n", x, exp(x));

  return 0;
}

/* Funcao:  double exp2 (double x, double epsilon)
 *
 * Esta funcao calcula exp(x) atraves da serie 
 *
 * 1 + x + x^2/2! + x^3/3! + ...
 *
 * ate o valor absoluto do termo se tornar <= epsilon.
 * A funcao devolve a soma aproximada obtida quando encontra um
 * tal termo.
 */

double exp2 (double x, double epsilon)
{
  int i;
  double soma = 1.0, termo = 1.0;

  i = 1;
  while (termo > epsilon || termo < -epsilon) { /*  |termo| > epsilon  */
    termo = termo * x / i;
    soma  = soma + termo;
    i++;
  }
  return soma;
}


/* OBS: No lugar de 
 * 
 *  while (termo > epsilon || termo < -epsilon)
 * 
 *  poderiamos usar a funcao fabs (floating abolute value): 
 * 
 *  while (fabs(termo) > epsilon)
 */ 

--------------------------------------------------------------
EXEMPLO 4
=========
/* 
 * arquivo: exp2indif.c
 * ---------------------
 * Dado numero real x, este programa calcula exp(x) 
 * atraves da soma dos termos da serie
 *
 * 1 + x + x^2/2! + x^3/3! + ...
 *
 * A soma e' feita ate' que a soma de um termo nao faca mais
 * diferenca.  Isto e', ate' que  somar novos termos fique
 * "indiferente".
 */

#include <stdio.h>
#include <math.h>  // para usar a funcao exp(.)

int main()
{
  int i;
  double x, s = 0.0, t = 1.0, tmp;

  printf("Forneca o valor de x: ");
  scanf("%lf", &x);

  tmp = t;
  i = 1;
  while (s != tmp) {
    s = tmp;
    t = t *  x / i;
    tmp = s + t;
    i++;
  }

  printf("exp(%g) = %.20g [nossa serie]\n", x, s);
  printf("exp(%g) = %.20g [biblioteca math]\n", x, exp(x));
  return 0;
}

-----------------------------------------
EXEMPLO 5
=========

/* 
 * arquivo: exp2indif2.c
 * ---------------------
 * Dado numero real x, este programa calcula exp(x) 
 * atraves da soma dos termos da serie
 *
 * 1 + x + x^2/2! + x^3/3! + ...
 *
 * A soma e' feita ate' que a soma de um termo nao faca mais
 * diferenca.  Isto e', ate' que  somar novos termos fique
 * "indiferente".
 */

#include <stdio.h>
#include <math.h>  // para usar a funcao exp(.)

int main()
{
  int i;
  double x, s = 1.0, t = 1.0, tmp;

  printf("Forneca o valor de x: ");
  scanf("%lf", &x);

  for (i = 1;; i++) { /* laco infinito */ 
    t *= x / i;
    tmp = s + t;
    if (s == tmp)
      break;
    s = tmp;
  }

  printf("exp(%g) = %.20g [nossa serie]\n", x, s);
  printf("exp(%g) = %.20g [biblioteca math]\n", x, exp(x));
  return 0;
}