Portada ¿Qué es? Curso de programación en C moderno Utilidad (II Edición) Operaciones Insertar Eliminar Lista del Kernel Neira Ayuso, Pablo Ejemplo list_entry Funciones Macros Falgueras García, Carlos Tema 9 Listas encadenadas Índice Portada 1 ¿Qué es una lista encadenada? ¿Qué es? Utilidad Operaciones Insertar Eliminar Lista del Kernel Ejemplo list_entry Funciones Macros 2 ¿Cuándo son útiles? 3 Operaciones Insertar Eliminar 4 Lista del Kernel Ejemplo ¿Cómo se obtiene el elemento a partir del list_head? Funciones principales Macros principales ¿Qué es una lista encadenada? Portada ¿Qué es? Utilidad Operaciones Insertar Eliminar Lista del Kernel Ejemplo list_entry Funciones Macros • Cada elemento guarda: 1 Información 2 Una referencia al siguiente elemento [y al anterior] • Los elementos están dispersos en la memoria. Se reservan individualmente. ¿Cuándo son útiles? Portada ¿Qué es? Utilidad Operaciones Insertar Eliminar Lista del Kernel Ejemplo list_entry Funciones Macros • No sabemos cuántos elementos vamos a tener que guardar • Vamos a recorrer los elementos de manera secuencial • Necesitamos hacer inserciones y/o eliminaciones de elementos o sublistas Insertar Portada ¿Qué es? Utilidad Operaciones Insertar Eliminar Lista del Kernel Ejemplo list_entry Funciones Macros Eliminar Portada ¿Qué es? Utilidad Operaciones Insertar Eliminar Lista del Kernel Ejemplo list_entry Funciones Macros Lista del Kernel Portada ¿Qué es? Utilidad Operaciones Insertar Eliminar Lista del Kernel Ejemplo list_entry Funciones Macros struct list_head { struct list_head *next; struct list_head *prev; }; struct element { int a; struct list_head list; int b; }; Ejemplo Portada ¿Qué es? Utilidad Operaciones Insertar Eliminar Lista del Kernel Ejemplo list_entry Funciones Macros 1 i n t main ( ) 2 { 3 struct list_head l i s t ; 4 s t r u c t element ∗ element ; 5 6 INIT_LIST_HEAD(& l i s t ) ; 7 8 element = e leme nt_a llo c (1 , 1) ; 9 l i s t _ a d d (&( e l e m e n t −> l i s t ) , & l i s t ) ; 10 11 element = e leme nt_a llo c (2 , 2) ; 12 l i s t _ a d d (&( e l e m e n t −> l i s t ) , & l i s t ) ; 13 14 list_for_each_entry ( element , &l i s t , l i s t ) 15 p r i n t f ( "{%d , %d }\ n " , e l e m e n t −>a , e l e m e n t −>b ) ; 16 17 return 0; 18 } Ejemplo Portada ¿Qué es? Utilidad Operaciones Insertar Eliminar Lista del Kernel Ejemplo list_entry Funciones Macros 1 i n t main ( ) 2 { 3 struct list_head l i s t ; 4 s t r u c t element ∗ element ; 5 6 INIT_LIST_HEAD(& l i s t ) ; 7 8 element = e leme nt_a llo c (1 , 1) ; 9 l i s t _ a d d (&( e l e m e n t −> l i s t ) , & l i s t ) ; 10 11 element = e leme nt_a llo c (2 , 2) ; 12 l i s t _ a d d (&( e l e m e n t −> l i s t ) , & l i s t ) ; 13 14 list_for_each_entry ( element , &l i s t , l i s t ) 15 p r i n t f ( "{%d , %d }\ n " , e l e m e n t −>a , e l e m e n t −>b ) ; 16 17 return 0; 18 } Ejemplo Portada ¿Qué es? Utilidad Operaciones Insertar Eliminar Lista del Kernel Ejemplo list_entry Funciones Macros 1 i n t main ( ) 2 { 3 struct list_head l i s t ; 4 s t r u c t element ∗ element ; 5 6 INIT_LIST_HEAD(& l i s t ) ; 7 8 element = e leme nt_a llo c (1 , 1) ; 9 l i s t _ a d d (&( e l e m e n t −> l i s t ) , & l i s t ) ; 10 11 element = e leme nt_a llo c (2 , 2) ; 12 l i s t _ a d d (&( e l e m e n t −> l i s t ) , & l i s t ) ; 13 14 list_for_each_entry ( element , &l i s t , l i s t ) 15 p r i n t f ( "{%d , %d }\ n " , e l e m e n t −>a , e l e m e n t −>b ) ; 16 17 return 0; 18 } Ejemplo Portada ¿Qué es? > list_example {2, 2} {1, 1} Utilidad Operaciones Insertar Eliminar Lista del Kernel Ejemplo list_entry Funciones Macros 1 i n t main ( ) 2 { 3 struct list_head l i s t ; 4 s t r u c t element ∗ element ; 5 6 INIT_LIST_HEAD(& l i s t ) ; 7 8 element = e leme nt_a llo c (1 , 1) ; 9 l i s t _ a d d (&( e l e m e n t −> l i s t ) , & l i s t ) ; 10 11 element = e leme nt_a llo c (2 , 2) ; 12 l i s t _ a d d (&( e l e m e n t −> l i s t ) , & l i s t ) ; 13 14 list_for_each_entry ( element , &l i s t , l i s t ) 15 p r i n t f ( "{%d , %d }\ n " , e l e m e n t −>a , e l e m e n t −>b ) ; 16 17 return 0; 18 } ¿Cómo se obtiene el elemento a partir del list_head? Portada ¿Qué es? Utilidad Operaciones Insertar Eliminar Lista del Kernel Ejemplo list_entry Funciones Macros 1 /∗ ∗ 2 ∗ l i s t _ e n t r y − get the s t r u c t f o r t h i s entry 3 ∗ @ptr : the &s t r u c t l i s t _ h e a d p o i n t e r . 4 ∗ @ t y p e : t h e t y p e o f t h e s t r u c t t h i s i s embedded i n . 5 ∗ @member : t h e name o f t h e l i s t _ s t r u c t w i t h i n t h e s t r u c t . 6 ∗/ 7 #d e f i n e l i s t _ e n t r y ( p t r , t y p e , member ) \ 8 ( ( t y p e ∗ ) ( ( c h a r ∗ ) ( p t r ) −( u n s i g n e d l o n g ) ( & ( ( t y p e ∗ ) 0 )−>member ) ) ) Funciones principales Portada ¿Qué es? • list_add: Añade después de la cabeza (pila) Utilidad • list_add_tail: Añade antes de la cabeza (cola) Operaciones • list_move: Mueve un elemento de una lista a después Insertar Eliminar Lista del Kernel Ejemplo list_entry Funciones Macros de la cabeza de otra (pila) • list_move_tail: Mueve un elemento de una lista a antes de la cabeza de otra (cola) • list_del: Borra el nodo que recibe • list_splice: Une dos listas • list_empty: Comprueba si una lista está vacía Macros principales Portada ¿Qué es? • INIT_LIST_HEAD: Inicializa la cabeza de una lista Utilidad • list_for_each: Recorre cada nodo de una lista Operaciones Insertar Eliminar Lista del Kernel Ejemplo list_entry Funciones Macros • list_for_each_safe: Recorre cada nodo de una lista y se puede borrar un elemento mientras se rocorre la lista. • list_for_each_entry: Recorre cada elemento de una lista • list_for_each_entry_safe: Recorre cada elemento de una lista y se puede borrar un elemento mientras se rocorre la lista.