Logo DIE

Funciones

Unidad de Apoyo para el Aprendizaje

Iniciar

Introducción


Un programa en lenguaje C consiste en una o más funciones. C permite tener dentro de un archivo fuente varias funciones; esto con el fin de dividir las tareas y que sea más fácil la depuración, la mejora y el entendimiento del código.

En lenguaje C la función principal se llama main. Cuando se ordena la ejecución del programa se inicia con la ejecución de las instrucciones que se encuentran dentro de la función main, y ésta puede llamar a ejecutar otras funciones, que a su vez pueden llamar a ejecutar otras funciones, y así sucesivamente.



Elaborar programas en C, en donde la solución del problema se divida en funciones, se distinga el prototipo o firma de una función y su implementación, y se manipulen los parámetros en la función principal, como en funciones adicionales creadas por el programador.

Funciones




Esquema



Una función es un “segmento” o “fracción” de programa que realiza determinadas tareas bien definidas. Esos “fragmentos” de programa son lo que se suele llamar “subrutinas”, “procedimientos” o “funciones”.

En el lenguaje C, el nombre que más se usa es el de funciones.



Hay dos tipos de funciones: las funciones propias de bibliotecas de C y las definidas por el programador.

Se pueden subordinar funciones adicionales a main, y posiblemente unas a otras. Si un programa contiene varias funciones, sus definiciones pueden aparecer en cualquier orden, pero deben ser independientes unas de otras; esto es, una definición de una función no puede estar incluida en otra.

Cuando se accede a una función desde alguna determinada parte del programa (cuando se «llama» a una función), se ejecutan las instrucciones de que consta. Se puede acceder a una misma función desde varios lugares distintos del programa. Una vez que se ha completado la ejecución de una función, se devuelve el control al punto desde el que se accedió a ella.

Generalmente, una función procesará la información que le es pasada desde el punto del programa en donde se accede a ella y devolverá un solo valor.

La información se le pasa a la función mediante identificadores especiales llamados argumentos (también denominados parámetros) y es devuelta por medio de la instrucción return; sin embargo, algunas funciones aceptan información, pero no devuelven nada (por ejemplo, la función de biblioteca printf).

La definición de una función tiene dos componentes principales:

La primera línea (incluyendo las declaraciones de los argumentos) y el cuerpo de la función.

La sintaxis básica para definir una función es la siguiente:

tipoRetorno nombre (parámetros){
     // bloque de código de la función
}

El nombre de la función se refiere al identificador con el cual se llamará o mandará a ejecutar la función; se debe seguir la notación CamelCase.

Los parámetros de entrada se deben definir dentro de los paréntesis de la función, separados por comas e indicando su tipo de dato, de la siguiente forma:

(tipoDato nom1, tipoDato nom2, tipoDato nom3…)

El tipo de dato puede ser cualquiera (entero, real, carácter o arreglo) y el nombre debe seguir la notación CamelCase. Los parámetros de una función son opcionales.

El tipo de retorno de una función indica el tipo de dato que va a regresar la función al terminar el bloque de código de la misma. El valor de retorno puede ser cualquiera de los tipos de datos vistos hasta el momento (entero, real, carácter o arreglo), aunque también se puede regresar el elemento vacío (void) lo cual equivale a “no devolver nada”.

El bloque de código de la función es una instrucción compuesta que define las acciones que debe realizar ésta. Se suele llamar a esta instrucción compuesta cuerpo de la función. Como cualquier otra instrucción compuesta, puede contener instrucciones de expresión, otras instrucciones compuestas, instrucciones de control, etc. Una función puede acceder a otras funciones. De hecho, puede acceder a sí misma (este proceso se conoce como recursividad).

Además, en el cuerpo de la función se debe incluir una o más instrucciones return para devolver un valor al punto de llamada. La instrucción return se puede escribir de la siguiente forma:

return expresión;

Se devuelve el valor de expresión al punto de llamada.

La expresión es opcional. Si se omite la expresión, la instrucción return simplemente devuelve el control al punto del programa desde donde se llamó a la función, sin ninguna transferencia de información.

Ejemplo

Esquema



La función se llamaría desde el cuerpo de nuestro programa así

Esquema

Ejemplo (cuando la función devuelve valores):

Esquema



En los ejemplos anteriores, la función definida por el programador siempre ha precedido a main. De este modo, al compilar el programa, la función definida por el programador estaría definida antes del primer acceso a la función.

Sin embargo, muchos programadores prefieren que main esté antes de la definición de función. En tales situaciones el acceso a la función (dentro de main) precedería la definición de la función.

Esto puede confundir al compilador, a menos que se alerte primero al compilador del hecho de que la función a acceder se definirá más adelante en el programa. Para esta finalidad se utilizan los prototipos de funciones.

El compilador C revisa que las funciones estén definidas o declaradas antes de ser invocadas. Por lo que una buena práctica es declarar todas las funciones al inicio del programa. Una declaración, prototipo o firma de una función tiene la siguiente sintaxis:

tipoRetorno nombre (parámetros);

La firma de una función está compuesta por tres elementos:

Esquema



Los nombres de los parámetros no necesariamente deben ser iguales a los que se encuentran en la definición de la función. Las funciones definidas en el programa no necesariamente deberán ser declaradas; esto dependerá de su ubicación en el código.

Código (funciones)

Esquema


Nota: strlen es una función que recibe como parámetro un arreglo de caracteres y regresa como valor de retorno un entero que indica la longitud de la cadena. La función se encuentra dentro de la biblioteca string.h; por eso se incluye ésta al principio del programa.





Ámbito o alcance de las variables


Hay dos formas diferentes de caracterizar variables:



Esquema


En C existen dos tipos de variables con base en el lugar en donde se declaren:

