Variáveis lógicas (bool) e Operadores lógicos


Olá, como vão? Hoje em nossa aula falaremos sobre mais um tipo de variável: As variáveis lógicas.
Na primeira aula deste capítulo vimos rapidamente sobre este tipo (se não viu, clique aqui), porém como prometido, eu irei abordar este assunto com mais detalhes nesta aula, então vamos lá?

O que são as variáveis lógicas?
Também conhecidas como variáveis booleanas (bool), são variáveis primitivas que podem armazenar apenas dois tipos de valores (chamados de valores binários):verdadeiro (true) ou falso (false).
Como vimos na aula sobre variáveis primitivas, para criar uma booleana, basta utilizar a palavra reservada "bool" para definir o seu tipo e em seguida referenciá-la através de um nome.
Para atribuir um valor à ela, basta utilizar o operador de atribuição (=) e definir seu valor binário, como no exemplo já mostrado ao longo dessas aulas:


A utilização das variáveis lógicas está muito ligada com as estruturas de decisões, onde dependendo do estado desta variável (true ou false) algo específico no código pode ocorrer.
A próxima aula irá abordar justamente o assunto sobre estruturas de decisões, por isso é muito importante entender a utilidade das variáveis lógicas.

É muito comum utilizarmos este tipo de atribuição explícita, onde literalmente colocamos o valor de true ou false neste tipo de variável (como fizemos no exemplo acima), porém existe uma forma implícita de atribuirmos estes tipos de valores à uma variável booleana: através de operações lógicas.

Operadores relacionais:
Como já dito, é muito comum atribuirmos diretamente às variáveis booleanas seus valores binários, mas podemos atribuir estes tipos de valores de uma forma menos direta.
Para tal, podemos nos utilizar dos operadores relacionais, que basicamente irão relacionar dois valores propostos.

Por exemplo, você concorda que o número 5 é maior que o número 3? Sim, não é mesmo? Então imagine como podemos escrever essa afirmação com símbolos matemáticos:

5  > 3

Concorda que o que há escrito acima é exatamente a afirmação de que 5 é maior que 3? Concorda também que isto é uma verdade?
Pois então, imagine que podemos escrever isso em C# também, observe:


O que fizemos no exemplo foi criar uma variável do tipo booleana com o nome de "verificarMaior" e atribuímos a ela a operação lógica de que 5 é maior que 3.
Mas agora você pode se perguntar do porquê este código não deu erro mesmo não temos tendo colocado "true" ou "false" nesta variável, não é?
A resposta é simples: Na verdade nós atribuímos um valor binário para esta variável, só que não explicitamente (diretamente com true ou false) mas sim com uma operação lógica que retornará true ou false.
Se 5 é de fato maior que 3 o valor de "verificaMaior" neste momento é true, e isto pode ser provado, basta utilizar o Console.WriteLine para mostrar "verificaMaior":


Perceba que se você rodar o debug, irá notar que a palavra "True" aparecerá na tela:


Então perceba que mesmo não atribuindo explicitamente um valor binário para esta variável, ela ainda sim teve este tipo de atribuição, porém de uma forma implícita (não-direta).
Para tal, nós nos utilizamos de um operador relacional (>) que relaciona o valor do número à sua esquerda com o valor do número à sua direita, e como é VERDADE que 5 é maior que 3, a variável "verificaMaior" teve como valor "true".

Na programação temos diversos operadores relacionais à nossa disposição, mas com certeza os principais são estes:


Operador: Significado:
>
Maior
>=
Maior ou igual
<
Menor
<=
Menor ou igual
==
Igual
!=
Diferente

Vamos ver alguns exemplos para cada operador:

Você tem ciência de que é apenas permitido vender bebidas alcoólicas para maiores de 18 anos, correto? Então podemos criar um programa que verifique através da idade, se a pessoa pode comprar tal bebida (true) ou se não pode (false).
Vamos criar uma varável inteira com o nome de "idade" e vamos pedir para o que o usuário informe uma idade, armazenando o valor informado dentro da variável "idade":



Agora vamos criar uma variável do tipo bool chamada de "checarIdade".
Dentro desta variável podemos realizar a seguinte operação: idade é maior que 18? Ou seja:

