Contenidos 1. Introducción a las variables untero 2. Reaso: - oerador de dirección: & - referencias 3. Declaración de variables de tio untero 4. Inicialización de variables de tio untero - El untero nulo: 5. Valor auntado or un untero: Indirección de unteros 6. Aritmética de unteros 7. Relación entre Arrays y unteros 8. Cadenas y unteros. 9. Punteros a estructuras. 1 Introducción El untero es una técnica muy otente que hace que la rogramación C++ sea tan utilizada. La técnica de unteros aoya a la rogramación orientada a objetos, que es una de las grandes diferencias entre C y C++. Definición: Un untero es una variable que almacena una dirección de memoria. Hasta ahora hemos visto variables 102 = que almacenan datos; los unteros almacenan direcciones de otras variables. 102 = x es una variable untero 2
REPASO: Oerador de dirección: & Cuando se declara una variable, se le asocian tres características: - nombre de la variable - tio de la variable - dirección de memoria char x = ; El valor de la variable x es. La dirección de memoria es. 100 g 0000001 MEMORIA x Para conocer la dirección de memoria donde se encuentra almacenada la variable, se uede utilizar el oerador &. cout << x; cout << &x; Se visualiza el valor: Se visualiza la dirección: 3 REPASO: Referencias Puede ser interesante declarar dos variables con la misma dirección de memoria. Para realizar ésta tarea también utilizamos el oerador &. 100 <tio> & <variable> = <variable>; g 0000001 MEMORIA z = x = #include <iostream.h> int main() { char x = ; char & z = x; cout << x << z; z = b ; cout << x << z; return 0; } La dirección de la variable z es la misma que la dirección de la variable x // x también vale b z y x son nombres diferentes ara la misma variable 4
Declaración de una variable de tio untero Para declarar una variable de tio untero, se utiliza el símbolo *. Además, la declaración de una variable de tio untero debe indicar al comilador el tio de dato al que aunta el untero. Sintaxis <tio> * <nombre_del_untero> ; Así, odemos hablar de untero a entero, untero a char, untero a float, etc. char * ; int *r ; Como ara el resto de variables, C++ no inicializa automáticamente los unteros. 102 GUARRERIA Dirección de memoria alta = = r = x Dirección de memoria baja 5 Inicialización de una variable de tio untero Es reciso inicializar las variables de tio untero antes de su uso. La inicialización roorciona al untero una dirección de memoria a la que auntar. A) Inicializar un untero a una dirección nula. char * = ; 0 = = r El untero aunta a la dirección 0. El untero no es una dirección de una variable en memoria. El untero nulo roorciona al rograma una manera de saber si un untero aunta a una dirección válida. 102 Dirección de memoria alta = x Dirección de memoria baja 6
Inicialización de una variable de tio untero Para oder usar el untero nulo, odemos hacer una de éstas dos cosas: - definirlo en la cabecera de nuestro rograma: # define 0 - incluir alguno de los archivos de cabecera donde ya se encuentra definido: # include <stdio.h> # include <string.h> 7 Inicialización de una variable de tio untero B) Inicializar un untero a una dirección de memoria válida Para asignar una dirección de memoria a un untero, se utiliza el oerador de dirección &. El oerador & alicado a una variable, devuelve la dirección donde se almacena dicha variable. &x = 0 Dirección de memoria alta = = r char * = ; char x = ; = &x ; aunta a x x 102 = x 8
Inicialización de una variable de tio untero B) Inicializar un untero a una dirección de memoria válida La inicialización también se uede hacer en la declaración. char x = ; char * = &x ; Otra forma de reresentar unteros = Es imortante tener en cuenta que el untero debe auntar a una variable del mismo tio. char x = ; int * = &x ; Error! x = 100 g 0000001 MEMORIA 9 Indirección de unteros Una vez definida e inicializada una variable de tio untero, disonemos de un mecanismo ara obtener el dato que almacena esa dirección de memoria. El símbolo * se llama también oerador de indirección y sirve ara acceder al valor al que aunta el untero. char x = ; char * = &x ; cout << *; // muestra or antalla la letra x & Oerador de dirección: Obtiene la dirección de una variable * Declara una variable untero. * Oerador de indirección. Obtiene el valor auntado or el untero. 10
Ejemlo: int y=5; int x= y*10; int * =&x; cout << *; cout << ; cout << &; Muestra el valor auntado or Muestra la dirección a la que aunta Muestra la dirección donde se almacena 100 50 5 0000001 = = x = y x 50 MEMORIA 11 Ejemlo: char c1, c2 = A ; char *1=, *2= ; 1=&c1; 2=&c2; *1 = *2; =2 =1 cout << El valor de c1 es: << c1; cout << El valor de c1 es: << *1; cout << El valor de c2 es: << c2; cout << El valor de c2 es: << *2; 100 A A? =c2 =c1 MEMORIA 12
Ejemlo: int *=; int x, y, z; =&x; x=2; y=*; * =9; int *q=, *r =; q=; r=; *r=*r+y; z y x 2 29 11 q r 13 Ejemlo: int a=10; int *; cout << ; //valor indefinido cout << *; //valor indefinido =&a; // ahora se inicializa, ero tarde. cout << ; cout << *; int a=10; int * = ; * = 9 ; Es correcto? El untero se inicializa desués de sus 2 rimeros usos. Si en vez de hacer una lectura, hubiésemos hecho una escritura, *=9, el resultado odría haber sido fatal, ya que odríamos haber accedido a osiciones de memoria indebidas. Hay que tener cuidado con no dejar un untero sin inicializar 14
Aritmética de unteros Un untero es una dirección de memoria. Las oeraciones ermitidas son: Incrementar y decrementar unteros, Sumar y restar un entero a un untero En éstas oeraciones el tio del untero es fundamental, or ejemlo si el untero es de tio int, cuando sea incrementado, lo será en 2 bytes, ara que el untero aunte al siguiente entero, no al siguiente byte. int *=; int x, y, z; = &x; ++; 1 2 x y z MEMORIA 15 Aritmética de unteros De modo similar ocurre con estructuras más comlejas. Por ejemlo si definimos la siguiente estructura: struct disco { char titulo[30]; int num_canciones; float recio; }; disco cd1 = { El iano, 15, 18}, cd2 = { Dirty work, 10, 12}; disco *_cd =&cd1; _cd = _cd + 1; Cada variable de tio disco ocua 36 bytes de memoria _cd 1 2 cd1 cd2 16
Relación entre arrays y unteros Existe una fuerte relación entre un vector y un untero. Un array es un untero. char letras[4]; letras 107 b h t 43 63 100 102 103 Cuando declaramos una variable de tio array, lo que en realidad estamos haciendo es crear un untero constante cuyo nombre no ocua memoria. cout << letras[0]; cout << *letras; cout << letras [1]; equivale a : cout << *(letras+1); cout << letras[3]; cout << *(letras+3); 17 Relación entre arrays y unteros. Ejemlo: (1) (2) int v[10]={6,0,5, 7,4,3,2,2,4,9 }; int *; = v; = v+2; El untero aunta a donde aunta v (3) (3) = &v[1]; v = ; ERROR: v es un untero constante, y or tanto no uede auntar a otro sitio (1) (2) 5 0 6 v[1] = v 18
Relación entre vectores y unteros El nombre del array sin índice se utiliza como la dirección de comienzo en la que está almacenado el array. La aritmética de unteros se utiliza de forma habitual ara acceder secuencialmente a los elementos de una array. Esta forma de acceso es más ráida que utilizar un índice. Ejemlo: int temeratura[ 10 ]; int *; = temeratura; for (int i = 0; i<10; i++) { * = 0; ++; } 19 Cadenas y unteros También odemos utilizar aritmética de auntadores ara recorrer cadenas. Ejemlo: char nombre_comleto[20] = Carmen Pérez ; char *; char *nombre; char *aellido; nombre_comleto = nombre_comleto; while ( *!= ) ++; * = \0 ; nombre = nombre_comleto; ++; aellido = ; = C a r m e n \0 P é r e z \0 \0 nombre aellido 20
Punteros a estructuras Podemos declarar un untero a una estructuras tal y como se declara ara cualquier otro tio de dato. struct disco { char titulo[30]; int num_canciones; float recio; }; disco cd1 = { El iano, 15, 18}; disco * =&cd1; Para acceder a los miembros, tenemos dos osibilidades: A) Utilizando el oerador unto (.) sobre el valor auntado or el untero (*).titulo B) Utilizando el oerador titulo 21 Punteros a estructuras 0 1 9 mis_cds = "El iano" 15 18 18112003" "18 Tracks" 18 20,5 "12122001".. "Dirty work" 10 12,75 "10091" disco * = ; = mis_cds; for (int i = 0; i<10; i++) { cout << (*).titulo; cout << (*).recio; ++; } for (int i = 0; i<10; i++) { cout << ->titulo; cout << ->recio; ++; } 22
Puntero a untero Un untero uede auntar a una variable de tio untero. Esto se utiliza con mucha frecuencia en rogramas comlejos de C++. Para declararlo onemos dos asteriscos (**) int x = 4; int * = ; int **q = ; = &x; q = &; cout << *; cout << **q; x q Estas dos instrucciones tienen el mismo efecto 4 23 Ejemlo: int x = 10, y = 5, z; int *, *q, *r; r = &z; *r =x; q = &x; *q =*r+4; =r; *=*q + *r + y ; cout << x; cout << y; cout << z; Cuál es la salida del siguiente fragmento de código? 24
Resumen Un untero es una variable que uede almacenar una dirección de memoria. El oerador de dirección &, se utiliza ara obtener la dirección de memoria de una variable. El símbolo * se utiliza ara declarar una variable de tio untero. El oerador de indirección * se utiliza ara acceder al valor auntado or un untero. Se llama de indirección, orque se accede de manera indirecta al valor almacenado en una dirección de memoria. 25