SDK Multiplataforma en C logo

SDK Multiplataforma en C

Arrays (punteros)

❮ Anterior
Siguiente ❯

Funciones

ArrPt(type)*arrpt_create (...)
ArrPt(type)*arrpt_copy (...)
ArrPt(type)*arrpt_read (...)
voidarrpt_destroy (...)
voidarrpt_destopt (...)
voidarrpt_clear (...)
voidarrpt_write (...)
uint32_tarrpt_size (...)
type*arrpt_get (...)
const type*arrpt_get_const (...)
type*arrpt_first (...)
const type*arrpt_first_const (...)
type*arrpt_last (...)
const type*arrpt_last_const (...)
type**arrpt_all (...)
const type**arrpt_all_const (...)
voidarrpt_append (...)
voidarrpt_prepend (...)
voidarrpt_insert (...)
type**arrpt_insert_n (...)
voidarrpt_join (...)
voidarrpt_delete (...)
voidarrpt_pop (...)
voidarrpt_sort (...)
voidarrpt_sort_ex (...)
uint32_tarrpt_find (...)
type*arrpt_search (...)
const type*arrpt_search_const (...)
type*arrpt_bsearch (...)
const type*arrpt_bsearch_const (...)
voidarrpt_foreach (...)
voidarrpt_foreach_const (...)
voidarrpt_forback (...)
voidarrpt_forback_const (...)
voidarrpt_end (void)

Estos contenedores son una especialización de los array, donde se almacenarán punteros a los objetos y no lo objetos en sí mismos (Figura 1). Aunque, en general, sirve todo lo visto en Arrays hay ciertas particularidades que debemos tener en cuenta:

  • Hay que crear y liberar memoria dinámica para cada objeto.
  • El acceso puede ser más lento, ya que hay que desreferenciar un puntero por cada elemento.
  • Mantener el array (insertar, eliminar, ordenar) puede ser más rápido ya que hay que mover menos memoria, sobre todo en el caso de manejar estructuras grandes o arrays de muchos elementos.
  • Se puede alojar el valor NULL en cualquier posición.
  • Es más seguro si otras partes de la aplicación mantienen punteros a los elementos del contenedor.
  • Es la única opción para trabajar con objetos opacos.
  • Esquema que compara un array de punteros con un array de objetos.
    Figura 1: Array de objetos vs array de punteros.

1. Crear arrays de punteros

  • Utiliza arrpt_create para crear un array.
  • Utiliza arrpt_destroy para destruir un array y sus elementos.
  • Utiliza arrpt_append para añadir un nuevo puntero al array.
  • Utiliza DeclPt para declarar tipos de puntero a struct.

En (Listado 1) vemos como crear y destruir arrays de punteros de Product. La principal diferencia con respecto a los arrays de objetos, radica en la gestión de la memoria dinámica de cada elemento.

Listado 1: Crear y destruir arrays de punteros.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
static void i_destroy(Product **product)
{
    str_destroy(&(*product)->code);
    str_destroy(&(*product)->desc);
    image_destroy(&(*product)->image);
    heap_delete(product, Product);
}

ArrPt(Product) *products = arrpt_create(Product);
Product *prod = heap_new(Product);
arrpt_append(products, prod, Product);
// Will modify the stored object
prod->type = ekHDD;
prod->code = str_c("GTK-1050");
prod->desc = str_c("Gigabyte GeForce GTX 1050 OC 2Gb GDDR5");
prod->image = load_image("card.png");
prod->price = 573.34;
...
arrpt_destroy(&products, i_destroy, Product);

2. Copia de arrays de punteros

Utiliza arrpt_copy para copiar un array.

La copia funciona de forma similar que en Copia de arrays, con la diferencia de que debemos reservar dinámicamente espacio para el objeto en sí (Listado 2).

Listado 2: Copiando un array de punteros Product.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
static Product *i_copy(const Product *src)
{
    Product *dest = heap_new(Product);
    dest->type = src->type;
    dest->code = str_copy(src->code);
    dest->desc = str_copy(src->desc);
    dest->image = image_copy(src->image);
    dest->price = src->price;
    return dest;
}

ArrSt(Product) *nproducts = arrpt_copy(products, i_copy, Product);
...
arrpt_destroy(&nproducts, i_destroy, Product);
❮ Anterior
Siguiente ❯

arrpt_create ()

Crea un array de punteros vacío.

ArrPt(type)*
arrpt_create(type);
type

Tipo de objeto.

Retorna

El nuevo array.


arrpt_copy ()

Crea una copia de un array de punteros.

