Fundamentos de la programación 9A GradoenIngenieríaInformática GradoenIngenieríadelSoftware GradoenIngenieríadeComputadores LuisHernándezYáñez FacultaddeInformática UniversidadComplutense Luis Hernández Yáñez Aritmética de punteros Recorrido de arrays con punteros Referencias Listas enlazadas Fundamentos de la programación: Punteros y memoria dinámica (Anexo) 940 953 962 964 Luis Hernández Yáñez Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 940 Operacionesaritméticasconpunteros Laaritméticadepunterosesunaaritméticauntantoespecial... Trabajatomandocomounidaddecálculoeltamañodeltipobase int 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++; Luis Hernández Yáñez punt++ hacequepunt paseaapuntaralsiguienteelemento cout << *punt << endl; // Muestra 28 (segundo elemento) Aladireccióndememoriaactualselesumantantasunidades comobytes(4)ocupeenmemoriaundatodeesetipo(int) Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 941 int dias[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; ... dias[0] 0F03:1A39 typedef int* tIntPtr; tIntPtr punt = dias; 0F03:1A38 0F03:1A3A 31 0F03:1A3B dias[1] 0F03:1A3C 0F03:1A3D 0F03:1A3E 28 0F03:1A3F dias[2] 0F03:1A40 0F03:1A41 0F03:1A42 31 0F03:1A43 ... Luis Hernández Yáñez dias punt 0F07:0417 0F 0F07:0418 03 0F07:0419 1A 0F07:041A 38 0F07:041B 0F 0F07:041C 03 0F07:041D 1A 0F07:041E 38 ... Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 942 int dias[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; ... dias[0] 0F03:1A39 typedef int* tIntPtr; tIntPtr punt = dias; punt++; 0F03:1A38 0F03:1A3A 31 0F03:1A3B dias[1] 0F03:1A3C 0F03:1A3D 0F03:1A3E 28 0F03:1A3F dias[2] 0F03:1A40 0F03:1A41 0F03:1A42 31 0F03:1A43 ... Luis Hernández Yáñez dias punt punt‐‐ hacequeapuntealelementoanterior 0F07:0417 0F 0F07:0418 03 0F07:0419 1A 0F07:041A 38 0F07:041B 0F 0F07:041C 03 0F07:041D 1A 0F07:041E 3C ... Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 943 int dias[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; ... dias[0] 0F03:1A39 typedef int* tIntPtr; tIntPtr punt = dias; punt = punt + 2; 0F03:1A38 0F03:1A3A 31 0F03:1A3B dias[1] 0F03:1A3C 0F03:1A3D 0F03:1A3E 28 0F03:1A3F dias[2] 0F03:1A40 0F03:1A41 0F03:1A42 31 0F03:1A43 ... Luis Hernández Yáñez dias punt Restandopasamosaelementosanteriores 0F07:0417 0F 0F07:0418 03 0F07:0419 1A 0F07:041A 38 0F07:041B 0F 0F07:041C 03 0F07:041D 1A 0F07:041E 40 ... Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 944 int dias[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; ... dias[0] 0F03:1A39 typedef int* tIntPtr; tIntPtr punt = dias; punt = punt + 2; 0F03:1A38 0F03:1A3A 31 0F03:1A3B dias[1] 0F03:1A3C 0F03:1A3D 0F03:1A3E 28 0F03:1A3F int num = punt ‐ dias; dias[2] 0F03:1A40 0F03:1A41 Nºdeelementosentrelospunteros 0F03:1A42 31 0F03:1A43 ... Luis Hernández Yáñez dias punt 0F07:0417 0F 0F07:0418 03 0F07:0419 1A 0F07:041A 38 0F07:041B 0F 0F07:041C 03 0F07:041D 1A 0F07:041E 3C ... Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 945 Otrotipobase ... short int (2bytes) dias[0] short int dias[12] = {31, 28, 31, 30, dias[1] 31, 30, 31, 31, 30, 31, 30, 31}; typedef short int* tSIPtr; 0F03:1A38 0F03:1A39 0F03:1A3A 0F03:1A3B dias[2] 0F03:1A3C 0F03:1A3D dias[3] tSIPtr punt = dias; 0F03:1A3E 0F03:1A3F dias[4] 0F03:1A40 0F03:1A41 31 28 31 30 31 ... dias Luis Hernández Yáñez punt 0F07:0417 0F 0F07:0418 03 0F07:0419 1A 0F07:041A 38 0F07:041B 0F 0F07:041C 03 0F07:041D 1A 0F07:041E 38 ... Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 946 short int dias[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; ... dias[0] typedef short int* tSIPtr; 0F03:1A38 0F03:1A39 tSIPtr punt = dias; dias[1] punt++; dias[2] 0F03:1A3A 0F03:1A3B 0F03:1A3C 0F03:1A3D dias[3] 0F03:1A3E 0F03:1A3F dias[4] 0F03:1A40 0F03:1A41 31 28 31 30 31 ... dias Luis Hernández Yáñez punt 0F07:0417 0F 0F07:0418 03 0F07:0419 1A 0F07:041A 38 0F07:041B 0F 0F07:041C 03 0F07:041D 1A 0F07:041E 3A ... Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 947 short int dias[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; ... dias[0] typedef short int* tSIPtr; 0F03:1A39 tSIPtr punt = dias; dias[1] punt++; dias[2] punt = punt + 3; 0F03:1A38 0F03:1A3A 0F03:1A3B 0F03:1A3C 0F03:1A3D dias[3] 0F03:1A3E 0F03:1A3F dias[4] 0F03:1A40 0F03:1A41 31 28 31 30 31 ... dias Luis Hernández Yáñez punt 0F07:0417 0F 0F07:0418 03 0F07:0419 1A 0F07:041A 38 0F07:041B 0F 0F07:041C 03 0F07:041D 1A 0F07:041E 40 ... Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 948 short int dias[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; ... dias[0] typedef short int* tSIPtr; 0F03:1A39 tSIPtr punt = dias; dias[1] punt++; dias[2] punt = punt + 3; punt‐‐; 0F03:1A38 0F03:1A3A 0F03:1A3B 0F03:1A3C 0F03:1A3D dias[3] 0F03:1A3E 0F03:1A3F dias[4] 0F03:1A40 0F03:1A41 31 28 31 30 31 ... dias Luis Hernández Yáñez punt 0F07:0417 0F 0F07:0418 03 0F07:0419 1A 0F07:041A 38 0F07:041B 0F 0F07:041C 03 0F07:041D 1A 0F07:041E 3E ... Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 949 short int dias[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; ... dias[0] typedef short int* tSIPtr; 0F03:1A39 tSIPtr punt = dias; dias[1] punt++; dias[2] punt = punt + 3; punt‐‐; 0F03:1A38 0F03:1A3A 0F03:1A3B 0F03:1A3C 0F03:1A3D dias[3] 0F03:1A3E 0F03:1A3F dias[4] tSIPtr punt2; 0F03:1A40 0F03:1A41 31 28 31 30 31 ... dias Luis Hernández Yáñez punt punt2 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) 0F07:0417 0F 0F07:0418 03 0F07:0419 1A 0F07:041A 38 0F07:041B 0F 0F07:041C 03 0F07:041D 1A 0F07:041E 3E 0F07:041F ? Página 950 short int dias[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; ... dias[0] typedef short int* tSIPtr; 0F03:1A39 siPtr punt = dias; dias[1] punt++; dias[2] punt = punt + 3; punt‐‐; Luis Hernández Yáñez 0F03:1A3C 0F03:1A3D dias[3] 0F03:1A3E 0F03:1A3F dias[4] 0F03:1A40 0F03:1A41 31 28 31 30 31 ... dias punt punt2 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) 0F03:1A3A 0F03:1A3B tSIPtr punt2; punt2 = dias; 0F03:1A38 0F07:0417 0F 0F07:0418 03 0F07:0419 1A 0F07:041A 38 0F07:041B 0F 0F07:041C 03 0F07:041D 1A 0F07:041E 3E 0F07:041F 0F Página 951 short int dias[12] = {31, 28, 31, 30, ... 31, 30, 31, 31, 30, 31, 30, 31}; dias[0] typedef short int* tSIPtr; siPtr punt = dias; punt++; 0F03:1A38 0F03:1A39 dias[1] 3 punt = punt + 3; punt‐‐; dias[2] dias[3] 0F03:1A3E 0F03:1A3F dias[4] 0F03:1A40 0F03:1A41 ... dias cout << punt – punt2; // 3 punt Luis Hernández Yáñez 0F03:1A3C 0F03:1A3D tSIPtr punt2; punt2 = dias; 0F03:1A3A 0F03:1A3B 31 28 31 30 31 punt2 0F07:0417 0F 0F07:0418 03 0F07:0419 1A 0F07:041A 38 0F07:041B 0F 0F07:041C 03 0F07:041D 1A 0F07:041E 3E 0F07:041F 0F Página 952 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 953 Luis Hernández Yáñez Fundamentos de la programación: Punteros y memoria dinámica (Anexo) arraypunt.cpp Punteroscomoiteradoresparaarrays const int MAX = 100; typedef int tArray[MAX]; typedef struct { tArray elementos; int cont; } tLista; typedef int* tIntPtr; tLista lista; Luis Hernández Yáñez Usamosunpunterocomoiterador pararecorrerelarray: tIntPtr punt = lista.elementos; for (int i = 0; i < lista.cont; i++) { cout << *punt << endl; punt++; } Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 954 ... intPtr punt = lista.elementos; punt lista.elementos 1 2 3 4 5 6 7 4 13 3 47 53 19 7 48 8 ... 98 99 8 Luis Hernández Yáñez lista.cont 0 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 955 ... for (int i = 0; i < lista.cont; i++) { cout << *punt << endl; punt++; } i punt 0 lista.elementos 0 1 2 3 4 5 6 7 4 13 3 47 53 19 7 48 lista.cont 8 ... 98 99 Luis Hernández Yáñez 8 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 956 ... for (int i = 0; i < lista.cont; i++) { cout << *punt << endl; punt++; } i punt 1 lista.elementos 0 1 2 3 4 5 6 7 4 13 3 47 53 19 7 48 8 ... 98 99 8 Luis Hernández Yáñez lista.cont 4 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 957 ... for (int i = 0; i < lista.cont; i++) { cout << *punt << endl; punt++; } i punt 2 lista.elementos 4 13 0 1 2 3 4 5 6 7 4 13 3 47 53 19 7 48 lista.cont 8 ... 98 99 Luis Hernández Yáñez 8 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 958 ... for (int i = 0; i < lista.cont; i++) { cout << *punt << endl; punt++; } i lista.cont Luis Hernández Yáñez punt 3 lista.elementos 4 13 3 0 1 2 3 4 5 6 7 4 13 3 47 53 19 7 48 8 ... 98 99 8 ... Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 959 ... for (int i = 0; i < lista.cont; i++) { cout << *punt << endl; punt++; } i punt 7 lista.elementos 4 13 3 47 53 19 7 0 1 2 3 4 5 6 7 4 13 3 47 53 19 7 48 lista.cont 8 ... 98 99 Luis Hernández Yáñez 8 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 960 ... for (int i = 0; i < lista.cont; i++) { cout << *punt << endl; punt++; } i punt 8 lista.elementos 0 1 2 3 4 5 6 7 4 13 3 47 53 19 7 48 8 ... 98 99 8 Luis Hernández Yáñez lista.cont 4 13 3 47 53 19 7 48 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 961 Luis Hernández Yáñez Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 962 Nombresalternativosparalosdatos Unareferenciaesunanuevaformadellamaraunavariable Nospermitenreferirnosaunavariableconotroidentificador: int x = 10; int &z = x; x yz sonahoralamismavariable(compartenmemoria) Cualquiercambioenx afectaaz ycualquiercambioenz afectaax z = 30; cout << x; Luis Hernández Yáñez Lasreferenciasseusanenelpasodeparámetrosporreferencia Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 963 Luis Hernández Yáñez Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 964 Unaimplementacióndinámicadelistasenlazadas Cadaelementodelalistaapuntaalsiguienteelemento: struct tNodo; // Declaración anticipada typedef tNodo *tLista; reg struct tNodo { tRegistro reg; tRegistro tLista sig; }; sig tLista Luis Hernández Yáñez Unalista(tLista)esunpunteroaunnodo SielpunterovaleNULL,noapuntaaningúnnodo:listavacía Unnodo(tNodo)esunelementoseguidodeunalista Lista Vacía Elementoseguidodeunalista ¡Definiciónrecursiva! Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 965 Cadaelementodelalistaensunodo Apuntaráalsiguienteelementooaninguno(NULL) struct tNodo; // Declaración anticipada typedef tNodo *tLista; struct tNodo { tRegistro reg; tLista sig; }; Además,unpunteroalprimerelemento(nodo)delalista Luis Hernández Yáñez tLista lista = NULL; // Lista vacía lista Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 966 struct tNodo; typedef tNodo *tLista; struct tNodo { tRegistro reg; tLista sig; }; Luis Hernández Yáñez tLista lista = NULL; // Lista vacía lista = new tNodo; lista‐>reg = nuevo(); lista‐>sig = NULL; lista ítem1 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 967 tLista lista = NULL; // Lista vacía lista = new tNodo; lista‐>reg = nuevo(); lista‐>sig = NULL; tLista p; p = lista; Luis Hernández Yáñez p lista ítem1 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 968 tLista lista = NULL; // Lista vacía lista = new tNodo; lista‐>reg = nuevo(); lista‐>sig = NULL; tLista p; p = lista; p‐>sig = new tNodo; p‐>sig‐>reg = nuevo(); p‐>sig‐>sig = NULL; Luis Hernández Yáñez p lista ítem1 ítem2 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 969 Luis Hernández Yáñez tLista lista = NULL; // Lista vacía lista = 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; p ... lista tRegistro tRegistro Fundamentos de la programación: Punteros y memoria dinámica (Anexo) tRegistro Página 970 Usamoslamemoriaquenecesitamos,nimásnimenos lista tRegistro tRegistro tRegistro Luis Hernández Yáñez Tantoselementos,tantosnodoshayenlalista ¡Peroperdemoselaccesodirecto! Algunasoperacionesdelalistasecomplicanyotrasno Acontinuacióntieneselmódulodelistaimplementado comolistaenlazada... Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 971 listaenlazada.h struct tNodo; typedef tNodo *tLista; struct tNodo { tRegistro reg; tLista sig; }; Luis Hernández Yáñez 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 puntero void cargar(tLista &lista, bool &ok); void guardar(tLista lista); void destruir(tLista &lista); // Liberar la memoria dinámica Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 972 Luis Hernández Yáñez listaenlazada.cpp 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 lista = nuevo; } nuevo else { tLista p = lista; // Localizamos el último nodo... while (p‐>sig != NULL) { nuevo p = p‐>sig; } p p‐>sig = nuevo; } lista } } ... Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 973 Luis Hernández Yáñez 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; p } else { lista tLista ant = p; p = p‐>sig; bool encontrado = false; while ((p != NULL) && !encontrado) { if (p‐>reg.codigo == code) { ant encontrado = true; } else { lista ant = p; p = p‐>sig; } } ... Fundamentos de la programación: Punteros y memoria dinámica (Anexo) p Página 974 if (!encontrado) { ok = false; // No existe ese código } else { ant‐>sig = p‐>sig; delete p; } } } ... ant p Luis Hernández Yáñez lista Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 975 Luis Hernández Yáñez 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 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 976 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 espacio getline(archivo, registro.nombre); ... Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 977 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(); Luis Hernández Yáñez } return ok; } ... Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 978 Luis Hernández Yáñez 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; } } Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 979 LicenciaCC(Creative Commons) Estetipodelicenciasofrecenalgunosderechosaterceraspersonas bajociertascondiciones. Estedocumentotieneestablecidaslassiguientes: Reconocimiento(Attribution): Encualquierexplotacióndelaobraautorizadaporlalicencia haráfaltareconocerlaautoría. Luis Hernández Yáñez Nocomercial(Noncommercial): Laexplotacióndelaobraquedalimitadaausosnocomerciales. Compartirigual(Sharealike): Laexplotaciónautorizadaincluyelacreacióndeobrasderivadas siemprequemantenganlamismalicenciaalserdivulgadas. Pulsaenlaimagendearribaaladerechaparasabermás. Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 980