Você está na página 1de 4

4.

10 Operadores lógicos
Até aqui, estudamos apenas condições simples, como contador <= 10, total > 1000, e número != valorSentinela.
Expressamos essas condições em termos dos operadores relacionais, >, <, >= e <=, e dos operadores de igualdade, == e !=. Cada deci-
são testou exatamente uma condição. Para testar várias condições no processo de tomada de decisão, tínhamos de realizar esses testes
em instruções separadas ou em estruturas if ou if...else aninhadas.
C oferece operadores lógicos, que podem ser usados para formar condições mais complexas ao combinar condições simples. Os
operadores lógicos são && (AND lógico), || (OR lógico) e ! (NOT lógico, também chamado de negação lógica). Vejamos alguns
exemplos de cada um desses operadores.

04 deitel0111_cap04 BR.indd 95 6/10/11 8:04 PM


96 C: como programar

Suponha que queiramos garantir que duas condições sejam verdadeiras antes de escolher certo caminho de execução. Nesse caso,
podemos usar o operador lógico && da seguinte forma:
if ( sexo == 1 && idade >= 65 )
++idosoFeminino;

Essa estrutura if contém duas condições simples. A condição sexo == 1 poderia ser avaliada, por exemplo, para determinar
se uma pessoa é do sexo feminino. A condição idade >= 65 é avaliada para determinar se uma pessoa é idosa. As duas condições
simples são avaliadas primeiro, pois as precedências de == e >= são ambas maiores que a precedência de &&. A estrutura if, então,
considera a condição combinada
sexo == 1 && idade >= 65

Essa condição é verdadeira se, e somente se, as duas condições simples forem verdadeiras. Por fim, se essa condição combinada
for realmente verdadeira, então a contagem de idosoFeminino será incrementada em 1. Se uma ou ambas as condições simples
forem falsas, então o programa saltará o incremento e prosseguirá com a instrução seguinte ao if.
A Figura 4.13 resume o operador &&. A tabela mostra as quatro combinações possíveis de zero (falso) e não zero (verdadeiro)
para expressão1 e expressão2. Essas tabelas normalmente são chamadas tabelas verdade. C avalia todas as expressões que incluem
operadores relacionais, operadores de igualdade e/ou operadores lógicos como 0 ou 1. Embora C defina um valor verdadeiro como 1, a
linguagem aceita qualquer valor não zero como verdadeiro.

expressão1 expressão2 expressão1 && expressão2


0 0 0
0 não zero 0
não zero 0 0
não zero não zero 1

Figura 4.13 n Tabela verdade para o operador AND lógico (&&).

Agora, consideremos o operador || (OR lógico). Suponha que queiramos garantir em algum ponto de um programa que uma ou
ambas as condições sejam verdadeiras antes de escolher certo caminho de execução. Nesse caso, usamos o operador || como neste
segmento de programa:
if ( médiaSemestre >= 90 || exameFinal >= 90 )
printf( “Nota do aluno é A\n” );

Essa instrução também contém duas condições simples. A condição médiaSemestre >= 90 é avaliada para determinar se o aluno
merece uma nota ‘A’, devido a um desempenho sólido durante o semestre. A condição exameFinal >= 90 é avaliada para determinar
se o aluno merece uma nota ‘A’ por um desempenho excelente no exame final. A estrutura if, então, considera a condição combinada
médiaSemestre >= 90 || exameFinal >= 90

e concede um ‘A’ ao aluno se uma ou ambas as condições simples forem verdadeiras. A mensagem ‘A nota do aluno é A’ não é
impressa somente se as duas condições simples forem falsas (zero). A Figura 4.14 é uma tabela verdade para o operador OR lógico (||).

expressão1 expressão2 expressão1 || expressão2


0 0 0
0 não zero 1
não zero 0 1
não zero não zero 1

Figura 4.14 n Tabela verdade para o operador OR lógico (||).

O operador && tem uma precedência mais alta que ||. Os dois operadores se associam da esquerda para a direita. Uma expressão
contendo os operadores && ou || é avaliada somente até que sua veracidade ou sua falsidade seja conhecida. Assim, a avaliação da condição
sexo == 1 && idade >= 65

04 deitel0111_cap04 BR.indd 96 6/10/11 8:04 PM


Controle de programa em C 97

terminará se sexo não for igual a 1 (ou seja, se a expressão inteira for falsa), e continuará se sexo for igual a 1 (ou seja, a expressão
inteira ainda poderia ser verdadeira se idade >= 65). Esse recurso de desempenho para a avaliação de expressões AND e OR lógicas
é chamado de avaliação em curto-circuito.

Dica de desempenho 4.2


Em expressões nas quais se use o operador &&, ponha a condição com mais chances de ser falsa no lado esquerdo.
Nas expressões em que se use o operador ||, ponha a condição com mais chances de ser verdadeira no lado esquer-
do. Isso pode reduzir o tempo de execução de um programa.

C oferece ! (negação lógica) para permitir que um programador ‘inverta’ o significado de uma condição. Diferentemente dos
operadores && e ||, que combinam duas condições (e que, portanto, são operadores binários), o operador de negação lógica tem ape-
nas uma única condição como operando (e, portanto, é um operador unário). O operador de negação lógica é colocado antes de uma
condição quando estamos interessados em escolher um caminho de execução se a condição original (sem o operador de negação lógica)
for falsa, como neste segmento de programa:
if ( !( nota == valorSentinela ) )
printf( “A próxima nota é %f\n”, nota );

Os parênteses em torno da condição nota == valorSentinela são necessários porque o operador de negação lógica tem uma
precedência maior que o operador de igualdade. A Figura 4.15 é uma tabela verdade para o operador de negação lógica.

