Descarga la aplicación para disfrutar aún más
Vista previa del material en texto
Funciones Funciones Los módulos en C se llaman funciones. Hemos estado utilizando funciones de la biblioteca estandar “stdio.h” como por ejemplo printf y scanf. Comenzaremos viendo algunas funciones de la biblioteca matemática y luego detallaremos la manera de definir funciones en C. En C, las funciones sólo reciben parámetros por valor. Funciones matemáticas (math.h) Función Descripción Ejemplo sqrt(x) Raíz cuadrada de x sqrt(900.0) es 30.0 exp(x) Función exponencial ex exp(1.0) es 2.718282 exp(2.0) es 7.389056 log(x) Logaritmo natural de x (base e) log(2.718282) es 1.0 log(7.389056) es 2.0 log10(x) Logaritmo de x base 10 log10(1.0) es 0.0 log10(10.0) es 1.0 Funciones matemáticas (math.h) Función Descripción Ejemplo fabs(x) Valor absoluto de x Si x>0, fabs(x) es x Si x=0, fabs(x) es 0 Si x<0, fabs(x) es -x ceil(x) Redondea x al entero menor que no sea inferior a x ceil(9.2) es 10.0 ceil(-9.8) es -9.0 floor(x) Redondea x al entero más grande no mayor que x floor(9.2) es 9.0 floor(-9.8) es -10.0 pow(x,y) x elevado a la potencia y (xy) pow(2,7) es 128.0 pow(9, 0.5) es 3.0 Funciones matemáticas (math.h) Función Descripción Ejemplo fmod(x) Residuo de x/y como un número de punto flotante fmod(13.657, 2.333) es 1.992 13.657 = 5*2.333+1.992 sin(x) Seno de x (x en radianes) sin(0.0) es 0.0 cos(x) Coseno de x (x en radianes) cos(0.0) es 1.0 tan(x) Tangente de x (x en radianes) tan(0.0) es 0.0 Funciones en C Sintaxis TipoValorRetornado NombreDeLaFuncion(parámetros) { declaraciones locales Instrucciones de la función } Ejemplo int Cuadrado ( int nro) { int resultado; resultado = nro * nro; return (resultado) ; } int Cuadrado ( int nro) { return (nro * nro) ; } Prototipo de la función Definición de la función Invocación Definición de una función También pudo haberse codificado así pero NO cumple con ANSI C Si se omite el tipo del valor a devolver se asumirá int Note que no lleva ; al cerrar el paréntesis int cuadrado(a) int a { return a*a } cuadrado(a) int a { return a*a } Cada parámetro debe ir precedido por el nombre del tipo. Si se omite se asume int Prototipo de la función Permite al compilador hacer validaciones referidas a los tipos, cantidad y orden de los parámetros y al tipo de valor retornado. También podíamos poner int cuadrado(int a) pero el compilador ignora los nombres de los parámetros. El prototipo de función se caracteriza por la coerción de argumentos ya que fuerza su conversión al tipo apropiado. Si el prototipo de la función se omite se tomará la primera invocación como prototipo. Esto puede llevar a errores. Coerción de Tipos Qué pasa si comentamos esta línea? y si cambiamos por %3d ? 02_FuncionCuadrado.c Retorno de la función Hay tres formas de regresar al punto desde el cual se hizo la invocación de la función: Si la función no retorna nada, el control sólo se devuelve cuando se llega a la llave derecha que termina la función. Cuando se ejecuta la instrucción return; Si la función devuelve un resultado, la instrucción return expresion; devuelve el valor de expresion al punto de llamada. Retorno de la función Qué devuelve? 02_RetornaFuncion.c Tipo void Void es un tipo de dato que representa que no hay valor. No cumple con el estándar. Se espera que la función main siempre retorne un entero Ejercicio Escriba una función que reciba tres números y retorne el valor mayor. Utilice la función anterior para desarrollar un programa que lea tres números enteros de teclado e indique cual fue el mayor valor ingresado. Puede utilizar la misma función para hallar el máximo de tres números sin importar si tienen decimales o no? Generación de números aleatorios La función rand() genera un número entero entre 0 y RAND_MAX con distribución uniforme. En ANSI C, el valor de RAND_MAX debe ser por lo menos 32767 (16 bits). Está definida en <stdio.h> Para acotar los valores posibles devueltos por la función rand() debe usarse la función módulo %. Ejemplos NumeroDelDado = 1 + rand() % 6 NroDeMes = 1 + rand() % 12 Ejemplo Escriba un programa C que simule tirar una moneda 7000 veces. Al finalizar debe informar cuantas veces salió cara y cuantas veces salió ceca. Ejecute varias veces el mismo programa y observe los resultados obtenidos. Cada vez que lo ejecuto imprime «Salieron 3521 caras y 3479 cecas» 02_LanzaMoneda.c Función srand La función rand genera números pseudoaleatorios. Para que la generación de números sea aleatoria debe usarse la función srand. La función srand tiene un argumento de tipo unsigned, llamado semilla y permite que en cada ejecución del programa la función rand genere una secuencia de números aleatorios diferentes. El tipo unsigned es equivalente a unsigned int y representa un entero sin signo. 02_LanzaMoneda1.c Un unsigned o unsigned int de dos bytes puede tener sólo valores positivos dentro del rango 0 hasta 65535. Un unsigned de 4 bytes puede tener sólo valores positivos entre 0 y 4294967295 02_LanzaMoneda1.c Dentro de scanf utilice "%u" para leer un unsigned. 02_LanzaMoneda1.c La función srand recibe la semilla indicada. Luego, la secuencia generada por la función rand cambiará cada vez que cambie la semilla (para la misma semilla la secuencia es la misma) 02_LanzaMoneda1.c Función time Para no tener que indicar el valor de la semilla en cada ejecución puede utilizarse la función time de la siguiente forma srand(time(NULL)) La función time devuelve la hora actual del día en segundos. Ese valor es convertido a un unsigned y utilizado como semilla. El argumento NULL hace que la función no devuelva ningún valor a través de la lista de parámetros. La función time está definida en <time.h> 02_LanzaMoneda2.c Clases de almacenamiento La clase de almacenamiento de un identificador permite determinar su duración de almacenamiento, su alcance y su enlace. Duración: un identificador puede existir durante todo el programa, sólo en algunos entornos o ser creado reiteradamente, El alcance de un identificador indica donde puede ser referenciado. El enlace de un identificador determina, cuando el programa está formado por varios archivos, si el identificador es conocido en un único archivo fuente o en cualquiera de ellos. Clases de almacenamiento Los cuatro especificadores se dividen en Persistencia automática (auto y register) Estos identificadores se aplican a variables. Se crean al comenzar el bloque donde están definidas y se destruyen al salir del bloque. Es una forma de ahorrar memoria. Persistencia estática (static y extern) Estos identificadores se aplican a variables y nombres de función. Existen desde el momento en que se inicia la ejecución del programa. Por ahora sólo aplicaremos el especificador static a variables. Sólo las variables tienen persistencia automática. La palabra auto declara de forma explícita las variables de persistencia automática. Por omisión, las variables locales tienen persistencia automática por lo que la palabra auto rara vez se utiliza. La palabra register puede ser utilizada sólo con variables automáticas. Esta declaración sugiere que se coloque la variable entera indice en uno de los registros de la computadora. El compilador puede ignorar declaraciones register (por ejemplo, quizás no exista un número suficiente de registros). Eltener variables directamente almacenadas en los registros elimina la sobrecarga de su traslado de memoria a los registros y el posterior almacenamiento de los resultados en memoria. Esta variable es local al for es decir que sólo existe cuando el for se está ejecutando. La variable automática MuyDinamica se crea al comienzo de la iteración y se destruye cuando el control llega a la llave que cierra el bloque. Cada vez que se crea, esta declaración dice que se inicializa en cero. Qué imprime? Variables.c Persistencia estática Existen dos tipos de identificadores con persistencia estática Los identificadores externos (variables globales y nombres de función). Estos identificadores, por omisión, pertenecen a la clase de almacenamiento extern. Las variables globales y las funciones pueden ser referenciadas por cualquier función luego de su declaración. Las variables locales declaradas con el especificador de clase de almacenamiento static. Son aun conocidas sólo dentro del bloque donde fueron definidas pero conservan su valor cuando éste termina. La próxima vez que se ejecute el bloque, la variable local static contendrá el valor que tenía cuando el bloque terminó por última vez. Variable global conocida en todo el programa. Se inicializa en cero automáticamente (por ser global) Variable global sólo conocida por las funciones que están definida debajo. Se inicializa en cero automáticamente (por ser global) Variable automática. También se pudo haber declarado como: auto int indice Son las variables habituales. Variable estática. Se inicializa sólo la primera y luego estará disponible con su valor anterior en las sucesivas llamadas de la función. Qué imprime? Variables1.c Qué imprime? Variables2.c Recursión Al igual que Pascal, C soporta la definición de funciones recursivas. Recuerde que el objetivo de este tipo de funciones es reducir la complejidad del problema. Se utiliza un caso base no recursivo y en cada llamada se busca reducir el tamaño de la entrada de manera de cercarse a dicho caso base. Las soluciones recursivas si bien facilitan la escritura de la solución ocupan más memoria que las soluciones iterativas. Ejercicio Escriba una función en C que dado un número entero retorne un unsigned con dicho número representado en binario. Ej: Recibe el número 27 y devuelve el número 11011 Use la función anterior para imprimir la conversión a binario de los múltiplos de 9 menores a 127. Utilice una función iterativa Utilice una función recursiva Analice las soluciones propuestas
Compartir