Docsity
Docsity

Prepara tus exámenes
Prepara tus exámenes

Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity


Consigue puntos base para descargar
Consigue puntos base para descargar

Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium


Orientación Universidad
Orientación Universidad


Punteros a objetos struct y class en C++, Apuntes de Programación Informática

Cómo un puntero puede apuntar a un objeto de estructura o clase en c++. Se detalla cómo se asignan y se acceden a los miembros de estos objetos a través de punteros, y se comparan arrays y punteros constantes. Además, se presenta un ejemplo de ordenación de un array de enteros usando punteros a funciones.

Tipo: Apuntes

2016/2017

Subido el 16/04/2017

rayohielo
rayohielo 🇪🇸

3.8

(26)

31 documentos

1 / 34

Toggle sidebar

Esta página no es visible en la vista previa

¡No te pierdas las partes importantes!

bg1
Metodología de la Programación
Tema 2. Punteros y memoria dinámica
Andrés Cano Utrera
Departamento de Ciencias de la Computación e I.A.
ETSIIT Universidad de Granada
Curso 2014-15
DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 1 / 134
Contenido del tema
Parte I: Tipo de Dato Puntero
1Definición y Declaración de variables
2Operaciones con punteros
3Punteros y arrays
4Punteros y cadenas
5Punteros, struct y class
6Punteros y funciones
7Punteros a punteros
8Punteros y const
9Arrays de punteros
10 Punteros a funciones
11 Errores comunes con punteros
Parte II: Gestión Dinámica de Memoria
12 Estructura de la memoria
13 Gestión dinámica de la memoria
14 Objetos Dinámicos Simples
15 Objetos dinámicos compuestos
16 Ejemplo: Objetos dinámicos autoreferenciados
17 Arrays dinámicos
18 Matrices dinámicas
DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 2 / 134
Motivación
Motivación
En muchos problemas es difícil saber en tiempo de compilación la
cantidad de memoria que se va a necesitar para almacenar los datos
que se requieren para dicho problema.
Este problema tendría solución si pudieramos definir variables cuyo
espacio se reserva en tiempo de ejecución.
La memoria dinámica permite justamente eso, crear variables en
tiempo de ejecución.
La gestión de esta memoria es responsabilidad del programador.
Para poder realizar la gestión es necesario el uso de variables tipo
puntero.
DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 3 / 134
Parte I
Tipo de Dato Puntero
DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 4 / 134
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22

Vista previa parcial del texto

¡Descarga Punteros a objetos struct y class en C++ y más Apuntes en PDF de Programación Informática solo en Docsity!

Metodología de la Programación

Tema 2. Punteros y memoria dinámica

Andrés Cano Utrera

([email protected])

Departamento de Ciencias de la Computación e I.A.

ETSIIT Universidad de Granada

Curso 2014-

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 1 / 134

Contenido del tema

Parte I: Tipo de Dato Puntero

(^1) Definición y Declaración de variables

2 Operaciones con punteros (^3) Punteros y arrays (^4) Punteros y cadenas

5 Punteros, struct y class (^6) Punteros y funciones (^7) Punteros a punteros (^8) Punteros y const

(^9) Arrays de punteros (^10) Punteros a funciones (^11) Errores comunes con punteros

Parte II: Gestión Dinámica de Memoria

(^12) Estructura de la memoria (^13) Gestión dinámica de la memoria (^14) Objetos Dinámicos Simples

(^15) Objetos dinámicos compuestos (^16) Ejemplo: Objetos dinámicos autoreferenciados (^17) Arrays dinámicos

(^18) Matrices dinámicas DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 2 / 134 Motivación

Motivación

En muchos problemas es difícil saber en tiempo de compilación la

cantidad de memoria que se va a necesitar para almacenar los datos

que se requieren para dicho problema.

Este problema tendría solución si pudieramos definir variables cuyo

espacio se reserva en tiempo de ejecución.

