Está en la página 1de 26

Algoritmos y Estructuras de Datos

Algoritmos y Estructuras de Datos

Clase: Apuntadores en C++


Dra. Adriana Menchaca Mndez

ENES Unidad Morelia, UNAM

Agosto 2016
Algoritmos y Estructuras de Datos

Apuntadores en C++

Una variable es un nombre que se le da a la pieza de memoria


que ser utilizada para almacenar un valor.
Cuando un programa realiza una instancia de una variable,
una direccin en memoria libre es asignada a la variable.
Algoritmos y Estructuras de Datos

Apuntadores en C++

Cuando la siguiente instruccin es ejecutada por la CPU, una


pieza de la memoria RAM es apartada.

1 int x;

Al utilizar variables no debemos preocuparnos por la direccin


de memoria especfica en la que se almacenan!
Algoritmos y Estructuras de Datos

Apuntadores en C++

Operador de direccin (&)

Este operador nos permite obtener la direccin en memoria


que tiene asignada una variable.

1 # include <iostream >


2
3 i n t main ( )
4 {
5 int x = 5;
6 s t d : : c o u t << x << \n ; / / p r i n t th e v a l u e o f v a r i a b l e x
7 s t d : : c o u t << &x << \n ; / / p r i n t th e memory address o f
variable x
8
9 return 0;
10 }
Algoritmos y Estructuras de Datos

Apuntadores en C++
Operador contenido (*)
Este operador nos permite obtener el contenido de una
direccin.

1 # include <iostream >


2
3 i n t main ( ) {
4 int x = 5;
5 / / p r i n t th e value of v a r i a b l e x
6 s t d : : c o u t << x << \n ;
7 / / p r i n t th e memory address o f v a r i a b l e x
8 s t d : : c o u t << &x << \n ;
9 / / p r i n t th e v a l u e a t th e memory address o f v a r i a b l e x
10 s t d : : c o u t << &x << \n ;
11
12 return 0;
13 }
Algoritmos y Estructuras de Datos

Apuntadores en C++

Un apuntador es una variable que almacena una direccin de


memoria.
La declaracin de variables de tipo apuntador es similar a
la de las variables normales, la diferencia est en que
debe colocarse un asterisco (*) entre el tipo de dato y el
nombre de la variable.
Algoritmos y Estructuras de Datos

Apuntadores en C++

Declaracin de variables de tipo apuntador

1 / / a p o i n t e r t o an i n t e g e r v alue
2 int i Ptr ;
3

4 / / a p o i n t e r t o a double v alue
5 double d P t r ;
6

7 / / d e c l a r e two p o i n t e r s t o i n t e g e r v a r i a b l e s
8 int iPtr4 , iPtr5 ;
Algoritmos y Estructuras de Datos

Apuntadores en C++

Declaracin de variables de tipo apuntador

Para indicar que una funcin regresa una variable de tipo


apuntador, el asterisco debe colocarse despus del tipo de
dato.

1 i n t doSomething ( ) ;
Algoritmos y Estructuras de Datos

Apuntadores en C++

Inicializando variables de tipo apuntador

Al igual que las variables normales, si una variable de tipo


apuntador no es inicializada sta tendr basura.

1 i n t v alue = 5 ;
2 i n t p t r = &v alue ; / / i n i t i a l i z e p t r w i t h address
o f v a r i a b l e v alue
Algoritmos y Estructuras de Datos

Apuntadores en C++

Inicializando variables de tipo apuntador

El tipo de apuntador tiene que ser igual al tipo de variable que


queremos apuntar.
Cuando hacemos uso del operador contenido, depender
del tipo de apuntador el nmero de bits que sern ledos.
Algoritmos y Estructuras de Datos

Apuntadores en C++

Inicializando variables de tipo apuntador

1 int iValue = 5;
2 double dValue = 7 . 0 ;
3
4 i n t i P t r = &i V a l u e ; / / ok
5 double d P t r = &dValue ; / / ok
6 / / wrong i n t p o i n t e r cannot p o i n t t o t h e address
o f a double v a r i a b l e
7 i P t r = &dValue ;
8 / / wrong double p o i n t e r cannot p o i n t t o t h e
address o f an i n t v a r i a b l e
9 d P t r = &i V a l u e ;
Algoritmos y Estructuras de Datos

