Expressoes Logicas _ Operadores _ Base Binaria _ Operadores de Bits

download Expressoes Logicas _ Operadores _ Base Binaria _ Operadores de Bits

of 15

Transcript of Expressoes Logicas _ Operadores _ Base Binaria _ Operadores de Bits

MAC 122 PDA Marcilio Revisado 11Ago10

Expresses lgicas, expresses condicionais, prioridades e operadores, base binria, operadores de bitsEquivalncia entre valores lgicos e aritmticos Quando uma expresso lgica calculada dentro do programa, feita a seguinte associao numrica com o valor da expresso: verdadeiro 1 falso 0 O valor zero est associado ao valor lgico falso, enquanto que qualquer valor diferente de zero est associado ao valor lgico verdadeiro. Assim, uma comparao como, por exemplo, a > b, quando calculada, tem associado a si o valor 1 se a > b (verdadeira) e 0 se a y; printf ("\n (3) valor de a = b = x+y < x*y || x == y; printf ("\n (4) valor de a =

e b so zero e um, dependendo se a falsa */ %5d",a); %5d",a); %5d",a); %5d",b);

/* comparaes */ if (1) printf ("\n (5) sempre verdadeiro"); if (-5) printf ("\n (6) sempre verdadeiro"); if (0) ; else printf ("\n (7) sempre falso"); if (1 == 1) printf ("\n (8) sempre verdadeiro"); if (0 == 0) printf ("\n (9) sempre verdadeiro"); /* a tambm pode receber valores aritmticos entre 0 e 255 */ a = x * y; if (a) printf ("\n (10) verdadeiro quando a diferente de zero - a = %2d", a); else printf ("\n (10) falso quando a igual a zero - a = %2d", a);MAC 122 PDA Marcilio Revisado 11Ago10

MAC 122 PDA Marcilio Revisado 11Ago10