expressão !expressão
0 1
não zero 0

Figura 4.15 n Tabela verdade para o operador ! (negação lógica).

Na maioria dos casos, você pode evitar o uso da negação lógica ao expressar a condição de modo diferente com um operador rela-
cional apropriado. Por exemplo, a instrução anterior também poderia ser escrita da seguinte forma:
if ( nota != valorSentinela )
printf( “A próxima nota é %f\n”, nota );

A Figura 4.16 mostra a precedência e a associatividade dos operadores apresentados até agora. Os operadores aparecem de cima
para baixo, e em ordem decrescente de precedência.

Operadores Associatividade Tipo


++ (pós-fixo) -- (pós-fixo) direita para esquerda pós-fixo
+ - ! ++ (prefixo) -- (prefixo) (tipo) direita para esquerda unário
* / % esquerda para direita multiplicativo
+ - esquerda para direita aditivo
< <= > >= esquerda para direita relacional
== != esquerda para direita igualdade
&& esquerda para direita AND lógico
|| esquerda para direita OR lógico
?: direita para esquerda condicional
= += -= *= /= %= direita para esquerda atribuição
, esquerda para direita vírgula

Figura 4.16 n Precedência e associatividade dos operadores.

4.11 Confundindo os operadores de igualdade (==) com os de atribuição (=)


Existe um tipo de erro que os programadores em C, por mais experientes que sejam, tendem a cometer com tanta frequência
que achamos que ele merecia uma seção separada. Esse erro é a troca acidental dos operadores == (igualdade) e = (atribuição). O que
torna essas trocas tão prejudiciais é o fato de elas normalmente não causarem erros de compilação. Em vez disso, instruções com esses

04 deitel0111_cap04 BR.indd 97 6/10/11 8:04 PM


98 C: como programar

erros normalmente são compiladas corretamente e permitem a execução dos programas até o fim, mas é provável que gerem resultados
incorretos por causa de erros lógicos durante a execução.
Dois aspectos da linguagem em C causam esses problemas. O primeiro é que qualquer expressão em C que produza um valor pode
ser utilizada na parte de decisão de qualquer estrutura de controle. Se o valor é 0, ele é tratado como falso, e se for diferente de zero, é
tratado como verdadeiro. O segundo é que as atribuições em C produzem um valor, a saber, o valor que é atribuído à variável no lado
esquerdo do operador de atribuição. Por exemplo, suponha que queiramos escrever
if ( codPgto == 4 )
printf( “Você ganha um bônus!” );

porém, por engano, escrevemos


if ( codPgto = 4 )
printf( “Você ganha um bônus!” );

A primeira estrutura if gera corretamente um aviso de bônus à pessoa cujo código de pagamento é igual a 4. A segunda estrutura
if — aquela com o erro — avalia a expressão de atribuição na condição if. Essa expressão é uma atribuição simples cujo valor é a
constante 4. Como qualquer valor diferente de zero é interpretado como ‘verdadeiro’, a condição nesse if sempre será verdadeira, e
não apenas o valor de codPgto inadvertidamente é definido como 4, mas a pessoa sempre receberá um bônus, independentemente
do valor real do código de pagamento!

Erro comum de programação 4.8


Usar o operador == para atribuição ou usar o operador = para a comparação de igualdade são erros lógicos.

Os programadores normalmente escrevem condições como x == 7 com o nome da variável à esquerda e a constante à direita. Ao
inverter esses termos, de modo que a constante fique na esquerda e o nome da variável, à direita, como em 7 == x, o programador que
acidentalmente substitui o operador == por = está protegido pelo compilador. O compilador tratará isso como um erro de sintaxe, pois
somente um nome de variável pode ser colocado no lado esquerdo de uma expressão de atribuição. Pelo menos, isso impedirá a
devastação em potencial de um erro lógico durante a execução.
Os nomes de variáveis são chamados de lvalues (de ‘left values’, ou valores da esquerda), pois podem ser usados no lado esquerdo
de um operador de atribuição. As constantes são chamadas de rvalues (de ‘right values’, ou valores da direita), pois somente podem ser
usadas no lado direito de um operador de atribuição. Lvalues também podem ser utilizados como rvalues, mas o contrário não ocorre.

Boa prática de programação 4.9


Quando uma expressão de igualdade tem uma variável e uma constante, como em x == 1, alguns programadores
preferem escrever a expressão com a constante à esquerda e o nome da variável à direita (por exemplo, 1 == x
como uma proteção contra o erro lógico que ocorre quando você acidentalmente substitui o operador == por =).

O outro lado da moeda pode ser igualmente desagradável. Suponha que você queira atribuir um valor a uma variável com uma
instrução simples como
x = 1;

porém, em vez disso, escreve


x == 1;

Isso tampouco é um erro de sintaxe. O compilador simplesmente avalia a expressão condicional. Se x é igual a 1, a condição é
verdadeira e a expressão restitui o valor 1. Se x não é igual a 1, a condição é falsa e a expressão restitui o valor 0. Independentemente do
valor devolvido, não existe operador de atribuição, de modo que o valor é simplesmente perdido, e o valor de x permanece inalterado,
o que causa, provavelmente, um erro lógico durante a execução. Infelizmente, não há um truque prático disponível para ajudá-lo com
esse problema! Muitos compiladores, porém, emitirão uma advertência ao encontrar tal situação.

Dica de prevenção de erro 4.6


Depois de escrever um programa, faça uma busca em todos os = e verifique se estão sendo usados corretamente.

04 deitel0111_cap04 BR.indd 98 6/10/11 8:04 PM

Você também pode gostar