martes, 9 de junio de 2009


Cada llamada a la función debe verificar:
El número de parámetros debe ser exactamente tres.
Los tipos deben ser compatibles con los de la declaración (más adelante explicaremos qué son tipos compatibles). Nótese que cuando llamamos a la función, la comprobación de tipo la hace el compilador basándose en el prototipo (en la declaración) puesto que la función todavía no ha sido definida.Los nombres de variables que aparecen en el prototipo son opcionales y actúan casi como comentarios al lector del programa, ya que son completamente ignorados por el compilador.
Tipos compatiblesSon compatibles cualquiera de los tipos simples (definidos en C++) que pueden ser convertidos de uno a otro de manera significativa. Por ejemplo, si llamamos con un entero a una función que está esperando un número real como parámetro, el sistema lo convertirá automáticamente, sin mencionarlo al usuario. Esto también es cierto de float a char, o de char a int.En cambio, si pasamos un puntero a un entero a una función que estaba esperando un entero, no habrá conversión de tipo, ya que son dos variables completamente distintas. De la misma forma, un tipo definido por el usuario (estructura o clase) no puede ser convertido automáticamente a un long float, a un array o incluso a otra estructura o clase diferente, porque son tipos incompatibles y no puede realizarse la conversión de manera significativa.Sin embargo, el tipo devuelto por la función, void en el ejemplo anterior, debe ser compatible con el tipo que se espera que devuelva en la función de llamada, o el compilador dará un warning.
Pequeños cambiosVolvamos al ejemplo anterior. Veamos qué sucede cuando hacemos pequeños cambios:
Llamamos a la función con do_stuff (12.2, 13, 12345). No se produce ningún error durante la compilación, pues estamos trabajando con tipos compatibles. La salida del programa es: There are 12 wings. There are 13 feet. There are 57 eyes.
There are 2 wings. There are 1000 feet. There are 2 eyes.
Llamamos a la función con sólo dos parámetros: do_stuff (12.2, 13). El compilador lanzará un mensaje de error:11:error: In this statement, "do_stuff(1.22e1, 13)" supplies 2 arguments, but 3 are expected.
En la segunda llamada a la función, ponemos un & delante del nombre de una de las variables, do_stuff (arm, &float, lookers). El mensaje de error es el siguiente:13:error:In this statement, "&lookers" is of type "pointer to char", and may not be converted to "char".
Cambiemos, en el prototipo, void por int, int do_stuff(int wings, float feet, char eyes);. Entonces, al compilar:16:error:In this declaration, the type of "do_stuff" is not compatible with the type of previous declaration of "do_stuff".
Si ahora modificamos además el tipo devuelto en la declaración de la función, int do_stuff (int wings, float feet, char eyes) { ...}, obtenemos:16:warning:Non-void function "do_stuff" does not contain a return statement.
Podemos cambiar la declaración de la función por:void do_stuff (int, float, char);
Esto no dará ninguna diferencia respecto al programa original. Esto demuestra que los nombres de las variables en el prototipo son tratados como comentarios por el compilador de C++.
La función podría haber sido declarada de la siguiente forma:
void do_stuff (int wings, //Number of wings float feet, //Number of feet char eyes, //Number of eyes
Esto hace que la cabecera de la función sea autoexplicatoria. Sin embargo, debe recordarse que los comentarios nunca deben usarse en lugar de nombres significativos para las variables. El uso de prototipos no supone coste alguno en tiempo ni en velocidad de ejecución. El prototipo se verifica durante la compilación. Ralentiza ésta, debido a que es una comprobación extra que el compilador debe hacer, pero es despreciable el tiempo que necesita. El prototipo sólo alarga el tamaño del código.

No hay comentarios:

Publicar un comentario