descomposición funcional (parte ii)void imprimir2(int *x) { int i; for (i=0; i

36
Descomposición funcional (Parte II) 2012 Ing. Ileana Camacho

Upload: others

Post on 23-Sep-2020

8 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

Descomposición funcional (Parte II)

2012

Ing. Ileana Camacho

Page 2: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

Pasar un array a una función

Cuando pasamos un array a una función lo que se escribe como argumento en la

llamada a esa función es el nombre del array, es decir, el argumento que se pasa es la

dirección del array, por lo que el parámetro formal correspondiente tiene que ser

también un array, el cual, después de la llamada, queda inicializado con esa dirección.

Los arrays son siempre pasados por referencia, porque no se pasa una copia de todos

sus elementos. Tanto la función que invoca, como la función invocada trabajan sobre

el mismo espacio de memoria (sobre el mismo array).

En otras palabras:

Cuando un argumento (parámetro) de una función es un arreglo, el parámetro (arreglo)

se pasa por referencia:

Cuando se declara un array unidimensional como parámetro de una función, no se

requiere que se especifique su dimensión (no se hace una reserva de memoria para

una copia total del array), ya que lo que se pasa es la dirección del array.

int leer(tficha bibli[ ], int NMAX);

Ejemplo - Imprime arreglo

Escriba una función en C llamada imprimir que reciba como argumento un vector

formado por 0; 1; 2; : : : ; 9 y los muestre por pantalla.

Solución

#include<stdio.h>

#define n 10 // define n=10

Page 3: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

/* declaración de la función imprimir de dos maneras */

void imprimir1(int x[]);

void imprimir2(int *x);

int main(){

int x[n], i;

// Inicializa arreglo

for (i=0; i<n; i++)

x[i] = i;

imprimir1(x); // Imprime arreglo

// imprimir2(x);

}

// Definición de la función imprimir1

void imprimir1(int x[]) {

int i;

for (i=0; i<n; i++)

printf(" %d nt", x[i]);

}

// Definición de la función imprimir2

void imprimir2(int *x) {

int i;

for (i=0; i<n; i++)

printf(" %d nt", x[i]);

Page 4: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

}

Ejemplo 2 (promedio arreglo)

Escriba un programa en C que calcule el promedio de los elementos de un arreglo de

tamaño n. El programa debe constar de tres funciones, una que lea el arreglo (leer

vector), otra que imprima el arreglo por pantalla (escribir arreglo) y otra que calcule el

promedio (promedio).

Solución

Datos de entrada:

n: tamaño del vector

x[n]: vector

Funciones:

void leer_arreglo(double x[], int n)

void escribir_arreglo(double x[], int n)

double promedio(double x[], int n)

int main(){

int n;

printf("Ingrese número de elementos: ");

scanf("%d", &n);

double x[n];

leer_arreglo(x, n);

escribir_arreglo(x, n);

printf("nnPromedio = %lf", promedio(x,n));

}

Page 5: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

//definión de las funciones

void leer_arreglo(double x[], int n) {

int i;

for (i=0; i<n; i++) {

printf("x( %d) = ", i+1);

scanf("%lf", &x[i]);

}

}

// Definición de las funciones

void escribir_arreglo(double x[], int n) {

int i;

for (i=0; i<n; i++)

printf(" %5.8lf nt", x[i]);

}

double promedio(double x[], int n) {

int i;

double suma = 0.0;

for (i=0; i<n; i++) suma += x[i];

return suma/n;

}

Ejemplo 3 (Busca elemento)

Escriba una función en C que determine si un elemento dado está en un arreglo

Page 6: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

Solución

Datos de entrada:

n: tamaño del vector

x[n]: vector

v: elemento a buscar

int pertenece(double v, double x[], int n) {

int s = 0, k = 0;

while (s==0 && k<n) {

if (v==x[k]) s=1;

k++;

}

return s;

}

Ejemplo 4. Funciones con arreglos de caracteres

void imp_rev(char s[])

{

int t;

for( t=strlen(s)-1; t>=0; t--)

printf("%c",s[t]);

}

int main()

{

Page 7: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

char nombre[]="Facultad";

imp_rev(nombre);

}

Observar que en la función imp_rev se usa la función strlen para calcular la longitud de

la cadena sin incluir el terminador nulo. Por otra parte, la función imp_rev no usa la

sentencia return ni para terminar de usar la función, ni para regresar algún valor.

Ejemplo 5: Función que pasa a mayúsculas una cadena de caracteres

void F1(char cadena[], int lng) {

int i;

for (i=0; i!=lng; i++)

cadena[i] = toupper(cadena[i]);

}

int main () {

char caracteres[80] = "Ejemplo";

int longitud = strlen(caracteres);

puts(caracteres);

F1(caracteres, longitud);

puts(caracteres);

return 0;

}

Un ejemplo con matrices bidimensionales

Page 8: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

Realizar una función llamada ceros, que toma como parámetro una matriz de 3x4 de

números enteros y no devuelve nada. Debe rellenar con ceros la matriz de 3x4 que

recibe como parámetro.

Realizar una función llamada mostrar, que toma como parámetro una matriz de 3x4 de

números enteros y no devuelve nada. Debe mostrar el contenido de las celdas de la

matriz en pantalla.

Solución

#include<stdio.h>

void ceros(int matriz[3][4]);

void mostrar(int matriz[3][4]);

int main()

{

int matriz[3][4];

ceros(matriz);

mostrar(matriz);

return(0);

}

// Función ceros: Pone las celdas a cero.

void ceros(int matriz[3][4])

{

int fila, columna;

for(fila=0;fila<=2;fila++)

for(columna=0;columna<=3;columna++)

Page 9: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

matriz[fila][columna]=0;

}

// Función mostrar: Muestra la matriz

void mostrar(int matriz[3][4])

matriz.

{

int fila, columna;

for(fila=0;fila<=2;fila++)

{

for(columna=0;columna<=3;columna++)

{

printf(“%i “, matriz[fila][columna]);

}

printf(“\n”);

}

}

Ejercicios propuestos

1) Escribir una función ``reemplaza'', la cual toma una cadena como parámetro, le

reemplaza todos los espacios de la cadena por un guión bajo, y devuelve el número de

espacios reemplazados. Por ejemplo:

char cadena[] = "El gato negro";

n = reemplaza( cadena );

Page 10: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

deberá devolver:

cadena convertida "El_gato_negro"

n = 2

2) Escribir un programa que lea una línea de texto en un buffer (una cadena de

caracteres) usando la función gets y calcule la longitud de la línea (NO usar la

función strlen).