Mas você concorda que a pessoa deve ser maior de 18, mas também pode ter 18 anos? Neste caso, utilizamos o operador relacional "maior ou igual" (>=) ou seja, o valor pode ser maior que o outro ou até mesmo igual:

Podemos então finalmente checar se a pessoa pode comprar a bebida ou não, basta mostrarmos com o Console.WriteLine se a idade informada vai ser maior ou igual a 18 (true) ou menor que 18 (false):


Vamos fazer dois testes: Primeiro colocando a idade em 23 (maior que 18) e depois exatamente 18. Veja que em ambos os casos, a mensagem que nos é mostrada é justamente (true), ou seja, a pessoa pode comprar a bebida:



Agora veja o que acontece quando a operação lógica não é satisfeita, bastando informar uma idade menor que 18:


Veja que o resultado impresso na tela agora é 'false', simplesmente porque 11 não é maior que 18.
Ou seja, quando a operação lógica é satisfeita, a variável booleana receberá o valor "true", e quando a mesma é insatisfeita, a variável recebe o valor "false". Simples e lógico, não é?

Podemos utilizar a lógica inversa para exemplificamos a funcionalidade do operador "menor".
Existem brinquedos infantis como alguns escorregadores que pedem uma altura máxima da criança para que ela possa utilizar o brinquedo, ou seja, a criança só poderá usar o brinquedo se for MENOR que a altura máxima estipulada.
Vamos então criar um programa que verifique através da altura da criança se ela poderá brincar no escorregador ou não, tendo que ser menor de um metro e vinte centímetros para poder brincar:


Perceba a presença do operador "menor" na operação!

Vamos fazer um teste informando uma altura menor que 1,20:


Agora vamos colocar uma altura maior que o valor estipulado:


Outro operador relacional muito importante que temos presente na programação é o operador "igual" (==).
Note a presença dos dois símbolos de 'igual' neste operador. Por tanto, não se confunda! O operador (=) é para atribuição, ou seja, para armazenar um valor na variável, já o operador (==) é para comparação, ele vai comparar se dois valores são IGUAIS, por exemplo:



Veja que o operador "igual" não se limita apenas às variáveis dos tipos numéricos (int, double, decimal, float e etc.) Mas também realiza comparações com variáveis de qualquer tipo.

Porém, para a comparação ocorrer sem problemas, ambas variáveis precisam ser exatamente do mesmo tipo:



Temos também o inverso do operador "igual" que é justamente o operador "diferente" (!=).
Ele não vai verificar se os valores são maiores ou menores, vai verificar apenas se os valores são DIFERENTES:


Mas e no caso de precisamos fazer mais de uma verificação ao mesmo tempo?

Operadores condicionais lógicos:
Além dos operadores relacionais, temos também os operadores condicionais lógicos que se baseiam principalmente nesses aqui:

Operador Significado:
&&
E (and)
||
Ou (or)
!
Negação (not)

Os dois primeiros operadores são úteis quando queremos realizar mais de uma validação em nosso código, já o último é importante para realizar negações.
Vamos ver cada caso:

Vamos imaginar que um cidadão deseje se alistar para o exército, e para tal ele deve ser maior de 16 anos e além disso também deve ter mais que 1,65 de altura!
Sem um operador condicional lógico não poderíamos fazer essas duas validações simultaneamente (não de um jeito prático).
Agora preste atenção: A pessoa precisa necessariamente ter 16 anos ou mais E também deve ser mais alta que 1,65! Concorda que ambas as validações precisam ser satisfeitas?
No caso de todas as validações necessitarem de serem satisfeitas, nós utilizamos o operador 'and' (&&), veja neste exemplo:


Note a presença do operador "and", fazendo com que duas validações sejam lidas ao mesmo tempo (se a idade é maior que 16 e se ao mesmo tempo a altura é maior que 1,65).
Também é uma boa prática de programação isolar as validações contendo os operadores relacionais dentro de parênteses, para melhor visualização e desempenho do código.

Vamos agora fazer o seguinte teste:


Perceba que o valor de "exercitoChecar" é 'true' (verdadeiro) porque a idade é maior que 16 E também porque a altura é maior que 1,65.
Agora veja o que acontece se alguma das duas validações não for satisfeita:


Veja que mesmo que a altura seja satisfatória (maior que 1,65) pelo fato de a idade ter sido insatisfatória (menor que 16) a variável irá ter como valor 'false'.
Isso significa que para obtermos o valor "true" com operações envolvendo o "and" é necessário que TODAS as operações sejam satisfeitas, sem exceções. Caso todas ou até mesmo uma operação seja insatisfeita iremos obter o valor "false" ao utilizarmos o operador 'and', o que não ocorre quando utilizamos o operador "||" (ou).
Para que o valor "true" seja obtido, basta que apenas UMA das operações seja satisfeita.

Imagine que seja necessário permitir a sua entrada numa universidade, você pode entrar se for um aluno, mas também poderá entrar se for um professor, não tendo necessariamente que ser ambos, apenas um OU outro:


Faremos o teste então:





Note que não importa qual dos dois você seja, iremos obter o resultado "true" por ser um OU outro, não precisa que ambas validações sejam satisfeitas, basta apenas uma delas ser.
Mas perceba que se você não for nenhum dos dois, obteremos "false":


Ou seja, para que o valor obtido seja "true" utilizando o operador "or" é apenas necessário que uma das validações seja satisfeita, e ele vai obter o valor "false" se TODAS as validações forem insatisfeitas.

Gostaria que você soubesse que em ambos operadores não existe um determinado 'limite' para a quantidade de validações que você deseje fazer num mesmo comando ou variável, você pode ainda neste exemplo utilizar outras validações como "visitante" e também "professora" e "aluna" no caso da pessoa ser do gênero feminino, criando assim várias validações diferentes com o operador condicional lógico:


Note que sempre é necessária a presença do operador condicional lógico quando for realizar as outras validações, e que também não existe problemas em pular linhas para isto, basta não se esquecer de concluir o comando com o ponto e vírgula ";".
No caso do exemplo acima, estamos validando se a variável "cargo" recebeu os valores: "aluno" ou "aluna" ou "professor" ou "professora" ou "visitante".
Caso apenas UMA dessas validações for verdade, obteremos o valor "true" para a variável "permitirEntrada", porém, se TODAS as validações forem falsas, teremos como resultado "false".

Para o caso do operador not (!) temos um comportamento um pouco diferente, porque ele não agrupa várias validações num mesmo comando (assim como o 'and' e o 'or') mas ele NEGA aquele valor.
Isso normalmente é muito importante para podermos "trocar" o valor de uma variável booleana, por exemplo:



Nós criamos uma variável booleana chamada "testando" e em sua inicialização atribuímos o valor "true", porém veja que na linha de baixo nós fizemos com que "testando" receba seu valor (ou seja, "true") no entanto, como usamos o operador ''not'' seu valor foi invertido, logo, 'testando' recebeu o inverso do seu valor, ou seja, "false".
Veja que isto se comprova se testarmos o código acima:


Isto pode ser útil em uma aplicação que em tempo de execução não temos o controle do estado daquela variável booleana e por isso se desejamos sempre validar seu inverso, basta utilizarmos o operador not (!).
Pode parecer inútil num primeiro momento, mas você vai acompanhar em aulas futuras na prática como esta validação foi importante para uma aplicação.

E não apenas trocar o valor de variáveis booleanas, mas o operador ''not'' também é útil para negar alguma afirmação através das estruturas de decisões, mas isto é um assunto para as aulas futuras quando aprendermos sobre o condicional if...else! Aliás, num exemplo prático nas aulas posteriores nós iremos realizar este tipo de operação, então não se preocupe se achar que este operador é inútil, pois com o tempo verá que não é.

Finalização:
Então é isso pessoal! Aqui estamos, em mais um final de aula e no final deste capítulo sobre as variáveis. 
Eu posso apostar que você aprendeu muito hoje, não é mesmo? Principalmente sobre variáveis lógicas e a utilização das mesmas para a realização de operações com validações.
Posso afirmar que no capítulo seguinte nós iremos retornar com este assunto sobre esse tipo de variável e os operadores, pois o entendimento de ambos assuntos vai ser crucial para que possamos prosseguir com a próxima etapa de seu aprendizado, onde você vai conhecer as estruturas de decisões, portanto até lá e bons estudos!

Comentários