La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

9A9A9A9A Grado en Ingeniería Informática Grado en Ingeniería del Software Grado en Ingeniería de Computadores Luis Hernández Yáñez Facultad de Informática.

Presentaciones similares


Presentación del tema: "9A9A9A9A Grado en Ingeniería Informática Grado en Ingeniería del Software Grado en Ingeniería de Computadores Luis Hernández Yáñez Facultad de Informática."— Transcripción de la presentación:

1 9A9A9A9A Grado en Ingeniería Informática Grado en Ingeniería del Software Grado en Ingeniería de Computadores Luis Hernández Yáñez Facultad de Informática Universidad Complutense Fundamentos de la programación

2 Luis Hernández Yáñez Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Aritmética de punteros940 Recorrido de arrays con punteros953 Referencias962 Listas enlazadas964

3 Luis Hernández Yáñez Página 940 Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

4 Luis Hernández Yáñez Operaciones aritméticas con punteros La aritmética de punteros es una aritmética un tanto especial... Trabaja tomando como unidad de cálculo el tamaño del tipo base int dias[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; typedef int* tIntPtr; tIntPtr punt = dias; punt empieza apuntando al primer elemento del array: cout << *punt << endl; // Muestra 31 (primer elemento) punt++; punt++ hace que punt pase a apuntar al siguiente elemento cout << *punt << endl; // Muestra 28 (segundo elemento) A la dirección de memoria actual se le suman tantas unidades como bytes (4) ocupe en memoria un dato de ese tipo ( int ) Página 941 Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

5 Luis Hernández Yáñez int dias[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 31, 31, 30, 31, 30, 31 }; typedef int* tIntPtr; tIntPtr punt = dias; Página 942 Fundamentos 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... dias0F07:04170F 0F07:041803 0F07:04191A 0F07:041A38 punt0F07:041B0F 0F07:041C03 0F07:041D1A 0F07:041E38... 3131 2828 3131

6 Luis Hernández Yáñez int dias[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 31, 31, 30, 31, 30, 31 }; typedef int* tIntPtr; tIntPtr punt = dias; punt++; punt-- hace que apunte al elemento anterior Página 943 Fundamentos 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... dias0F07:04170F 0F07:041803 0F07:04191A 0F07:041A38 punt0F07:041B0F 0F07:041C03 0F07:041D1A 0F07:041E3C... 3131 2828 3131

7 Luis Hernández Yáñez int dias[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 31, 31, 30, 31, 30, 31 }; typedef int* tIntPtr; tIntPtr punt = dias; punt = punt + 2; Restando pasamos a elementos anteriores Página 944 Fundamentos 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... dias0F07:04170F 0F07:041803 0F07:04191A 0F07:041A38 punt0F07:041B0F 0F07:041C03 0F07:041D1A 0F07:041E40... 3131 2828 3131

8 Luis Hernández Yáñez int dias[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 31, 31, 30, 31, 30, 31 }; typedef int* tIntPtr; tIntPtr punt = dias; punt = punt + 2; int num = punt - dias; Nº de elementos entre los punteros Página 945 Fundamentos 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... dias0F07:04170F 0F07:041803 0F07:04191A 0F07:041A38 punt0F07:041B0F 0F07:041C03 0F07:041D1A 0F07:041E3C... 3131 2828 3131

9 Luis Hernández Yáñez Otro tipo base short int (2 bytes) short int dias[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 31, 30, 31, 31, 30, 31, 30, 31}; typedef short int* tSIPtr; tSIPtr punt = dias; Página 946 Fundamentos 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... dias0F07:04170F 0F07:041803 0F07:04191A 0F07:041A38 punt0F07:041B0F 0F07:041C03 0F07:041D1A 0F07:041E38... 3131 2828 3131 3030 3131

10 Luis Hernández Yáñez short int dias[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 31, 30, 31, 31, 30, 31, 30, 31}; typedef short int* tSIPtr; tSIPtr punt = dias; punt++; Página 947 Fundamentos 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... dias0F07:04170F 0F07:041803 0F07:04191A 0F07:041A38 punt0F07:041B0F 0F07:041C03 0F07:041D1A 0F07:041E3A... 3131 2828 3131 3030 3131

11 Luis Hernández Yáñez short int dias[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 31, 30, 31, 31, 30, 31, 30, 31}; typedef short int* tSIPtr; tSIPtr punt = dias; punt++; punt = punt + 3; Página 948 Fundamentos 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... dias0F07:04170F 0F07:041803 0F07:04191A 0F07:041A38 punt0F07:041B0F 0F07:041C03 0F07:041D1A 0F07:041E40... 3131 2828 3131 3030 3131

12 Luis Hernández Yáñez short int dias[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 31, 30, 31, 31, 30, 31, 30, 31}; typedef short int* tSIPtr; tSIPtr punt = dias; punt++; punt = punt + 3; punt--; Página 949 Fundamentos 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... dias0F07:04170F 0F07:041803 0F07:04191A 0F07:041A38 punt0F07:041B0F 0F07:041C03 0F07:041D1A 0F07:041E3E... 3131 2828 3131 3030 3131

13 Luis Hernández Yáñez short int dias[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 31, 30, 31, 31, 30, 31, 30, 31}; typedef short int* tSIPtr; tSIPtr punt = dias; punt++; punt = punt + 3; punt--; tSIPtr punt2; Página 950 Fundamentos 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... dias0F07:04170F 0F07:041803 0F07:04191A 0F07:041A38 punt0F07:041B0F 0F07:041C03 0F07:041D1A 0F07:041E3E punt20F07:041F? 3131 2828 3131 3030 3131

14 Luis Hernández Yáñez short int dias[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 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 951 Fundamentos 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... dias0F07:04170F 0F07:041803 0F07:04191A 0F07:041A38 punt0F07:041B0F 0F07:041C03 0F07:041D1A 0F07:041E3E punt20F07:041F0F 3131 2828 3131 3030 3131

15 Luis Hernández Yáñez short int dias[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 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 952 Fundamentos 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... dias0F07:04170F 0F07:041803 0F07:04191A 0F07:041A38 punt0F07:041B0F 0F07:041C03 0F07:041D1A 0F07:041E3E punt20F07:041F0F 3131 2828 3131 3030 3131 33

16 Luis Hernández Yáñez Página 953 Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

17 Luis Hernández Yáñez Punteros como iteradores para arrays const int MAX = 100; typedef int tArray[MAX]; typedef struct { tArray elementos; tArray elementos; int cont; int cont; } tLista; typedef int* tIntPtr; tLista lista; Usamos un puntero como iterador para recorrer el array: tIntPtr punt = lista.elementos; for (int i = 0; i < lista.cont; i++) { cout << *punt << endl; cout << *punt << endl; punt++; punt++;} Página 954 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) arraypunt.cpparraypunt.cpp

18 Luis Hernández Yáñez... intPtr punt = lista.elementos; Página 955 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) lista.elementoslista.elementospuntpunt 8 8lista.contlista.cont

19 Luis Hernández Yáñez... for (int i = 0; i < lista.cont; i++) { cout << *punt << endl; cout << *punt << endl; punt++; punt++;} Página 956 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) lista.elementoslista.elementospuntpunt 8 8lista.contlista.cont 0 0ii