La memoria dinámica permite justamente eso, crear variables en

tiempo de ejecución.

La gestión de esta memoria es responsabilidad del programador.

Para poder realizar la gestión es necesario el uso de variables tipo

puntero.

Parte I

Tipo de Dato Puntero

Definición y Declaración de variables

Contenido del tema

(^1) Definición y Declaración de variables (^2) Operaciones con punteros (^3) Punteros y arrays (^4) Punteros y cadenas (^5) Punteros, struct y class (^6) Punteros y funciones (^7) Punteros a punteros (^8) Punteros y const (^9) Arrays de punteros

(^10) Punteros a funciones

11 Errores comunes con punteros

(^12) Estructura de la memoria (^13) Gestión dinámica de la memoria (^14) Objetos Dinámicos Simples (^15) Objetos dinámicos compuestos (^16) Ejemplo: Objetos dinámicos

autoreferenciados (^17) Arrays dinámicos 18 Matrices dinámicas

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 5 / 134

Definición y Declaración de variables

Definición de una variable tipo puntero

Tipo de dato puntero

Tipo de dato que contiene la dirección de memoria de otro dato.

Incluye una dirección especial llamada dirección nula que es el valor 0.

En C esta dirección nula se suele representar por la constante NULL

(definida en stdlib.h en C o en cstdlib en C++).

Sintaxis

*;

es el tipo de dato cuya dirección de memoria contiene

es el nombre de la variable puntero.

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 6 / 134 Definición y Declaración de variables

Ejemplo: Declaración de punteros

4 // Se declara variable de tipo entero

5 int i=5;

7 // Se declara variable de tipo char

8 char c=’a’;

10 // Se declara puntero a entero

11 int * ptri;

13 // Se declara puntero a char

14 char * ptrc;

Definición y Declaración de variables

Ejemplo: Declaración de punteros

// Se declara la variable de tipo entero

int i=5;

// Se declara la variable de tipo char

char c=’a’;

// Se declara puntero a entero

int * ptri;

// Se declara el puntero a char

char * ptrc;

1001

1002

1003

1004

1005

1006

1007

1008

1009

1010

1011

1012

i

5

a c

ptri

????

ptrc

????

Operaciones con punteros

Operador de indirección *

* devuelve el valor del objeto apuntado por .

char c *ptrc;

.............

// Hacemos que el puntero apunte a c

ptrc = &c;

// Cambiamos contenido de c mediante ptrc

*ptrc = ’A’; // equivale a c = ’A’

ptrc c

A

ptrc es un puntero a caracter que contiene la dirección de c, por

tanto, la expresión *ptrc es el objeto apuntado por el puntero, es

decir, c.

Un puntero contiene una dirección de memoria y se puede interpretar como

un número entero aunque un puntero no es un número entero. Existen un

conjunto de operadores que se pueden aplicar sobre punteros (como

veremos más adelante): +, −, ++, −−,! =, ==

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 13 / 134

Operaciones con punteros

Operador de indirección *

// Se declara la variable de tipo entero

int i=5;

// Se declara la variable de tipo char

char c=’a’;

// Se declara puntero a entero

int * ptri;

// Se declara el puntero a char

char * ptrc;

// ptri apunta a la variable i

ptri=&i;

// ptrc apunta a c

ptrc=&c;

//cambia contenido con ptrc

(^1001) *ptrc=’A’;

1002

1003

1004

1005

1006

1007

1008

1009

1010

1011

1012

i

5

c

ptri

1001

ptrc

1003

A

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 14 / 134 Operaciones con punteros

Asignación e inicialización de punteros

Un puntero se puede inicializar con la dirección de una variable:

int a;

int *ptri = &a;

A un puntero se le puede asignar una dirección de memoria. La única

dirección de memoria que se puede asignar directamente a un puntero

es la dirección nula:

int *ptri = 0;

Operaciones con punteros

Asignación e inicialización de punteros