/* a e b como valores lgicos */ a = x * y; b = x + y; if (a && b) printf ("\n (11) verdadeiro se a e b nao zero: a = %2d b = %2d",a,b); else printf ("\n (11) falso se a ou b sao zero: a = %2d b = %2d",a,b); b = 0; /* a repetio ser infinita */ while (1) { if (b++ > 4) break; // fora a sada printf("\n (%2d) valor de b = %2d", 11+b, b); } /* outro exemplo de while */ a = 1; b = 0; while (a) { printf("\n (%2d) valor de a = %2d valor de b = %2d", 18+b, a, b); a = (b++) < 3; } printf("\n (%2d) valor final de a = %2d e de b = %2d", 18+b, a, b); } (1) valor de a = 1 (2) valor de a = 1 (3) valor de a = 0 (4) valor de a = 0 (5) sempre verdadeiro (6) sempre verdadeiro (7) sempre falso (8) sempre verdadeiro (9) sempre verdadeiro (10) falso quando a igual a zero - a = 0 (11) falso se a ou b sao zero: a = 0 b = (12) valor de b = 1 (13) valor de b = 2 (14) valor de b = 3 (15) valor de b = 4 (16) valor de b = 5 (18) valor de a = 1 valor de b = 0 (19) valor de a = 1 valor de b = 1 (20) valor de a = 1 valor de b = 2 (21) valor de a = 1 valor de b = 3 (22) valor final de a = 0 e de b = 4

1

Supondo int x,y; as seguintes expresses lgicas so equivalentes:(x && y) (x || y) (x != 0 && y != 0) (x != 0 || y!= 0) !(x == 0 || y == 0) !(x == 0 && y == 0)

MAC 122 PDA Marcilio Revisado 11Ago10

MAC 122 PDA Marcilio Revisado 11Ago10

Lembram-se daquele problema que dada uma seqncia terminada por zero, calcular a soma dos elementos da seqncia?int soma, x; : : x = 1; soma = 0; while (x) { scanf(%d, &x); soma = soma + x; } printf (o valor da soma = %d, soma);

Otimizao do clculo de expresses lgicas Quando se usa uma expresso composta, com os operadores && e ||, o compilador otimiza o clculo das mesmas, quando o valor j est definido no meio do clculo. Por exemplo, considere a expresso (a > b && c > d). Se a > b j falso, no necessrio verificar se c > d, pois o resultado da expresso j ser falso. O mesmo ocorre com (a > b || c > d). Se a > b verdadeiro, a expresso verdadeira independente se c > d ou no. Normalmente os compiladores da linguagem C usam esta regra como padro, sendo possvel alter-la atravs de uma opo de compilao para que o clculo seja completo. Em alguns casos, h efeitos colaterais provocados pelo clculo da expresso. O uso de expresses que pressupe a otimizao de clculo deve ser feito com muito cuidado, para evitar tais efeitos colaterais. Considere por exemplo a seguinte soluo para verificar se x igual a algum elemento de um vetor a de n elementos. Lembre-se que os elementos so a[0],a[1],...,a[n-1].i = 0; while (i < n && a[i] != x) i++;

Considerando o caso em que x no igual a nenhum dos elementos, o programa sai do while quando i = n e no realiza a comparao a[i] != x. Se comparasse estaria errado, pois o elemento a[n]est fora dos n elementos considerados. Invertendo agora a expresso acima:i = 0; while (a[i] != x && i < n) i++;

Embora a operao && seja comutativa, a soluo acima est errada, pois quando i = n a comparao a[n] != x ser efetuada, pois vem antes da comparao i < n. Expresses condicionaisMAC 122 PDA Marcilio Revisado 11Ago10

MAC 122 PDA Marcilio Revisado 11Ago10

Considere o comando abaixo:/* atribui a c o maior entre a e b */ if (a > b) c = a; else c = b;

O mesmo resultado pode ser obtido usando-se uma expresso condicional com o operador ternrio ?: da seguinte forma:c = (a > b) ? a : b;

Como muitas construes em C, o uso do operador ?: compacta demais (pouco clara), porm s vezes facilita. A forma geral de uma expresso condicional : expresso1? expresso2: expresso3 A expresso1 calculada. Se seu valor for verdadeiro, calculado o valor de expresso2, seno calculado o valor de expresso3. Somente um dos valores expresso1 ou expresso2 calculado. Considere o seguinte programa abaixo que imprime os nmeros de 0 a 99, dez deles por linha. Aps cada nmero, com exceo do ltimo de cada linha, impresso -:#include int main() { int i; for (i = 0; i < 100; i++) printf("%5d%1c", i, (i%10 == 9) ? '\n' : '-'); } 0102030405060708090111213141516171819121222324252627282923132333435363738393414243444546474849451525354555657585956162636465666768696717273747576777879781828384858687888989 19 29 39 49 59 69 79 89 99

Tabela de operadores e suas prioridades de avaliao A tabela abaixo mostra os operadores do c, em ordem decrescente de prioridade de clculo:Prioridade 1 2 3 4MAC 122 PDA Marcilio Revisado 11Ago10

Operadores () [] -> . ! ~ ++ -- + - (tipo) * & sizeof * / % + -

Obs: esquerda para direita direita para esquerda esquerda para direita esquerda para direita

MAC 122 PDA Marcilio Revisado 11Ago10

5 6 7 8 9 10 11 12 13 14 15

> esquerda para direita < >= esquerda para direita == != esquerda para direita & esquerda para direita ^ esquerda para direita | esquerda para direita && esquerda para direita || esquerda para direita ?: direita para esquerda = += -= *= /= %= = &= |= ^= direita para esquerda , esquerda para direita

Os unrios +, - e * (linha 2) tem maiores prioridades que os binrios correspondentes. Os operadores -> e . so usados em structs . O operador sizeof(tipo) devolve o tamanho em bytes do tipo. Muito cuidado deve ser tomado com a mistura excessiva de operadores numa expresso, devido definio das prioridades. Na dvida use parntesis. Por exemplo:if (x & 5 == 0)

diferente de if( (x & 5) == 0). Veja a tabela acima.

Alm disso, na linguagem C no especificada (definida) a ordem de avaliao dos operandos de um operador. Assim compiladores diferentes podem levar a resultados diferentes. Portanto no uma boa prtica de programao, usar comandos cujo resultado depende da ordem de avaliao dos seus operandos. Exemplo:a = exp1 + exp2 (quem calculado primeiro exp1 ou exp2?)

Da mesma forma a ordem de clculo dos parmetros de funo no est definido no C. Por exemplo, se n 5: func(n, n++); pode ser func(5, 6) ou func(6,6)

Nmeros na base 2 Para o prximo assunto bom uma recordao de como se escreve nmeros na base binria: Um nmero na base 2 possui apenas os algarismos 0 e 1, da mesma forma que um nmero na base 10 possui algarismos de 0 a 9. O nmero 1235 na base 10 significa 5 + 3*10 + 2*100 + 1*1000. O nmero 10101 na base 2 significa 1 + 0*2 +1*4 + 0*8 + 1*16 = 21.MAC 122 PDA Marcilio Revisado 11Ago10

MAC 122 PDA Marcilio Revisado 11Ago10

Alguns exemplos de nmeros na base 2.base 10 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 base 2 0 1 10 11 100 101 110 111 1000 1001 1010 1011 1100 1101 1110 1111

Dado um nmero na base 10, escrev-lo na base 2. Lembram-se do algoritmo? Basta ir dividindo o nmero por 2 at acabar e ir pegando os restos na ordem inversa.Quociente 25 12 6 3 1 0 resto da diviso por 2 1 0 0 1 1

25 na base 10 = 11001 na base 2Quociente 67 33 16 8 4 2 1 0 resto da diviso por 2 1 1 0 0 0 0 1

67 na base 10 = 1000011 na base 2 Este mesmo mtodo pode ser usado para escrever um nmero em qualquer base. Vejamos por exemplo na base 7.Quociente resto da diviso por 7

MAC 122 PDA Marcilio Revisado 11Ago10

MAC 122 PDA Marcilio Revisado 11Ago10

276 39 5 0

3 4 5

276 na base 10 = 543 na base 7 (de fato 3 + 4*7 + 5*49 = 276) O programa abaixo, dado um nmero n, escreve-o na base 2, porm os dgitos saem na ordem inversa. Veja a sada.#include /* dado n>=0 escrever n na base 2 os dgitos vo sair ao contrrio */ int main() { int n; /* ler o n */ printf("digite o valor de n:"); scanf("%d", &n); /* imprima o resto e divida n por 2 o nmero binrio vai estar ao contrrio */ while (n > 0) { printf("%1d", n%2); n = n / 2; } } digite o valor de n:76 0011001

O programa abaixo faz a mesma coisa, s que faz com que os dgitos sejam impressos na ordem correta.#include /* dado n>=0 escrever n na base 2 */ int main() { int n, d; /* ler o n */ printf("digite o valor de n:"); scanf("%d", &n); /* descubra a potncia de 2 imediatamente superior a n */ d = 1; while (d 0) { printf("%1d", n / d); n = n % d; d = d / 2; } }MAC 122 PDA Marcilio Revisado 11Ago10

MAC 122 PDA Marcilio Revisado 11Ago10

digite o valor de n:125 1111101

Representao interna de nmeros binrios J vimos acima que variveis do tipo char ocupam 8 bits, short 16 bits, int 32 bits e long int 64 bits. Assim, supondo:unsigned unsigned unsigned unsigned char a = 1; short b = 2; int c = 3; long int d = 4;

Teriam a seguinte representao interna:a 00000001 b 00000000 00000010 c 00000000 00000000 00000000 00000011 d 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000100

Notao complemento de 2 para a representao de nmeros negativos Os nmeros negativos so representados internamente numa notao denominada complemento de 2. Uma primeira idia para se representar nmeros negativos, seria reservar o bit mais da esquerda para o sinal. Assim em um char (8 bits) poderamos representar os nmeros 127 a +127 (255 possveis), isto , em binrio 11111111 e 01111111. O zero possui 2 representaes: 00000000 e 10000000. A notao complemento de 2, permite armazenar um valor a mais (de 128 a +127, ou seja, 256 possveis), alm de outras facilidades que veremos abaixo. Vejamos um exemplo para uma palavra de 4 bits apenas, para ficar mais fcil. Os valores representveis sero:-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2 ,3 ,4, 5, 6, 7 Valor -8 -7 -6 -5 -4 -3 -2 -1 0 Bits 1000 1001 1010 1011 1100 1101 1110 1111 0000

MAC 122 PDA Marcilio Revisado 11Ago10

MAC 122 PDA Marcilio Revisado 11Ago10

1 2 3 4 5 6 7

0001 0010 0011 0100 0101 0110 0111

Para se obtermos o tal complemento de 2 de um nmero negativo, basta pegar o padro de bits correspondente ao positivo, invertermos todos os bits (zeros por uns e vice-versa) e somar um em binrio. Como a tabela acima cclica, somas e subtraes so somas e correspondem a deslocar-se na tabela. Por exemplo: 2 4 2 + (-4), ou 0010 + 1100 = 1110, ou seja 2 (veja a tabela). Outro efeito, dessa notao quando os valores passam dos limites. Por exemplo:7+2 = -7 5+5 = -6

Portanto, cuidado quando usar um char com sinal (no unsigned), para fazer operaes aritmticas e o resultado eventualmente no couber em um char. Se quiser armazenar valores maiores o iguais a 128=27, use unsigned char. O mesmo ocorre com short (maiores ou iguais a 215) e int (valores maiores ou iguais a 231). O que ser impresso pelo programa abaixo? #include #include int main() { char a=150; unsigned char b=150; printf("a=%d;b=%d",a,b); system("PAUSE"); return 0; } a=-106;b=150 E pelo programa abaixo? #include #include int main() { char a=120;MAC 122 PDA Marcilio Revisado 11Ago10

MAC 122 PDA Marcilio Revisado 11Ago10

unsigned b=120; char i=0; while (i++ 1; } } a b a&b a|b a^b ~a a b a&b a|b a^b ~a a b a&b a|b a^b ~a a b a&b a|b a^b ~a a b a&b a|b a^b ~a a b a&b a|b a^b ~a a b a&b a|b a^b ~a decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 1 255 1 255 254 254 2 127 2 127 125 253 4 63 4 63 59 251 8 31 8 31 23 247 16 15 0 31 31 239 32 7 0 39 39 223 64 3 0 67 67 191 hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 1 ff 1 ff fe fe 2 7f 2 7f 7d fd 4 3f 4 3f 3b fb 8 1f 8 1f 17 f7 10 f 0 1f 1f ef 20 7 0 27 27 df 40 3 0 43 43 bf

MAC 122 PDA Marcilio Revisado 11Ago10

MAC 122 PDA Marcilio Revisado 11Ago10

a b a&b a|b a^b ~a a b a&b a|b a^b ~a

-

decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal decimal

= = = = = = = = = = = =

128 1 0 129 129 127 0 0 0 0 0 255

-

hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal hexadecimal

= = = = = =

80 1 0 81 81 7f

= 0 = 0 = 0 = 0 = 0 = ff

Veja agora outro programa que escreve os nmeros de 0 a n na base 2. Veja tambm o que ser impresso:#include #include int main() { int i, j, k, n; printf("entre com n:"); scanf("%d", &n); n = abs(n); /* considere positivo */ for (i = 1; i