ArrPt(type)*
arrpt_copy(const ArrPt(type) *array,
           FPtr_copy func_copy,
           type);
array

El array original.

func_copy

Función de copia del objeto.

type

Tipo de objeto.

Retorna

La copia del array original.

Observaciones

La función de copia debe crear un objeto dinámico y asignar memoria para los campos internos que lo requieran. Si pasamos NULL, se realizará una copia de los punteros originales, lo que puede suponer un riesgo de integridad ya que un mismo objeto puede ser destruido dos veces si no ponemos especial cuidado. Ver Copia de arrays de punteros.


arrpt_read ()

Crea un array leyendo su contenido de un Streams (de-serialización).

ArrPt(type)*
arrpt_read(Stream *stream,
           FPtr_read func_read,
           type);
stream

Un stream de lectura.

func_read

Constructor para crear un objeto a partir de los datos obtenidos de un stream.

type

Tipo de objeto.

Retorna

El array leído.


arrpt_destroy ()

Destruye un array y todos sus elementos.

void
arrpt_destroy(ArrPt(type) **array,
              FPtr_destroy func_destroy,
              type);
array

El array. Será puesto a NULL tras la destrucción.

func_destroy

Función para destruir un elemento del array. Si es NULL se destruirá solo el array, pero no sus elementos.

type

Tipo de objeto.


arrpt_destopt ()

Destruye un array y todos sus elementos, siempre y cuando el objeto array no sea NULL.

void
arrpt_destopt(ArrSt(type) **array,
              FPtr_destroy func_destroy,
              type);
array

El array.

func_destroy

Ver arrpt_destroy.

type

Tipo de objeto.


arrpt_clear ()

Borra el contenido del array, sin destruir el contenedor que quedará con cero elementos.

void
arrpt_clear(ArrPt(type) *array,
            FPtr_destroy func_destroy,
            type);
array

El array.

func_destroy

Destructor del elemento. Puede ser NULL. Ver arrpt_destroy.

type

Tipo de objeto.


arrpt_write ()

Escribe un array en un Streams (serialización).

void
arrpt_write(Stream *stream,
            const ArrPt(type) *array,
            FPtr_write func_write,
            type);
stream

Un stream de escritura.

array

El array.

func_write

Función que escribe el contenido de un elemento en un stream.

type

Tipo de objeto.


arrpt_size ()

Obtiene el número de elementos en un array.

uint32_t
arrpt_size(const ArrPt(type) *array,
           type);
array

El array.

type

Tipo de objeto.

Retorna

Número de elementos.


arrpt_get ()

Obtiene un puntero al elemento en la posición pos.

type*
arrpt_get(ArrPt(type) *array,
          const uint32_t pos,
          type);
array

El array.

pos

Posición o índice del elemento.

type

Tipo de objeto.

Retorna

Puntero al elemento.


arrpt_get_const ()

Obtiene un puntero const al elemento en la posición pos.

const type*
arrpt_get_const(const ArrPt(type) *array,
                const uint32_t pos,
                type);
array

El array.

pos

Posición o índice del elemento.

type

Tipo de objeto.

Retorna

Puntero al elemento.


arrpt_first ()

Obtiene un puntero al primer elemento del array.

type*
arrpt_first(ArrPt(type) *array,
            type);
array

El array.

type

Tipo de objeto.

Retorna

Puntero al elemento.


arrpt_first_const ()

Obtiene un puntero const al primer elemento del array.

const type*
arrpt_first_const(const ArrPt(type) *array,
                  type);
array

El array.

type

Tipo de objeto.

Retorna

Puntero al elemento.


arrpt_last ()

Obtiene un puntero al último elemento del array.

type*
arrpt_last(ArrPt(type) *array,
           type);
array

El array.

type

Tipo de objeto.

Retorna

Puntero al elemento.


arrpt_last_const ()

Obtiene un puntero const al último elemento del array.

const type*
arrpt_last_const(const ArrPt(type) *array,
                 type);
array

El array.

type

Tipo de objeto.

Retorna

Puntero al elemento.


arrpt_all ()

Obtiene un puntero a la memoria interna del array, que da acceso a todos los elementos.

type**
arrpt_all(ArrPt(type) *array,
          type);
array

El array.

type

Tipo de objeto.

Retorna

Puntero base. Incrementándolo uno a uno iteraremos sobre los elementos.

Observaciones

Utiliza arrpt_foreach para iterar sobre los elementos de forma más segura y elegante.


arrpt_all_const ()

Obtiene un puntero const a la memoria interna del array, que da acceso a todos los elementos.

