Noções básicas de C++ em um Arduino, parte 4, declarações de controle e loops

Tempo de leitura: 5 minutes

Este Noções básicas de C++ em uma série Arduino cobre muitos elementos diferentes necessários para todos os tipos de projetos e ideias em um Arduino. Nesta entrada, cobrimos instruções de controle e loops.

A série até agora cobriu variáveis, matrizes e métodos simples. No entanto, escrever um programa envolve um pouco mais do que essas coisas. Todas as coisas que você aprendeu até agora permitirão que você armazene valores e execute cálculos simples; no entanto, às vezes você precisa tomar decisões em seu programa ou repetir certas instruções várias vezes. Portanto, é importante entender as instruções de controle e loops que permitirão que você escreva programas mais avançados.

 

Booleanos e condições

Lembra dos booleanos discutidos na primeira parte? Essas variáveis permitem que você armazene um único valor booleano – verdadeiro ou falso. O Arduino pode avaliar expressões booleanas para você, e você pode instruí-lo a armazenar o resultado em uma variável:

// a será falso (5 é menor que 2 -> falso)
boolean a = 5 < 2;

// b será verdadeiro (10 é igual a 10 -> verdadeiro)
boolean b = 10 == 10;

// c será falso
// (10 não é igual a 2 -> verdadeiro) AND (a é igual a b -> falso)
// verdadeiro AND falso -> falso
boolean c = (10 != 2) && ('a' == 'b');

// d será verdade
// verdadeiro OU falso -> verdadeiro
boolean d = true || false;

// e sempre será falso
// O ponto de exclamação nega uma expressão booleana
// (não verdadeiro) -> falso
boolean e = !true;

Como você pode ver, é possível comparar diferentes variáveis. No entanto, você também pode combinar os resultados dessas comparações com o && (lógico e) e || operadores (lógicos ou). Além disso, você também pode inverter o resultado de uma expressão booleana usando um ponto de exclamação (não lógico).

 

Declarações If-Else

Agora, dê uma olhada nos blocos discutidos na parte dois desta série. Conforme mencionado, você pode encapsular certas instruções dentro de um bloco. Você também pode adicionar uma instrução if ao início de um bloco para executar o código dentro dele apenas se uma determinada condição for atendida:

float divide(float a, float b)
{
  if(b > 0)
  {
    // Só executa o código neste bloco se b for maior que zero
    return a / b;
  }

  return 0;
}

Você pode adicionar um bloco else opcional logo abaixo de um bloco if, que só é executado quando a expressão booleana é avaliada como falsa:

float divide(float a, float b)
{
  if(b > 0)
  {
    // Só executa o código neste bloco se b for maior que zero
    return a / b;
  }
  else
  {
    // Só executa o código neste bloco se b for menor que zero
    return 0;
  }
}

Você também pode encadear vários blocos if e else-if juntos:

float divide(float a, float b)
{
  if(b > 0 && a > 0)
  {
    // Só executa o código neste bloco se b for maior que zero
    return a / b;
  }
  else if(b <= 0 && a > 0)
  {
    // Só executa o código neste bloco se b for menor que zero
    return 0;
  }
  else
  {
    // Faça outra coisa
  }

  return 0;
}

Observe que você pode adicionar quantos blocos else-if desejar. No entanto, você deve sempre ter um bloco if; e você só pode adicionar no máximo um bloco else.

Mudar de declarações

As declarações switch representam uma maneira de verificar se uma variável tem um valor específico:

String getGreeting(int number)
{
  switch(number)
  {
    // if (number == 0) -> return "Hello, "
    case 0:
  	return "Hello, ";
  	break;

    // else if (number == 1) -> return "Greetings, "
    case 1:
  	return "Greetings, ";
  	break;

    // else if (number == 2) -> return "Hi, "
    case 2:
  	return "Hi, ";
  	break;

    // else -> return "Dear, "
    default:
  	return "Dear, ";
  }
}