Apuntadores en C++

Inicializando variables de tipo apuntador

C++ no permite asignar una direccin de memoria especfica


a un apuntador.

1 / / n o t okay , t r e a t e d as a s s i g n i n g an i n t e g e r
literal
2 double d P t r = 0x0012FF7C ;
Algoritmos y Estructuras de Datos

Apuntadores en C++

Apuntadores nulos

C++ permite inicializar un apuntador con un valor nulo, lo cual


indica que dicho apuntador no est apuntando a ninguna
direccin de memoria.

1 int ptr (0) ; / / p t r i s now a n u l l p o i n t e r


2
3 int ptr2 ; / / ptr2 is u n i n i t i a l i z e d
4 p t r 2 = 0 ; / / p t r 2 i s now a n u l l p o i n t e r
5
6 / / NULL i s a macro o f C ( b u t n o t C++)
7 i n t p t r 3 = NULL ;
Algoritmos y Estructuras de Datos

Apuntadores en C++

Apuntadores nulos

Dado que un apuntador nulo es evaluado como 0, puede ser


usado dentro de una condicional.

1 double p t r ( 0 ) ;
2
3 if ( ptr )
4 c out << "ptr is pointing to a double value." ;
5 else
6 c out << "ptr is a null pointer." ;
Algoritmos y Estructuras de Datos

Apuntadores en C++

Accediendo a direccin de memoria invlidas

Cuando usamos apuntadores es posible que se haga un mal


uso de la memoria.
Por seguridad, los sistemas operativos nuevos no permiten
acceder a direccin de memoria no vlidas. En caso de
que una aplicacin lo intente el sistema operativo
terminar la ejecucin de la misma.
Algoritmos y Estructuras de Datos

Apuntadores en C++

Por qu son tiles los apuntadores?

Los arreglos estn implementados utilizando apuntadores.


