HOWTO · Arduino

Arduino Longitud del array

Descubre cómo contar los elementos de un arreglo de tamaño fijo en Arduino con el operador sizeof().

En esta página

Un arreglo de tamaño fijo en Arduino se puede contar con sizeof(array) / sizeof(array[0]) mientras el arreglo completo esté dentro del ámbito. El resultado es el número de elementos, por lo que puedes usarlo como límite de un bucle. sizeof() mide bytes; la división convierte el tamaño total del arreglo en bytes en un recuento de elementos.

Obtén la longitud de un arreglo de Arduino con sizeof()

Por ejemplo, si values contiene cinco enteros, sizeof(values) / sizeof(values[0]) da 5. Esto funciona porque, en este punto del programa, values designa el arreglo completo. La misma expresión sirve para un arreglo de tamaño fijo con otro tipo de elemento, ya que el denominador usa el tamaño del primer elemento de ese arreglo.

Por qué funciona la división con sizeof()

sizeof es un operador de C++, no una función. Aplicado a un arreglo, indica cuántos bytes ocupa el arreglo completo. Aplicado a array[0], indica cuántos bytes ocupa un elemento. Al dividir el primer tamaño por el segundo se obtiene el número de elementos, siempre que ambas expresiones se refieran al arreglo real y al tipo de sus elementos.

Por ejemplo, la expresión también cuenta los elementos de un arreglo float de tamaño fijo sin tener que suponer cuántos bytes ocupa un float en una placa concreta. Ambos tamaños se determinan para el mismo tipo y destino, y su cociente es el recuento de elementos. No fijes a mano un tamaño en bytes, como cuatro: el bucle necesita el número de elementos.

Aplica la fórmula a otros tipos y dimensiones de arreglos

El tipo de elemento no cambia la fórmula. Para un arreglo llamado readings, usa sizeof(readings) / sizeof(readings[0]). Esto resulta útil si cambia la lista de inicialización: el recuento se ajusta al arreglo declarado en lugar de depender de un número escrito por separado.

En un arreglo bidimensional de tamaño fijo, divide el tamaño del arreglo completo por el tamaño de su primera fila para contar las filas. Divide el tamaño de la primera fila por el tamaño de su primer elemento para contar las columnas. Por ejemplo, para int matrix[3][4], sizeof(matrix) / sizeof(matrix[0]) da el número de filas, y sizeof(matrix[0]) / sizeof(matrix[0][0]) da el número de columnas. Estas expresiones reflejan las dimensiones declaradas; no averiguan la longitud actual de una colección cuyo tamaño cambia dinámicamente.

Gestiona la longitud de los arreglos al pasarlos a funciones

Cuando se pasa un arreglo como parámetro de una función, el parámetro se trata como un puntero a su primer elemento. Dentro de esa función, sizeof(parameter) mide el puntero, no el arreglo completo de quien hizo la llamada. Por eso, dividir ese resultado por sizeof(parameter[0]) no permite recuperar el recuento original de elementos.

Pasa el recuento como un parámetro independiente y úsalo como límite del bucle. Calcúlalo en el punto de llamada, donde el arreglo completo todavía está dentro del ámbito: printValues(values, sizeof(values) / sizeof(values[0])). Así, la función puede procesar exactamente esa cantidad de elementos. Si pasas el arreglo por varias funciones, lleva el recuento junto con él para que cada función disponga de la información necesaria.

La fórmula de sizeof se aplica a arreglos de tamaño fijo cuyo tipo completo está disponible en la expresión. No sigue los cambios de tamaño de una colección dinámica o cuyo tamaño varía durante la ejecución. En esos casos, conserva el recuento de elementos o consúltalo mediante el mecanismo de longitud propio de la colección.

Usa la longitud en un sketch completo de Arduino

En un sketch de Arduino, declara el arreglo de tamaño fijo a nivel de archivo o dentro de setup(), calcula su recuento en ese mismo ámbito y recorre sus elementos desde el índice 0 mientras el índice sea menor que el recuento. Así, cada acceso queda dentro de los límites del arreglo declarado. En una placa, el sketch usa Serial de Arduino. Si se compila como C++ normal, un sustituto local sencillo de Serial permite que la misma lógica de setup() escriba en la salida estándar.

El código y las etiquetas o salidas visibles de esta sección se mantienen en inglés.

#include <stddef.h>

#ifdef ARDUINO
#include <Arduino.h>
#else
#include <iostream>

class SerialPort {
public:
  void begin(unsigned long) {}
  void print(const char* value) { std::cout << value; }
  template <typename T>
  void println(const T& value) { std::cout << value << '\n'; }
};
SerialPort Serial;
#endif

int values[] = {10, 20, 30, 40, 50};
const size_t valueCount = sizeof(values) / sizeof(values[0]);

void setup() {
  Serial.begin(9600);
  for (size_t i = 0; i < valueCount; ++i) {
    Serial.println(values[i]);
  }
  Serial.print("Count: ");
  Serial.println(valueCount);
}

void loop() {
}

#ifndef ARDUINO
int main() {
  setup();
}
#endif
10
20
30
40
50
Count: 5

En una placa, carga el sketch y abre el Monitor Serie a 9600 baudios para ver los valores y el recuento. Si mueves el bucle a una función auxiliar, pasa valueCount explícitamente junto con el arreglo; la función auxiliar no puede recuperar la longitud original del arreglo a partir de su parámetro de tipo puntero.