3) Modificar el programa anterior para que lea un archivo de texto. El archivo deberá

redireccionarse al programa, debiendo mostrar el contenido del mismo. En caso de

que se lea una línea con longitud 0 deberá terminar el programa.

Estructuras y funciones

Hemos visto que las variables y los arrays pueden pasarse como argumentos a las

funciones y todo ello sin problemas. ¿Por lo tanto puede ocurrir lo mismo con las

estructuras? la respuesta, como todos esperábamos, es afirmativa. Es posible pasar

estructuras a las funciones como argumentos.

Una estructura puede ser pasada a una función por valor o por referencia.

Cuando pasamos una estructura por valor, el parámetro actual que representa la

estructura se copia en el correspondiente parámetro formal, produciéndose un

duplicado. Si alguno de los miembros del parámetro formal se modifica, los cambios

no afectan al parámetro actual correspondiente.

Si pasamos la estructura por referencia, lo que recibe la función es el lugar de la

memoria donde se localiza dicha estructura.

En el siguiente ejemplo veremos cómo funciona mediante el uso de funciones. Para

ello escribiremos dos nuevas funciones. Una de ellas leerá del teclado la información

sobre un nuevo trabajador y la otra visualizará en pantalla la información de un

trabajador.

#include <stdio.h>

Page 11: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

#define LONGITUD 30

struct trabajadores

{

char nombre [LONGITUD];

int num;

};

/****

la función nuevo_nombre lee la información de un nuevo trabajador y la función

visualizar_datos visualiza la información de un trabajador.

****/

struct trabajadores nuevo_nombre(void);

void visualizar_datos (struct trabajadores currela);

void main (void)

{

struct trabajadores tra_1 ;

struct trabajadores tra_2 ;

tra_1 = nuevo_nombre();

tra_2 = nuevo_nombre ();

printf (“LISTA DE AGENTES SECRETOS:\n”);

visualizar_datos (tra_1);

visualizar_datos (tra_2);

}