Variables locales

Variables globales

Las variables locales se declaran siempre dentro de una función y son locales a la función donde han sido declaradas, es decir, su ámbito está confinado a esa función. Las variables locales definidas en funciones diferentes serán independientes unas de otras, incluso si tienen el mismo nombre. Cualquier variable declarada dentro de una función se interpreta como una variable local. Esto incluye la declaración de argumentos o parámetros.

void sumar() {
      int x;
      // ámbito de la variable x
}

Se pueden asignar valores iniciales a las variables o asignarse valores en cualquier parte de la función. Tales valores se reasignarán cada vez que se entre en la función. Si una variable local no es inicializada de alguna manera, su valor inicial será impredecible y probablemente incomprensible.

Una variable local no mantiene su valor cuando se transfiere el control fuera de la función en que está definida; por lo tanto, cualquier valor asignado a una variable local dentro de una función se perderá una vez que se sale de la función. Si la lógica del programa requiere que un valor particular sea asignado a una variable local cada vez que se ejecuta la función, ese valor tendrá que reasignarse cada vez que se entre en la función (siempre que se acceda a la función).

Iniciar

int cuadrado(int n){
       int cuadrado = n * n;
      return cuadrado;
}

maximo(int x, int y){
      int z;
      z = (x >= y) ? x : y;
      printf("\n\nValor máximo; %d", z);
      return;
}

Las variables globales, en contraste con las variables locales, no están confinadas a funciones simples. Su ámbito se extiende desde el punto de definición hasta el resto del programa; por lo tanto, generalmente abarcan dos o más funciones y frecuentemente todo el programa. Las variables globales existen durante toda la ejecución del programa y pueden ser utilizadas por cualquier función.

#include <stdio.h>
int resultado;
void multiplicar() {
      resultado = 5 * 4;
}

Como estas variables se reconocen globalmente, se puede acceder a las mismas desde cualquier función que se encuentre dentro de su ámbito. Mantienen los valores asignados dentro de este ámbito; por lo tanto, a una variable global se le puede asignar un valor dentro de una función, y este valor puede usarse (al acceder a la variable global) dentro de otra función.

Código (ámbito de las variables)

Esquema

Variables estáticas


Las variables estáticas se definen dentro de funciones individuales y tienen, por lo tanto, el mismo ámbito que las variables locales; esto es, son locales a la función en que están definidas; sin embargo, a diferencia de las variables locales, las variables estáticas retienen sus valores durante toda la vida del programa.

Como consecuencia, si se sale de una función y posteriormente se vuelve a entrar, las variables estáticas definidas dentro de esa función retendrán sus valores previos. Esta característica permite a las funciones mantener información permanente a lo largo de toda la ejecución del programa.

Las variables estáticas se definen dentro de una función, de la misma forma que las variables locales, excepto que la declaración de variables tiene que empezar con la designación del tipo de almacenamiento static.

static tipoDato nombre;

Las variables estáticas se pueden utilizar dentro de una función, de la misma manera que las otras variables; sin embargo, no se puede acceder a ellas fuera de la función en que están definidas.

Código (variables estáticas)

Esquema



Una vez declarada una variable estática, ésta permanece en memoria a lo largo de la ejecución del programa; por lo tanto, la segunda vez que se llama a la función ya no se vuelve a crear la variable, sino que se utiliza la que está en la memoria y por eso conserva su valor.

Argumentos para la función main


La función main también puede recibir parámetros. Debido a que la función main es la primera que se ejecuta en un programa, los parámetros de la función hay que enviarlos al ejecutar el programa. La firma completa de la función main es…

int main (int argc, char ** argv);

La función main puede recibir como parámetro de entrada un arreglo de cadenas al ejecutar el programa. La longitud del arreglo se guarda en el primer parámetro (argument counter) y el arreglo de cadenas se guarda en el segundo parámetro (argument vector).

Para enviar parámetros, el programa se debe ejecutar de la siguiente manera:

Esquema



Esto es, el nombre del programa seguido de los argumentos de entrada. Estos argumentos son leídos como cadenas de caracteres dentro del argument vector, en donde en la posición 0 se encuentra el nombre del programa, en la posición 1 el primer argumento, en la posición 2 el segundo argumento y así sucesivamente.

Código (argumentos función main)

Esquema
ícono

Actividad 1. Tabulando funciones

Ahora que ya sabes cómo usar funciones en C, vamos a usarlas para tabular funciones matemáticas.

Realizarás un programa que tabule el siguiente polinomio:

y = 5x3 + 4x2 + 3x + 2

Dándole valores a x desde 1 a 10.



ícono

Actividad 2. Raíces de ecuación de segundo grado

Vamos a calcular las raíces de una ecuación de segundo grado, utilizando la formula general.

Esquema

En esta ocasión utilizaremos funciones para realizar tareas como calcular el discriminante, imprimir la ecuación, etc. y así poder indicar qué tipo de raíces son (reales diferentes, reales repetidas o complejas), además de calcularlas e imprimirlas.



ícono

Autoevaluación. Bibliotecas y prototipos en lenguaje C

La modularidad permite separar en unidades funcionalmente independientes, lo que hace más legible y entendible un código y permite la reutilización de software.


Fuentes de información

Solano, J., García, E., Sandoval, L., Nakayama, A., Arteaga, I. y Castañeda, M. (2016). Manual de prácticas del laboratorio de Fundamentos de programación. Facultad de Ingeniería. Consultado de http://lcp02.fi-b.unam.mx



Cómo citar


Arteaga, T. I. y Nakayama, M. A. (2018). Funciones. Unidades de Apoyo para el Aprendizaje. CUAED/Facultad de Ingeniería-UNAM. Consultado el (fecha) de (vínculo)