Você está na página 1de 33

APUNTADORES

LIC. LINO AVILA


• Permiten el paso por referencia, y se pueden
utilizar para crear y manipular estructuras
dinámicas de datos (es decir, estructuras de
datos que pueden crecer y reducirse), como listas
enlazadas, colas, pilas y árboles.
DECLARACIONES E
INICIALIZACIÓN DE VARIABLES
APUNTADORES
• Las variables apuntadores contienen direcciones
de memoria como sus valores. Por lo general,
una variable contiene directamente un valor
específico.
• Un apuntador contiene la dirección de memoria
de una variable que, a su vez, contiene un valor
específico.
• En este sentido, el nombre de una variable hace
referencia directa a un valor, y un apuntador
hace referencia indirecta a un valor
• Al proceso de hacer referencia a un valor a través
de un apuntador se le conoce comúnmente como
indirección.
EJEMPLO

• int *cuentaPtr, cuenta;

Declara a la variable cuentaPtr como de tipo int * (es decir,


un apuntador a un valor int) y se lee así: “cuentaPtr es un
apuntador a un valor int” o “cuentaPtr apunta a un objeto de
tipo int”.
OPERADORES DE APUNTADORES

El operador dirección (&)


• Es un operador unario que obtiene la dirección de
memoria de su operando. Por ejemplo:
• int y = 5; // declara la variable y
• int *yPtr; // declara la variable apuntador yPtr
• yPtr = &y; // asigna la dirección de y a yPtr
• asigna la dirección de la variable y a la variable
apuntador yPtr. Entonces, se dice que la variable
yPtr “apunta a” y.
• El operando del operador dirección debe ser un
lvalue (es decir, algo a lo que se pueda asignar
un valor, comoel nombre de una variable o una
referencia).
• No se puede aplicar a constantes o expresiones
que no den como resultado referencias.
El operador *
• Se conoce comúnmente como el operador de
indirección u operador de desreferencia,
devuelve un sinónimo (es decir, un alias o
sobrenombre) para el objeto al que apunta su
operando apuntador.

cout << *yPtr << endl;


• imprime el valor de la variable y, al igual que la
instrucción
cout << y << endl;
• Al proceso de utilizar el * de esta manera, se le
conoce como desreferenciar un apuntador.
• Un apuntador desreferenciado también se puede usar
en:

• El lado izquierdo de una instrucción de asignación,


como en
*yPtr = 9;

• Recibir un valor de entrada, como en:


cin >> *yPtr; lo cual coloca el valor de entrada
en y.

El apuntador desreferenciado es un lvalue.


PASO DE ARGUMENTOS A FUNCIONES
POR REFERENCIA MEDIANTE
APUNTADORES
• En C++ hay tres formas de pasar argumentos a una función:
• paso por valor
• paso por referencia con argumentos tipo referencia
• paso por referencia con argumentos tipo apuntador.

• Los apuntadores se pueden usar para modificar una o más


variables en la función que hace la llamada, o pasar
apuntadores a objetos de datos grandes para evitar la
sobrecarga de pasar los objetos por valor.

• Cuando se llama a una función con un argumento que se


debe modificar, se pasa la dirección del argumento aplicando
el operador dirección (&) al nombre de la variable cuyo valor
se va a modificar.
• Los arreglos no se pasan usando el operador &,
ya que el nombre del arreglo es la ubicación
inicial en memoria del mismo

• El nombre de un arreglo, nombreArreglo, es


equivalente a &nombreArreglo[ 0 ].

• Cuando se pasa la dirección de una variable a


una función, el operador indirección (*) se puede
usar en la función para formar un sinónimo para
el nombre de la variable
• Diferencia de una funcion usando
• paso por valor y paso por referencia con
argumentos tipo apuntador.
CADENAS
• ¿Cómo almacenar cadenas de caracteres en arreglos
tipo carácter?
• Una cadena como "hola" es en realidad un arreglo de
caracteres.
• Un arreglo de caracteres se puede inicializar mediante
el uso de una literal de cadena.

• Por ejemplo
char cadena1[] = "primero";

char cadena1[] = { 'f', 'i', 'r', 's', 't', '\0' };

char cadena2[ 20 ];
cin >> cadena2;
• carácter nulo La constante tipo carácter que
representa el carácter nulo es '\0' (barra diagonal
inversa seguida de un cero).
• Todas las cadenas representadas mediante
arreglos de caracteres terminan con este
carácter.