Page 12: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

/*

Como se puede apreciar esta función devuelve una estructura tipo trabajadores donde

se almacena la información necesaria sobre cada trabajador, utilizando para ello la

sentencia return

*/

struct trabajadores nuevo_nombre(void)

{

struct trabajadores currela;

printf (“\nDatos del agente. \nIntroduce el nombre: “);

gets (currela.nombre);

printf (“Introduce el número: “);

scanf (“%d”, & currela.num);

fflush (stdin);

return (currela);

}

void visualizar_datos (struct trabajadores currela)

{

printf (“\n\n Agente secreto\n”);

printf (“\tNombre : %s \n”, currela.nombre);

printf (“\t Número del agente %d\n”, currela.num);

}

Ejemplo 2. Geometría

Page 13: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

Crear un programa que contenga los siguientes elementos:

Una estructura que represente puntos formada por sus coordenadas x e y

Una estructura que represente triángulos utilizando tres vértices (cada vértices es un

elemento de tipo punto)

Una función llamada mostrarCoordenadas que saque por pantalla las coordenadas de

los puntos en este formato: (2,3) (la x es el dos y la y el tres)

Una función llamada cambiarCoordenadas que permita cambiar las coordenadas del

punto que se envía como parámetro.

Una función llamada distanciaPuntos que devuelva la distancia entre dos puntos (que

recibe como parámetros de la función)

Una función llamada escribirTriangulo que escriba los vértices del triángulo en esta

forma, por ejemplo:

(3,2),(8,3),(7,5)

Una función llamada perimetroTriangulo que permita escribir el perímetro de un

triángulo dado. Para solucionarlo. podemos entender que el perímetro de un triángulo

es la suma de las distancias entre cada vértice.

#include <conio.h>

#include <stdio.h>

/*Estructura para representar puntos */

typedef struct{

double x;

double y;

}Punto;

Page 14: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

typedef struct{

Punto v1;

Punto v2;

Punto v3;

}Triangulo;

/* Prototipos */

Punto leerCoordenadas();

void mostrarCoordenadas(Punto punto);

void cambiarCoordenadas(Punto *p,int x, int y);

double distanciaPuntos(Punto p1, Punto p2);

void escribirTriangulo(Triangulo tri);

double perimetroTriangulo(Triangulo tri);

int main(){

/* Código para prbar las funciones */

Punto pa,pb;

pa.x=1;

pa.y=2;

pa=leerCoordenadas();

pb=leerCoordenadas();

printf("Los puntos son:\n");

mostrarCoordenadas(pa);printf("\n");

mostrarCoordenadas(pb);printf("\n");

cambiarCoordenadas(&pa,4,5);

printf("Nuevas coordenadas: ");

mostrarCoordenadas(pa);printf("\n");

printf("Distancia entre los puntos: %lf\n",distanciaPuntos(pa,pb));

Triangulo t;

Page 15: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

t.v1.x=2;t.v1.y=2;

t.v2.x=8;t.v2.y=2;

t.v3.x=4;t.v3.y=8;

escribirTriangulo(t);printf("\n");

printf("Perímetro: %lf",perimetroTriangulo(t));

}

/*Lee las coordenadas de un punto por teclado y devuelve el

punto

resultante*/

Punto leerCoordenadas(){

Punto aux;

printf("Coordenada x: ");fflush(stdin);scanf("%lf",&aux.x);

printf("Coordenada y: ");fflush(stdin);scanf("%lf",&aux.y);

return aux;

}

/* Saca las coordenadas por pantalla en formato (x,y)*/

void mostrarCoordenadas(Punto punto){

printf("(%lf,%lf)",punto.x,punto.y);

}

/*Modifica las coordenadas de un punto, según los valores de

los parámetros de la función*/

void cambiarCoordenadas(Punto *p,int x, int y){

p->x=x;

p->y=y;

}

/*Obtiene la distancia entre dos puntos*/

double distanciaPuntos(Punto p1, Punto p2){

Page 16: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

double distX=abs(p1.x-p2.x);/*Distancia horizontal entre los puntos*/

double distY=abs(p1.y-p2.y);/*Distancia vertical entre los puntos*/

/*Distancia aplicando Pitágoras*/

return sqrt(pow(distX,2)+pow(distY,2));

}

