Está en la página 1de 3

UNLaR - APUNTES DE PROGRAMACIÓN

Prof. Ing. Marcelo Daniel Camargo

Referencias
Si bien la referencia, es un mecanismo incorporado con el lenguaje C++, es importante introducirlo,
dado que será necesario para introducir los siguientes temas. Una referencia almacena la
dirección de un dato que se encuentra en otra parte de la memoria. Las referencias se deben
inicializar al declararse ya que no es en sí una variable, sino como “una etiqueta” de otra y se
declaran poniendo el operador & después del tipo de dato. A diferencia del puntero, una referencia
inicializada no puede referenciar a un nuevo dato ni ponerla a NULL.
Ejemplo:

/* Ejemplo de referencias */
#include <stdio.h>
int main() {
printf("Con un char\n");
char ch = 'a';
char &char_ref= ch, // Referencia
*char_ptr=&ch; // Puntero
printf("dato= %c, referencia-> %c, puntero-> %c\n", ch, char_ref,
*char_ptr);
char_ref='b';
printf("dato= %c, referencia-> %c, puntero-> %c\n", ch, char_ref,
*char_ptr);

printf("Con un struct\n");
struct stru {
char dato;
} s;

stru& stru_ref = s; // Declara una referencia al tipo stru y lo


inicializa.
stru* stru_ptr = &s; // Declara un puntero al tipo stru y lo inicializa.

s.dato = 'c';
printf("dato= %c, referencia= %c, puntero-> %c\n", s.dato, stru_ref.dato,
stru_ptr->dato);

stru_ref.dato = 'd';
printf("dato= %c, referencia= %c, puntero-> %c\n", s.dato, stru_ref.dato,
stru_ptr->dato);
}

Llamadas a funciones por referencia y pseudoreferencia


Es la forma en que se pasan los argumentos a las funciones, cuando se necesita cambiar o
modificar los argumentos dentro de la función.
En las llamadas por valor, se copia el valor del argumento en la variable usada como parámetro
formal, de esta forma los cambios hechos al parámetro dentro del cuerpo de la función no afectan
a la variable utilizada como argumento. Es el caso de todas las funciones de usuario planteadas
hasta el momento.
La llamada por referencia es la segunda forma de pasar los argumentos, en lugar de pasar el
valor, se pasa una referencia la variable. De esta forma los cambios hechos a la variable
referenciada, la afectan fuera del ámbito de la función. En el ANSI C, se puede simular este tipo de
llamadas, pasando como parámetros de la función las direcciones de la variable (los punteros a
ellas).
El C++, mejoró este aspecto, implementando concretamente las llamadas por referencia.
El siguiente ejemplo muestra una simple función que incrementa el primer argumento y
decrementa al segundo. En el se verán las dos alternativas, la del ANSI C y la de C++.

-76-
UNLaR - APUNTES DE PROGRAMACIÓN
Prof. Ing. Marcelo Daniel Camargo

/********************************************************************/
/* REFEREN.CPP Llamada por referencia, diferencias entre en C y C++ */
/********************************************************************/
#include <STDIO.H>
#include <CONIO.H>
void incdec_en_c(int *x,int *y);
void incdec_en_cpp(int &x,int &y);
int main() {
int a=5,b=9;
printf("Valor inicial a=%d b=%d\n",a,b);
incdec_en_c(&a,&b); /* Invoca funcion por referencia en ANSI C */
printf("incdec_en_c(&a,&b); a=%d b=%d\n",a,b);
incdec_en_cpp(a,b); /* Invoca funcion por referencia en C++ */
printf("incdec_en_cpp(a,b); a=%d b=%d\n",a,b);
return 0;
}
void incdec_en_c(int *x,int *y) { /* Ej. de llamada por ref. en ANSI C*/
(*x)++; /* *x++ no tiene efecto, podria ser *x=*x+1 */
(*y)--;
}
void incdec_en_cpp(int &x,int &y) { /* Ej. de llamada por ref. en C++ */
x++;
y--;
}

La salida:
Valor inicial a=5 b=9
incdec_en_c(&a,&b); a=6 b=8
incdec_en_cpp(a,b); a=7 b=7
Se puede ver en el ej. anterior como se simplifica la declaración e invocación de la función con las
llamadas por referencia del C++.
En incrdecr_en_c los parámetros formales de la función (int *x e int *y) declaran que estos son
dos punteros a enteros. Más adelante, cuando se aborde el tema punteros, se comprenderá más
aún esta declaración.
En la declaración de los parámetros formales de incrdecr_en_cpp el símbolo & está indicando
que x y y son variables referenciadas. Esto significa que los cambios, hechos a ellas dentro del
ámbito de la función, afectarán también al entorno desde el que se hizo la invocación.
En el ejemplo se muestra una función más útil que la anterior, en la que no sería factible su
implementación, sino fuera a través de llamada por referencia. Se trata de la función swap, que
permite intercambiar los valor de dos variables. Se mostrará nuevamente, las implementaciones
para ANSI C y C++.

-77-
UNLaR - APUNTES DE PROGRAMACIÓN
Prof. Ing. Marcelo Daniel Camargo

Velocidad de ejecución de las funciones


Se habló en su momento de las ventajas que suponía la modularidad de los programas a través de
las funciones. Pero no se habló, de cuáles podrían ser las posibles desventajas.
Cuando se ejecuta una función se desencadenan una serie de actividades desconocidas para el
programador de lenguajes de alto nivel. Estas son salvar el estado de los registros del
microprocesador, entre ellos, la posición de ejecución antes de la llamada a la función, salvar los
parámetros con que se llama a la función. Luego ceder el control a la función, que restaura los
parámetros y ejecutar el código. Una vez que finaliza el código de la función, restaurar los registros
del microprocesador y finalmente devolver el control a la sentencia posterior, a la que se hizo la
llamada.
Todo esto supone una cantidad de tiempo extra, que influirá sobre la performance final del
programa. Hoy en día estos aspectos despreocupan a los programadores, ya que los
microprocesadores incrementan día a día su velocidad de procesamiento. Pero si la aplicación que
se está realizando, tiene como elemento crítico la velocidad (por ejemplo, un cierto módulo del
kernel de un sistema operativo, o un compilador), se debe evitar o economizar el uso de funciones.
Por esta razón, cuando se programa se debe poner en la balanza por un lado la modularidad, la
facilidad de mantenibilidad y la reusabilidad del código y por otro su performance.
Una regla muy utilizada por el programador de C es que, si una función puede ser reemplazada
por una macro, se utiliza a esta última. Esto se justifica, si la función va a ser invocada reiteradas
veces dentro del programa. En los últimos dos programas de ejemplo salen funciones que se
pueden reemplazar por macros. La función swap, podría formar parte de un programa de
ordenamiento, lo que lleva a pensar que será invocada reiteradas veces. En este caso se justifica
su reemplazo por una macro.

#include <STDIO.H>
#include <CONIO.H>
void swap_cpp(int &x,int &y);
void swap_c(int *x,int *y);
int main() {
int a=2,b=3;
printf("antes del swap a=%d b=%d\n",a,b);
swap_cpp(a,b); /*swap_C(&a,&b);*/
printf("despues del swap a=%d b=%d\n",a,b);
return 0;
}
void swap_cpp(int &x,int &y) {
int aux=x;
x=y;
y=aux;
}
void swap_c(int *x,int *y) {
int aux=*x;
*x=*y;
*y=aux;
}
La salida:
antes del swap a=2 b=3
despues del swap a=3 b=2

-78-

También podría gustarte