The Circuit Maker
Arduino8 min leitura

Como Encontrar o Comprimento de um Array no Arduino

Learn how to find the length or number of elements of an array in Arduino using sizeof() with code examples and explanations.

·

É comum usar arrays como parte do código que queremos carregar no Arduino. Há chances de que em algum momento você tenha declarado um array sem definir explicitamente seu tamanho, mas em vez disso, optou por popular o array imediatamente como no seguinte exemplo:

int digitalPins[] = {2, 3, 4, 5, 6};

Em algum momento do seu código, você quer executar lógica usando cada elemento do array. Portanto, você pensa em usar um loop for. Usar um loop para iterar sobre cada elemento de um array significa que devemos conhecer o número total de elementos do array, como no seguinte exemplo:

for (int i = 0; i < totalDigitalPins; i++) {
    // aplicar lógica ao digitalPins[i]
  }

Você quer determinar o número de elementos de um array dinamicamente para obter o valor de totalDigitalPins. A primeira coisa que você encontra na documentação do Arduino é usar a função utilitária sizeOf() sem entender completamente a definição do que ela faz.

int digitalPins[] = {2, 3, 4, 5, 6};
int totalDigitalPins = sizeOf(digitalPins);

for (int i = 0; i < totalDigitalPins; i++) {
    // aplicar lógica ao digitalPins[i]
}

Infelizmente, você rapidamente percebe que usar a função utilitária sizeOf não obtém verdadeiramente o número de elementos do array.

Neste artigo, vou explicar em detalhes como encontrar o número de elementos de um array, falar sobre as razões pelas quais não há uma função integrada que obtém o comprimento de um array, compartilhar algumas recomendações, bem como compartilhar minha experiência sobre por que precisei de uma maneira de obter dinamicamente o tamanho do array.

Como encontrar o número de elementos de um array no Arduino?

O código Arduino é escrito em C++, e a fórmula para obter o número de elementos em um array em C++ é obter o tamanho do array em bytes dividido pelo tamanho de um único elemento do array.

tamanho do array em bytes / tamanho de um único elemento do array

Fórmula para encontrar o número de elementos em um array

Em nosso exemplo inicial, declaramos um array chamado digitalPins. Portanto, se aplicarmos esta fórmula para obter o valor de totalDigitalPins, o código resultaria assim:

int digitalPins[] = {2, 3, 4, 5, 6};
int totalDigitalPins = sizeOf(digitalPins) / sizeOf(digitalPins[0]);

for (int i = 0; i < totalDigitalPins; i++) {
    // aplicar lógica ao digitalPins[i]
}

Dessa forma, podemos iterar através de cada elemento do array ao usar um loop for.

Explicação

No Arduino, podemos determinar quantos bytes são usados na memória sempre que declaramos uma variável usando um tipo de dados usando a função sizeOf.

bool bo;
boolean boo;
byte byt;
char cha;
double doubl;
float floa;
int in;
long lon;
short shor;
size_t size_;

void setup() {
  Serial.begin(9600);

  Serial.println("total BYTES de um Tipo de Dados bool");
  Serial.println(sizeof(bo));

  Serial.println("total BYTES de um Tipo de Dados boolean");
  Serial.println(sizeof(boo));

  Serial.println("total BYTES de um Tipo de Dados byte");
  Serial.println(sizeof(byt));

  Serial.println("total BYTES de um Tipo de Dados char");
  Serial.println(sizeof(cha));

  Serial.println("total BYTES de um Tipo de Dados double");
  Serial.println(sizeof(doubl));

  Serial.println("total BYTES de um Tipo de Dados float");
  Serial.println(sizeof(floa));

  Serial.println("total BYTES de um Tipo de Dados int");
  Serial.println(sizeof(in));

  Serial.println("total BYTES de um Tipo de Dados long");
  Serial.println(sizeof(lon));

  Serial.println("total BYTES de um Tipo de Dados short");
  Serial.println(sizeof(shor));

  Serial.println("total BYTES de um Tipo de Dados size_t");
  Serial.println(sizeof(size_));
}