/* Escribe los vértices del triángulo por pantalla

en este formato (x,y),(x,y),(x,y)*/

void escribirTriangulo(Triangulo tri){

mostrarCoordenadas(tri.v1);

printf(",");

mostrarCoordenadas(tri.v2);

printf(",");

mostrarCoordenadas(tri.v3);

}

/*Devuelve el perímetro del triángulo indicado*/

double perimetroTriangulo(Triangulo tri){

return distanciaPuntos(tri.v1,tri.v2)+distanciaPuntos(tri.v3,tri.v2)+

distanciaPuntos(tri.v1,tri.v3);

}

Arreglos de estructuras y funciones

Cuando hablamos de arrays dijimos que se podían agrupar, para formarlos, cualquier

tipo de variables, esto es extensible a las estructuras y podemos entonces agruparlas

ordenadamente, como elementos de un array .

Se puede crear un array de estructuras tal como se crea un array de otros tipos. Los

arrays de estructuras son idóneos para almacenar un archivo completo de empleados,

un archivo de inventario o cualquier otro conjunto de datos que se adapte a un formato

de estructura. Mientras que los arrays proporcionan un medio práctico de almacenar

Page 17: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

diversos valores del mismo tipo, los arrays de estructuras le permiten almacenar juntos

diversos valores de diferentes tipos, agrupados como estructuras.

“Para acceder a los miembros de cada uno de los elementos estructura se utiliza

una notación de array”.

Veamos un ejemplo :

typedef struct {

char material[50] ;

int existencia ;

double costo_unitario ;

} Item ;

Item stock[10] ;

Hemos definido aquí un array de 10 elementos , donde cada uno de ellos es una

estructura del tipo Item compuesta por tres variables , un int , un double y un string ó

array de 50 caracteres.

Los arrays de estructuras pueden inicializarse de la manera habitual, así en una

definición de stock, podríamos haber escrito:

Item stock2[3] = {

"tornillos" , 120 , .15 ,

"tuercas" , 200 , .09 ,

"arandelas" , 90 , .01

} ;

Crear una función que guarde los datos para cada estructura Item Leer(void);

Item Leer()

{

Page 18: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

Item aux;

printf("Introduzca los datos de la estructura\n");

printf("Material: ");

fflush(stdin);

gets(aux.material);

printf("Existencias: ");

fflush(stdin);

scanf("%d",&aux.existencia);

printf("Costo unitario: ");

fflush(stdin);

scanf("%lf",&aux.costo_unitario);

return aux;

}

Función para imprimir un arreglo de estructuras

void Imprimir(Item vector[], int tam)

{

int i;

for(i=0;i<tam;i++)

{

printf("Material: %s\n",vector[i].material);

printf("Existencias: %d\n",vector[i].existencia);

printf("Costo unitario: %.2lf\n",vector[i].costo_unitario);

Page 19: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

}

}

int main()

{

Item stock[10] ;

Item stock2[3] = {

"tornillos" , 120 , .15 ,

"tuercas" , 200 , .09 ,

"arandelas" , 90 , .01

} ;

int i;

for(i=0;i<10;i++)

stock[i]=Leer();

Imprimir(stock2,3);

}

Vemos que en el main al llamar a la función Leer(), se le asignó el valor retornado a

cada elemento del arreglo, a cada stock[i].

Y al llamar a la función Imprimir, se le pasa como parámetro, el nombre del arreglo de

estructuras.

Función que retorna un puntero

Cuando una función retorna un puntero a un objeto, el objeto debe persistir después

de finalizar la función.

Page 20: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

/**************** Operaciones con complejos ****************/

#include <stdio.h>

#include <stdlib.h>

typedef struct

{

float real;

float imag;

} tcomplejo;

tcomplejo *SumarComplejos(tcomplejo c1, tcomplejo c2);

int main( )

{

tcomplejo ca, cb, *pcr;

printf("\nIntroducir datos de la forma: x yi\n");

printf("ca = ");

scanf("%f %f", &ca.real,&ca.imag); fflush(stdin);

printf("cb = ");

scanf("%f %f", &cb.real,&cb.imag); fflush(stdin);

pcr = SumarComplejos(ca, cb);

printf("Resultado: %g%+gi\n", pcr->real, pcr->imag);

}

tcomplejo *SumarComplejos(tcomplejo c1, tcomplejo c2)

{

Page 21: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

tcomplejo cx;

cx.real = c1.real + c2.real;

cx.imag = c1.imag + c2.imag;

return &cx;

}

El programa anterior presenta resultados inesperados. La función SumarComplejos,

utiliza un complejo local cx del cual retorna su dirección. Cuando la función finalice el

complejo cx se destruirá automáticamente, con lo que el puntero pcr que apunta al

resultado, estará apuntando a un objeto inexistente.

La solución radica en hacer que la función SumarComplejos cree un objeto que

persista a lo largo de la ejecución del programa, asignando memoria dinámicamente

para el objeto.

/**************** Operaciones con complejos ****************/

#include <stdio.h>

#include <stdlib.h>

typedef struct

{

float real;

float imag;

} tcomplejo;

tcomplejo *SumarComplejos(tcomplejo c1, tcomplejo c2);

int main( )

{

Page 22: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

tcomplejo ca, cb, *pcr;

printf("\nIntroducir datos de la forma: x yi\n");

printf("ca = ");

scanf("%f %f", &ca.real,&ca.imag); fflush(stdin);

printf("cb = ");

scanf("%f %f", &cb.real,&cb.imag); fflush(stdin);

pcr = SumarComplejos(ca, cb);

printf("Resultado: %g%+gi\n", pcr->real, pcr->imag);

/* Liberar la memoria asignada */

free(pcr);

}

tcomplejo *SumarComplejos(tcomplejo c1, tcomplejo c2)

{

tcomplejo *pcx;

/* Asignar memoria para el complejo suma */

pcx = (tcomplejo *)malloc(sizeof(tcomplejo));

if ( pcx == NULL )

{

printf("Memoria insuficiente\n");

exit(-1);

}

pcx->real = c1.real + c2.real;

Page 23: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

pcx->imag = c1.imag + c2.imag;

return pcx;

}

Funciones recursivas

Las funciones en C pueden ser recursivas, en otras palabras, pueden llamarse a sí

mismas directa o indirectamente. La recursividad directa es el proceso mediante el que

una función se llama a sí misma desde el propio cuerpo de la función, mientras que la

recursividad indirecta implica más de una función.

Un proceso recursivo tiene que tener una condición de finalización, ya que de lo

contrario podría continuar infinitamente.

Un ejemplo típico de aplicación de la recursividad es el cálculo del factorial de un

número entero. Recordemos que el factorial de un número entero (n!) se calcula de la

siguiente manera:

n! = n * (n-1) * (n-2) * ... * 2 * 1

En principio, la solución a este problema podría realizarse sin tener que utilizar la

recursividad con el siguiente programa:

#include <stdio.h>

int factorial(int numero);

main()

{

int valor = 4;

int resultado;

resultado = factorial(valor);

printf("El factorial de %d es %d \n", valor, resultado);

Page 24: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

return 0;

}

int factorial(int numero)

{

int i;

int devuelve = 1;

for(i = 1; i <= numero; i++)

{

devuelve = devuelve * i;

}

return devuelve;

}

Sin embargo, resulta más intuitivo dada la definición de número factorial utilizar una

función recursiva como la siguiente:

int factorial(int numero)

{

if(numero == 1)

return 1;

else

return (numero * factorial(numero-1));

}

Page 25: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

En la función anterior, en el caso de que el argumento utilizado en la llamada sea 1,

ésta devuelve 1, y en caso contrario se calcula un producto que involucra a la variable

numero y una nueva llamada a la función cuyo argumento es menor en una unidad

(numero -1). El funcionamiento de una función recursiva se realiza almacenando las

llamadas pendientes, con sus argumentos, en la pila en tiempo de ejecución.

Veamos un ejemplo:

imagina que utilizamos el valor 4 como argumento de la función que calcula el

factorial, es decir, factorial(4), el proceso de llamadas será el siguiente:

Llamada # 1:

numero = 4

numero != 1 entonces ejecutamos la siguiente sentencia

return ( 4 * (realizamos la segunda llamada))

Llamada # 2:

numero = 3

numero != 1 entonces ejecutamos la siguiente sentencia

return ( 3 * (realizamos la tercera llamada))

Llamada # 3:

numero = 2

