Introdução ao comando de seleção e às expressões lógicas
[ Expressão em C | Expressão em Python | Operadores | Seleção | Seleções | Exemplo | Par ou ímpar ]
Como ler este texto. Aqui procuro explicar os fundamentos do comando de seleção if-else tanto para as linguagens C quanto Python. Em várias seções apresento os conceitos básicos ilustrando-os em tabelas, com uma coluna ou linha para cada linguagem. Mas existe uma seção em que apresento o conceito de expressão lógica separandamente, assim, se lhe interessar apenas uma das linguagens, leia apenas a seção correspondente. |
Na seção sobre variáveis, ressaltamos a importância de poder variar os valores armazenados em determinada posição de memória, por intermédio das variáveis.
Entretanto se não fosse possível executar uma ação específica apenas quando determinada condição ocorrer, de acordo com o valor de algumas variáveis, não se poderia fazer muito com o computador. Isso pode ser feito efetuando-se uma conta e verificando se o resultado é nulo ou não, sendo nulo segue-se determinado "caminho" no código e em caso negativo, segue-se outro (executa outros comando).
Mas a explicação acima está quase ao nível do hardware, portanto baixo-nível. De um ponto de vista mais elevado (alto-nível), as linguagens de programação como C e Python dispõem de um comando que permite tal seleção de caminho de execução é o comando if-else.
A figura 1.a e 1.b ilustram o desvio do fluxo de execução de acordo com o resultado da condição, do resultado da condição lógica, se verdadeiro segue o caminho indicado pela seta com rótulo sim e se falso segue outro. Adicionalmente, nota-se que o comando de seleção (ou desvio de fluxo) pode explicitar um caminho para o caso da expressão lógica resultar falso, figura 1.b, ou simplesmente apresentar o caminho no caso de verdadeiro, na figura 1.a.
Na linguagem C, qualquer expressão (mesmo que aritmética) dentro de abre e fecha parênteses (...) é interpretado como uma expressão lógica, como nos dois exemplos de comandos abaixo:
if (a==b) |
Ou seja, o tratamento de expressões é mais um exemplo de que o contexto pode mudar a forma como os dados são interpretados.
Mas vale a pena notar que a linguagem C permite construções cujo processamento é uma pouco mais rápido, mas menos intuitivo, é permitido usar qualquer expressão aritmética (como a-b) dentro do contexto de expressão lógica! Isso é possível a partir do seguinte "truque": calcula-se o resultado da expressão aritmética, se o seu resultado for diferente de 0, ele é interpretado como sendo o valor lógico verdeiro, caso contrário como falso. Desse modo, no comando seguinte, sempre que a variável inteira N tiver valor não nulo, será "impresso" OK e se o valor for nulo será "impresso" NAO:
|
|
Fica fácil entender a razão dos dois códigos serem equivalente ao observarmos que a == b é a mesma coisa que a - b == 0 e, usando a negação, a != b é a mesma coisa que a - b != 0 e essa última expressão equivale à expressão !((a - b) == 0) (negar que (a - b) == 0).
Portanto, a expressão a-b é interpretada como expressão lógica, do seguinte modo: seu resultado é verdadeiro se, e somente se a-b!=0 (a-b não nulo), por isso usamos a negação para inverter o resultado, ou seja, !(a-b) equivale a negar a-b (e portanto negar a-b!=0).
O resultado de um comando como if (a=b)
Para descobrir este tipo de erro uma boa técnica é usar
bandeiras.
Expressão e valor lógicos em Python
Em Python existem um particular tipo de variável que é booleano, sendo que uma variável boleana pode ter apenas os valores: True e False.
Assim, uma expressão lógica em Python deve sempre resultar nos valores lógicos True ou False. Deste modo os três blocos de comandos abaixo podem ser usados e são equivalente, entretanto o primeiro (mais à esquerda) é mais eficiente:
|
|
|
Note que no exemplo acima mais à direita usamos not (varlog == False) que equivale a varlog == True, que portanto também equivale a varlog (pois está armazenando valore booleanos).
Operadores lógicos em C e em Python
Os operadores lógicos e relacionais básicos são os mesmo tanto em C quanto em Python. Os operadores relacionais (relações entre expressões aritméticas) são:
Operação | Operador | Exemplo |
---|---|---|
iguais | == | n1 == 4 |
diferentes | != | n1 != 4 |
maior | > | n1 > n2 |
menor | < | n2 < n1 |
maior ou igual | >= | n1 >= 3 |
menor ou igual | <= | n1 <= 33 |
Os operadores lógicos principais em C e em Python são
Operação | Operador | Exemplo | ||
---|---|---|---|---|
C | Python | C | Python | |
conjunção (e) | && | and | (n1 > 1 && n1 < 10) | (n1 > 1 and n1 < 10) |
disjunção (ou) | || | or | (n1 > 1) || (n1 < 10) | (n1 > 1) or (n1 < 10) |
negação (não) | ! | not | !(n1 > 1 || n1 < 10) | not(n1 > 1 or n1 < 10) |
Comando de seleção if-else em C e em Python
O comando de seleção é essencial para qualquer software, é ele que permite que o programa desvie seu fluxo de execução de acordo com os valores dos dados (as já citadas variáveis). Ele está presente em qualquer linguagem de programação e está baseado no cômputo de uma expressão lógica (EXPLOG), se o resultado dela for verdadeiro, o fluxo segue por um "caminho", senão segue por outro. Essa estrutura está ilustrada na figura abaixo:
Existem outras duas características de comando de seleção (em qualquer linguagem) que são:
Tanto a linguagem C quanto na linguagem Python, usam as masmas palavras reservadas (palavras que não podem ser usados como nomes para variáveis): as palavras if e o else. A sintaxe de ambas é ilustrada na tabela abaixo.
Além disso, as linguagens C e Python permitem que vários comandos (bloco de comandos) sejam subordinados à uma seleção. Em C deve-se usar abre e fecha chaves ({...}) para delimitar os blocos, enquanto que na linguagem Python isso é feito com o deslocamento horizontal de linhas, ou seja, com "indentação".
A tabela a seguir ilustra a sintaxe do comando de seleção tanto em C quanto em Python:
Linguagem | Apenas 1 comando | Vários comandos |
---|---|---|
C |
if (EXPR) comando1; |
if (EXPR) { comando1; |
Python |
if (EXPR) : comando1; |
if (EXPR) : |
Vale destacar que o comando else é opcional (como já citado), ou seja, não existindo ação a ser executada caso
a condição seja falsa, não é necessário usar um else com algum comando.
Assim é correto em C escrever if (1==1)
Em Python os parênteses não são obrigatórios em expressões, quer dizer é válido redigir o comando if n1==n2 : comando1 (assim como if (n1==n2) : comando1). Deste modo para o interpretador Python conseguir traduzir corretamente o comando, lançou-se mão dos dois pontos para indicar final de expressão (if EXPR :) e no else, e por uniformidade, os : também é obrigatório no else :.
Outro item em que C e Python diferem é no modo como indicam a existência de um bloco de comandos subordinados a outro comando. Em C utiliza-se abre e fecha chaves, enquanto em Python usa-se a "indentação". Experimente em Python eliminar o deslocamento horizontal e deixe, e.g., o comando1 alinhado com o if e tente rodar o programa. Você receberá uma mensagem de erro.
Comandos de seleção if-else aninhados em C e em Python
Em geral, toda linguagem de programação de alto-nível permite que os comandos if-else sejam utilizados de modo aninhado, ou seja, qualquer dos comando1 acima podem ser um novo if-else. Por exemplo:
Linguagem | if aninhado |
---|---|
C |
if (a<b) { |
Python |
if (a<b) : |
Note que a regra para associar um "else" a um "if" é por proximidade (o "else" é associado ao "if" mais próximo), e em caso que precisamos que o "else" seja associado a um "if" mais longe, somos obrigados a usar os blocos de comandos. Isso está ilustrado nos exemplos acima, o primeiro "else" está associado ao if (a<b) e não ao mais "próximo".
Um exemplo para decidir se uma variável inteira armazena um valor par ou ímpar
Utilizando a divisão inteira (quer dizer 7/2 resultando 3) pode-se conseguir determinar se um inteiro é ou não par. Nos códigos abaixo ilustramos este método, mas note que existe uma diferença sensível entre as versões Python 2 e Python 3, este último obriga o uso de "duas barras" (//) para indicar divisão inteira. Vejamos os códigos abaixo:
C | Python 2 | Python 3 |
---|---|---|
if (n1/2*2==n1) |
if (n1/2*2==n1) : |
if (n1//2*2==n1) : |
Mas pode-se obter o mesmo resultado utilizando o operador binário % que é "resto da divisão inteira". Este operador devolve o resto da divisão, por exemplo, 7%2 resulta 1 (o quociente é 3: 3 * 2 + 1 = 7). Assim o código fica:
C | Python |
---|---|
if (n1%2==0) |
if (n1%2==0) : |
Mas por que razão "n1/2*2==n1" é suficiente para decidir se n1 é ou não par?
Bem, isso é um truque computacional baseado em como o computador interpreta e trata os valores numéricos de acordo com seu tipo. Quanto todos os valores (variáveis) são inteiros, é utilizada uma aritmética de precisão inteira, como examinamos ao final da seção sobre variáveis e expressões.
Lembre-se que em C sempre que fizer divisão entre inteiros o resultado é inteiro (ou seja, 7/2 resulta 3) e em Python é análogo, entretanto no Python 3 é preciso usar o operador // (7/2 resulta erro, deve-se usar 7//2) e no Python 2 pode-se usar 7/2 (resultando 3).
Novamente é o contexto determinando o resultado.
Leônidas de Oliveira Brandão
http://line.ime.usp.br
Alterações:
2020/08/20: revisado formato, pequenas correções;
2020/08/10: novo formato, pequenas correções;
2019/06/06: vários pequenos acertos;
2019/01/13: pequenas melhorias de frases e mudanca no CSS
2018/04/16: pequenos acertos
2018/03/28: melhorado quadro de operadores lógicos C e Python, reescrita a seção "Comandos de seleção ao if-else aninhados em C e em Python"
2017/04/14: adicionados novos itens (como True/False e // do Python e % C e Python)