La asignación sólo está permitida entre punteros de igual tipo.

int a=7;

int *p1=&a;

char *p2=&a; //ERROR: char p2 = reinterpret_cast<char>(&a);

int *p3=p1;

asignacionPunteros.cpp: En la función ‘int main()’: asignacionPunteros.cpp:8:14: error: no se puede convertir ‘int’ a ‘char’ en la inicialización

Operaciones con punteros

Asignación e inicialización de punteros

Un puntero debe estar correctamente inicializado antes de usarse

int a=7;

int *p1=&a, *p2;

*p1 = 20;

*p2 = 30; // Error

Violación de segmento (‘core’ generado)

Es conveniente inicializar los punteros en la declaración, con el puntero

nulo: 0

int *p2=0;

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 17 / 134

Operaciones con punteros

Ejemplo

int main() {

char y = 5, z = 3;

char *nptr;

char *mptr;

1007

1003

1002

1001

nptr

z

y

? mptr

3

5

?

nptr = &y;

1007

1003

1002

1001

1001 nptr

z

y

? mptr

3

5

z = *nptr; (^1003 1001) nptr

5

?

1002

1001

mptr

z

y

5

1007

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 18 / 134 Operaciones con punteros

*nptr = 7; 1003 1001 nptr

1007?

1002

1001

mptr

z

y

5

7

mptr = nptr; 1003 1001 nptr

1007

1002

1001

mptr

z

y

5

7

1001

mptr = &z; (^1003 1001) nptr

1007

1002

1001

mptr

z

y

5

7

1002

Operaciones con punteros

*mptr = *nptr; (^1003 1001) nptr

1007

1002

1001

mptr

z

y

7

7

1002

y = (*mptr) + 1;

}

(^1003 1001) nptr

1007

1002

1001

mptr

z

y

7

8

1002

Operaciones con punteros

Operadores relacionales: otro ejemplo

int *p1, *p2, n1 = 5, n2 = 5;

p1 = &n1;

p2 = &n2;

if (p1 == p2)

cout << "Punteros iguales\n";

else

cout << "Punteros diferentes\n";

if (*p1 == *p2)

cout << "Valores iguales\n";

else

cout << "Valores diferentes\n";

p1 5 n

p2 5 n

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 25 / 134

Operaciones con punteros

Operadores relacionales: otro ejemplo (ej. animado)

// Se declaran las variables

int *p1, *p2, n1=5, n2=5;

// Se asignan los punteros

p1=&n1;

p2=&n2;

// Se hacen las operaciones sobre ellos

if (p1 == p2)

cout << “Punteros iguales ”<< endl;

else

cout << “Punteros distintos ”<< endl;

if(*p1 == *p2)

cout << “Valores iguales”<< endl;

else

(^1001) cout << “Valores diferentes ”<< endl;

1002

1003

1004

1005

1006

1007

1008

1009

1010

1011

1012

p

p

n

5

n

5

1009

1011

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 26 / 134 Operaciones con punteros

Operadores relacionales

Operadores <, >, <=, >=

Los operadores <, >, <= y >= tienen sentido para conocer la

posición relativa de un objeto respecto a otro en la memoria.

Sólo son útiles si los dos punteros apuntan a objetos cuyas posiciones

relativas guardan relación (por ejemplo, elementos del mismo array).

p = &v[2];

q = &v[4];

2 6 3 5 3

q

v

p

p==q false

p!=q true

p==q true

p<q true

p>q false

p<=q true

p>=q false

Operaciones con punteros

Operadores aritméticos

Los operadores +, -, ++, –, += y -= son aplicables a punteros.

Al usar estos operadores, el valor del puntero (la dirección que

almacena) se comporta CASI como un número entero.

Al sumar o restar un número N al valor del puntero, éste se

incrementa o decrementa un determinado número de posiciones, en

función del tipo de dato apuntado, según la fórmula:

N ∗ sizeof (tipobase)

Esto proporciona una forma rápida de acceso a los elementos de un

array, aprovechando que todos sus elementos se almacenan en

posiciones sucesivas.

Operaciones con punteros

Operadores aritméticos

Situación inicial:

int v [5] = {2, 6, 3, 5, 3};

int *p;

p = &v[2];

0 1 2 3 4

p

vv 22 66 33

p

Si sumamos 1 a p:

p++; // p=p+

0 1 2 3 4

v 2 6 3 5 3

p

v 2 6 3 5 3

p

Si sumamos 2 a p:

p+=2; // p=p+

0 1 2 3 4

v 2 6 3 5 3

p

v 2 6 3 5 3

p

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 29 / 134

Operaciones con punteros

Operadores aritméticos

¿Qué devuelve q - p?

p = &v[2];

q = &v[4];

2 6 3 5 3

q

v

p

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 30 / 134 Punteros y arrays

Contenido del tema

1 Definición y Declaración de variables (^2) Operaciones con punteros (^3) Punteros y arrays (^4) Punteros y cadenas (^5) Punteros, struct y class (^6) Punteros y funciones (^7) Punteros a punteros (^8) Punteros y const (^9) Arrays de punteros

(^10) Punteros a funciones

(^11) Errores comunes con punteros

(^12) Estructura de la memoria (^13) Gestión dinámica de la memoria (^14) Objetos Dinámicos Simples (^15) Objetos dinámicos compuestos (^16) Ejemplo: Objetos dinámicos

autoreferenciados (^17) Arrays dinámicos (^18) Matrices dinámicas

Punteros y arrays

Punteros y arrays

Los punteros y los arrays están estrechamente vinculados.

Al declarar un array

[<n_elem>]

(^1) Se reserva memoria para almacenar <n_elem> elementos de tipo

.

(^2) Se crea un puntero CONSTANTE llamado que apunta a la

primera posición de la memoria reservada.

Por tanto, el identificador de un array, es un puntero CONSTANTE a

la dirección de memoria que contiene el primer elemento. Es decir, v es

igual a &(v[0]).

Punteros y arrays

Algunos Ejemplos III

(^5) Recorrer e imprimir los elementos de un array:

int v[10] = {3,5,2,7,6,7,5,1,2,5};

int *p=v;

for (; p<v+10; ++p)

cout << *p << endl;

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 37 / 134

Punteros y cadenas

Contenido del tema

(^1) Definición y Declaración de variables (^2) Operaciones con punteros (^3) Punteros y arrays (^4) Punteros y cadenas (^5) Punteros, struct y class (^6) Punteros y funciones (^7) Punteros a punteros (^8) Punteros y const (^9) Arrays de punteros (^10) Punteros a funciones 11 Errores comunes con punteros

(^12) Estructura de la memoria (^13) Gestión dinámica de la memoria (^14) Objetos Dinámicos Simples (^15) Objetos dinámicos compuestos (^16) Ejemplo: Objetos dinámicos

autoreferenciados (^17) Arrays dinámicos 18 Matrices dinámicas

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 38 / 134 Punteros y cadenas

Punteros y cadenas

Según vimos en el tema anterior:

Una cadena de caracteres estilo C es un array de tipo char

de un tamaño determinado acabado en un carácter especial,

el carácter ’\0’ (carácter nulo), que marca el fin de la

cadena.

También se vio que:

Un literal de cadena de caracteres es un array constante de

char con un tamaño igual a su longitud más uno.

"Hola" de tipo const char[5]

"Hola mundo" de tipo const char[11]

Realmente, C++ considera que un literal cadena de caracteres es de

tipo const char *

Punteros y cadenas

Ejemplos de uso

Calcular longitud cadena:

const char *cadena="Hola"; // Se reservan 5

const char *p;

int i=0;

for(p=cadena;*p!=’\0’;++p)

++i;

cout << "Longitud: " << i << endl;