Você pode, é claro, também usar várias instruções if-else encadeadas, conforme indicado pelos comentários. No entanto, a instrução switch geralmente aumenta a legibilidade de seu programa quando você deseja realizar tais verificações.

Loops “While”

Agora você sabe como verificar as condições! No entanto, e se você quiser repetir a execução de um determinado bloco várias vezes? Você poderia, é claro, fazer o seguinte para executar o bloco duas vezes:

void setup()
{
  int counter = 0;
 
  {
    readSensor();
    counter = counter + 1;
    
    Serial.print("The sensor got read ");
    Serial.print(counter);
    Serial.println(" times!");
  }

  {
    readSensor();
    counter = counter + 1;
    
    Serial.print("The sensor got read ");
    Serial.print(counter);
    Serial.println(" times!");
  }
}

No entanto, isso é considerado uma prática ruim porque diminui a capacidade de leitura e manutenção de seu código. Além disso, e se você quiser repetir essa parte 10 vezes, 100 vezes, ou nem mesmo souber exatamente quantas vezes? É aqui que você pode utilizar loops. Um loop while repete o código dentro de um bloco, desde que uma determinada condição seja atendida:

while(counter <= 10)
{
  readSensor();
  counter = counter + 1;
    
  Serial.print("The sensor got read ");
  Serial.print(counter);
  Serial.println(" times!");
}

Isso executará o bloco até que o contador atinja um valor de onze. Observe que você pode usar qualquer expressão booleana, assim como com instruções if.

 

“For” Loops

Se você quiser executar um bloco um certo número de vezes, geralmente é melhor usar um loop for em vez de um loop while. Esta construção repete um bloco um certo número de vezes e também aumentará automaticamente a variável do contador para você:

for(int counter = 0; counter <= 10; counter++)
{
  readSensor();
    
  Serial.print("The sensor got read ");
  Serial.print(counter);
  Serial.println(" times!");
}

No cabeçalho do loop for, você define a variável do contador e seu valor inicial. Em seguida, você especifica uma condição. O loop se repete enquanto essa condição for mantida. Por último, você pode especificar o que deseja que aconteça com a variável após cada iteração do loop. Neste exemplo, o contador é aumentado em um.

Observe que você pode usar a variável do contador dentro do loop. No entanto, assim que você chegar ao fim, a variável se torna inválida.

O loop for e while muitas vezes pode ser utilizado de forma intercambiável. Você pode, por exemplo, também omitir todos os campos no loop for para criar um loop infinito. Também é possível especificar qualquer condição ou omitir campos únicos. Aqui estão alguns exemplos:

// Você pode usar qualquer expressão booleana
for(int counter = 0; 2 <= 5; counter++)
{
   // Vai correr para sempre
}

// Você pode omitir todos os campos ...
for(;;)
{
  // Vai correr para sempre
}

// ... ou apenas fornecer alguns deles
for(;false;)
{
  // Nunca será executado
}

// Você pode inicializar várias variáveis e modificá-las
// como quiser
for(int x = 0, y = 200; x < y; x = x + 100)
{
  // Será executado duas vezes
}

// Você também pode usar outros tipos de dados
for(char x = 'z'; x >= 'a'; x--)
{
   // Responda você mesmo:
   // Quantas vezes isso será executado? Que valores x terá?
   // Agora tente no IDE do Arduino! Você estava correto?
}

// Os loops For também são perfeitos para acessar todos os elementos de um array!
int values[array_length] = { ... };
for(int i = 0; i < array_length; i++)
{
  // Faça algo com os elementos
  values[i] = values[i] * values[i];
  Serial.println(values[i]);
}

 

Resumo

Você pode usar muitos operadores para construir expressões booleanas complexas. Eles podem ser utilizados para executar alguns segmentos de código apenas se uma determinada condição for atendida. Você pode usar loops while e for alternadamente para repetir um determinado bloco várias vezes. Esses loops são especialmente úteis quando você deseja percorrer todos os elementos de um array.