Declaración y definición

El concepto función correspondiente a un subprograma que devuelve un resultado es, a C, equivalente a una función que devuelve un dato. El concepto de acción correspondiente a un subprograma que no devuelve ningún resultado es en C, equivalente a una función que devuelve void.

El tipo void se utiliza entre otras situaciones para:

  • Indicar que una función no acepta argumentos:
int funcion (void)
  • Declarar funciones que no devuelven ningún valor:
void funcion (int, char) 

 Declaración de funciones

La declaración de una función, también llamada prototipo de la función, indica cuántos argumentos tiene la función y de qué tipo son, y el tipo del valor devuelto.

<tipo_retornado> <nombre_función> ([<lista_argumentos>]);

El prototipo de una función es una plantilla que utiliza el compilador para comprobar que cualquier llamada a la función es correcta, es decir, que los parámetros actuales son adecuados a los argumentos y el valor devuelto se trata correctamente.

Ejemplos:

void leer_SN_1 (int, int, char *);
char leer_SN_2 (int, int);

La declaración de una función da características de la función, pero no define el proceso que hace. La definición de una función contiene la declaración de las variables locales y del código correspondiente.

La declaración es explícita cuando el compilador detecta el prototipo de la función o su definición antes de detectar ninguna llamada. La declaración es implícita cuando se detecta alguna llamada antes de encontrarse la declaración o definición. En este último caso, el compilador de C construye un prototipo por defecto, el cual consiste en una función que siempre devuelve un resultado int y que tiene por lista de argumentos la construida a partir de los tipos de parámetros actuales especificados en la llamada de la función. Esto obliga a que el tipo de resultado en la definición de la función sea int.

Definición de funciones

La definición de una función consta de una cabecera de función, similar a un prototipo pero con la obligatoriedad de incluir los identificadores de la lista de argumentos, y el cuerpo de la función.

<tipo_retornado> <nombre_función> ([<lista_argumentos>]) {
   [declaraciones de variables locales];
   /* sentencias; */
   [return [(]expresión[)];
}

Los parámetros formales o argumentos consisten en una lista de identificadores con sus tipos, separados por comas.

char leer_SN_2 (int hilo, int col) {
   char c;
   int n;
   n = 0;
   do {
      n = n + scanf("%c", &c);
   } while (n < hilocol || c !='.');
   return c;
}

Llamamiento de funciones

Para ejecutar una función es necesario llamarla. La llamada a una función consta del nombre de ésta y de la lista de parámetros actuales cerrados entre paréntesis y separados por comas. Así por ejemplo:

...
char opc
...
opc = leer_SN_2(2,2);
printf("Ha dicho %c\n",opc);
...

En C una función puede llamarse sin formar parte de ninguna expresión, si devuelve un valor y la llamada no forma parte de una expresión, el resultado de la función se pierde.

Accesibilidad de variables

Variables globales y locales

Una variable declarada dentro del cuerpo de una función es local y no son globales en ninguna de las funciones llamadas desde la función en la que están declaradas. Si una función necesita unas variables de la función que la llamada se le tendrán que transferir como parámetros. Mirando ahora el lenguaje C, el programa main no deja de ser otra función, por tanto todas las variables declaradas dentro del su cuerpo son locales. Esto no es lo que ocurre con muchos lenguajes de programación ni lo que se supone en el seudocódigo.

El ámbito de accesibilidad de una función puede estar limitado a un blog, a un archivo, a una función o a una declaración de una función.

Una variable es declarada en ámbito externo cuando se declara fuera de cualquier blog en un programa; en principio se puede acceder desde el punto de la declaración hasta el final del archivo fuente donde ha sido declarada.

En lenguaje C se entiende blog como cualquier conjunto de código limitado por las claves.

Una variable es declarada en ámbito interno cuando la declaración se efectúa dentro de un blog; en principio se accede dentro del blog y dentro de todos los blogs contenidos en el mismo por debajo del punto de declaración.

Las variables definidas en un blog deben estar situadas necesariamente al inicio del blog.

Los argumentos declarados en la declaración de una función o prototipo existen únicamente en la propia declaración, esto hace que los identificadores de los argumentos puedan obviarse.

Los argumentos declarados en la definición de la función son internos en la función al igual que las variables declaradas en el inicio del cuerpo de la función.

Clases de almacenamiento: auto, register, static y externo

Las variables llevan asociado un tipo de almacenamiento que determina su accesibilidad y la existencia. Estos conceptos tanto para las variables como para las funciones pueden alterarse con unos calificadores que se utilizan ante la definición de la variable o función.

  • auto y register utilizadas únicamente con variables locales.
  • externo utilizable con variables globales y funciones
  • static utilizable con variables locales, globales y funciones.

Variables declaradas como auto

Cómo lo asigna por defecto el compilador cuando encuentra variables locales. Una variable definida como auto sólo es visible en el bloque donde está definida. Las variables auto no son inicializadas automáticamente.

Variables declaradas como static

Una variable static es inicializada una sola vez cuando comienza la ejecución del programa. C inicializa la variable si es numérica a cero y '\0' si es carácter. Una variable static sólo es visible dentro del bloque si se trata de una variable interna o dentro del archivo fuente si se trata de una variable externa. El valor de una variable static (en caso de que sea interna) es permanente en lugar de aparecer y desaparecer en el inicio y final de la ejecución del blog que la contiene.

En caso de que sea externa una variable static permite tener declaradas otras variables static con el mismo nombre en otros archivos fuente correspondientes al mismo programa.

Variables declaradas como externo

Una variable de ámbito externo no inicializada explícitamente recibe, de forma automática, el valor cero. Una variable declarada como externo hace referencia a una variable definida con el mismo nombre en el ámbito externo en cualquier lugar del programa (de la misma o diferente fuente) la cual no sería accesible en el sitio donde se califica como externo.

Ejemplo

#include <stdio.h>
void f1 (void) {
  externo int v;
  printf("Valor de v a f1 es %d\n",v);
}

void f2 (void) {
  externo int v;
  v++;
  printf("Valor de v a f2 es %d\n",v);
}

int main() {
  f1();
  f2();
}

int v=15;

Variables declaradas como register

Una variable de ámbito interno declarada como register indica al compilador que la variable sea almacenada, si es posible, en un registro de la máquina. Si no es posible almacenarla en un registro recibe el tratamiento de automática. Este tipo de declaración sólo es válido para variables de tipo entero (char, unsigned char, int,...) y de tipo puntero que todavía no hemos visto. Una variable de este tipo sólo es visible en el blog donde se encuentra definida y no se inicializan automáticamente.

Declaración de funciones en ámbito externo

Una función también puede ser calificada como static o externo.

Una función declarada como static es accesible únicamente dentro del archivo fuente en el que está definida.

La definición como static de funciones permite tener diferentes funciones con el mismo nombre en diferentes archivos que formen el programa. Una función declarada como externo es accesible desde de todos los archivos fuente que forman un programa. Por defecto una función es externa.

Pin It