Un parámetro en programación es un argumento aceptado por una función. El término "argumento" implica qué se pasó exactamente y a qué función en particular, y el parámetro, en qué capacidad la función aplicó este recibido. Es decir, el código de llamada pasa el argumento a un parámetro que está definido en un miembro de la especificación de la función.
Es importante distinguir:
Ejemplo en lenguaje C :
// Función descriptiva. int a - parámetro formal, el nombre del parámetro puede estar ausente. int mifuncion ( int a ); // Definición de función. int b - parámetro formal, el nombre del parámetro puede no coincidir con el especificado al declarar la función. int mifuncion ( int b ) { devolver 0 ; } int principal () { int c = 0 ; mifuncion ( c ); // Llamada de función. c es el parámetro real. devolver 0 ; }La semántica del uso de parámetros formales y reales se denomina estrategia de evaluación . Una estrategia de evaluación determinada dicta cuándo se deben evaluar los argumentos de una función (método, operación, relación) y qué valores se deben pasar. Hay bastantes estrategias de cálculo diferentes.
Nota : el uso del término " paso de parámetros ", común en la comunidad de programación imperativa , no es del todo correcto para muchos lenguajes de programación; por ejemplo, en el caso de una llamada de necesidad , utilizada en el lenguaje Haskell , el parámetro se puede usar en el cuerpo de la función, pero nunca se pasa para todos los casos de su llamada, e incluso se excluye por completo del código de máquina resultante.
Las estrategias de evaluación más comúnmente mencionadas son llamada por valor y llamada por referencia , pero el uso real de estos términos no siempre es apropiado. Por ejemplo, en la comunidad del lenguaje Java dicen " Java usa llamada por valor, donde 'valor' es una referencia de objeto " y en la comunidad del lenguaje Ruby dicen " Ruby usa llamada por referencia ", pero en realidad ambos lenguajes utilice la estrategia de llamada por referencia . .call -by -sharing ) [3] [4] . Muchos lenguajes, como C , no tienen un mecanismo de llamada por referencia, pero permiten simular uno dentro de la semántica de llamada por valor a través de tipos de referencia , en particular punteros . En este último caso, en las comunidades de tales idiomas, se suele decir “ el idioma admite dos estrategias de evaluación ”, así como “ llamar por puntero ” o “ llamar por dirección ”.
En la práctica, el modelo computacional de muchos lenguajes industriales ( Java , C# ) se reduce a una estrategia de " call-at-mention/pass-by-reference ". Algunos lenguajes más antiguos, especialmente los lenguajes inseguros como C++ , combinan varios patrones de llamada diferentes, incluidos los exóticos como call-by-reference-to- constant . Históricamente, la llamada por valor y la llamada por nombre se remontan a Algol-60 , creado a fines de la década de 1950 . Solo los lenguajes funcionales puros , como Clean y Haskell , usan call - by - need , que a menudo se identifica (que tampoco es del todo correcto) con evaluación perezosa .
Pasar un parámetro por referencia significa que no se copia el valor en sí , sino la dirección de la variable original (como en el caso de pasar un parámetro por dirección), sin embargo, se usa la sintaxis para que el programador no tenga que usar la operación de desreferenciación y puede tratar directamente con el valor almacenado en esta dirección (como en el caso del paso de parámetros por valor).
Pasar por referencia evita copiar toda la información que describe el estado del objeto (que puede ser significativamente mayor que sizeof(int)) y es necesario para el constructor de copias .
Si una función devuelve un valor por referencia (por ejemplo, en la forma "devuelve *esto;"), su llamada se puede usar a la izquierda del operador de asignación (ver también L-expresión ).
Si el paso por referencia se usa precisamente como un medio para aumentar el rendimiento, pero no se desea cambiar el parámetro, puede usar el paso por referencia de un objeto constante.
Ejemplo en C++ : #incluir <iostream> utilizando el espacio de nombres estándar ; // para usar cout vacío f ( int x ) { // pasando un parámetro por valor cout << x ; x = 1 _ cout << x ; } vacío g ( int * x ) { // pasar un parámetro a la dirección cout << * x ; * x = 2 ; cout << * x ; } vacío h ( int & x ) { // pasar un parámetro por referencia cout << x ; x = 3 ; cout << x ; } void i ( const int & x ) { // pasar un parámetro inmutable por referencia cout << x ; x = 4 ; // Error por el cual no se compilará el código cout << x ; } int principal () { int x = 0 ; cout << x ; f ( x ); cout << x << " " ; g ( & x ); cout << x << " " ; h ( x ); cout << x << " " ; yo ( x ); cout << x ; devolver 0 ; }Por lo tanto, uno esperaría que el programa de ejemplo imprima (si la línea errónea está comentada) "0010 022 233 333".
Algunos idiomas (o sus dialectos) no admiten el paso por referencia, mientras que otros, por el contrario, pasan parámetros exclusivamente por referencia, lo que crea el riesgo de cambiar inadvertidamente el contexto de la función de llamada.
El lenguaje Fortran implica pasar parámetros exclusivamente por referencia:
Ejemplo de Fortran :Programa:
PARÁMETROS DEL PROGRAMA IMPLÍCITO NINGUNO ENTERO A , B , C A = 7,0 B = 9,0 C = 0,0 FORMATO 100 ( 'A =' , I2 , ', B =' , I2 , ', C =' , I3 ) ESCRIBIR ( * , 100 ) A , B , C LLAMADA MUL ( A , B , C ) ESCRIBIR ( * , 100 ) A , B , C FINALIZAR PROGRAMA SUBRUTINA MUL ( A , B , C ) ENTERO A , B , C C = A * B FIN SUBRUTINAImprimirá:
A=7, B=9, C=0 A=7, B=9, C=63