Olá a todos. Hoje, para dar sequência aos posts sobre programação eu vou falar de um outro laço de repetição, que se chama while. While é uma palavra inglesa que significa "enquanto", e esse nome é muito bom pois descreve exatamente o que esse laço faz: executa um trecho do programa enquanto uma determinada condição for verdadeira. Para entender melhor, vamos discutir um exemplo:
int main()
{
unsigned char i = 0;
while( i < 5)
{
printf("O valor de i: %d.\n",i);
i++;
}
}
Bom, o que este exemplo faz? Exatamente a mesma coisa que o exemplo principal do post sobre o laço "for" fazia, que é escrever o valor de "i" que irá variar de 0 até 4. Então vamos analisar a sintaxe do comando while.
Primeiro, existe a palavra do comando (while) e entre parênteses a condição que, nesse caso, é i < 5. Dessa forma, enquanto o valor de "i" for menor que 5 o laço continuará repetindo os comandos que estiverem dentro das chaves do comando.
Basicamente o que podemos falar do laço while é isso. O while é uma instrução mais simples que o for e, em geral, menos poderoso. Para quem já conhece o laço for (quem não conhecer pode buscar o post nesse link) será interessante comparar a estrutura dos dois laços.
Primeiramente, o laço while não tem inicialização. Enquanto no laço for podíamos inicializar o valor de uma ou mais variáveis que seriam utilizadas no laço dentro da sintaxe do comando, no while não temos essa possibilidade. É por isso que no exemplo dado nesse post a variável "i" recebeu seu valor antes de entrar no laço.
Outra diferença entre o while e o for é que o while não altera automaticamente a variável testada. Por isso que nesse exemplo a variável "i" está sendo alterada dentro do laço. No laço for não há a necessidade disso pois o próprio laço, após uma iteração, altera os valores das variáveis determinadas pelo programador.
Uma utilização comum do while é criar laços infinitos. Embora eu tenha comentado no post sobre o for que laços infinitos são perigosos (e realmente são, quando criados de forma não intencional), eles algumas vezes são necessários. Um exemplo disso é em programas de microcontroladores, que geralmente possuem dentro da função main um laço infinito. A função desse laço é repetir continuamente a execução do programa. Caso esse laço não fosse utilizado, o microcontrolador iria executar todo o programa uma única vez e, depois disso, ficaria sem fazer nada. Isso é ruim. Imagine que seu trabalho seja programar um sensor de temperatura. Você quer um sensor que leia a temperatura 1 única vez? Que para fazer outra medição você tenha que religar o equipamento? Provavelmente não. Mais comum é um programa que a cada intervalo de tempo faça uma leitura de temperatura e mostre o valor em um display. Nesse caso usa-se um laço while com alguma função que controle o tempo para executar a leitura no intervalo de tempo necessário. A estrutura genérica e simplificada de um programa para microcontrolador é:
#includes e qualquer tipo de definição inicial de hardware
void main()
{
inicialização de registradores e periféricos;
while(1)
{
comandos do programa;
}
}
Nesse esqueleto de programa temos os includes e definições de hardware. Os includes tem a mesma utilidade dos que utilizamos para computador. Eles permitem que usemos funções prontas desenvolvidas pelos fabricantes do microcontrolador ou outras pessoas. As definições de hardware dependem do compilador e hardware utilizado, que em geral não seguem um padrão. Em microcontroladores geralmente deve-se definir o tipo e a velocidade do oscilador utilizado (os osciladores de microcontroladores geralmente estão na casa de MHz) e, algumas vezes, os tipos de interrupções que serão habilitadas.
Dentro do main temos um trecho sobre inicialização de registradores e periféricos, que se encontra antes do laço while. Um microcontrolador pode ter diversos registradores que controlam, por exemplo, se um pino será entrada ou saída, ou se será uma entrada digital ou analógica. Para informarmos ao microcontrolador a função específica de cada pino utilizamos registradores. Esse é apenas um exemplo dos usos de registradores, que estudaremos mais detalhadamente no futuro. O microcontrolador pode também ter diversos periféricos, que são circuitos internos ao microcontrolador que executam tarefas específicas, como medir tensões analógicas ou se comunicar via protocolo RS-232 (padrão das seriais de computador). Ter um periféricos específico para uma tarefa facilita muito a execução da mesma.
Após isso temos um laço while(1). Perceba que no lugar da condição do laço temos apenas um número constante de valor 1. Para entender a razão disso devemos entender que na linguagem C o valor 0 representa algo falso e qualquer valor diferente de zero representa algo verdadeiro. Se tomarmos uma variável "i" com valor 4 e fizermos a comparação (i == 5), a linguagem C entende essa sentença como 0, pois é uma sentença falsa. Por outro lado, a sentença (i == 4) seria interpretada como 1, pois é verdadeira. Mas não somente o 1 representa verdadeiro, como qualquer outro número diferente de 0.
Como visto o número 1 equivale a uma sentença verdadeira. Como o laço for executa comandos enquanto a condição for verdadeira, e o número 1 será sempre uma sentença verdadeira, isso significa que o programa jamais encerrará o laço while. Após entrar nele o programa só sairá se ocorrer o desligamento ou alguma interrupção (trataremos disso no futuro). Portanto, esse laço garantirá a repetição indefinida do nosso programa, como desejávamos.
Conforme o que foi dito nos parágrafos anteriores, também seria um laço infinito escrever while(2), por exemplo. Porém, a prática mais comum é utilizar o valor 1 para representar sentenças verdadeiras.
Por hoje era isso. Espero ter explicado claramente o laço while e sua funcionalidade. Espero também ter sido claro na minha breve introdução sobre programação de microcontroladores, que será descrita neste blog em um futuro não tão distante. Qualquer dúvida, crítica, sugestão ou comentário, por favor, use o campo dos comentários. Abraço e até a próxima!
Nenhum comentário:
Postar um comentário