Eliminar los primeros caracteres de la cadena:

const char *cadena="Hola Adios";

cout << "Original: " << cadena << endl

<< "Sin la primera palabra: " << cadena+5;

Punteros y cadenas

Inicialización de cadenas

Notación de corchetes

Se copia el contenido del literal en el array.

Es posible modificar caracteres de la cadena.

char cad1[]="Hola"; // Copia literal "Hola" en cad

cad1[2] = ’b’; // cad1 contiene ahora "Hoba"

Notación de punteros

Copia la dirección de memoria de la constante literal en el puntero.

No es posible modificar caracteres de la cadena.

const char *cad2="Hola"; // Se asignan los punteros

cad2[2] = ’b’; // Error

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 41 / 134

Punteros, struct y class

Contenido del tema

(^1) Definición y Declaración de variables (^2) Operaciones con punteros (^3) Punteros y arrays (^4) Punteros y cadenas (^5) Punteros, struct y class (^6) Punteros y funciones (^7) Punteros a punteros (^8) Punteros y const (^9) Arrays de punteros (^10) Punteros a funciones 11 Errores comunes con punteros

(^12) Estructura de la memoria (^13) Gestión dinámica de la memoria (^14) Objetos Dinámicos Simples (^15) Objetos dinámicos compuestos (^16) Ejemplo: Objetos dinámicos

autoreferenciados (^17) Arrays dinámicos 18 Matrices dinámicas

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 42 / 134 Punteros, struct y class

Punteros a objetos struct o class

Un puntero también puede apuntar a un objeto de estructura o clase:

struct Persona{

int edad;

double estatura;

};

Persona pepe;

Persona *ptr;

pepe.edad=27;

pepe.estatura=1.89;

ptr = &pepe;

cout << (*ptr).edad << endl;

edad

ptr

pepe

estatura

Punteros, struct y class

Punteros a objetos struct o class

Igualmente un puntero puede apuntar a un objeto de una clase:

class Persona{

int edad;

double estatura;

public:

int getEdad() const;

double getEstatura() const;

void setEdad(int anios);

void setEstatura(double metros);

Persona pepe, *ptr;

pepe.setEdad(27); pepe.setEstatura(1.89);

// pepe.edad=27; CUIDADO: no valido desde fuera

//de metodo de la clase, edad es privado

ptr = &pepe;

cout << (*ptr).getEdad() << endl;

// cout << (*ptr).edad << endl; CUIDADO: no valido

//desde fuera de metodo de la clase, edad es privado

edad

ptr

pepe

estatura 27 1.

Punteros, struct y class

Un struct o class puede contener campos de tipo puntero.

struct Persona{

string nombre;

int edad;

double estatura;

Persona *pareja;

};

Persona pepe={"Pepe",27,1.89,0},

maria={"Maria",25,1.74,0},

*ptr=&pepe;

pepe.pareja=&maria;

maria.pareja=&pepe;

cout << "La pareja de "

<< ptr->nombre

<< " es "

<< ptr->pareja->nombre

<< endl;

pepe "Pepe" 27 1.

nombre edad estaturapareja

ptr

nombre edad estaturapareja

maria "Maria" 25 1.

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 49 / 134

Punteros, struct y class

Ejemplo con class

class Persona{ string nombre; int edad; double estatura; Persona *pareja; public: Persona(string name, int anios, double metros); int getEdad() const; double getEstatura() const; Persona *getPareja() const; void setPareja(Pareja *compa); ... }; Persona pepe("Pepe",27,1.89), maria("Maria",25,1.74), *ptr=&pepe; pepe.setPareja(&maria); maria.setPareja(&pepe); cout << "La pareja de " << ptr->getNombre() << " es " << ptr->getPareja()->getNombre() << endl;

pepe "Pepe" 27 1.

nombre edad estaturapareja

ptr

nombre edad estaturapareja

maria "Maria" 25 1.

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 50 / 134 Punteros, struct y class

Persona::Persona(string name, int anios,

double metros){

nombre=name;

edad=anios;

estatura=metros;

pareja=0;

}

Pareja* Persona::getPareja() const{

return pareja;

}

void Persona::setPareja(Pareja *compa){

pareja=compa;

}

pepe "Pepe" 27 1.

nombre edad estaturapareja

ptr

nombre edad estaturapareja maria "Maria" 25 1.

Punteros y funciones

Contenido del tema

1 Definición y Declaración de variables (^2) Operaciones con punteros (^3) Punteros y arrays (^4) Punteros y cadenas (^5) Punteros, struct y class (^6) Punteros y funciones (^7) Punteros a punteros (^8) Punteros y const (^9) Arrays de punteros (^10) Punteros a funciones (^11) Errores comunes con punteros

(^12) Estructura de la memoria (^13) Gestión dinámica de la memoria (^14) Objetos Dinámicos Simples (^15) Objetos dinámicos compuestos (^16) Ejemplo: Objetos dinámicos

autoreferenciados (^17) Arrays dinámicos (^18) Matrices dinámicas

Punteros y funciones

Punteros y funciones I

Un puntero puede ser un argumento de una función

Puede usarse por ejemplo para simular el paso por referencia.

1 void incrementa(int* p){

2 (*p)++;

3 }

4 int main()

5 {

6 int var = 1;

7 cout << var << endl; // 1

8 incrementa(&var);

9 cout << var << endl; // 2

10 }

Situación en línea 1

var 1

main()

p

Incrementa()

Situación en línea 3

var

main()

p

Incrementa()

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 53 / 134

Punteros y funciones

Punteros y funciones II

Otra posibilidad

1 void incrementa(int* p){

2 (*p)++;

3 }

4 int main()

5 {

6 int var = 1;

7 int *ptr=&var;

8 cout << var << endl; // 1

9 incrementa(ptr);

10 cout << var << endl; // 2

11 }

Situación en línea 1

main()

Incrementa()

ptr var

p

Situación en línea 3

main()

Incrementa()

ptr var

p

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 54 / 134 Punteros y funciones

Punteros y funciones III

El puntero se puede pasar por referencia

Si deseamos modificar el puntero original, podemos usar paso por

referencia.

1 void incrementa(int* &p){

2 (*p)++;

3 p=0;

4 }

5 int main()

6 {

7 int var = 1;

8 int *ptr=&var;

9 cout << var << endl; // 1

10 incrementa(ptr);

11 cout << var << endl; // 2

12 }

Situación en línea 1

main()

Incrementa()

ptr var

p

Situación en línea 4

main()

Incrementa()

ptr var

p

Punteros y funciones

Punteros y funciones IV

Devolución de punteros a datos locales

La devolución de punteros a datos locales a una función es un error típico:

Los datos locales se destruyen al terminar la función.

int *doble(int x)

{

int a;

a = x*2;

return &a;

}

int main(){

int *x;

x = doble(3);

cout << *x << endl;

}

Punteros y const

Punteros y const I

Cuando tratamos con punteros manejamos dos datos:

El dato puntero.

El dato que es apuntado.

Pueden ocurrir las siguientes situaciones:

Ninguno sea const double *p;

Sólo el dato apuntado sea const const double *p;

Sólo el puntero sea const double *const p;

Los dos sean const const double *const p;

Las siguientes expresiones son equivalentes:

const double *p; double const *p;

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 61 / 134

Punteros y const

Punteros y const II

Es posible asignar un puntero no const a uno const, pero no al revés

(en la asignación se hace una conversión implícita).

double a = 1.0;

double * const p=&a; // puntero constante a double

double * q; // puntero no constante a double

q = p; // BIEN: q puede apuntar a cualquier dato

p = q; // MAL: p es constante

Error de compilación:

...error: asignación de la variable de sólo lectura ‘p’

p ha quedado asignado en la declaración de la constante y no admite

cambios posteriores (como buena constante.....)

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 62 / 134 Punteros y const

Punteros y const III

Un puntero a dato no const no puede apuntar a un dato const.

Ejemplo 1

El siguiente código da error ya que &f devuelve un const double *

double *p;

const double f=5.2;

p = &f; // INCORRECTO, ya que permitiría cambiar el

*p = 5.0; // valor de f a través de p

Error de compilación:

...error: conversión inválida de ‘const double’a ‘double’[-fpermissive]

Nota: observad que de permitirse la operación se permitiría cambiar el

valor de f, que fue declarada como constante.

Punteros y const

Punteros y const IV

Ejemplo 2

El siguiente código da error ya que *p devuelve un const double

const double *p;

double f;

p = &f; // (const double *) = (double *)

*p = 5.0; // ERROR: no se puede cambiar el valor

Error de compilación:

...error: asignación de la ubicación de sólo lectura ‘*p’

Punteros y const

Punteros y const V

Ejemplo 3

El siguiente código da error ya que &(vocales[2]) devuelve un const

char *

const char vocales[5]={’a’,’e’,’i’,’o’,’u’};

char *p;

p = &(vocales[2]); // ERROR de compilación

Error de compilación:

...error: conversión inválida de ‘const char’a ‘char’[-fpermissive]

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 65 / 134

Punteros y const

Punteros, funciones y const

Podemos llamar a una función que espera un puntero a dato const con uno a dato no const.

void HacerCero(int *p){

*p = 0;

void EscribirEntero(const int *p){

cout << *p;

int main(){

const int a = 1;

int b=2;

HacerCero(&a); // ERROR

EscribirEntero(&a); // CORRECTO

EscribirEntero(&b); // CORRECTO

Error de compilación:

...error: conversión inválida de ‘const int’a ‘int’[-fpermissive]

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 66 / 134 Punteros y const

Punteros, arrays y const

Dada la estrecha relación entre arrays y punteros, podemos usar un array

de constantes como un puntero a constantes, y al contrario:

const int matConst[5]={1,2,3,4,5};

int mat[3]={3,5,7};

const int *pconst;

int *p;

pconst = matConst; // CORRECTO

pconst = mat; // CORRECTO

p = mat; // CORRECTO

p = matConst; // ERROR

Arrays de punteros

Contenido del tema

1 Definición y Declaración de variables (^2) Operaciones con punteros (^3) Punteros y arrays (^4) Punteros y cadenas (^5) Punteros, struct y class (^6) Punteros y funciones (^7) Punteros a punteros (^8) Punteros y const (^9) Arrays de punteros (^10) Punteros a funciones (^11) Errores comunes con punteros

(^12) Estructura de la memoria (^13) Gestión dinámica de la memoria (^14) Objetos Dinámicos Simples (^15) Objetos dinámicos compuestos (^16) Ejemplo: Objetos dinámicos

autoreferenciados (^17) Arrays dinámicos (^18) Matrices dinámicas

Arrays de punteros

int main(){ const int DIMARRAY=100; const int* arrayPunts[DIMARRAY]; const int arrayInts[DIMARRAY]={5,7,3,2}; int utilArray=4;

for(int i=0; i< utilArray; i++){ arrayPunts[i] = &arrayInts[i]; }

cout<<"Array antes de ordenar (impreso con arrayPunts):"<<endl; for(int i=0; i< utilArray; i++){ cout << *arrayPunts[i] << " "; } cout << endl;

ordenacionPorSeleccion(arrayPunts,utilArray);

cout<<"Array despues de ordenar (impreso con arrayPunts):"<<endl; for(int i=0; i< utilArray; i++){ cout << *arrayPunts[i] << " "; } cout << endl;

cout<<"Array despues de ordenar (impreso con arrayInts):"<<endl; for(int i=0; i< utilArray; i++){ cout << arrayInts[i] << " "; } cout << endl; }

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 73 / 134

Arrays de punteros

Arrays de punteros

Array antes de ordenar (impreso con arrayPunts):

Array despues de ordenar (impreso con arrayPunts):

Array despues de ordenar (impreso con arrayInts):

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 74 / 134 Arrays de punteros

Arrays de punteros

Otro ejemplo de array de punteros a enteros

Podemos usar un array de punteros a cadenas de caracteres estilo C.

’O’ ’r’ ’o’ ’s’’\0’

’C’ ’p’ ’a’ ’s’ ’\0’

’E’ ’s’ ’p’ ’a’’d’ ’a’ ’s’ ’\0’

’B’ ’a’ ’s’ ’t’ ’o’ ’s’ ’\0’

’o’

palosBaraja

Arrays de punteros

Arrays de punteros

#include

using namespace std;

int main(){

const char* const palosBaraja[4]={"Oros", "Copas", "Espadas", "Bastos"};

cout<<"Palos de la baraja: ";

for(int i=0; i< 4; i++){

cout << palosBaraja[i] << " ";

cout << endl;

Palos de la baraja: Oros Copas Espadas Bastos

Punteros a funciones

Contenido del tema

(^1) Definición y Declaración de variables (^2) Operaciones con punteros (^3) Punteros y arrays (^4) Punteros y cadenas (^5) Punteros, struct y class (^6) Punteros y funciones (^7) Punteros a punteros (^8) Punteros y const (^9) Arrays de punteros

(^10) Punteros a funciones

11 Errores comunes con punteros

(^12) Estructura de la memoria (^13) Gestión dinámica de la memoria (^14) Objetos Dinámicos Simples (^15) Objetos dinámicos compuestos (^16) Ejemplo: Objetos dinámicos

autoreferenciados (^17) Arrays dinámicos 18 Matrices dinámicas

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 77 / 134

Punteros a funciones

Punteros a funciones

Puntero a función

Contiene la dirección de memoria de una función, o sea la dirección donde

comienza el código que realiza la tarea de la función apuntada.

Con estos punteros podemos hacer las siguientes operaciones:

Usarlos como parámetro a una función.

Ser devueltos por una función con return.

Crear arrays de punteros a funciones.

Asignarlos a otras variables puntero a función.

Usarlos para llamar a la función apuntada.

DECSAI (Universidad de Granada) Metodología de la Programación Curso 2014-15 78 / 134 Punteros a funciones

Declaración de variables o parámetro puntero a función

Declaración de variables o de parámetros puntero a función

Puntero a función que devuelve bool y que tiene dos parámetros de tipo

int:

bool ( *comparar )( int, int );

Los paréntesis alrededor de *comparar son obligatorios para indicar que es

un puntero a función.

Cuidado con los paréntesis

Si no incluimos los paréntesis, estaríamos declarando una función que

recibe dos enteros y devuelve un puntero a un valor bool.

bool *comparar( int, int );

Punteros a funciones

Ejemplo de punteros a funciones

Ordenación de un array ascendente o descendentemente

Construimos una función con un parámetro puntero a función para permitir

ordenar ascendente o descendentemente.

bool ascendente( int a, int b ){ return a < b; } bool descendente( int a, int b ){ return a > b; } void ordenarPorSeleccion( int arrayInts[], const int utilArrayInts, bool (comparar)( int, int ) ){ ... if ( !(comparar)( arrayInts[ masPequenoOMasGrande ], arrayInts[ index ] ) ) ... } int main(){ const int DIMARRAY = 10; int array[DIMARRAY] = { 2, 6, 4, 8, 10, 12, 89, 68, 45, 37 };

... ordenarPorSeleccion(array, DIMARRAY, ascendente ); // Ordena ascendentemente

... ordenarPorSeleccion(array, DIMARRAY, descendente ); // Ordena descendentemente }