a) Acceso a una función:
Se puede acceder ( llamar
)a
una función especificando su nombre, seguido de una lista de argumentos
cerrados entre paréntesis y separados por comas. Si la llama a la
función no requiere ningún argumento, se debe escribir a
continuación del nombre de la función un par de paréntesis
vacíos. La llamada a la función puede aparecer sola (esto
es, puede formar una expresión simple), o puede ser uno de los operandos
de una expresión más compleja.
b) Argumentos de una función. Prototipos:
Los argumentos que aparecen en la llamada a la función
se denominan argumentos actuales, mientras
que los argumentos formales son los que aparecen
en la primera línea de definición de la función. (También
se llaman los argumentos actuales, a veces,
argumentos
simplemente, o parámetros actuales).
En una llamada normal a una función, habrá un argumento actual
por cada argumento formal. Los argumentos actuales pueden ser constantes,
variables simples, o expresiones más complejas. No obstante, cada
argumento actual debe ser del mismo tipo de datos que el argumento formal
correspondiente.
Los parámetros formales son
variables locales a una función, ya que son creados al entrar en
la función (se crean en la pila) y destruidos cuando ésta
termina. El tipo de variable declarado para cada parámetro formal
debe ser el mismo que se utilice cuando se llama a la función
Si esto no sucede, pueden introducirse errores, ya que el compilador no
verificará los tipos. Para prevenir estos
errores se emplean los prototipos de las funciones.
Los prototipos consisten en declarar al principio del programa (de cada
módulo si el programa contiene varios módulos) las funciones
que se utilizan y los tipos de sus argumentos. De esta forma el compilador
puede reconocer una incongruencia entre el prototipo de una función
y su llamada.
Los prototipos, también nos pueden solveltar los errores
que se pueden dar al hacer una llamada a una función func2
(que no devuelve un entero), y que aparece implementada debajo de func1,
siendo llamada desde func1,
por tanto, para resolver el problema de orden de definición son
útiles igualmente los prototipos
o declaraciones por adelantado.
Veamos como sería todo esto:
Los parámetros son siempre pasados
por valor. Por tanto, el parámetro de la función recibe
el valor de la variable que se utiliza como argumento. Cualquier modificación
sobre estos parámetros no afecta a las variables que se utilizan
para llamar a la función, puesto que el parámetro en estos
casos es una copia de esas variables.
Veamos un ejemplo en el que se modifica el valor de su argumento.
Se visualiza el valor original de a (a=2)
cuando comienza la ejecución de main.
Este valor se pasa a la función modificar,
en donde se multiplica por 3 y se visualiza el nuevo valor. Nótese
que se altera el valor del argumento formal que se visualiza en la función.
Finalmente, el valor de a en
main (el argumento actual) se vuelve a visualizar,
después de haberse devuelto el control a main
desde
modificar.
Se genera la siguiente salida:
a = 2 (desde main, antes de llamar a la función)
a = 6 (desde la función, después de modificar el valor)
a = 2 (desde main, después de llamar a la función)
Pasar los argumentos por valor tiene sus ventajas y sus desventajas. Algo positivo es que los valores hallados dentro de la función no son vistos fuera de ella. Su desventaja es que impide que se transfiera información desde la función hasta el punto de llamada mediante los argumentos. Por tanto, el paso por valor implica que la transferencia de información sólo puede realizarse en un sentido. |
Cuando sea necesario modificar el valor de la variable utilizada
para llamar a la función hay que pasar la dirección de dicha
variable. Por tanto, los parámetros deben ser declarados como punteros
(se
verán en temas sucesivos). El
único caso en el que sin necesidad de especificarlo explícitamente
se pasa la dirección de una variable como argumento es cuando se
pasa una matriz.
Las dos formas descritas anteriormente
serían:
|
|
|
|
|
|
|
|
|
|
|
|
Leer un carácter y convertirlo a mayúscula utilizando una función definida por el programador que sea llamada desde el programa principal ( main() ).
#include <stdio.h>
main()
{
printf("Por favor introduce una letra: ");
scanf("%c", &minus);
mayus=minus_a_mayus(minus);
printf("\nLa mayúscula equivalente
es: %c\n\n",mayus);
char minus_a_mayus( char c1)
/* definición de función */
{
c2= (c1>='a' && c1<='z') ? ('A'
+ c1 - 'a'): c1;
return(c2);
Este programa contiene una
llamada a la función definida por el programador minus_a_mayus.
La llamada es una parte de la expresión mayus=minus_a_mayus(minus).
Activar la función mediante la llamada a ésta hace que se transfiera el valor de minus a la función. Este valor es representado por c1 dentro de la función, con return(c2) devolvemos el valor de la mayúscula que lo hemos introducido anteriormente en la variable carácter c2. |
Ejemplos de argumentos
de una función:
Ejemplo 1:
Estas dos formas son equivalentes:
int cabeceras(char *mensaje, int fila, int
columna) {
if (fila>25 || fila<1 || columna<1 || columna>80)
printf(mensaje); return(1); } |
int cabeceras(mensaje, fila, columna)
char *mensaje; int fila; int columna; { if (fila>25 || fila<1 || columna<1 || columna>80)
printf(mensaje); return(1); } |
Para esta función se declararía
el prototipo: