Fundamentos de la programación 9A · 2013. 9. 4. · Fundamentos de la programación: Punteros y...

Post on 04-Sep-2020

10 views 0 download

Transcript of Fundamentos de la programación 9A · 2013. 9. 4. · Fundamentos de la programación: Punteros y...

9A

GradoenIngenieríaInformáticaGradoenIngenieríadelSoftware

GradoenIngenieríadeComputadores

LuisHernándezYáñez

FacultaddeInformáticaUniversidadComplutense

Fundamentos de la programaciónLuis Hernández Yáñez

Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

Aritmética de punteros 940Recorrido de arrays con punteros 953Referencias 962Listas enlazadas 964

Luis Hernández Yáñez

Página 940Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

Luis Hernández Yáñez

OperacionesaritméticasconpunterosLaaritméticadepunterosesunaaritméticauntantoespecial...

Trabajatomandocomounidaddecálculoeltamañodeltipobaseint dias[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

typedef int* tIntPtr;

tIntPtr punt = dias;

punt empiezaapuntandoalprimerelementodelarray:cout << *punt << endl; // Muestra 31 (primer elemento)

punt++;

punt++ hacequepunt paseaapuntaralsiguienteelementocout << *punt << endl; // Muestra 28 (segundo elemento)

Aladireccióndememoriaactualselesumantantasunidadescomobytes(4)ocupeenmemoriaundatodeesetipo(int)

Página 941Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

Luis Hernández Yáñez

int dias[12] = { 31, 28, 31, 30, 31, 30, 

31, 31, 30, 31, 30, 31 };

typedef int* tIntPtr;

tIntPtr punt = dias;

Página 942Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

...

dias[0] 0F03:1A38

0F03:1A39

0F03:1A3A

0F03:1A3B

dias[1] 0F03:1A3C

0F03:1A3D

0F03:1A3E

0F03:1A3F

dias[2] 0F03:1A40

0F03:1A41

0F03:1A42

0F03:1A43

...

dias 0F07:0417 0F

0F07:0418 03

0F07:0419 1A

0F07:041A 38

punt 0F07:041B 0F

0F07:041C 03

0F07:041D 1A

0F07:041E 38

...

3131

2828

3131

Luis Hernández Yáñez

int dias[12] = { 31, 28, 31, 30, 31, 30, 

31, 31, 30, 31, 30, 31 };

typedef int* tIntPtr;

tIntPtr punt = dias;

punt++;

punt‐‐ hacequeapuntealelementoanterior

Página 943Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

...

dias[0] 0F03:1A38

0F03:1A39

0F03:1A3A

0F03:1A3B

dias[1] 0F03:1A3C

0F03:1A3D

0F03:1A3E

0F03:1A3F

dias[2] 0F03:1A40

0F03:1A41

0F03:1A42

0F03:1A43

...

dias 0F07:0417 0F

0F07:0418 03

0F07:0419 1A

0F07:041A 38

punt 0F07:041B 0F

0F07:041C 03

0F07:041D 1A

0F07:041E 3C

...

3131

2828

3131

Luis Hernández Yáñez

int dias[12] = { 31, 28, 31, 30, 31, 30, 

31, 31, 30, 31, 30, 31 };

typedef int* tIntPtr;

tIntPtr punt = dias;

punt = punt + 2;

Restandopasamosaelementosanteriores

Página 944Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

...

dias[0] 0F03:1A38

0F03:1A39

0F03:1A3A

0F03:1A3B

dias[1] 0F03:1A3C

0F03:1A3D

0F03:1A3E

0F03:1A3F

dias[2] 0F03:1A40

0F03:1A41

0F03:1A42

0F03:1A43

...

dias 0F07:0417 0F

0F07:0418 03

0F07:0419 1A

0F07:041A 38

punt 0F07:041B 0F

0F07:041C 03

0F07:041D 1A

0F07:041E 40

...

3131

2828

3131

Luis Hernández Yáñez

int dias[12] = { 31, 28, 31, 30, 31, 30, 

31, 31, 30, 31, 30, 31 };

typedef int* tIntPtr;

tIntPtr punt = dias;

punt = punt + 2;

int num = punt ‐ dias;

Nºdeelementosentrelospunteros

Página 945Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

...

dias[0] 0F03:1A38

0F03:1A39

0F03:1A3A

0F03:1A3B

dias[1] 0F03:1A3C

0F03:1A3D

0F03:1A3E

0F03:1A3F

dias[2] 0F03:1A40

0F03:1A41

0F03:1A42

0F03:1A43

...

dias 0F07:0417 0F

0F07:0418 03

0F07:0419 1A

0F07:041A 38

punt 0F07:041B 0F

0F07:041C 03

0F07:041D 1A

0F07:041E 3C

...

3131

2828

3131

Luis Hernández Yáñez

Otrotipobaseshort int (2bytes)short int dias[12] = {31, 28, 31, 30,

31, 30, 31, 31, 30, 31, 30, 31};

typedef short int* tSIPtr;

tSIPtr punt = dias;

Página 946Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

...

dias[0] 0F03:1A38

0F03:1A39

dias[1] 0F03:1A3A

0F03:1A3B

dias[2] 0F03:1A3C

0F03:1A3D

dias[3] 0F03:1A3E

0F03:1A3F

dias[4] 0F03:1A40

0F03:1A41

...

dias 0F07:0417 0F

0F07:0418 03

0F07:0419 1A

0F07:041A 38

punt 0F07:041B 0F

0F07:041C 03

0F07:041D 1A

0F07:041E 38

...

3131

2828

3131

3030

3131

Luis Hernández Yáñez

short int dias[12] = {31, 28, 31, 30,

31, 30, 31, 31, 30, 31, 30, 31};

typedef short int* tSIPtr;

tSIPtr punt = dias;

punt++;

Página 947Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

...

dias[0] 0F03:1A38

0F03:1A39

dias[1] 0F03:1A3A

0F03:1A3B

dias[2] 0F03:1A3C

0F03:1A3D

dias[3] 0F03:1A3E

0F03:1A3F

dias[4] 0F03:1A40

0F03:1A41

...

dias 0F07:0417 0F

0F07:0418 03

0F07:0419 1A

0F07:041A 38

punt 0F07:041B 0F

0F07:041C 03

0F07:041D 1A

0F07:041E 3A

...

3131

2828

3131

3030

3131

Luis Hernández Yáñez

short int dias[12] = {31, 28, 31, 30,

31, 30, 31, 31, 30, 31, 30, 31};

typedef short int* tSIPtr;

tSIPtr punt = dias;

punt++;

punt = punt + 3;

Página 948Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

...

dias[0] 0F03:1A38

0F03:1A39

dias[1] 0F03:1A3A

0F03:1A3B

dias[2] 0F03:1A3C

0F03:1A3D

dias[3] 0F03:1A3E

0F03:1A3F

dias[4] 0F03:1A40

0F03:1A41

...

dias 0F07:0417 0F

0F07:0418 03

0F07:0419 1A

0F07:041A 38

punt 0F07:041B 0F

0F07:041C 03

0F07:041D 1A

0F07:041E 40

...

3131

2828

3131

3030

3131

Luis Hernández Yáñez

short int dias[12] = {31, 28, 31, 30,

31, 30, 31, 31, 30, 31, 30, 31};

typedef short int* tSIPtr;

tSIPtr punt = dias;

punt++;

punt = punt + 3;

punt‐‐;

Página 949Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

...

dias[0] 0F03:1A38

0F03:1A39

dias[1] 0F03:1A3A

0F03:1A3B

dias[2] 0F03:1A3C

0F03:1A3D

dias[3] 0F03:1A3E

0F03:1A3F

dias[4] 0F03:1A40

0F03:1A41

...

dias 0F07:0417 0F

0F07:0418 03

0F07:0419 1A

0F07:041A 38

punt 0F07:041B 0F

0F07:041C 03

0F07:041D 1A

0F07:041E 3E

...

3131

2828

3131

3030

3131

Luis Hernández Yáñez

short int dias[12] = {31, 28, 31, 30,

31, 30, 31, 31, 30, 31, 30, 31};

typedef short int* tSIPtr;

tSIPtr punt = dias;

punt++;

punt = punt + 3;

punt‐‐;

tSIPtr punt2;

Página 950Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

...

dias[0] 0F03:1A38

0F03:1A39

dias[1] 0F03:1A3A

0F03:1A3B

dias[2] 0F03:1A3C

0F03:1A3D

dias[3] 0F03:1A3E

0F03:1A3F

dias[4] 0F03:1A40

0F03:1A41

...

dias 0F07:0417 0F

0F07:0418 03

0F07:0419 1A

0F07:041A 38

punt 0F07:041B 0F

0F07:041C 03

0F07:041D 1A

0F07:041E 3E

punt2 0F07:041F ?

3131

2828

3131

3030

3131

Luis Hernández Yáñez

short int dias[12] = {31, 28, 31, 30,

31, 30, 31, 31, 30, 31, 30, 31};

typedef short int* tSIPtr;

siPtr punt = dias;

punt++;

punt = punt + 3;

punt‐‐;

tSIPtr punt2;

punt2 = dias;

Página 951Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

...

dias[0] 0F03:1A38

0F03:1A39

dias[1] 0F03:1A3A

0F03:1A3B

dias[2] 0F03:1A3C

0F03:1A3D

dias[3] 0F03:1A3E

0F03:1A3F

dias[4] 0F03:1A40

0F03:1A41

...

dias 0F07:0417 0F

0F07:0418 03

0F07:0419 1A

0F07:041A 38

punt 0F07:041B 0F

0F07:041C 03

0F07:041D 1A

0F07:041E 3E

punt2 0F07:041F 0F

3131

2828

3131

3030

3131

Luis Hernández Yáñez

short int dias[12] = {31, 28, 31, 30,

31, 30, 31, 31, 30, 31, 30, 31};

typedef short int* tSIPtr;

siPtr punt = dias;

punt++;

punt = punt + 3;

punt‐‐;

tSIPtr punt2;

punt2 = dias;

cout << punt – punt2; // 3

Página 952Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

...

dias[0] 0F03:1A38

0F03:1A39

dias[1] 0F03:1A3A

0F03:1A3B

dias[2] 0F03:1A3C

0F03:1A3D

dias[3] 0F03:1A3E

0F03:1A3F

dias[4] 0F03:1A40

0F03:1A41

...

dias 0F07:0417 0F

0F07:0418 03

0F07:0419 1A

0F07:041A 38

punt 0F07:041B 0F

0F07:041C 03

0F07:041D 1A

0F07:041E 3E

punt2 0F07:041F 0F

3131

2828

3131

3030

3131

33

Luis Hernández Yáñez

Página 953Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

Luis Hernández Yáñez

Punteroscomoiteradoresparaarraysconst int MAX = 100;typedef int tArray[MAX];typedef struct {

tArray elementos;int cont;

} tLista;typedef int* tIntPtr;tLista lista;

Usamosunpunterocomoiterador pararecorrerelarray:tIntPtr punt = lista.elementos;for (int i = 0; i < lista.cont; i++) {

cout << *punt << endl;punt++;

}

Página 954Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

arraypunt.cpparraypunt.cppLuis Hernández Yáñez

...intPtr punt = lista.elementos;

Página 955Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

0 1 2 3 4 5 6 7 8 ... 98 99

4 13 3 47 53 19 7 48lista.elementoslista.elementos

puntpunt

8lista.contlista.cont

Luis Hernández Yáñez

...for (int i = 0; i < lista.cont; i++) {

cout << *punt << endl;punt++;

}

Página 956Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

0 1 2 3 4 5 6 7 8 ... 98 99

4 13 3 47 53 19 7 48lista.elementoslista.elementos

puntpunt

8lista.contlista.cont

0ii

Luis Hernández Yáñez

Página 957Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

0 1 2 3 4 5 6 7 8 ... 98 99

4 13 3 47 53 19 7 48lista.elementoslista.elementos

puntpunt

8lista.contlista.cont

1ii

44

...for (int i = 0; i < lista.cont; i++) {

cout << *punt << endl;punt++;

}

Luis Hernández Yáñez

Página 958Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

0 1 2 3 4 5 6 7 8 ... 98 99

4 13 3 47 53 19 7 48lista.elementoslista.elementos

puntpunt

8lista.contlista.cont

2ii

413413

...for (int i = 0; i < lista.cont; i++) {

cout << *punt << endl;punt++;

}

Luis Hernández Yáñez

...for (int i = 0; i < lista.cont; i++) {

cout << *punt << endl;punt++;

}

Página 959Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

0 1 2 3 4 5 6 7 8 ... 98 99

4 13 3 47 53 19 7 48lista.elementoslista.elementos

puntpunt

8lista.contlista.cont

3ii

......

4133

4133

Luis Hernández Yáñez

...for (int i = 0; i < lista.cont; i++) {

cout << *punt << endl;punt++;

}

Página 960Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

0 1 2 3 4 5 6 7 8 ... 98 99

4 13 3 47 53 19 7 48lista.elementoslista.elementos

puntpunt

8lista.contlista.cont

7ii

41334753197

41334753197

Luis Hernández Yáñez

...for (int i = 0; i < lista.cont; i++) {

cout << *punt << endl;punt++;

}

Página 961Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

0 1 2 3 4 5 6 7 8 ... 98 99

4 13 3 47 53 19 7 48lista.elementoslista.elementos

puntpunt

8lista.contlista.cont

8ii

4133475319748

4133475319748

Luis Hernández Yáñez

Página 962Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

Luis Hernández Yáñez

NombresalternativosparalosdatosUnareferenciaesunanuevaformadellamaraunavariable

Nospermitenreferirnosaunavariableconotroidentificador:int x = 10;int &z = x;

x yz sonahoralamismavariable(compartenmemoria)

Cualquiercambioenx afectaaz ycualquiercambioenz afectaaxz = 30;cout << x;

Lasreferenciasseusanenelpasodeparámetrosporreferencia

Página 963Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

Luis Hernández Yáñez

Página 964Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

Luis Hernández Yáñez

Página 965Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

UnaimplementacióndinámicadelistasenlazadasCadaelementodelalistaapuntaalsiguienteelemento:struct tNodo; // Declaración anticipadatypedef tNodo *tLista;struct tNodo {

tRegistro reg;tLista sig;

};

Unalista(tLista)esunpunteroaunnodo

SielpunterovaleNULL,noapuntaaningúnnodo:listavacía

Unnodo(tNodo)esunelementoseguidodeunalista

tRegistro tListatLista

regreg sigsig

ElementoseguidodeunalistaLista

Vacía¡Definiciónrecursiva!

Luis Hernández Yáñez

Página 966Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

Cadaelementodelalistaensunodo

Apuntaráalsiguienteelementooaninguno(NULL)struct tNodo; // Declaración anticipadatypedef tNodo *tLista;struct tNodo {

tRegistro reg;tLista sig;

};

Además,unpunteroalprimerelemento(nodo)delalistatLista lista = NULL; // Lista vacía

listalista

Luis Hernández Yáñez

Página 967Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

struct tNodo;typedef tNodo *tLista;struct tNodo {

tRegistro reg;tLista sig;

};

tLista lista = NULL; // Lista vacíalista = new tNodo;lista‐>reg = nuevo();lista‐>sig = NULL;

listalista ítem1

Luis Hernández Yáñez

Página 968Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

tLista lista = NULL; // Lista vacíalista = new tNodo;lista‐>reg = nuevo();lista‐>sig = NULL;tLista p;p = lista;

listalista ítem1

pp

Luis Hernández Yáñez

Página 969Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

tLista lista = NULL; // Lista vacíalista = new tNodo;lista‐>reg = nuevo();lista‐>sig = NULL;tLista p;p = lista;p‐>sig = new tNodo;p‐>sig‐>reg = nuevo();p‐>sig‐>sig = NULL;

listalista ítem1

pp

ítem2

Luis Hernández Yáñez

Página 970Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

tLista lista = NULL; // Lista vacíalista = new tNodo;lista‐>reg = nuevo();lista‐>sig = NULL;tLista p;p = lista;p‐>sig = new tNodo;p‐>sig‐>reg = nuevo();p‐>sig‐>sig = NULL;p = p‐>sig;p‐>sig = new tNodo;p‐>sig‐>reg = nuevo();p‐>sig‐>sig = NULL;...

listalista tRegistro tRegistro

pp

tRegistro

Luis Hernández Yáñez

Página 971Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

Usamoslamemoriaquenecesitamos,nimásnimenos

Tantoselementos,tantosnodoshayenlalista

¡Peroperdemoselaccesodirecto!

Algunasoperacionesdelalistasecomplicanyotrasno

Acontinuacióntieneselmódulodelistaimplementadocomolistaenlazada...

listalista tRegistro tRegistro tRegistro

Luis Hernández Yáñez

Página 972Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

