Programar em C/Operadores
Operadores Aritméticos
Tabela: Operadores aritmeticos
Operador | Finalidade | Exemplo | Resultado |
+ | Adição | 5 + 2 | 7 |
- | Subtração | 5 – 2 | 3 |
* | Multiplicação | 5 * 2 | 10 |
/ | Divisão (Quociente) | 5 / 2 | 2 |
% | Divisão Euclidiana (Resto) | 30 % 7 | 2 |
Notar o último operador.
Notar que são operadores que operam apenas com 2 operandos (operadores binários).
Na divisão euclidiana temos 30 dividido 7 tem por quociente 4 e como resto 2.
30 / 7 = 4 30 = 7 x 4 + 2 30 % 7 = 2
Existe uma maneira de fazer abreviaturas:
Expressão Original | Expressão equivalente |
x=x+k; | x+=k; |
x=x-k; | x-=k; |
x=x*k; | x*=k; |
x=x/k; | x/=k; |
x=x>>k; | x>>=k; |
x=x<<k; | x<<=k; |
x=x&k; | x&=k;; |
x=x+1 | x+=1 ou x++ |
Isto é mais uma abreviatura para os programadores escreverem menos. Há quem ache isto muito estúpido pois é um esforço de assimilação desnecessário em troca a escrever uma letra.
Iremos ver que ter a++ ou ++a é diferente! Mas isso vai ser na história dos loops. (iremos ter situações tipo”++a+5” que seria a+5 mas antes fazer a+1+5.)
Mais uma nota. Em relação ao operador adição ele para além dos números também permite adicionar strings, isto é, junta a segunda string no fim da primeira string. No entanto se juntarmos um dígito com uma string isso já não é permitido.
Precedência de Operadores aritméticos
Precedência de operadores aritméticos (o operador aritmético tem maior precedência do que o operador de asignment)
Table 4-3: Prioridade dos operadores aritméticos
Prioridade | Operador |
Alta | ! (Operador unário de negação) |
Média-alta | * / % |
Normal | + – |
No caso de termos na mesma instrução operadores com o mesmo nível de precedência (prioridade) fazer a regra da esquerda para a direita. eg. a=8/2*4 seria 16 e não 1, porque temos a divisão está no lado esquerdo.
Mais um ponto em relação ao operador “%” módulo (modulus). Podemos fazer o módulo para números inteiros mas se tentarmos para números do tipo float (ou um deles) fica indefinido. Geralmente resulta num erro de compilação (mas isso vai depender do compilador)
Notar igualmente overflow de que já falamos (antes e depois de compilar). ou seja pego no valor de uma variável adiciono o valor de uma segunda variável e dou esse resultado a uma terceira variável. Isto pode resultar em overflow. Será trabalho do programador em controlar isto.
O que é que resulta se adicionarmos um int por um float e esse float com casas decimais e colocarmos esse resultado num int? o que resulta é que o resultado fica truncado. é a mesma situação de declarar um int e colocar um float. como foi visto no capitulo das variáveis.
type casting
É fazer com que o resultado saia com a tipologia desejada.
#include <stdio.h> int main(void) { int firstOp = 10, secondOp = 4; float result = (float) firstOp / secondOp; printf("%d / %d = %f\n", firstOp, secondOp, result ); return 0; } |
Neste exemplo estamos a fazer com que o firstOp seja convertido para tipo float, quando antes tínhamos declarado como um int, ou seja o valor 10 passa a ser 10.0. e agora como temos um float a dividir por um int, o que acontece é que há uma conversão automática, ou seja o 2ª int é convertido em float, fazendo com que o resultado seja um float Podemos utilizar qualquer uma das expressões seguintes para exprimir o tycasting.
float result = (float) firstOp / secondOp; float result = firstOp / (float) secondOp;
Expoentes
O C e o C++ não têm o operador expoente, no entanto, tem a função pow (de power) que está no cabeçalho da biblioteca padrão <math.h>. a função pow() tem 2 argumentos, o primeiro para a base e o 2º para o expoente. o 1º argumento tem de ser float ou double.
Operadores relacionais
Permite fazer comparações lógicas de ordenação de números, e ainda de letras (mas não strings) Table: Relational Operators
Operador | Significado |
> | Maior que |
< | Menor que |
>= | Maior ou igual à |
<= | Menor ou igual à |
== | Igual a |
!= | Diferente de |
Você poderia se perguntar: Como é que o computador faz essa comparação ? de onde é que ele sabe que um número A é maior que outro B?
Resposta: Considere que você quisesse comparar dois dados tipo char, lembrando que um char na verdade é um número inteiro na tabela ASCII. Sendo assim suponha que gostarias de comparar o caractere 'a' que é igual a 97 na tabela ascii com o caractere 't' que é 116 na tabela; assim, ao comparar 97 com 116 o que aconteçe na memória é a comparação de 01100001 (97) com 01110100 (116) em um registrador específico, vão sendo somadas as potências de 2 da esquerda para a direita de forma que fica evidente para ele (o registrador) quem é maior. Isso é o que aconteçe quando comparamos duas strings com a função strcmp e ela retorna um número para a diferença entre elas. Esse número é justamente a diferença entre os valores da tabela ASCII entre o primeiro caractere das duas.
notar o operador == que é a comparação de igualdade. o operador = é de atribuição.
Estes operadores também são binários, ie, comparam dois operandos. o resultado de uma expressão relacional dá um valor bool (verdadeiro=1 ou falso=0)
- 4 != 4 false
- 4 == 5 false
Eu ainda posso comparar um int com um float que isso não dá problema. ou seja com dados númericos não há problema. Comparações entre dois caracteres também não há problema pois os caracteres são números na tabela ASCII. Mas não usem para strings (pois aí estaríamos a comparar o quê, se as strings são conjunto de caracteres?) Não esquecer o ponto que o digito pode ser um char ou estar em forma númerica. e esse char vai ter o valor na tabela. nós num capitulo posterior iremos ver que poderemos fazer a conversão de char para int e vice versa.
Precedência dos operadores relacionais
Table: Precedence of Relational Operators
Precedence | Operator |
Highest | > >= < <= |
Lowest | == != |
Novamente existe a regra da esquerda para a direita caso haja igualdade de precedência
Operadores lógicos
Estes operadores comparam já condições de precedência Table: Logical Operators
Operator | Name | What It Does |
&& | And | Connects two relational expressions. Both expressions must be true for the overall expression to be true. |
|| | Or | Connects two relational expressions. If either expression is true, the overall expression is true. |
! | Not | Reverses the “truth” of an expression, making a true expression false, and a false expression true. |
Estes operadores também são binários mas desta vez os operandos são resultados boolean, que podem advir dos operadores relacionais (comparação) pois davam valores boolean.
- Para o operador and (&&) – basta uma das comparações ser falsa para o resultado ser falso
- Para o operador or (||) – basta uma das comparações dos operandos ser verdadeira para se tornar verdadeira
- Por fim o operador not— é um operador unário – é apenas para um valor boolean que pode ser resultado de comparação
Exemplo:
if (age <= 12 || age >= 65) printf("Admission is free"); else printf("You have to pay");
Precedência Operadores lógicos e Relacionais
Tabela: A precedência dos operadores lógicos e relacionais
Operador (da mais alta para a mais baixa) ! Relacionais (>, >=, <, <=, ==. !=) && ||
cuidado!
- if (!age > 12 && age < 65)
Note o ! no exemplo. é sempre bom recorrer aos parênteses
Operadores Lógicos Bit a Bit
Operador | Ação lógica |
& | AND ( E ) |
¦ | OR (OU) |
^ | XOR (OR exclusivo/OU exclusivo) |
~ | NOT |
>> | Deslocamento de bits à direita |
<< | Deslocamento de bits à esquerda |
Deslocamento de bits
x = a << b é igual a x = a*2^b;
x = a >> b é igual a x = a/2^b;
Todos os Operadores
Comparações de precedência entre Operadores aritméticos, relacionais e lógicos
Nivel | Operador | Descriçao | Agrupamento |
1 | :: | escope | Esquerda para direita |
2 | () [] . -> ++ -- | dynamic_cast static_cast reinterpret_cast const_cast typeid postfix | Esquerda para direita |
3 | ++ -- ~ ! | sizeof new delete unary (prefix) | Direita para esquerda |
* & | referencia (ponteiros) | Direita para esquerda | |
+ - | unary sign operator | Direita para esquerda | |
4 | (type) | type casting | Direita para esquerda |
5 | .* ->* | pointer-to-member | Esquerda para direita |
6 | * / % | multiplicative | Esquerda para direita |
7 | + - | adiçao (+) e subtraçao (-) | Esquerda para direita |
8 | << >> | trocar | Esquerda para direita |
9 | < > <= >= | relacional | Esquerda para direita |
10 | == != | comparativos | Esquerda para direita |
11 | & | bitwise "AND"/E | Esquerda para direita |
12 | ^ | bitwise "XOR" | Esquerda para direita |
13 | | | bitwise "OR"/"OU" | Esquerda para direita |
14 | && | "AND"/ "E" lógico | Esquerda para direita |
15 | || | "OR"/ "OU" lógico | Esquerda para direita |
16 | ?: | Descrição | Direita para esquerda |
17 | = *= /= %= += -= >>= <<= &= ^= != | Atribuição | Direita para esquerda |
18 | , | subparágrafo/inciso | Esquerda para direita |
Exercícios
- (7 == 5) // Avalia como falso.
- (5 > 4) //Avalia como verdadeiro
- (3 != 2) //Avalia como verdadeiro
- (6 >= 6) //Avalia como verdadeiro
- (5 < 5) // Avalia como falso
- (a == 5) // Avalia como falso , porque a não é igual à 5.
- (2*3 >= 6) // Avalia como verdadeiro porque (2*3 >= 6) é verdadeiro.
- (3+4 > 2*6) // Avalia como falso porque (3+4 > 2*6) é falso.
- !(5 == 5) // Avalia como falso,porque a expressão a direita (5 == 5) é verdadeira.
- !true // Avalia como falso
- !false //Avalia como verdadeiro
- ( (5 == 5) && (3 > 6) ) // Avalia como falso ( true && false ).
- ( (5 == 5) || (3 > 6) ) // Avalia como verdadeiro ( true || false ).