numero != 1 entonces ejecutamos la siguiente sentencia

return ( 2 * (realizamos la cuarta llamada))

Llamada # 4:

numero = 1

numero == 1 entonces se ejecuta la sentencia del if:

Page 26: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

return 1

Fin Llamada # 4 -> DEVUELVE 1

return ( 2 * 1)

Fin Llamada # 3 -> DEVUELVE 2

return ( 3 * 2)

Fin Llamada # 2 -> DEVUELVE 6

return ( 4 * 6)

Fin Llamada #1 -> DEVUELVE 24

En la Figura siguiente podemos ver ilustrado el proceso descrito anteriormente.

Page 27: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

En muchas ocasiones, la resolución de un problema mediante una función recursiva

resulta conceptualmente más clara que la resolución mediante una función iterativa.

Tal es el caso de algunas estructuras de datos como los árboles binarios, cuyo manejo

es sencillo mediante una función recursiva. Sin embargo, la función iterativa resulta

algo más compleja. Es evidente que hay tareas que se pueden resolver mediante

funciones recursivas o funciones iterativas, aunque es el programador el que tiene que

optar por una solución u otra.

Page 28: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

Funciones predefinidas en c

Funciones matemáticas

Las declaraciones para estas funciones están en el fichero math.h

Los argumentos y el resultado son de tipo double.

En muchos casos utilizaremos conversión cast para convertir explícitamente los

argumentos al tipo deseado. Ejemplo:

a = tan((double)valor);

Las funciones matemáticas se clasifican en:

– Funciones trigonométricas

– Funciones hiperbólicas.

– Funciones exponencial y logarítimica.

– Funciones varias.

• cos

Resultado: el coseno de x ( x en radianes).

#include <math.h>

double cos(double x);

• sin

Resultado: seno de x ( x en radianes).

#include <math.h>

double sin(double x);

• tan:

Resultado: tangente de x ( x en radianes).

Page 29: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

#include <math.h>

double tan(double x);

• exp

Da como resultado el valor de ex ( e = 2.718282)

#include <math.h>

double exp(double x);

• log

Da como resultado el logaritmo natural de x .

#include <math.h>

double log(double x);

• log10

Da como resultado el logaritmo en base 10 de x .

#include <math.h>

double log10(double x);

• ceil

Resultado: un valor double, que representa el entero

más pequeño que es mayor o igual que x.

#include <math.h>

double ceil(double x);

double x = 2.8, y = -2.8;

printf(“%g %g\n”,ceil(x),ceil(y));

• fabs

Page 30: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

Calcula el valor absoluto de x( siendo x un valor real en doble precisión). Las

funciones abs y labs calculan el valor absoluto de un int y un long respectivamente.

#include <math.h>

double fabs(double x);

• floor

Resultado: un valor double, que representa el entero más grande que es menor o

igual que x.

double floor(double x);

double x = 2.8, y = -2.8;

printf(“%g %g\n”,floor(x),floor(y));

• pow

Resultado: xy. Si x es 0 e y es negativo o si x e y son 0 o si x es negativo e y no es

entero, se obtiene un error(argumento fuera del dominio da la función). Si xy da un

resultado superior al valor límite para el tipo double, el resultado es el valor

límite(1.79769e+308)

double pow(double x);

double x = 2.8, y = -2.8;

printf(“%g\n”,pow(x,y));

• sqrt

Calcula la raíz cuadrada de x. Si x es negativo, ocurre un error(argumento fuera del

dominio de la función).

#include <math.h>

double sqrt(double x);

Números seudoaleatorios

Page 31: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

• rand

Da como resultado un número seudoaleatorio entero, entre 0 y el valor máximo para

un int.

#include <stdlib.h>

int rand(void);

Funciones de fecha y hora

• time

Resultado: el número de segundos transcurridos desde las 0 horas del 1 de Enero de

1970.

#include <time.h>

time_t time(time_t *seg);

• ctime

Convierte un tiempo almacenado como un valor de tipo time_t, en una cadena de

caracteres de la forma:

Thu Jul 08 12:01:29 2010

#include <time.h>

char *ctime(const time_t *seg);

Devuelve un puntero a la cadena de caracteres resultante o un puntero nulo si seg

representa un dato anterior al 1 de Enero de 1970.

#include <stdio.h>

#include <time.h>