struct tNodo;typedef tNodo *tLista;struct tNodo {

tRegistro reg;tLista sig;

};

const string BD = "bd.txt";

void mostrar(tLista lista);void insertar(tLista &lista, tRegistro registro, bool &ok);void eliminar(tLista &lista, int code, bool &ok);tLista buscar(tLista lista, int code); // Devuelve punterovoid cargar(tLista &lista, bool &ok);void guardar(tLista lista);void destruir(tLista &lista); // Liberar la memoria dinámica

listaenlazada.hlistaenlazada.hLuis Hernández Yáñez

Página 973Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

void insertar(tLista &lista, tRegistro registro, bool &ok) {ok = true;tLista nuevo = new tNodo;if (nuevo == NULL) {

ok = false; // No hay más memoria dinámica}else {

nuevo‐>reg = registro;nuevo‐>sig = NULL;if (lista == NULL) { // Lista vacía

lista = nuevo;}else {

tLista p = lista;// Localizamos el último nodo...while (p‐>sig != NULL) {

p = p‐>sig;}p‐>sig = nuevo;

}}

} ...

listaenlazada.cpplistaenlazada.cpp

listalista

nuevonuevo

listalista

nuevonuevo

pp

Luis Hernández Yáñez

Página 974Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

void eliminar(tLista &lista, int code, bool &ok) {ok = true;tLista p = lista;if (p == NULL) {

ok = false; // Lista vacía}else if (p‐>reg.codigo == code) { // El primero

lista = p‐>sig;delete p;

}else {

tLista ant = p;p = p‐>sig;bool encontrado = false;while ((p != NULL) && !encontrado) {

if (p‐>reg.codigo == code) {encontrado = true;

}else {

ant = p;p = p‐>sig;

}} ...

listalista

pp

antant

pp

listalista

Luis Hernández Yáñez

Página 975Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

if (!encontrado) {ok = false; // No existe ese código

}else {

ant‐>sig = p‐>sig;delete p;

}}

}...

