Funciones

Definición:

Una función en C, es un bloque de código que realiza una tarea definida. printf() es un ejemplo de función que realiza una impresión por la salida estándar de los parámetros que recibe. Las variables declaradas como parámetros, son locales a la función, esto quiere decir que cuando finaliza la función, las variables son destruidas.

Las funciones que escribamos deben limitarse a realizar una tarea sencilla y bien definida y el nombre que le pongamos debe clarificar que hace la función.

          tipo_devuelto nombre_función(lista de parámetros)
          {
                    cuerpo de la función
          }

tipo_devuelto           puede ser cualquier tipo válido de C. return es la sentencia encargada de devolver el tipo a la función que hace la llamada (ver sentencias de salto). Si no se pone nada, se asume que es de tipo entero. Si la función no retorna valor alguno, se pone void como valor de retorno, de esta manera podemos omitir la sentencia return dentro de cuerpo de la función.
Una función sólo puede devolver un valor, para lo que se utiliza la palabra reservada return

return expresión;

donde expresión puede ser cualquier tipo de dato excepto un array o una función.

nombre_función           La longitud puede variar entre 1 y varios caracteres, el primero debe de ser una letra o el símbolo de subrayado, los siguientes caracteres pueden ser letras, números o símbolos de subrayado. Las letras mayúsculas y minúsculas se tratan como caracteres diferentes. Un identificador no puede se igual a una palabra clave de C, y no debe tener el mismo nombre que una función ya escrita en la biblioteca de C.

lista de parámetros       Es la lista de variables separadas por comas  con sus tipos asociados, que recibe la función al ser llamada. Puede no tener parámetros, en cuyo caso decimos que la lista está vacía, podemos no poner nada o poner la palabra reservada void. Tenga o no lista de parámetros nuestra función, los paréntesis son necesarios.

Las llaves de apertura y cierre definen un bloque de sentencias. Cuerpo de la función.

Antes de poder utilizar una función, esta debe de ser declarada, normalmente al comienzo del archivo fuente. A la declaración de una función la llamamos prototipo de función.

Una función es visible para ella misma y otras funciones desde el momento en que se define. Es visible para el propio cuerpo de la función, es decir, la recursividad está permitida.

La variables definidas dentro de una función son locales por lo que no conservan su valor de una llamada a otra, salvo que sean declaradas como static, en cuyo caso, el compilador no las destruye y almacena  su valor para la próxima llamada.

Un ejemplo ayudará..
Vamos a sumar dos valores enteros, para ello declararemos una función llamada suma() que recibirá dos valores enteros y devolverá el resultado de sumarlos. La función main() se encargará de imprimir el resultado de la suma por pantalla.



En la línea 3 podemos ver la declaración de la función suma,  como se puede observar, en la declaración de la función no es necesario ponerle nombre a la variables parámetros, pero si su tipo.
int suma(int, int);

y a continuación
/*Declaración de la función suma*/
Esta es la forma de incluir comentarios. Un comentario es un texto que será ignorado por el compilador, y sirve para aclarar partes del código.

Dentro de main() se declaran dos variables de tipo int, valor1 y valor2. Se les asigna un valor y por último se llama a la función suma() desde dentro de la función printf(), como un parámetro de esta. Como se puede observar la función printf() cumple con la definición dada de una función.

  • El nombre comienza con una letra o con un símbolo de subrayado
  • Tiene una lista de parámetros, en este caso un texto y un valor entero. Si, el segundo parámetro es un valor entero, que es el valor devuelto por la función suma().
  • La declaración de la función printf() está en el archivo de cabecera stdio.h que es incluido por el preprocesador con la directiva #include<> al comienzo de nuestro archivo.

Paso por valor o por referencia.

Hay dos formas de pasar parámetros a una función, por valor o por referencia. El paso de parámetros por valor quiere decir que se pasa una copia, por lo que si se modifica dicho valor, no se verá reflejado en la función llamadora.

Ej 1.-

#include<stdio.h>

void no_hace_nada(int, int);

int main(void){

        int valor1 = 234;
        int valor2 = 39458;

        no_hace_nada(valor1, valor2);
        printf("Valor1 contiene: %d\nValor2 contiene: %d\n",valor1, valor2);
     
       return 0;

}

void no_hace_nada( int v1, int v2){
        v1++;
        v2++;
}


La función no_hace_nada() recibe copia de valor1 y valor2,  y los incrementa en uno dentro de ella. Sin embargo, cuando printf() imprime los valores de esas mismas variables, vemos que no han sido modificados

Valor1 contiene 234
Valor2 contiene 39458

Esto es por que se ha pasado una copia de los valores contenidos en las variable valor1 y valor2, y cualquier cosa que se haga con las copias no afecta a las variables originales. A esta forma se le llama paso por valor.


Ej 2.-

#include<stdio.h>

void _hace_algo(int *, int *);

int main(void){

        int valor1 = 234;
        int valor2 = 39458;

        _hace_algo(&valor1, &valor2);
        printf("Valor1 contiene: %d\nValor2 contiene: %d\n",valor1, valor2);
     
       return 0;

}

void _hace_algo( int *v1, int *v2){
        *v1 += 1;
        *v2 += 1;
}

El resultado de este otro ejemplo es:

Valor1 contiene 235
Valor2 contiene 39459

Como se puede observar, si se ha modificado el contenido de las variables valor1 y valor2, esto es por que hemos pasado las direcciones de memoria de cada una de las variables por lo que hemos operado directamente con ellas. A esto se le llama paso por referencia.