main( )

Page 32: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

{

time_t segundos;

printf("El numero de segundos transcurridos desde el 01/01/1970 es

%ld\n",time(&segundos));

printf("La fecha actual es %s",ctime(&segundos));

}

Conversión de cadenas

Existen unas cuantas funciones para convertir cadenas a enteros, enteros largos y

valores flotantes. Estas son:

double atof(const char *cadena) Convierte una cadena a un valor flotante.

int atoi(const char *cadena) Convierte una cadena a un valor entero.

int atol(const char *cadena) Convierte una cadena a un valor entero largo.

double strtod(const char *cadena, char **finap) Convierte una cadena a un valor de

punto flotante.

double strtol(const char *cadena, char *finap, int base) Convierte una cadena a un

entero largo de acuerdo a una base dada, la cual deberá estar entre 2 y 36 inclusive.

unsigned long strtoul(const char *cadena, char *finap, int base) Convierte una cadena

a un entero largo sin signo.

Varias de las funciones se pueden usar en forma directa, por ejemplo:

char *cad1 = "100";

char *cad2 = "55.444";

char *cad3 = " 1234";

char *cad4 = "123cuatro";

Page 33: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

char *cad5 = "invalido123";

char *cad6 = "123E23Hola";

char *cad7;

int i;

float f:

i = atoi(cad1); /* i = 100 */

f = atof(cad2); /* f = 55.44 */

i = atoi(cad3); /* i = 1234 */

i = atoi(cad4); /* i = 123 */

i = atoi(cad5); /* i = 0 */

f = strtod(cad6, &cad7); /* f=1.230000E+25 y cad7=hola*/

Nota:

Los caracteres en blanco son saltados.

Caracteres ilegales son ignorados.

Si la conversión no puede ser hecha se regresa cero y errno es puesta con el

valor ERANGE.

Funciones para manipular bloques de memoria

• memset

Permite iniciar un bloque de memoria.

#include <string.h>

void *memset(void *destino, int b, size_t nbytes);

destino: dirección del bloque de memoria que se desea inicializar.

Page 34: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

b: valor empleado para iniciar cada byte del bloque.

nbytes: número de bytes del bloque que se iniciará.

double a[10][10];

memset(a, 0, sizeof(a));

#include <stdio.h>

#include <string.h>

int main()

{

char c = 'F';

char *s;

int i;

s = (char*)malloc(5*sizeof(char));

memset( s, c, 5 );

for( i=0; i<5; i++ )

printf( "c[%d]=%c ", i, c );

printf( "\n" );

free(s);

return 0;

}

• memcpy

Copia un bloque de memoria en otro.

#include <string.h>

void *memcpy(void *destino, const void *origen, size_t nbytes);

destino: es la dirección del bloque de memoria destino de los datos.

origen: es la dirección del bloque de memoria origen de los datos.

nbytes: número de bytes que se copiarán desde el origen al destino.

double a[10][10], b[10][10];

memcpy(b, a, sizeof(a));

#include <stdio.h>

Page 35: Descomposición funcional (Parte II)void imprimir2(int *x) { int i; for (i=0; i

/* memcpy example */

#include <stdio.h>

#include <string.h>

int main ()

{

char str1[]="Cadena de ejempo";

char str2[40];

char str3[40];

memcpy (str2,str1,strlen(str1)+1);

memcpy (str3,"Copia exitosa!",16);

printf ("str1: %s\nstr2: %s\nstr3: %s\n",str1,str2,str3);

return 0;

}

• memcmp

Compara byte a byte dos bloques de memoria.

#include <string.h>

int memcmp(void *bm1, const void *bm2, size_t nbytes);

bm1, bm2: son las direcciones de los bloques de memoria a comparar .

nbytes: número de bytes que se compararán.

double a[10][10], b[10][10];

if(memcmp(a, b, sizeof(a)) == 0)

printf(“Las matrices contienen los mismos datos\n”);

else

printf(“Las matrices no contienen los mismos datos\n”);

#include <stdio.h>

#include <string.h>

int main()

{

char a[3] = { 82, 81, 84 };

char b[3] = { 85, 83, 86 };

int i;

for( i=0; i<3; i++ )

printf( "a[%d]=%c ", i, a[i] );

printf( "\n" );

for( i=0; i<3; i++ )