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.
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.
La forma en que las funciones devuelven un valor es empleando la sentencia return.
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.
En C99 se ha incluido una forma de utilizar funciones como si fueran macros, son las funciones inline.
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.
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 */ }