• Programa 8.3
USO DE CONST CON
APUNTADORES
• Existen muchas posibilidades para usar (o no
usar) const con los parámetros de funciones.
• ¿Cómo elegir la más apropiada de estas
posibilidades?
• Hay que dejar que el principio del menor
privilegio sea nuestro guía.
• Siempre debemos otorgar a una función el
suficiente acceso a los datos en sus parámetros
para que pueda realizar su tarea especificada,
pero nada más.
4 MANERAS DE PASAR UN APUNTADOR
A UNA FUNCIÓN:
• Un apuntador no constante a datos no constantes
• Un apuntador no constante a datos constantes
• Un apuntador constante a datos no constantes
• Un apuntador constante a datos constantes
UN APUNTADOR NO CONSTANTE A
DATOS NO CONSTANTES
• Es el mayor nivel de acceso, se otorga mediante
los datos se pueden modificar a través del
apuntador desreferenciado, y el apuntador se
puede modificar para que apunte a otros datos.
• La declaración para dicho apuntador no incluye
const.
APUNTADOR NO CONSTANTE A
DATOS CONSTANTES
• Es un apuntador que se puede modificar para
apuntar a cualquier elemento de datos del tipo
apropiado, pero los datos a los que apunta no se
pueden modificar a través de ese apuntador.
APUNTADOR CONSTANTE A DATOS
NO CONSTANTES
• Es un apuntador que siempre apunta a la misma
ubicación de memoria
• los datos en esa ubicación se pueden modificar a
través del apuntador.
• Un ejemplo de dicho apuntador es el nombre de un
arreglo, el cual es un apuntador constante al principio
del arreglo.
• se pueden utilizar para recibir un arreglo como
argumento a una función que acceda a los elementos
de un arreglo, usando la notación de subíndices.
• Los apuntadores que se declaran como const se
deben inicializar a la hora de declararse.
APUNTADOR CONSTANTE A DATOS
CONSTANTES
• La menor cantidad de privilegio de acceso se
otorga mediante un apuntador constante a
datos constantes.
• Dicho apuntador siempre apunta a la misma
ubicación de memoria, y los datos en esa
ubicación de memoria no se pueden modificar
mediante el uso del apuntador.
• Así es como se debe pasar un arreglo a una
función que sólo lea el arreglo, usando la
notación de subíndices de arreglos, y no se
modifica el arreglo.
EL ALGORITMO DE ORDENAMIENTO
POR SELECCIÓN.
• fácil de programar, pero por desgracia ineficiente.
• En la primera iteración del algoritmo se selecciona el
elemento más pequeño en el arreglo y se intercambia
con el primer elemento.
• En la segunda iteración se selecciona el segundo
elemento más pequeño (que es el elemento más
pequeño del elemento restante) y se intercambia con
el segundo elemento.
• El algoritmo continúa hasta que en la última iteración
se selecciona el segundo elemento más grande y se
intercambia con el penúltimo subíndice, dejando el
elemento más grande en el último subíndice.
OPERADOR SIZEOF

sizeof para determina el tamaño de un arreglo (o


de cualquier otro tipo de datos,variable o
constante) en bytes durante la compilación de un
programa.
Devuelve el número total de bytes en el arreglo
como un valor de tipo size_t.
(un tipo entero sin signo que es por lo menos tan
grande como un unsigned int).
EXPRESIONES Y ARITMÉTICA DE
APUNTADORES
• No todos los operadores que se utilizan son
válidos con las variables apuntadores.
• Un apuntador se puede incrementar (++)
• o decrementar (--)
• Se puede sumar un entero a un apuntador (+ o
+=).
• Restar un entero de un apuntador (- o -=).
• Se puede restar un apuntador de otro apuntador
del mismo tipo..
EJEMPLOS

• Suponga que se ha declarado el arreglo int v[ 5 ],


y que su primer elemento se encuentra en la
ubicación de memoria 3000.
• Suponga que se ha inicializado el apuntador vPtr
para que apunte a v[ 0 ]
• La aritmética de apuntadores no
tiene significado, a menos que se
realice en un apuntador que apunte
a un arreglo.
• No podemos asumir que dos
variables del mismo tipo se
almacenan en forma contigua en la
memoria, a menos que sean
elementos adyacentes de un arreglo.
RELACIÓN ENTRE APUNTADORES Y
ARREGLOS
• Los arreglos y los apuntadores en C++ y se
pueden utilizar de manera casi intercambiable.
• Suponga las siguientes declaraciones:

int b[ 5 ]; // crea el arreglo int b de 5 elementos


int *bPtr; // crea el apuntador int bPtr;
• Podemos establecer bPtr a la dirección del primer
elemento en el arreglo b con la instrucción

bPtr = b; // asigna la dirección del arreglo b a


bPtr

• Esto es equivalente a asignar la dirección del


primer elemento del arreglo, como se muestra a
continuación:
bPtr = &b[ 0 ]; // también asigna la dirección
del arreglo b a bPtr
NOTACIÓN
APUNTADOR/DESPLAZAMIENTO
• El elemento b[ 3 ] del arreglo se puede
referenciar de manera alternativa con la siguiente
expresión de apuntador:
*( bPtr + 3 )
• Se puede hacer referencia al elemento del arreglo con
una expresión de apuntador.
la dirección &b[ 3 ]
• se puede escribir con la expresión de apuntador
bPtr + 3
• El nombre del arreglo (que es const de manera
implícita) se puede tratar como apuntador y se puede
utilizar en la aritmética de apuntadores.
*( b + 3 )
se refiere al elemento b[ 3 ] del arreglo.

• La expresión b += 3 produce un error de compilación


NOTACIÓN
APUNTADOR/SUBÍNDICE.
• Los apuntadores pueden usar subíndices de la
misma forma que los arreglos.
• Por ejemplo, la expresión bPtr[ 1 ] hace
referencia al elemento b[ 1 ] del arreglo.
ARREGLOS DE APUNTADORES

• arreglo de cadenas.
• Cada entrada en el arreglo es una cadena, pero
en C++ una cadena es en esencia un apuntador
a su primer carácter, por lo que cada entrada en
un arreglo de cadenas es simplemente un
apuntador al primer carácter de una cadena.

const char *palo[ 4 ] ={ "Corazones",


"Diamantes", "Bastos", "Espadas" };
• Aunque parece ser que estas cadenas se colocan
en el arreglo palo, sólo los apuntadores se
guardan en el arreglo.
• Cada apuntador apunta al primer carácter de su
cadena correspondiente.
• Por ende, aun y cuando el arreglo palo tiene un
tamaño fijo, proporciona acceso a cadenas de
caracteres de cualquier longitud.
EJEMPLO PRÁCTICO: SIMULACIÓN
PARA BARAJAR
Y REPARTIR CARTAS

Você também pode gostar