A travs de apuntadores podemos reservar memoria de
manera dinmica (en tiempo de ejecucin.
Haciendo uso de apuntadores podemos pasar informacin
a una funcin sin hacer copias por valor.
Permiten el uso de polimorfismo cuando se est
trabajando con herencia (programacin orientada a
objetos).
Se utilizan para implementar estructuras de datos ms
avanzadas.
Algoritmos y Estructuras de Datos

Apuntadores en C++

Apuntadores nulos

Como buenas prcticas de programacin se recomienda:


Inicializar con nulo todas las variables de tipo apuntador que
estn apuntando a alguna direccin especfica.
No usar la macro NULL ya que est corresponde a C
Algoritmos y Estructuras de Datos

Apuntadores en C++
Arreglos y apuntadores
Una variable de tipo arreglo almancena la direccin de
memoria del primer elemento del arreglo.

1 # include < ios tr eam >


2
3 i n t main ( )
4 {
5 int array [ 5 ] = { 9 , 7 , 5 , 3 , 1 } ;
6

7 / / p r i n t t h e v alue o f t h e a r r a y v a r i a b l e
8 s t d : : c out << "The array has address: " << a r r a y
<< \n ;
9
10 / / p r i n t address o f t h e a r r a y elements
Algoritmos y Estructuras de Datos

Apuntadores en C++
Arreglos y apuntadores
Se debe tener cuidado al hacer uso de los arreglos y
apuntadores porque no son lo mismo.

1 # include <iostream >


2
3 i n t main ( ) {
4 in t array [ 5 ] = { 9 , 7 , 5 , 3 , 1 } ;
5
6 / / w i l l p r i n t sizeof ( i n t ) array length
7 s t d : : c o u t << s iz e o f ( a r r a y ) << \n ;
8
9 in t p t r = array ;
10 / / w i l l p r i n t th e s i z e o f a p o i n t e r
11 s t d : : c o u t << s iz e o f ( p t r ) << \n ;
12
13 return 0;
14 }
Algoritmos y Estructuras de Datos

Apuntadores en C++

Arreglos y apuntadores

C++ convierte los parmetros de tipo arreglo a un apuntador.


Por lo anterior, las siguientes declaraciones son equivalentes.

1 void p r i n t S i z e ( i n t a r r a y [ ] ) ;
2 void p r i n t S i z e ( i n t a r r a y ) ;
Algoritmos y Estructuras de Datos

Apuntadores en C++
Arreglos y apuntadores

1 # include <iostream >


2
3 / / C++ w i l l i m p l i c i t l y c o n v e r t parameter a r r a y [ ] t o a r r a y
4 void p r i n t S i z e ( i n t a r r a y [ ] ) {
5 / / a r r a y i s t r e a t e d as a p o i n t e r here , n o t a f i x e d a r r a y
6 / / p r i n t s th e s i z e o f a p o i n t e r , n o t th e s i z e o f th e a r r a y !
7 s t d : : c o u t << s iz e o f ( a r r a y ) << \n ;
8 }
9
10 i n t main ( ) {
11 i n t a r r a y [ ] = { 1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 } ;
12 s t d : : c o u t << s iz e o f ( a r r a y ) << \n ; / / w i l l p r i n t s i z e o f ( i n t
) array length
13 p r i n t S i z e ( a r r a y ) ; / / th e a r r a y argument decays i n t o a
p o i n t e r here
14 return 0;
15 }
Algoritmos y Estructuras de Datos

Apuntadores en C++

Arreglos y apuntadores

Los elementos de un arreglo siempre estn almacenados de


manera consecutiva.

1 # include <iostream >


2
3 i n t main ( ) {
4 in t array [ ] = { 9 , 7 , 5 , 3 , 1 } ;
5
6 std :: cout << "Element 0 is at address: " << &a r r a y [ 0 ] << \n ;
7 std :: cout << "Element 1 is at address: " << &a r r a y [ 1 ] << \n ;
8 std :: cout << "Element 2 is at address: " << &a r r a y [ 2 ] << \n ;
9 std :: cout << "Element 3 is at address: " << &a r r a y [ 3 ] << \n ;
10
11 return 0;
12 }
Algoritmos y Estructuras de Datos

Apuntadores en C++

Aritmtica de apuntadores

C++ permite sumar o restar enteros a apuntadores.


Si ptr es un apuntador a un arreglo, entonces ptr+1 es
la direccin del siguiente entero en la memoria.
Si ptr es un apuntador a un arreglo, entonces ptr-1 es
la direccin del entero anterior en la memoria.
Algoritmos y Estructuras de Datos

Apuntadores en C++

Aritmtica de apuntadores

Cuando se calcula el resultado de una expresin aritmtica con


apuntadores, el compilador multiplica el operando entero por el
tamao del tipo de dato del apuntador.
Algoritmos y Estructuras de Datos

Apuntadores en C++
Aritmtica de apuntadores
El operador * tiene preferencia sobre el operador +.

1 # include <iostream >


2
3 i n t main ( ) {
4 in t array [ 5 ] = { 9 , 7 , 5 , 3 , 1 } ;
5
6 // p r i n t memory address o f a r r a y element 1
7 std : : c o u t << &a r r a y [ 1 ] << \n ;
8 // p r i n t memory address o f a r r a y p o i n t e r + 1
9 std : : c o u t << a r r a y +1 << \n ;
10
11 s t d : : c o u t << a r r a y [ 1 ] << \n ; / / p r i n t s 7
12 s t d : : c o u t << ( a r r a y +1) << \n ; / / p r i n t s 7 ( note th e
p a r e n t h e s i s r e q u i r e d here )
13 return 0;
14 }
Algoritmos y Estructuras de Datos

Apuntadores en C++

Aritmtica de apuntadores

1 const i n t a r r a y L e n g t h = 7 ;
2 char name [ a r r a y L e n g t h ] = "Mollie" ;
3 i n t numVowels ( 0 ) ;
4 f o r ( char p t r = name ; p t r < name + a r r a y L e n g t h ; ++ p t r ) {
5 switch ( p t r ) {
6 case A :
7 case a :
8 case E :
9 case e :
10 case I :
11 case i :
12 case O :
13 case o :
14 case U :
15 case u :
16 numVowels ++;
17 }
18 }
19 c o u t << name << " has " << numVowels << " vowels.\n" ;