Definición de funciones y procedimientos

Sintaxis

tipo_devuelto nombre_función(tipo1 param1,tipo2 param2, ...){
   ...
}

Las funciones se definen indicando primero qué tipo de valor devuelven, después el nombre de la función y a continuación los parámetros que acepta encerrados entre paréntesis y separados por comas.

En C no existen procedimientos, sólo existen funciones. Una función es equivalente a un procedimiento cuando el tipo que devuelve es void. Se puede despreciar el valor resultante de cualquier expresión lo que permite que se pueda ignorar el valor devuelto por una función.
Las definiciones de funciones no pueden anidarse; no es posible definir una función local a otra.
Una función puede llamarse a sí misma o a cualquier otra.

Paso de parámetros a una función

Los parámetros en C se pasan siempre por valor, es decir, se produce una copia del valor pasado al parámetro formal de la función, el cual no actúa sino como una variable local a la función pero con una inicialización externa.
Más información en parámetros de entrada/salida.

Sentencia return

La forma en que las funciones devuelven un valor es empleando la sentencia return.

Funciones sin parámetros

Una función sin parámetros se establece poniendo como único parámetro void. Por compatibilidad, si se define una función sin establecer parámetros, ni siquiera void, indica que acepta cualquier número de parámetros.

Funciones inline

En C99 se ha incluido una forma de utilizar funciones como si fueran macros, son las funciones inline.

Paso de vectores como parámetros

En C no está permitido pasar por valor a una función parámetros que sean vectores, o funciones, si bien se pueden pasar punteros a éstos. El nombre de un vector, cuando se escribe sin subíndice, se interpreta como un puntero al primer elemento del vector.

La definición de funciones que aceptan como parámetros punteros a vectores tiene una sintaxis variada que se puede prestar a confusión para los neófitos. En C, como no se pueden pasar vectores como parámetros se pasa un puntero a éstos (en realidad un puntero al primer elemento) y esto es lo que siempre ocurre. En la definición del paso de parámetros de un vector puede aparecer int v[20], que al no existir chequeo de rangos, puede ser de cualquier tamaño, el 20 no es sino una cifra informativa, incluso se puede sustituir la definición por int v[]. Además, por la relación existente entre vectores y punteros, también se puede definir como int *v.

 

 

Ejemplo

En el ejemplo siguiente se muestra tres funciones: max, min y media que aunque tienen aparentemente parámetros distintos son totalmente equivalentes pudiendo recibir vectores de cualquier tamaño. Este es el motivo del segundo parámetro entero que informa a la función de su tamaño real.

#include <stdio.h>
int max(int v[20], int n){ /* Función con parámetros */
   int max=v[0], i;
   for( i=1; i<n; i++) max=max<v[i]?v[i]:max;
   return max;
}
int min(int v[], int n){ /* Función con parámetros */
   int min=v[0], i;
   for( i=1; i<n; i++) min=min>v[i]?v[i]:min;
   return min;
}
int media(int *v, int n){ /* Función con parámetros */
   int suma=0, i;
   for( i=0; i<n; i++) suma+=v[i];
   return suma/n;
}
void usa(void){   /* Procedimiento que no acepta parámetros */
   int i, j, v1[10], v2[30];
   for(i=0;i<10;i++) 
      scanf("%d",&v1[i]);
   for(j=0;j<30;j++)
      scanf("%d",&v2[j]);
   printf("Máximo de v1 = %i\n",max(v1,10));
   printf("Mínimo de v1 = %i\n",min(v1,10));
   printf("Media de v1 = %i\n",media(v1,10));
   printf("Máximo de v2 = %i\n",max(v2,30));
   printf("Mínimo de v2 = %i\n",min(v2,30));
   printf("Media de v2 = %i\n",media(v2,30));
   /* return implícito */
}