Programar em C/Operadores: diferenças entre revisões

Origem: Wikilivros, livros abertos por um mundo aberto.
[revisão pendente][revisão pendente]
Conteúdo apagado Conteúdo adicionado
m Foram revertidas as edições de 200.198.216.231 (disc) para a última revisão de 187.60.151.67
m Foram revertidas as edições de Praxidicae (disc) para a última revisão de 200.198.216.231
Etiqueta: Reversão
Linha 122: Linha 122:
|}
|}


Voçê 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?
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.
'''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.
Linha 164: Linha 164:


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.
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 paro resultado ser falso
* 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
* 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
* Por fim o operador not— é um operador unário – é apenas para um valor boolean que pode ser resultado de comparação
Linha 176: Linha 176:
== Precedência Operadores lógicos e Relacionais ==
== Precedência Operadores lógicos e Relacionais ==
Tabela: A preçedençia dos operadores logicos e relacionais
Tabela: A precedência dos operadores lógicos e relacionais
Operador (da mais alta para a mais baixa)
Operador (da mais alta para a mais baixa)
!
!

Revisão das 13h36min de 18 de junho de 2019

Esta página precisa ser reciclada (discuta).
Ao melhorá-la, você estará ajudando o Wikilivros.

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 = float (firstOp) / secondOp;
float result = firstOp / (float) 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 ).