Baixe o app para aproveitar ainda mais
Prévia do material em texto
Operadores e Expressões: bit-a-bit e especiais Objetivos Em C, OPERADORES e EXPRESSÕES podem ser classificados em cinco grande categorias: Atribuições Aritméticos Lógicos e Relacionais Bit-a-Bit Especiais 2 Objetivos Na última aula, disticutimos as três primeiras categorias acima. Agora, iremos dar prosseguimento ao estudo apresentado os OPERADORES e EXPRESSÕES: Bit-a-Bit Especiais Ao final, concluiremos o assunto mostrando um quadro que resume e compara os OPERADORES da linguagem C por ordem de precedência e associatividade. 3 Manipulação de Bits OPERADORES e EXPRESSÕES de manipulação de bits ( bit-a-bit ) referem-se a testar, atribuir ou deslocar os bits efetivos em um byte ou palavra que correspondem aos tipos básicos char, int e variantes. OBS.: Operações bit-a-bit não podem ser feitas sobre float, double, long double, void ou outros tipos mais complexos. 4 Operadores bit-a-bit 5 Significados Os operadores &, | e ~ têm a mesma tabela verdade que &&, || e ! (respectivamente), com a diferença que operam sobre os bits individuais da representação de dois números (ou apenas um, no caso de ~) e não sobre expressões numéricas. 6 Significados o operador ^ tem a mesma tabela verdade que a função xor() – ou exclusivo o operador >> desloca os bits de um número k casas para à esquerda fazendo com que os k bits mais à esquerda se percam e os k bits mais à direita sejam '0‘ o operador << desloca os bits de um número k casas para à direita fazendo com que os k bits mais à direita se percam e os k bits mais à esquerda sejam '0' 7 Exemplo 1 (<< e >>): Considere: unsigned int x = 7; Se pudéssemos olhar a representação do valor 7 (decimal) 'dentro' da variável x, veríamos os seguinte padrão de bits: x = 0...00000111 ( a quantidade total de bits depende de quantos bytes são utilizados para armazenar um unsigned int, quantidade que depende da máquina alvo e compilador ). 8 Exemplo 1 (<< e >>): Considere: A EXPRESSÃO abaixo (deslocamento à esquerda): x = x << 2; faz com que o padrão de bits representando o valor inicial 7 se transforme em x = 0...00011100. Quer dizer, os bits, todos foram deslocados para a esquerda dois bits! Assim, o valor agora reresentado na variável x é 28 ! 9 Representação De maneira geral, se uma variável tem o seguinte padrão de bits: x = | bn-1 | bn-2 | ... | b2 | b1 | b0 | onde: a variável é representada por n bits cada um dos bi (para 0 ≤ i ≤ n-1 ) denota um bit com valor '0' ou '1' 10 Representação então: x << k, resulta em: x = | bn-k-1 | bn-k-2 | ... | b2 | b1 | b0 | 0 | 0 | .. | 0 |0 | 0 | onde a seq. final de '0's contém k '0's x >> k, resulta em: x = | 0 | 0 | ... | 0 | 0 | 0 | bn-1 | bn-2 | ... | bk-1 | bk | onde a seq. inicial de '0's contém k '0's 11 Exemplo 2 (~): Continuando o exemplo anterior, tem-se x = 0...00011100. A EXPRESSÃO abaixo ( complemento de 1 ): x = ~ x; tem o seguinte efeito na representação de x em binário: x = 1...11100011 . Ou seja, os bits que são '0' passam a ser '1', os que são '1' tornam-se '0'. 12 Exemplo 3 (|) Continuando o exemplo anterior, tem-se x = 1...11100011. A EXPRESSÃO abaixo ( OR ): x = x | 8 ; transforma x em : x = 1...11101011 . Quer dizer, muda o quarto bit (da direita para a esquerda) de '0' para '1'. Isto acontece por que: 13 Exemplo 3 (|) x = 1...11100011 4 = 0...00001000 ----------------- x | 4 = 1...11101011 /* OU bit a bit */ | é frequentemente utilizado para LIGAR bits particulares 14 Exemplo 4 (&) Continuando o exemplo anterior, tem-se x = 1...11101011. A EXPRESSÃO abaixo ( AND ): x = x & 0xf...f7 ; transforma x em : x = 1...11100011 . Quer dizer, muda o quarto bit (da direita para a esquerda) de '1' para '0'. Isto acontece por que: 15 Exemplo 4 (&) x = 1...11101011 0xf...f7 = 1...11110111 ----------------- x | 0xf...f7 = 1...11100011 /* AND bit a bit */ & é frequentemente utilizado para DESLIGAR bits particulares 16 Aplicações Rotinas de SO, drivers de dispositivos Criptografia Compactação de dados 17 Operadores Especiais Operador Condicional ? : Operador sizeof Operadores de Conversão de Tipo ou Casting (tipo) Operador Vírgula , Operadores () e [] Serão vistos em mais detalhes em aulas futuras: Operadores de ponteiros * e & Operadores de estruturas . e -> 18 Operador Condicional ? : Uso EXP1 ? EXP2 : EXP3; Significado EXP1 é avaliada ... Se ela for verdadeira, então EXP2 é avaliada e se torna o valor da expressão como um todo. ... Se EXP1 for falsa, então EXP3 é avaliada e se torna o valor da expressão como um todo. 19 Operador sizeof Uso sizeof ID-VAR; sizeof (ESP-TIPO); Significado sizeof é um operador unário em tempo de compilação que retorna o tamanho, em BYTES, de uma variável ou de um especificador de tipo de dados, este último escrito entre parênteses. 20 Conversão explicita de tipos (casting) Uso (ESPECIFICADOR-DE-TIPO) EXPRESSÃO; Significado Força - explicitamente - uma EXPRESSÃO a ser de um determinado tipo dado por ESPECIFICADOR-DE-TIPO. 21 Casting Além de conversões explícitas, o compilador realiza algumas conversões implícitas ... 22 Casting 23 Casting 24 Operador virgula , Uso EXP1, EXP2; Significado O operador vígula é usado para encadear diversas expressões. O lado esquerdo (EXP1) é sempre avaliado como void. Assim, a expressão do lado direito (EXP2) torna-se o valor de toda a expressão separada por vírgula. 25 Operador virgula , int x,y; x = ( y = 3, y+1 ); primeiro o valor 3 é atribuído a y e, em seguida, o valor 4 é atribuído a x. Os parênteses são necessários porque o operador vírgula tem a menor precedência de todos os operadores de C. Um outro exemplo é: 26 Operador virgula , int i,x; for ( i = 0 , x = 1; i < 10; i++ , x+=2) { ... } 27 Operadores [] e () Parênteses () são operadores que aumentam a precedência das operações dentro deles. Colchetes [] realizam indexação de vetores e matrizes. 28 Quadro geral de operadores em C A tabela a seguir lista a precedência de todos os operadores de C. Note que todos os operadores, exceto os operadores unários e o ?, associam da esquerda para a direita. Os operadores unários ( *, ! e ~) e o ternário ? associam da direita para a esquerda. 29 Precedência de operadores em C 30 Ordem de Avaliação O padrão C ANSI (C89) não estipula que as subexpressões de uma expressão devam ser avaliadas e uma ordem específica. Assim, seu código nunca deve contar com a ordem em que as subexpressões são avaliadas. Por exemplo, a expressão: x = f() + g(); não garante que f() será chamada antes de g()! 31
Compartilhar