20 Luis Hernández Yáñez Página 957 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) lista.elementoslista.elementospuntpunt 8 8lista.contlista.cont 1 1ii44... for (int i = 0; i < lista.cont; i++) { cout << *punt << endl; cout << *punt << endl; punt++; punt++;}

21 Luis Hernández Yáñez Página 958 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) lista.elementoslista.elementospuntpunt 8 8lista.contlista.cont 2 2ii413413... for (int i = 0; i < lista.cont; i++) { cout << *punt << endl; cout << *punt << endl; punt++; punt++;}

22 Luis Hernández Yáñez... for (int i = 0; i < lista.cont; i++) { cout << *punt << endl; cout << *punt << endl; punt++; punt++;} Página 959 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) lista.elementoslista.elementospuntpunt 8 8lista.contlista.cont 3 3ii... 41334133

23 Luis Hernández Yáñez... for (int i = 0; i < lista.cont; i++) { cout << *punt << endl; cout << *punt << endl; punt++; punt++;} Página 960 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) lista.elementoslista.elementospuntpunt 8 8lista.contlista.cont 7 7ii4133475319741334753197

24 Luis Hernández Yáñez... for (int i = 0; i < lista.cont; i++) { cout << *punt << endl; cout << *punt << endl; punt++; punt++;} Página 961 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) lista.elementoslista.elementospuntpunt 8 8lista.contlista.cont 8 8ii41334753197484133475319748

25 Luis Hernández Yáñez Página 962 Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

26 Luis Hernández Yáñez Nombres alternativos para los datos Una referencia es una nueva forma de llamar a una variable Nos permiten referirnos a una variable con otro identificador: int x = 10; int &z = x; x y z son ahora la misma variable (comparten memoria) Cualquier cambio en x afecta a z y cualquier cambio en z afecta a x z = 30; cout << x; Las referencias se usan en el paso de parámetros por referencia Página 963 Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

27 Luis Hernández Yáñez Página 964 Fundamentos de la programación: Punteros y memoria dinámica (Anexo)

28 Luis Hernández Yáñez Página 965 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Una implementación dinámica de listas enlazadas Cada elemento de la lista apunta al siguiente elemento: struct tNodo; // Declaración anticipada typedef tNodo *tLista; struct tNodo { tRegistro reg; tRegistro reg; tLista sig; tLista sig;}; Una lista ( tLista ) es un puntero a un nodo Si el puntero vale NULL, no apunta a ningún nodo: lista vacía Un nodo ( tNodo ) es un elemento seguido de una lista tRegistro tListatListaregregsigsig Elemento seguido de una lista ListaVacía ¡Definición recursiva!

29 Luis Hernández Yáñez Página 966 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Cada elemento de la lista en su nodo Apuntará al siguiente elemento o a ninguno ( NULL ) struct tNodo; // Declaración anticipada typedef tNodo *tLista; struct tNodo { tRegistro reg; tRegistro reg; tLista sig; tLista sig;}; Además, un puntero al primer elemento (nodo) de la lista tLista lista = NULL; // Lista vacía listalista

30 Luis Hernández Yáñez Página 967 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) struct tNodo; typedef tNodo *tLista; struct tNodo { tRegistro reg; tRegistro reg; tLista sig; tLista sig;}; tLista lista = NULL; // Lista vacía lista = new tNodo; lista->reg = nuevo(); lista->sig = NULL; listalista ítem1

31 Luis Hernández Yáñez Página 968 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) tLista lista = NULL; // Lista vacía lista = new tNodo; lista->reg = nuevo(); lista->sig = NULL; tLista p; p = lista; listalista ítem1 pp

32 Luis Hernández Yáñez Página 969 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) 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; listalista ítem1 pp ítem2

33 Luis Hernández Yáñez Página 970 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) 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;... listalista tRegistro pp

34 Luis Hernández Yáñez Página 971 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Usamos la memoria que necesitamos, ni más ni menos Tantos elementos, tantos nodos hay en la lista ¡Pero perdemos el acceso directo! Algunas operaciones de la lista se complican y otras no A continuación tienes el módulo de lista implementado como lista enlazada... listalista tRegistro

35 Luis Hernández Yáñez Página 972 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) struct tNodo; typedef tNodo *tLista; struct tNodo { tRegistro reg; tRegistro reg; tLista sig; 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 puntero void cargar(tLista &lista, bool &ok); void guardar(tLista lista); void destruir(tLista &lista); // Liberar la memoria dinámica listaenlazada.hlistaenlazada.h

36 Luis Hernández Yáñez Página 973 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) void insertar(tLista &lista, tRegistro registro, bool &ok) { ok = true; ok = true; tLista nuevo = new tNodo; tLista nuevo = new tNodo; if (nuevo == NULL) { if (nuevo == NULL) { ok = false; // No hay más memoria dinámica ok = false; // No hay más memoria dinámica } else { else { nuevo->reg = registro; nuevo->reg = registro; nuevo->sig = NULL; nuevo->sig = NULL; if (lista == NULL) { // Lista vacía if (lista == NULL) { // Lista vacía lista = nuevo; lista = nuevo; } else { else { tLista p = lista; tLista p = lista; // Localizamos el último nodo... // Localizamos el último nodo... while (p->sig != NULL) { while (p->sig != NULL) { p = p->sig; p = p->sig; } p->sig = nuevo; p->sig = nuevo; } } }... listaenlazada.cpplistaenlazada.cpp listalistanuevonuevo listalistanuevonuevopp

37 Luis Hernández Yáñez Página 974 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) void eliminar(tLista &lista, int code, bool &ok) { ok = true; ok = true; tLista p = lista; tLista p = lista; if (p == NULL) { if (p == NULL) { ok = false; // Lista vacía ok = false; // Lista vacía } else if (p->reg.codigo == code) { // El primero else if (p->reg.codigo == code) { // El primero lista = p->sig; lista = p->sig; delete p; delete p; } else { else { tLista ant = p; tLista ant = p; p = p->sig; p = p->sig; bool encontrado = false; bool encontrado = false; while ((p != NULL) && !encontrado) { while ((p != NULL) && !encontrado) { if (p->reg.codigo == code) { if (p->reg.codigo == code) { encontrado = true; encontrado = true; } else { else { ant = p; ant = p; p = p->sig; p = p->sig; } }... }... listalistappantant pplistalista

38 Luis Hernández Yáñez Página 975 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) if (!encontrado) { if (!encontrado) { ok = false; // No existe ese código ok = false; // No existe ese código } else { else { ant->sig = p->sig; ant->sig = p->sig; delete p; delete p; } }}... listalista ppantant

39 Luis Hernández Yáñez Página 976 Fundamentos 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; tLista p = lista; bool encontrado = false; bool encontrado = false; while ((p != NULL) && !encontrado) { while ((p != NULL) && !encontrado) { if (p->reg.codigo == code) { if (p->reg.codigo == code) { encontrado = true; encontrado = true; } else { else { p = p->sig; p = p->sig; } } return p; return p;} void mostrar(tLista lista) { cout << endl << "Elementos de la lista:" << endl cout << endl << "Elementos de la lista:" << endl << "----------------------" << endl; << "----------------------" << endl; tLista p = lista; tLista p = lista; while (p != NULL) { while (p != NULL) { mostrar(p->reg); mostrar(p->reg); p = p->sig; p = p->sig; } }...

40 Luis Hernández Yáñez Página 977 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) void cargar(tLista &lista, bool &ok) { ifstream archivo; ifstream archivo; char aux; char aux; ok = true; ok = true; lista = NULL; lista = NULL; archivo.open(BD.c_str()); archivo.open(BD.c_str()); if (!archivo.is_open()) { if (!archivo.is_open()) { ok = false; ok = false; } else { else { tRegistro registro; tRegistro registro; tLista ult = NULL; tLista ult = NULL; archivo >> registro.codigo; archivo >> registro.codigo; while (registro.codigo != -1) { while (registro.codigo != -1) { archivo >> registro.valor; archivo >> registro.valor; archivo.get(aux); // Saltamos el espacio archivo.get(aux); // Saltamos el espacio getline(archivo, registro.nombre); getline(archivo, registro.nombre);......

41 Luis Hernández Yáñez Página 978 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) if (lista == NULL) { if (lista == NULL) { lista = new tNodo; lista = new tNodo; ult = lista; ult = lista; } else { else { ult->sig = new tNodo; ult->sig = new tNodo; ult = ult->sig; ult = ult->sig; } ult->reg = registro; ult->reg = registro; ult->sig = NULL; ult->sig = NULL; archivo >> registro.codigo; archivo >> registro.codigo; } archivo.close(); archivo.close(); } return ok; return ok; }...

42 Luis Hernández Yáñez Página 979 Fundamentos de la programación: Punteros y memoria dinámica (Anexo) void guardar(tLista lista) { ofstream archivo; ofstream archivo; archivo.open(BD); archivo.open(BD); tLista p = lista; tLista p = lista; while (p != NULL) { while (p != NULL) { archivo registro.codigo registro.codigo << " "; archivo registro.valor registro.valor << " "; archivo registro.nombre registro.nombre << endl; p = p->sig; p = p->sig; } archivo.close(); archivo.close();} void destruir(tLista &lista) { tLista p; tLista p; while (lista != NULL) { while (lista != NULL) { p = lista; p = lista; lista = lista->sig; lista = lista->sig; delete p; delete p; }}

43 Luis Hernández Yáñez Licencia CC (Creative Commons) Creative CommonsCreative Commons Este tipo de licencias ofrecen algunos derechos a terceras personas bajo ciertas condiciones. Este documento tiene establecidas las siguientes: Pulsa en la imagen de arriba a la derecha para saber más. Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 980 Reconocimiento (Attribution): En cualquier explotación de la obra autorizada por la licencia hará falta reconocer la autoría. No comercial (Non commercial): La explotación de la obra queda limitada a usos no comerciales. Compartir igual (Share alike): La explotación autorizada incluye la creación de obras derivadas siempre que mantengan la misma licencia al ser divulgadas.


Descargar ppt "9A9A9A9A Grado en Ingeniería Informática Grado en Ingeniería del Software Grado en Ingeniería de Computadores Luis Hernández Yáñez Facultad de Informática."

Presentaciones similares


Anuncios Google