La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Introducción a punteros en C

Presentaciones similares


Presentación del tema: "Introducción a punteros en C"— Transcripción de la presentación:

1 Introducción a punteros en C
Algoritmos y Estructuras de Datos II (2015) Leonardo M. Rodríguez (presionar F5)

2 PARTE I: Uso básico de punteros

3 4 x1 3 x2 'z' c2 'a' c1 3.4 f1 int x1 = 4; int x2 = 3; char c1 = 'a';
char c2 = 'z'; float f1 = 3.4; x1 = x2 * 2; 3 x2 'z' c2 'a' c1 3.4 f1

4 x1 6 3 x2 'z' c2 'a' c1 3.4 f1 int x1 = 4; int x2 = 3; char c1 = 'a';
char c2 = 'z'; float f1 = 3.4; x1 = x2 * 2; 3 x2 'z' c2 'a' c1 3.4 f1

5 x1 6 3 x2 'z' c2 p 'a' c1 q 3.4 f1 r int *p = & x1; int *q = & x2;
char *r = & c2; p = q; 3 x2 'z' c2 p 'a' c1 q 3.4 f1 r

6 x1 6 3 x2 'z' c2 p 'a' c1 q 3.4 f1 r int *p = & x1; int *q = & x2;
char *r = & c2; p = q; *p = 9; 3 x2 'z' c2 p 'a' c1 q 3.4 f1 r

7 x1 6 x2 9 'z' c2 p 'a' c1 q 3.4 f1 r int *p = & x1; int *q = & x2;
char *r = & c2; p = q; *p = 9; q = & x1; x2 9 'z' c2 p 'a' c1 q 3.4 f1 r

8 x1 6 x2 9 'z' c2 p 'a' c1 q 3.4 f1 r int *p = & x1; int *q = & x2;
char *r = & c2; p = q; *p = 9; q = & x1; *q = *p + 1; x2 9 'z' c2 p 'a' c1 q 3.4 f1 r

9 x1 10 x2 9 'z' c2 p 'a' c1 q 3.4 f1 r int *p = & x1; int *q = & x2;
char *r = & c2; p = q; *p = 9; q = & x1; *q = *p + 1; r = & c1; x2 9 'z' c2 p 'a' c1 q 3.4 f1 r

10 x1 10 x2 9 'z' c2 p 'a' c1 q 3.4 f1 r int *p = & x1; int *q = & x2;
char *r = & c2; p = q; *p = 9; q = & x1; *q = *p + 1; r = & c1; *r = c2; x2 9 'z' c2 p 'a' c1 q 3.4 f1 r

11 x1 10 x2 9 'z' c2 p c1 'z' q 3.4 f1 r int *p = & x1; int *q = & x2;
char *r = & c2; p = q; *p = 9; q = & x1; *q = *p + 1; r = & c1; *r = c2; x2 9 'z' c2 p c1 'z' q 3.4 f1 r

12 Checkpoint int *p; Declaración de un puntero. En este caso la variable p es un puntero a una variable de tipo entero. El tipo de los punteros (color de la flecha) es muy importante. (&) Operador de referencia (“crear una flecha”) (*) Operador de dereferenciación (“seguir la flecha”)

13 PARTE II: Pasaje de referencias

14 ¿Qué número imprime en pantalla este programa?
int main (void) { int x = 4; mitad(x); printf(“%d\n”, x); return 0; } void mitad(int y) { y = y / 2; ¿Qué número imprime en pantalla este programa?

15 x 4 int main (void) { int x = 4; mitad(x); printf(“%d\n”, x);
return 0; } void mitad(int y) { y = y / 2;

16 x 4 y 4 int main (void) { int x = 4; mitad(x); printf(“%d\n”, x);
return 0; } void mitad(int y) { y = y / 2; y 4

17 x 4 y 2 int main (void) { int x = 4; mitad(x); printf(“%d\n”, x);
return 0; } void mitad(int y) { y = y / 2; y 2

18 x 4 y 2 int main (void) { int x = 4; mitad(x); printf(“%d\n”, x);
return 0; } void mitad(int y) { y = y / 2; IMPRIME 4! y 2

19 ¿Qué número imprime en pantalla este programa?
int main (void) { int x = 4; mitad(&x); printf(“%d\n”, x); return 0; } void mitad(int *y) { *y = *y / 2; ¿Qué número imprime en pantalla este programa?

20 x 4 int main (void) { int x = 4; mitad(&x); printf(“%d\n”, x);
return 0; } void mitad(int *y) { *y = *y / 2;

21 x 4 y int main (void) { int x = 4; mitad(&x); printf(“%d\n”, x);
return 0; } void mitad(int *y) { *y = *y / 2; y

22 x 2 y int main (void) { int x = 4; mitad(&x); printf(“%d\n”, x);
return 0; } void mitad(int *y) { *y = *y / 2; y

23 x 2 y int main (void) { int x = 4; mitad(&x); printf(“%d\n”, x);
return 0; } void mitad(int *y) { *y = *y / 2; IMPRIME 2! y

24 PARTE III: Punteros y arreglos

25 int a[4] = {1,3,8,6}; int *p = NULL; 1 3 8 6 a

26 int a[4] = {1,3,8,6}; int *p = NULL; p = a; 1 3 8 6 a p

27 int a[4] = {1,3,8,6}; int *p = NULL; p = a; *p = 5; 1 3 8 6 a p

28 a p int a[4] = {1,3,8,6}; int *p = NULL; p = a; *p = 5; *(p + 1) = 0;

29 a p int a[4] = {1,3,8,6}; int *p = NULL; p = a; *p = 5; *(p + 1) = 0;
8 6 a p

30 a p int a[4] = {1,3,8,6}; int *p = NULL; p = a; *p = 5; *(p + 1) = 0;
8 7 a p

31 a p int a[4] = {1,3,8,6}; int *p = NULL; p = a; *p = 5; *(p + 1) = 0;
3 7 a p

32 a p int a[4] = {1,3,8,6}; int *p = NULL; p = a; *p = 5; *(p + 1) = 0;
3 7 a p

33 a p int a[4] = {1,3,8,6}; int *p = NULL; p = a; *p = 5; *(p + 1) = 0;
2 7 a p

34 Checkpoint Arreglos y punteros int a[4] = {1,3,5,8} En la asignación siguiente, el arreglo “decae” o “se convierte” a un puntero a su primer elemento. int *p = a; Un poco de aritmética de punteros Nos aprovechamos que los arreglos siempre se alojan en memoria contigua (consecutiva) *(p + 1) = 4 “Seguir la flecha de p y moverse 1 lugar a la derecha” Esa operación es equivalente a usar la notación de arreglos: p[1] = 4; p = p + 1; “Desplazar la flecha 1 lugar a la derecha”

35 PARTE IV: Punteros y estructuras

36 struct _punto { int x; Int y; }; struct _punto r; r.x = 0; x y r

37 x r y struct _punto { int x; Int y; }; struct _punto r; r.x = 0;

38 x r y struct _punto { int x; Int y; }; struct _punto r; 1 r.x = 0;
struct _punto *p = NULL; x y r 1

39 p x r y struct _punto { int x; Int y; }; struct _punto r; 1 r.x = 0;
struct _punto *p = NULL; p = & r; x y r 1 p

40 p x r y struct _punto { int x; Int y; }; struct _punto r; 1 r.x = 0;
struct _punto *p = NULL; p = & r; (*p).x = 2; x y r 1 p

41 p x r y struct _punto { int x; Int y; 2 }; struct _punto r; 1 r.x = 0;
struct _punto *p = NULL; p = & r; (*p).x = 2; p->y = 3; x y r 2 1 p

42 p x r y struct _punto { int x; Int y; 2 }; struct _punto r; 3 r.x = 0;
struct _punto *p = NULL; p = & r; (*p).x = 2; p->y = 3; x y r 2 3 p

43 p x r y struct _punto { int x; Int y; 2 };
typedef struct _punto *punto_t; struct _punto r; r.x = 0; r.y = 1; struct _punto *p = NULL; p = & r; (*p).x = 2; p->y = 3; x y r 2 3 p

44 p x r y struct _punto { int x; Int y; 2 };
typedef struct _punto *punto_t; struct _punto r; r.x = 0; r.y = 1; punto_t p = NULL; p = & r; (*p).x = 2; p->y = 3; x y r 2 3 p

45 Checkpoint Punteros y estructuras El operador “->” sirve para acceder al campo de una estructura a partir de un puntero. (*p).x es equivalente a p->x De paso vimos... Sinónimos de tipos typedef es útil para hacer sinónimos de tipos. typedef int entero; typedef char caracter; typedef int *puntero_a_entero; entero x = 0; puntero_a_entero p = & x;

46 PARTE V: Memoria Dinámica

47 HEAP STACK void g() { int x = 2; int y = 1; return; } void f() {
int z = 0; g(); int main() { int x = 0; int i = 0; f(); return 0; HEAP STACK x y 2 1 x z 1 x i

48 HEAP STACK int main() { int *p = NULL; p = calloc(2, sizeof(int));
free(p); p = NULL; return (0); } HEAP STACK p

49 HEAP STACK int main() { int *p = NULL; p = calloc(2, sizeof(int));
free(p); p = NULL; return (0); } HEAP STACK p

50 HEAP STACK int main() { int *p = NULL; p = calloc(2, sizeof(int));
free(p); p = NULL; return (0); } HEAP STACK 2 p

51 HEAP STACK int main() { int *p = NULL; p = calloc(2, sizeof(int));
free(p); p = NULL; return (0); } HEAP STACK 2 DANGLING POINTER p

52 HEAP STACK int main() { int *p = NULL; p = calloc(2, sizeof(int));
free(p); p = NULL; return (0); } HEAP STACK p

53 HEAP STACK int main() { int *p = NULL; p = calloc(2, sizeof(int));
free(p); p = NULL; return (0); } HEAP STACK p

54 HEAP STACK void modificar (int *q) { q[1] = 2; return; } int main() {
int *p = NULL; p = calloc(2, sizeof(int)); assert(p != NULL); modificar(p); free(p); p = NULL; return (0); HEAP STACK p

55 HEAP STACK void modificar (int *q) { q[1] = 2; return; } int main() {
int *p = NULL; p = calloc(2, sizeof(int)); assert(p != NULL); modificar(p); free(p); p = NULL; return (0); HEAP STACK p

56 HEAP STACK void modificar (int *q) { q[1] = 2; return; } int main() {
int *p = NULL; p = calloc(2, sizeof(int)); assert(p != NULL); modificar(p); free(p); p = NULL; return (0); HEAP STACK p

57 HEAP STACK void modificar (int *q) { q[1] = 2; return; } int main() {
int *p = NULL; p = calloc(2, sizeof(int)); assert(p != NULL); modificar(p); free(p); p = NULL; return (0); HEAP STACK q p

58 HEAP STACK void modificar (int *q) { q[1] = 2; return; } int main() {
int *p = NULL; p = calloc(2, sizeof(int)); assert(p != NULL); modificar(p); free(p); p = NULL; return (0); HEAP STACK 2 q p

59 HEAP STACK void modificar (int *q) { q[1] = 2; return; } int main() {
int *p = NULL; p = calloc(2, sizeof(int)); assert(p != NULL); modificar(p); free(p); p = NULL; return (0); HEAP STACK q 2 p

60 HEAP STACK void modificar (int *q) { q[1] = 2; return; } int main() {
int *p = NULL; p = calloc(2, sizeof(int)); assert(p != NULL); modificar(p); free(p); p = NULL; return (0); HEAP STACK 2 p

61 HEAP STACK void modificar (int *q) { q[1] = 2; return; } int main() {
int *p = NULL; p = calloc(2, sizeof(int)); assert(p != NULL); modificar(p); free(p); p = NULL; return (0); HEAP STACK p

62 HEAP STACK void modificar (int *q) { q[1] = 2; return; } int main() {
int *p = NULL; p = calloc(2, sizeof(int)); assert(p != NULL); modificar(p); free(p); p = NULL; return (0); HEAP STACK p

63 HEAP STACK void amnesia() { int *q = NULL; q = calloc(1, sizeof(int));
return; } int main() { amnesia(); for (int i = 0; i<5; i++) { return (0); HEAP STACK

64 HEAP STACK void amnesia() { int *q = NULL; q = calloc(1, sizeof(int));
return; } int main() { amnesia(); for (int i = 0; i<5; i++) { return (0); HEAP STACK

65 HEAP STACK void amnesia() { int *q = NULL; q = calloc(1, sizeof(int));
return; } int main() { amnesia(); for (int i = 0; i<5; i++) { return (0); HEAP STACK q

66 HEAP STACK void amnesia() { int *q = NULL; q = calloc(1, sizeof(int));
return; } int main() { amnesia(); for (int i = 0; i<5; i++) { return (0); HEAP STACK q

67 HEAP STACK void amnesia() { int *q = NULL; q = calloc(1, sizeof(int));
return; } int main() { amnesia(); for (int i = 0; i<5; i++) { return (0); HEAP STACK q MEMORY LEAK

68 HEAP STACK void amnesia() { int *q = NULL; q = calloc(1, sizeof(int));
return; } int main() { amnesia(); for (int i = 0; i<5; i++) { return (0); HEAP STACK

69 HEAP $> gcc -g -o ejemplo ejemplo.c
$> valgrind --show-reachable=yes --leak-check=full ./ejemplo ==8066== HEAP SUMMARY: ==8066== in use at exit: 24 bytes in 6 blocks ==8066== total heap usage: 6 allocs, 0 frees, 24 bytes allocated ==8066== ==8066== 4 bytes in 1 blocks are definitely lost in loss record 1 of 2 ==8066== at 0x4C272B8: calloc (vg_replace_malloc.c:566) ==8066== by 0x40052A: amnesia (ejemplo.c:6) ==8066== by 0x400543: main (ejemplo.c:12) ==8066== 20 bytes in 5 blocks are definitely lost in loss record 2 of 2 ==8066== by 0x400556: main (ejemplo.c:14) ==8066== LEAK SUMMARY: ==8066== definitely lost: 24 bytes in 6 blocks ==8066== indirectly lost: 0 bytes in 0 blocks ==8066== possibly lost: 0 bytes in 0 blocks ==8066== still reachable: 0 bytes in 0 blocks ==8066== suppressed: 0 bytes in 0 blocks

70 p struct _data { int x; int *a; }; struct _data *p = NULL;
p = calloc(1, sizeof(struct _data)); p->x = 1; p->a = calloc(3, sizeof(int)); .... free(p->a); p->a = NULL; free(p); p = NULL; p

71 x p a struct _data { int x; int *a; }; struct _data *p = NULL;
struct _data { int x; int *a; }; struct _data *p = NULL; p = calloc(1, sizeof(struct _data)); p->x = 1; p->a = calloc(3, sizeof(int)); .... free(p->a); p->a = NULL; free(p); p = NULL; p

72 x p a 1 struct _data { int x; int *a; }; struct _data *p = NULL;
p = calloc(1, sizeof(struct _data)); p->x = 1; p->a = calloc(3, sizeof(int)); .... free(p->a); p->a = NULL; free(p); p = NULL; 1 p a

73 x p a 1 struct _data { int x; int *a; }; struct _data *p = NULL;
p = calloc(1, sizeof(struct _data)); p->x = 1; p->a = calloc(3, sizeof(int)); .... free(p->a); p->a = NULL; free(p); p = NULL; 1 p a

74 x p a 1 struct _data { int x; int *a; }; struct _data *p = NULL;
p = calloc(1, sizeof(struct _data)); p->x = 1; p->a = calloc(3, sizeof(int)); .... free(p->a); p->a = NULL; free(p); p = NULL; 1 p a

75 x p a 1 struct _data { int x; int *a; }; struct _data *p = NULL;
p = calloc(1, sizeof(struct _data)); p->x = 1; p->a = calloc(3, sizeof(int)); .... free(p->a); p->a = NULL; free(p); p = NULL; 1 p a

76 x p a 1 struct _data { int x; int *a; }; struct _data *p = NULL;
p = calloc(1, sizeof(struct _data)); p->x = 1; p->a = calloc(3, sizeof(int)); .... free(p->a); p->a = NULL; free(p); p = NULL; p

77 p struct _data { int x; int *a; }; struct _data *p = NULL;
p = calloc(1, sizeof(struct _data)); p->x = 1; p->a = calloc(3, sizeof(int)); .... free(p->a); p->a = NULL; free(p); p = NULL; p

78 Checkpoint Memoria estática: Se ubica en la pila. Liberada por el sistema operativo. Tiene tamaño limitado. TIPS: Consultar el tamaño máximo permitido de la pila usando “ulimit -s” En GDB se puede analizar la pila actual usando el comando “frame”. Memoria dinámica: Se ubica en el heap. En C es liberada por el programador. En otros lenguajes como Java es liberada por el garbage collector (ver wikipedia). No tiene límite (depende del SO). CALLOC ( <cantidad de bloques>, <tamaño de cada bloque>) Crea una secuencia contigua de bloques de memoria y devuelve un puntero al bloque inicial. Inicializa todo el bloque nuevo con 0 (a nivel bit). Si no hay memoria en el sistema devuelve NULL. Incluir librería estándar para tenerla disponible: #include <stdlib.h>

79 Checkpoint Dangling pointer (puntero colgante) Puntero apuntando a una zona de memoria que ya fue liberada. Intentar dereferenciar un puntero colgante puede resultar en un error de violación de segmento. free() sólo libera la memoria pero no modifica el puntero. Memory leak (fuga de memoria) Memoria del heap que nunca es liberada. Una causa de memory leak es cuando queda memoria “suelta” en el heap a la cuál no apunta ningún puntero. El programador no tiene forma de liberarla pues se ha perdido el acceso a ella. Los programas con memory leaks se vuelven lentos con el tiempo, ya que el heap se llena de bloques de memoria sin uso. Utilizar el comando valgrind para chequear fugas de memoria. Violación de segmento Dereferenciar (*p) un puntero NULL o colgante. Hacer free(p) donde p es colgante. Pasarse de rango en un arreglo, pues se accede a memoria inválida.

80 PARTE VI: Introducción a Listas Enlazadas

81 list struct _node { struct _node *next; int elem; };
typedef struct _node *list_t; La lista vacía [] es representada con un puntero nulo. list_t list = NULL;

82 list 4 3 9 3 struct _node { struct _node *next; int elem; };
9 3 list struct _node { struct _node *next; int elem; }; typedef struct _node *list_t; La lista no vacía es representada como una “cadena” de nodos. En este ejemplo usaremos listas de enteros. [4, 3, 0, 9] 3

83 list 4 3 9 3 INSERCIÓN AL COMIENZO list_t aux = NULL;
9 3 list INSERCIÓN AL COMIENZO list_t aux = NULL; aux = calloc(1, sizeof(struct _node)); aux->elem = 7; aux->next = list; list = aux; 3

84 list aux 4 3 9 3 INSERCIÓN AL COMIENZO list_t aux = NULL;
9 3 list INSERCIÓN AL COMIENZO list_t aux = NULL; aux = calloc(1, sizeof(struct _node)); aux->elem = 7; aux->next = list; list = aux; 3 aux

85 list aux 4 3 9 3 INSERCIÓN AL COMIENZO list_t aux = NULL;
9 3 list INSERCIÓN AL COMIENZO list_t aux = NULL; aux = calloc(1, sizeof(struct _node)); aux->elem = 7; aux->next = list; list = aux; 3 aux

86 list aux 4 3 9 3 INSERCIÓN AL COMIENZO list_t aux = NULL;
9 3 list INSERCIÓN AL COMIENZO list_t aux = NULL; aux = calloc(1, sizeof(struct _node)); aux->elem = 7; aux->next = list; list = aux; 3 aux 7

87 list aux 4 3 9 3 INSERCIÓN AL COMIENZO list_t aux = NULL;
9 3 list INSERCIÓN AL COMIENZO list_t aux = NULL; aux = calloc(1, sizeof(struct _node)); aux->elem = 7; aux->next = list; list = aux; 7 3 aux

88 list aux 4 3 9 3 INSERCIÓN AL COMIENZO list_t aux = NULL;
9 3 list INSERCIÓN AL COMIENZO list_t aux = NULL; aux = calloc(1, sizeof(struct _node)); aux->elem = 7; aux->next = list; list = aux; 7 3 aux

89 4 3 9 3 list 7 3 [7,4,3,0,9]

90 list 4 3 9 3 INSERCIÓN AL ÚLTIMO (CASO LISTA NO VACÍA)
9 3 list INSERCIÓN AL ÚLTIMO (CASO LISTA NO VACÍA) list_t aux = NULL; aux = calloc(1, sizeof(struct _node)); aux->elem = 7; list_t curr = list; while (curr->next != NULL) { curr = curr->next; } curr->next = aux; 3

91 list aux 4 3 9 3 INSERCIÓN AL ÚLTIMO (CASO LISTA NO VACÍA)
9 3 list INSERCIÓN AL ÚLTIMO (CASO LISTA NO VACÍA) list_t aux = NULL; aux = calloc(1, sizeof(struct _node)); aux->elem = 7; list_t curr = list; while (curr->next != NULL) { curr = curr->next; } curr->next = aux; 3 aux

92 list aux 4 3 9 3 INSERCIÓN AL ÚLTIMO (CASO LISTA NO VACÍA)
9 3 list INSERCIÓN AL ÚLTIMO (CASO LISTA NO VACÍA) list_t aux = NULL; aux = calloc(1, sizeof(struct _node)); aux->elem = 7; list_t curr = list; while (curr->next != NULL) { curr = curr->next; } curr->next = aux; aux

93 list aux 4 3 9 3 INSERCIÓN AL ÚLTIMO (CASO LISTA NO VACÍA)
9 3 list INSERCIÓN AL ÚLTIMO (CASO LISTA NO VACÍA) list_t aux = NULL; aux = calloc(1, sizeof(struct _node)); aux->elem = 7; list_t curr = list; while (curr->next != NULL) { curr = curr->next; } curr->next = aux; aux 7

94 list curr aux 4 3 9 3 INSERCIÓN AL ÚLTIMO (CASO LISTA NO VACÍA)
9 3 list INSERCIÓN AL ÚLTIMO (CASO LISTA NO VACÍA) list_t aux = NULL; aux = calloc(1, sizeof(struct _node)); aux->elem = 7; list_t curr = list; while (curr->next != NULL) { curr = curr->next; } curr->next = aux; curr 7 aux

95 list curr aux 4 3 9 3 INSERCIÓN AL ÚLTIMO (CASO LISTA NO VACÍA)
9 3 list INSERCIÓN AL ÚLTIMO (CASO LISTA NO VACÍA) list_t aux = NULL; aux = calloc(1, sizeof(struct _node)); aux->elem = 7; list_t curr = list; while (curr->next != NULL) { curr = curr->next; } curr->next = aux; curr 7 aux

96 list curr aux 4 3 9 3 INSERCIÓN AL ÚLTIMO (CASO LISTA NO VACÍA)
9 3 list INSERCIÓN AL ÚLTIMO (CASO LISTA NO VACÍA) list_t aux = NULL; aux = calloc(1, sizeof(struct _node)); aux->elem = 7; list_t curr = list; while (curr->next != NULL) { curr = curr->next; } curr->next = aux; curr 7 aux

97 4 3 9 3 list 7 [4,3,0,9,7]

98 list 4 3 7 9 3 BORRAR UN NODO (CON ERRORES!) list_t curr = list;
7 9 3 list BORRAR UN NODO (CON ERRORES!) list_t curr = list; list_t prev = NULL; while (curr != NULL && curr->elem != 7) { prev = curr; curr = curr->next; } prev->next = curr->next; free(curr); curr = NULL; 3

99 list curr 4 3 7 9 3 BORRAR UN NODO (CON ERRORES!) list_t curr = list;
7 9 3 list BORRAR UN NODO (CON ERRORES!) list_t curr = list; list_t prev = NULL; while (curr != NULL && curr->elem != 7) { prev = curr; curr = curr->next; } prev->next = curr->next; free(curr); curr = NULL; curr 3

100 list prev curr 4 3 7 9 3 BORRAR UN NODO (CON ERRORES!)
7 9 3 list BORRAR UN NODO (CON ERRORES!) list_t curr = list; list_t prev = NULL; while (curr != NULL && curr->elem != 7) { prev = curr; curr = curr->next; } prev->next = curr->next; free(curr); curr = NULL; prev curr 3

101 list prev curr 4 3 7 9 3 BORRAR UN NODO (CON ERRORES!)
7 9 3 list BORRAR UN NODO (CON ERRORES!) list_t curr = list; list_t prev = NULL; while (curr != NULL && curr->elem != 7) { prev = curr; curr = curr->next; } prev->next = curr->next; free(curr); curr = NULL; prev curr 3

102 list prev curr 4 3 7 9 3 BORRAR UN NODO (CON ERRORES!)
BORRAR UN NODO (CON ERRORES!) list_t curr = list; list_t prev = NULL; while (curr != NULL && curr->elem != 7) { prev = curr; curr = curr->next; } prev->next = curr->next; free(curr); curr = NULL; prev curr 3

103 list prev curr 4 3 7 9 3 BORRAR UN NODO (CON ERRORES!)
BORRAR UN NODO (CON ERRORES!) list_t curr = list; list_t prev = NULL; while (curr != NULL && curr->elem != 7) { prev = curr; curr = curr->next; } prev->next = curr->next; free(curr); curr = NULL; prev curr 3

104 list prev curr 4 3 9 3 BORRAR UN NODO (CON ERRORES!)
BORRAR UN NODO (CON ERRORES!) list_t curr = list; list_t prev = NULL; while (curr != NULL && curr->elem != 7) { prev = curr; curr = curr->next; } prev->next = curr->next; free(curr); curr = NULL; prev curr 3 Ejercicio: Arreglar el código. No funciona cuando: - La lista es vacía. - El “7” no está en la lista. - El “7” está en el primer nodo.

105 4 3 9 3 list 3 [4,3,0,9]

106 PARTE VII: Diccionario con Listas Enlazadas

107 dict 3 3 2 4 length length list next pair next next pair pair
index data index data index data index data content content content content length content length content length 3 2 4

108 (to be continued...)


Descargar ppt "Introducción a punteros en C"

Presentaciones similares


Anuncios Google