const type**
arrpt_all_const(const ArrPt(type) *array,
                type);
array

El array.

type

Tipo de objeto.

Retorna

Puntero base. Incrementándolo uno a uno iteraremos sobre los elementos.

Observaciones

Utiliza arrpt_foreach_const para iterar sobre los elementos de forma más segura y elegante.


arrpt_append ()

Añade un puntero al final del array.

void
arrpt_append(ArrPt(type) *array,
             type *value,
             type);
array

El array.

value

Puntero al elemento a añadir.

type

Tipo de objeto.


arrpt_prepend ()

Inserta un puntero al inicio del array. El resto de elementos serán desplazados a la derecha.

void
arrpt_prepend(ArrPt(type) *array,
              type *value,
              type);
array

El array.

value

Puntero al elemento a insertar.

type

Tipo de objeto.


arrpt_insert ()

Inserta un puntero en una posición arbitraria del array.

void
arrpt_insert(ArrPt(type) *array,
             const uint32_t pos,
             type *value,
             type);
array

El array.

pos

Posición donde será insertado. El actual elemento en pos y siguientes serán desplazados a la derecha.

value

Puntero al elemento a insertar.

type

Tipo de objeto.


arrpt_insert_n ()

Inserta varios punteros en una posición arbitraria del array.

type**
arrpt_insert_n(ArrPt(type) *array,
               const uint32_t pos,
               const uint32_t n,
               type);
array

El array.

pos

Posición donde será insertado el primer elemento. El actual elemento en pos y siguientes serán desplazados a la derecha.

n

Número de elementos a insertar.

type

Tipo de objeto.

Retorna

Puntero al primer puntero insertado.

Observaciones

Los punteros insertados serán inicializados a NULL.


arrpt_join ()

Une dos vectores. Añade todos los elementos de src al final de dest.

void
arrpt_join(ArrPt(type) *dest,
           const ArrPt(type) *src,
           FPtr_copy func_copy,
           type);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
ArrPt(Product) *products = create_products(...);
ArrPt(Product) *new_products = new_products(...);

// Join without 'copy' func. Dynamic 'Product' objects will be reused.
arrpt_join(products, new_products, NULL, Product);
arrpt_destroy(&new_products, NULL, Product);
...
arrpt_destroy(&products, i_destroy, Product);

// Join with 'copy' func. Dynamic 'Product' objects will be duplicate.
arrpt_join(products, new_products, i_copy, Product);
arrpt_destroy(&new_products, i_destroy, Product);
...
arrpt_destroy(&products, i_destroy, Product);
dest

El array destino.

src

El array cuyos elementos serán añadidos a dest.

func_copy

Función de copia del objeto.

type

Tipo de objeto.

Observaciones

La función de copia debe crear memoria dinámica tanto para el objeto como para los campos que lo requieran. Si es NULL se solo se añadirá una copia del puntero original a dest.


arrpt_delete ()

Elimina un puntero del array.

void
arrpt_delete(ArrPt(type) *array,
             const uint32_t pos,
             FPtr_destroy func_destroy,
             type);
array

El array.

pos

Posición del elemento a borrar. El actual elemento en pos+1 y siguientes serán desplazados a la izquierda.

func_destroy

Destructor del elemento. Puede ser NULL. Ver arrpt_destroy.

type

Tipo de objeto.


arrpt_pop ()

Elimina el último puntero del array.

void
arrpt_pop(ArrPt(type) *array,
          FPtr_destroy func_destroy,
          type);
array

El array.

func_destroy

Destructor del elemento. Puede ser NULL. Ver arrpt_destroy.

type

Tipo de objeto.


arrpt_sort ()

Ordena los elementos del array utilizando Quicksort.

void
arrpt_sort(ArrPt(type) *array,
           FPtr_compare func_compare,
           type);
array

El array.

func_compare

Función para comparar dos elementos. Ordenar y buscar en arrays.

type

Tipo de objeto.


arrpt_sort_ex ()

Ordena los elementos del array utilizando Quicksort y datos adicionales.

void
arrpt_sort_ex(ArrPt(type) *array,
              FPtr_compare_ex func_compare,
              type,
              dtype);
array

El array.

func_compare

Función para comparar dos elementos utilizando un dato adicional.

type

Tipo de objeto.

dtype

Tipo de dato en la función de comparación.


arrpt_find ()

Busca un determinado puntero en el array.

uint32_t
arrpt_find(const ArrPt(type) *array,
           type *elem,
           type);
array

El array.

elem

