Funciones:
Una función es un conjunto de instrucciones relacionadas entre sí y que implementan una funcionalidad concreta y autocontenida.
Las funciones constan de:
- Un prototipo, que es opcional.
- Una definición o implementación.
El prototipo sólo es necesario si la función se utiliza, es decir, se llama, antes de ser definida. Consiste en el nombre de la función, su valor de retorno y sus parámetros. Los parámetros se suelen documentar con tipo y nombre, aunque para el prototipo es suficiente con el tipo.
Un ejemplo de prototipo de función sería así:

Y luego está la definición o implementación de la función, que es la función propiamente dicha. La definición consta de nombre, valor de retorno, parámetros (tipo y nombre), y cuerpo, que constará de un conjunto de instrucciones.
No todos estos elementos son obligatorios. En realidad, sólo el nombre lo es. El retorno, los parámetros, e incluso el cuerpo son opcionales (aunque no tiene mucho sentido una función vacía, es posible hacerla).
Un ejemplo de implementación de función sería así:

No es lo mismo el tipo void, que significa que no hay parámetros o retorno, que no poner tipo, en cuyo caso se sobreentiende que es int. No se considera buena práctica apoyarse en estos tipos implícitos.
Lógicamente, la implementación tiene que concordar con el prototipo, en el sentido de usar el mismo nombre de función y los mismos tipos de parámetros y retorno. Si no fuera así, el compilador se quejaría.
La comunicación entre la función llamante y la función llamada es mediante los parámetros y el retorno. Al llamar, los parámetros se convierten en variables locales a la función, a las que se copia el valor de los parámetros (paso por valor, con la excepción de los arrays y las cadenas que se pasan por referencia o puntero).
La comunicación en sentido contrario es mediante el retorno, que se produce cuando la función ejecuta la instrucción return. La función llamante puede usar ese retorno o prescindir de él.

Variables externas:
Las variables externas ya las hemos introducido en alguna entrada anterior. Son variables que no se definen dentro de una función y, por tanto, son globales al programa. En principio, son visibles en todas las funciones del programa, salvo que se declaren como static, en cuyo caso sólo se ven desde el fichero en que están declaradas.
Las funciones son, en cierto modo, siempre externas, ya que C no permite definir funciones dentro de otras funciones.
Otra variante del main() anterior usando una variable externa sería así:

Como se puede observar, la variable externa o global a es visible desde main().
Por tanto, otra forma de comunicación entre un programa o función llamante y una función llamada es mediante las variables externas que, al ser globales al programa, son visibles desde todas las funciones (en principio).
Estructura de un programa en C:
Las funciones son la abstracción principal de un programa en C. Permiten dividir un problema complejo en varios problemas más sencillos, reutilizar código y crear niveles de abstracción.
Por tanto, un programa en C básicamente consiste en un conjunto de variables externas y funciones que se organizan en uno o varios ficheros, que se compilan por separado.
Una de esas funciones debe ser la función main(), que es donde empieza la ejecución del programa.
Código de ejemplo: funciones