Solucionario lab 7
Ejercicio 1
#include <stdio.h>
#include <math.h>
/* Prototipos */
int raices(double, double, double, double*, double*);
void testear_funcion(double, double, double);
int main(void)
{
// Casos test
testear_funcion(1, 4, 4);
testear_funcion(1, 0, 1);
testear_funcion(1, 5, 6);
return 0;
}
/**
* Encuentra las raices de una ecuacion cuadratica ax^2 + bx + c = 0
* @a: Valor de a
* @b: Valor de b
* @c: Valor de c
* @x1: Paso por referencia a la solucion 1 (parte real si hay sol. imaginarias)
* @x2: Paso por referencia a la solucion 2 (parte imag si hay sol. imaginarias)
* @return: 0 si no hay raices reales, 1 si hay unica solucion, 2 si hay dos soluciones
*/
int raices(double a, double b, double c, double* x1, double* x2)
{
double d = b*b - 4*a*c;
// Si discriminante menor que 0
if (d < 0)
{
*x1 = -b/(2*a);
*x2 = sqrt(-d)/(2*a);
return 0;
}
// Si es mayor que 0
if (d > 0)
{
*x1 = (-b + sqrt(d))/(2*a);
*x2 = (-b - sqrt(d))/(2*a);
return 2;
}
// Si no ocurre nada de lo anterior, entonces discriminante igual 0.
*x1 = -b/(2*a);
*x2 = *x1;
return 1;
}
/**
* Funcion auxiliar, para testear la funcion de las raices.
*/
void testear_funcion(double a, double b, double c)
{
double x1, x2;
switch(raices(a, b, c, &x1, &x2))
{
case 0:
printf("Se encontraron soluciones imaginarias: \n");
printf("x1 = %.4f + %.4f i\nx2 = %.4f - %.4f i\n", x1, x2, x1, x2);
break;
case 1:
printf("Se encontro una unica solucion: \n");
printf("x = %.4f\n", x1);
break;
default:
printf("Se encontraron dos soluciones: \n");
printf("x1 = %.4f\nx2 = %.4f\n", x1, x2);
}
}
Ejercicio 2
#include <stdio.h>
#include <stdlib.h>
/* Prototipo de funciones */
int largo(const char*);
char* concatenar(const char*, const char*);
int main(void)
{
char* string1 = "hola", *string2 = "mundo loco!";
printf("El largo del string %s es %d\n", string1, largo(string1));
char* concatenado = concatenar(string1, string2);
// Asegurarse de no obtener NULL.
if (concatenado == NULL)
{
printf("Fallo la funcion concatenar.\n");
return 1;
}
printf("Si concatenamos: %s y %s obtenemos: %s", string1, string2, concatenado);
// No olvidar liberar memoria pedida!
free(concatenado);
return 0;
}
/**
* Calcula el largo del string str
* @str: String del cual se desea calcular el largo
* @return: El largo del string
*/
int largo(const char* str)
{
int len = 0;
// Recorrer string hasta encontrar caracter nulo
while(*str)
{
len++;
str++;
}
return len;
}
/**
* Concatena dos strings
* @str1: String primero
* @str2: String segundo
* @return: Un puntero a la direccion del string concatenado
*/
char* concatenar(const char* s1, const char* s2)
{
int len1 = largo(s1), len2 = largo(s2);
// Pedir memoria para el nuevo string
char* resultado = malloc((len1 + len2 + 1)*sizeof(char));
if (resultado == NULL) return NULL;
// Llenamos el string nuevo
int i = 0, j;
for (j = 0; j < len1; j++) resultado[i++] = s1[j];
for (j = 0; j < len2; j++) resultado[i++] = s2[j];
resultado[i] = '\0';
return resultado;
}
Ejercicio 5
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
char* leer_string(void);
int main(void)
{
char* test = leer_string();
printf("Usted ingreso:\n\n%s", test);
free(test);
return 0;
}
char* leer_string(void)
{
char *buffer = NULL;
unsigned int capacidad = 0;
unsigned int n = 0;
int c;
// Mientras no se lea EOF o el usuario no ingrese un salto de linea
while ((c = getchar()) != '\n' && c != EOF)
{
// Si la cantidad de caracteres es mayor que la capacidad definida
if (n + 1 > capacidad)
{
if (capacidad == 0)
capacidad = 128;
else if (capacidad <= (UINT_MAX / 2)) // capacidad maxima a considerar
capacidad *= 2;
else
{
free(buffer);
return NULL;
}
// Aumentar capacidad del buffer
char* temp = realloc(buffer, capacidad * sizeof(char));
if (temp == NULL)
{
free(buffer);
return NULL;
}
buffer = temp;
}
// Agregar al buffer el caracter leido
buffer[n++] = c;
}
// Si no se ingreso nada
if (n == 0 || c == EOF)
{
return NULL;
}
// Copiar caracteres del buffer a un nuevo string
char* minimal = malloc((n + 1) * sizeof(char));
strncpy(minimal, buffer, n);
// liberar memoria pedida para el buffer
free(buffer);
minimal[n] = '\0';
return minimal;
}
Ejercicios 6 y 7
#include <stdio.h>
#include <math.h>
/* Prototipo de funciones */
double f1(double x);
double f2(double x);
double derivada(double f(double), double x);
double newton_raphson(double f(double), double x0, double tol);
double funcion_ejercicio(double x);
int main(void)
{
// Testear funcion derivada (ejercicio 6)
printf("f(x) = x^2, f(1) = %f, f\'(1) = %f\n", f1(1), derivada(f1, 1));
printf("f(x) = e^(2x), f(1) = %f, f\'(1) = %f\n\n", f2(1), derivada(f2, 1));
// Testear newton raphson (ejercicio 7)
double x0 = 0.5, tol = 1e-6;
printf("Una raiz de la ecuacion, dado x0 = %f con una tol = %f es:\n", x0, tol);
printf("%f\n", newton_raphson(funcion_ejercicio, x0, tol));
return 0;
}
/**
* Calcular f(x) = x^2
* @x: Valor de x
* @return: Valor de f(x)
*/
double f1(double x)
{
return x*x;
}
/**
* Calcular f(x) = e^(2x)
* @x: Valor de x
* @return: Valor de f(x)
*/
double f2(double x)
{
return exp(2*x);
}
/**
* Calcula de forma aproximada la derivada de una funcion f
* @f: Puntero a funcion a la cual se desea calcular la derivada
* @x: Valor en el cual se calculara la derivada
* @return: f'(x)
*/
double derivada(double f(double), double x)
{
double h = 1e-9;
return (f(x + h) - f(x)) / h;
}
/**
* Encuentra raices de una ecuacion no lineal mediante metodo N.R
* @f: Puntero a funcion a la cual se desea encontrar la solucion
* @x0: aproximacion inicial de la raiz
* @tol: Tolerancia deseada para la solucion
* @return: El valor de la raiz de f, cercana a x0
*/
double newton_raphson(double f(double), double x0, double tol)
{
double xk, diff;
do
{
xk = x0 - f(x0) / derivada(f, x0);
diff = fabs(xk - x0);
x0 = xk;
} while (diff >= tol);
return xk;
}
/**
* Calcular f(x) = cos(x) - x^3
* @x: Valor de x
* @return: Valor de f(x)
*/
double funcion_ejercicio(double x)
{
return cos(x) - x*x*x;
}