Puntero a buscar.

type

Tipo de objeto.

Retorna

La posición del puntero si existe, o UINT32_MAX si no.


arrpt_search ()

Busca un elemento en el array de forma lineal O(n).

type*
arrpt_search(ArrPt(type) *array,
             FPtr_compare func_compare,
             ktype key,
             uint32_t *pos,
             type,
             ktype);
array

El array.

func_compare

Función de comparación. El primer parámetro es el elemento, el segundo la clave de búsqueda. Ordenar y buscar en arrays.

key

Clave a buscar. Puntero a un tipo de dato que puede ser diferente al tipo de elemento del array.

pos

Posición del elemento en el array (si existe), o UINT32_MAX si no existe. Puede ser NULL.

type

Tipo de objeto.

ktype

Tipo de clave.

Retorna

Puntero al primer elemento que coincida con el criterio de búsqueda o NULL si no existe ninguno.


arrpt_search_const ()

Versión const de arrpt_search.

const type*
arrpt_search_const(const ArrPt(type) *array,
                   FPtr_compare func_compare,
                   const ktype *key,
                   uint32_t *pos,
                   type,
                   ktype);
array

El array.

func_compare

Función de comparación.

key

Clave a buscar.

pos

Posición del elemento en el array.

type

Tipo de objeto.

ktype

Tipo de clave.

Retorna

Elemento.


arrpt_bsearch ()

Busca un elemento en el array de forma logarítmica O(logn).

type*
arrpt_bsearch(ArrPt(type) *array,
              FPtr_compare func_compare,
              ktype key,
              uint32_t *pos,
              type,
              ktype);
array

El array.

func_compare

Función de comparación. El primer parámetro es el elemento, el segundo la clave de búsqueda. Ordenar y buscar en arrays.

key

Clave a buscar. Puntero a un tipo de dato que puede ser diferente al tipo de elemento del array.

pos

Posición del elemento en el array (si existe), o UINT32_MAX si no existe. Puede ser NULL.

type

Tipo de objeto.

ktype

Tipo de clave.

Retorna

Puntero al primer elemento que coincida con el criterio de búsqueda o NULL si no existe ninguno.

Observaciones

El array debe estar ordenado según el mismo criterio que la búsqueda. De no ser así el resultado es impredecible.


arrpt_bsearch_const ()

Versión const de arrpt_bsearch.

const type*
arrpt_bsearch_const(const ArrPt(type) *array,
                    FPtr_compare func_compare,
                    const ktype *key,
                    uint32_t *pos,
                    type,
                    ktype);
array

El array.

func_compare

Función de comparación.

key

Clave a buscar.

pos

Posición del elemento en el array.

type

Tipo de objeto.

ktype

Tipo de clave.

Retorna

Elemento.


arrpt_foreach ()

Itera sobre todos los elementos del array. Usa arrpt_end para cerrar el bucle.

void
arrpt_foreach(type *elem,
              ArrPt(type) *array,
              type);
1
2
3
arrpt_foreach(product, array, Product)
    bstd_printf("Index:%d, Id:%d\n", product_i, product->id);
arrpt_end()
elem

Nombre de la variable 'elemento' dentro del bucle. Añadiendo el sufijo '_i' obtenemos el índice.

array

El array.

type

Tipo de objeto.


arrpt_foreach_const ()

Versión const de arrpt_foreach.

void
arrpt_foreach_const(const type *elem,
                    const ArrPt(type) *array,
                    type);
elem

Elemento.

array

El array.

type

Tipo de objeto.


arrpt_forback ()

Itera sobre todos los elementos del array hacia atrás, desde el último al primero. Usa arrpt_end para cerrar el bucle.

void
arrpt_forback(type *elem,
              ArrPt(type) *array,
              type);
1
2
3
4
// Now in reverse order
arrpt_forback(product, array, Product)
    bstd_printf("Index:%d, Id:%d\n", product_i, product->id);
arrpt_end()
elem

Nombre de la variable 'elemento' dentro del bucle. Añadiendo el sufijo '_i' obtenemos el índice.

array

El array.

type

Tipo de objeto.


arrpt_forback_const ()

Versión const de arrpt_forback.

void
arrpt_forback_const(const type *elem,
                    const ArrPt(type) *array,
                    type);
elem

Elemento.

array

El array.

type

Tipo de objeto.


arrpt_end ()

Cierra el bucle abierto por arrpt_foreach, arrpt_foreach_const, arrpt_forback o arrpt_forback_const.

void
arrpt_end(void);
❮ Anterior
Siguiente ❯