Se você executar a lógica anterior no Arduino enquanto tem o Monitor Serial aberto para ler os logs usando a função Serial.println(), logo entenderá quanto espaço esses tipos de dados estão ocupando na memória. Por exemplo, os tipos de dados bool, boolean, byte e char usam um byte, enquanto os tipos de dados double, float e long usam 4 bytes no Arduino UNO R3.

A saída de obter o tamanho em bytes de diferentes tipos de dados no Arduino
A saída de obter o tamanho em bytes de diferentes tipos de dados no Arduino

De forma similar, podemos fazer isso com um array.

int digitalPins[] = {2, 3, 4, 5, 6};

void setup() {
  Serial.begin(9600);

  Serial.println("total BYTES do array digitalPins");
  Serial.println(sizeof(digitalPins));
}

Neste caso, os bytes usados em digitalPins com 5 elementos dentro do array é 10.

Registrando tamanho em bytes de um array int
Registrando tamanho em bytes de um array int

Se você adicionar mais elementos ou remover elementos, os bytes ocupados neste array irão variar. No entanto, e se tivermos outro array com o mesmo número de elementos mas com um tipo de dados diferente, digamos o tipo de dados char. Usará o mesmo número de bytes que digitalPins?

char letters[] = {'a', 'r', 'd', 'u', 'c'};

void setup() {
  Serial.begin(9600);

  Serial.println("total BYTES do array letters");
  Serial.println(sizeof(letters));
}

Dependendo de quais tipos de dados são usados nos dois arrays, a resposta pode ser sim ou não. Neste caso, a resposta é não.

Registrando tamanho em bytes de um array char
Registrando tamanho em bytes de um array char

Por que isso está acontecendo?

Lembre-se, cada tipo de dados pode usar um número diferente de bytes. Como vimos anteriormente, um tipo de dados int usa dois bytes, e um tipo de dados char usa um byte.

A saída de obter o tamanho em bytes de diferentes tipos de dados no Arduino
A saída de obter o tamanho em bytes de diferentes tipos de dados no Arduino

Portanto, para calcular o número de bytes em um array, você precisa determinar o número de elementos desse array vezes o tamanho em bytes do tipo de dados usado no array.

tamanho do tipo de dados x número de elementos no array

Tamanho de um array em bytes

Portanto, no caso de digitalPins, sabemos que tem 5 elementos e seu tipo de dados é int, e o tipo de dados int usa 2 bytes. Se multiplicarmos esses dois números, obtemos 10.

bytes de digitalPins = 5 x 2 = 10

Se fizermos o mesmo para o array letters, obtemos o seguinte cálculo:

bytes de letters = 5 x 1 = 5

No entanto, sabemos que sizeOf já obtém os bytes de qualquer variável, e não necessariamente teríamos que calcular o tamanho de bytes de um array.

int digitalPins[] = {2, 3, 4, 5, 6};
char letters[] = {'a', 'r', 'd', 'u', 'c'};

void setup() {
  Serial.begin(9600);

  Serial.println(sizeof(digitalPins));
  Serial.println(sizeof(letters));
}

No entanto, usando essa informação, podemos determinar o número de elementos de um array caso você queira obter esse valor dinamicamente.

char letters[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
int totalLetters = sizeOf(letters) / sizeOf(letters[0]);

Por que não há uma função integrada que obtém o comprimento de um array no Arduino?

Se você é um engenheiro de software, desenvolvedor de software ou programador, provavelmente trabalhou com outras linguagens de programação como JavaScript, PHP, C#, Java, etc. Similar ao C/C++, essas linguagens de programação também usam arrays.

No entanto, essas linguagens têm métodos ou propriedades integradas para obter o comprimento de um array. Por exemplo, em Javascript, obter o número de elementos de um array seria assim:

const myArray = [1,2,3,4,5,6,7];
const totalElementsOfArray = myArray.length;

Por que não há uma função integrada em C/C++ para obter o comprimento de um array?

Muito disso tem a ver com como essas duas linguagens de programação foram usadas em uma época em que os computadores tinham recursos limitados. Se você pensar sobre isso, o Arduino não é tão poderoso quanto um telefone ou computador, e também tem limitações quando se trata de armazenamento de memória. Adicionar funções integradas significa usar parte desse espaço extra que poderia ser usado para escrever a lógica a ser usada no Arduino.

Outra boa razão é que C/C++, ao contrário das linguagens de programação de alto nível como JavaScript, você não pode anexar elementos a um array. Portanto, se você criar um array em JavaScript sem declarar o número de elementos que o array pode ter, você pode anexar mais elementos ao array e ser limitado pelo tamanho do array. Por outro lado, em C/C++ não há maneira de adicionar mais elementos a um array de tamanho fixo.

Recomendação

A recomendação geral é definir o tamanho do array antes de declarar o array. Dessa forma, você evita tentar calcular o número de elementos de um array.

int arraySize = 5;
int digitalPins[arraySize] = {2, 3, 4, 5, 6};
char letters[arraySize] = {'a', 'r', 'd', 'u', 'c'};

Casos de Uso

No outro dia, eu estava trabalhando na construção de um circuito simples para conectar múltiplos LEDs usando múltiplos pinos do Arduino. O código consistia em definir um array de pinos de LED e usar um loop for para configurar todos os pinos digitais do Arduino no modo OUTPUT para enviar sinais HIGH ou LOW desses pinos do Arduino para ligar e desligar múltiplas luzes LED. O código era este:

/*
    Conectar Múltiplos LEDs usando Múltiplos Pinos do Arduino.
    Para mais guias e tutoriais: https://www.thecircuitmaker.com
*/
// configurar variável de array para armazenar todos os números de pinos que acenderão os LEDs
int ledPins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
int totalPins = sizeof(ledPins) / sizeof(int);
// atraso de 1 segundo
int delayTime = 1000;
void setup() {
  // configurar os pinos dos LEDs para se comportarem no modo OUTPUT para enviar sinais HIGH ou LOW
  for (int i = 0; i < totalPins; i++) {
    pinMode(ledPins[i], OUTPUT);
  }
}
void loop() {
  blinkRandomLED();
}
void blinkAllLeds() {
  for (int i = 0; i < totalPins; i++) {
    // ligar o LED
    digitalWrite(ledPins[i], HIGH);
  }
  // esperar por 1 segundo
  delay(delayTime);
  for (int i = 0; i < totalPins; i++) {
    // desligar o LED
    digitalWrite(ledPins[i], LOW);
  }
  // esperar por um segundo
  delay(delayTime);
}
void blinkOneLEDAtATime() {
  for (int i = 0; i < totalPins; i++) {
    // ligar o LED
    digitalWrite(ledPins[i], HIGH);
    // esperar por 1 segundo
    delay(delayTime);
    // desligar o LED
    digitalWrite(ledPins[i], LOW);
    // esperar por um segundo
    delay(delayTime);
  }
}
void blinkRandomLED() {
  // selecionar número de pino aleatório
  int randomIndex = random(totalPins);
  int pinSelected = ledPins[randomIndex];
  
  // ligar o LED
  digitalWrite(pinSelected, HIGH);
  // esperar por 1 segundo
  delay(delayTime);
  // desligar o LED
  digitalWrite(pinSelected, LOW);
  // esperar por um segundo
  delay(delayTime);
}

Observe como estou usando totalPins ou o número de elementos do ledPins para executar lógica para piscar os LEDs.

Conclusão

Neste artigo, você aprendeu como calcular o número de elementos de um array em C++, a linguagem de programação usada no Arduino. Embora não haja uma função integrada que calcule o comprimento de um array, ainda podemos determinar o número total de elementos do array usando sizeOf. No entanto, é recomendado definir em uma variável o tamanho do array para evitar fazer cálculos adicionais.

Você gostou deste artigo?

Espero que este artigo tenha sido não apenas útil, mas também educativo. Se você gostou, compartilhe este artigo com amigos que estão interessados em eletrônica e gostam de fazer projetos divertidos usando Arduino.

Se você tiver dúvidas, perguntas ou encontrar problemas ao seguir este tutorial, não hesite em deixar um comentário na seção abaixo.

Note que os comentários são moderados para prevenir spam.