listalista

ppantant

Luis Hernández Yáñez

Página 976Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

tLista buscar(tLista lista, int code) {// Devuelve un puntero al nodo, o NULL si no se encuentra

tLista p = lista;bool encontrado = false;while ((p != NULL) && !encontrado) {

if (p‐>reg.codigo == code) {encontrado = true;

}else {

p = p‐>sig;}

}return p;

}

void mostrar(tLista lista) {cout << endl << "Elementos de la lista:" << endl

<< "‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐" << endl;tLista p = lista;while (p != NULL) {

mostrar(p‐>reg);p = p‐>sig;

}} ...

Luis Hernández Yáñez

Página 977Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

void cargar(tLista &lista, bool &ok) {ifstream archivo;char aux;ok = true;lista = NULL;archivo.open(BD.c_str());if (!archivo.is_open()) {

ok = false;}else {

tRegistro registro;tLista ult = NULL;archivo >> registro.codigo;while (registro.codigo != ‐1) {

archivo >> registro.valor;archivo.get(aux); // Saltamos el espaciogetline(archivo, registro.nombre);...

Luis Hernández Yáñez

Página 978Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

if (lista == NULL) {lista = new tNodo;ult = lista;

}else {

ult‐>sig = new tNodo;ult = ult‐>sig;

}ult‐>reg = registro;ult‐>sig = NULL;archivo >> registro.codigo;

}archivo.close();

}return ok;

} ...

Luis Hernández Yáñez

Página 979Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

void guardar(tLista lista) {ofstream archivo;archivo.open(BD);tLista p = lista;while (p != NULL) {

archivo << p‐>registro.codigo << " ";archivo << p‐>registro.valor << " ";archivo << p‐>registro.nombre << endl;p = p‐>sig;

}archivo.close();

}

void destruir(tLista &lista) {tLista p;while (lista != NULL) {

p = lista;lista = lista‐>sig;delete p;

}}

Luis Hernández Yáñez

LicenciaCC(Creative Commons)Estetipodelicenciasofrecenalgunosderechosaterceraspersonasbajociertascondiciones.

Estedocumentotieneestablecidaslassiguientes:

Pulsaenlaimagendearribaaladerechaparasabermás.

Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 980

Reconocimiento(Attribution):Encualquierexplotacióndelaobraautorizadaporlalicenciaharáfaltareconocerlaautoría.

Nocomercial(Noncommercial):Laexplotacióndelaobraquedalimitadaausosnocomerciales.

Compartirigual(Sharealike):Laexplotaciónautorizadaincluyelacreacióndeobrasderivadassiemprequemantenganlamismalicenciaalserdivulgadas.