Linguagem C - Operadores bit a bit
-
Upload
elaine-cecilia-gatto -
Category
Education
-
view
2.508 -
download
5
description
Transcript of Linguagem C - Operadores bit a bit
OPERADORES BIT A BIT
Profª Ms. Engª Elaine Cecília GattoCurso de Bacharelado em Engenharia de ComputaçãoUniversidade do Sagrado CoraçãO – USCBauru/SP
Operadores sobre bits
• Computadores representam internamente todos os dados como sequencias de bits;
• Os bits podem assumir o valor 0 ou o valor 1;• Na maioria dos sistemas, uma sequencia de
8 bits forma um byte – unidade de armazenamento padrão para uma variável do tipo char;
• Outros tipos de dados são armazenados em números maiores de bytes;
• Os operadores sobre bits são usados para manipular os bits de operandos inteiros;
• Os inteiros sem sinal normalmente são usados com o os operadores sobre bits;
Operadores sobre bits
• Os operadores sobre bits são:
• Comparação dos dois operandos bit a bit:– And (&)– OR inclusivo ( | )– OR exclusivo ( ^ )
• Deslocamento à esquerda ( < < )• Deslocamenteo à direita ( > > )• Complemento ( ~ )
• Ser capaz de operar no nível dos bits é especialmente importante quando o programa deve atuar diretamente no hardware da máquina.
Operadores sobre bits
AND Os bits são definidos como 1 no resultado, se os bits correspondentes em ambos os operandos forem 1.
OR inclusivo Os bits são definidos como 1 no resultado, se pelo menos um dos bits correspondentes em amobs os operandos for 1.
OR exclusivo Os bits são definidos como 1 no resultado, se exatamente um dos bits correspondentes em ambos os operandos for 1.
Deslocamento à esquerda
Desloca os bits do primeiro operando à esquerda pelo número de bits especificado pelo segundo operando: preenche a partir da direita com zero (0) bits.
Deslocamento à direita
Desloca os bits do primeiro operando à direita pelo número de bits especificado pelo segundo operando: o método de preenchimento a partir da esquerda depende da máquina.
Complemento de um
Todos os bits 0 são definidos como 1, e todos os bits 1 são definidos como 0.
Exibição de um inteiro sem sinal em bits
• Ao usar os operadores sobre bits, é útil imprimir valores em sua representação binária para ilustrar os efeitos exatos desses operadores.
• O programa a seguir imprime um inteiro sem sinal em sua representação binária em grupos de 8 bits cada.
• Os inteiros sem sinal são armazenados, neste exemplo, em 4 bytes ou 32 bits de memória.
Exibição de um inteiro sem sinal em bits
#include <stdio.h>void displayBits (unsigned value); //protótipo da funçãoint main(void) {
unsigned x;printf(“Digite um inteiro sem sinal: ”);scanf(“%u”, &x);displayBits(x); //chama a funçãoreturn 0;
}//função: mostra bits de um valor inteiro sem sinalvoid displayBits(unsigned value) {
unsigned c; //contador
Exibição de um inteiro sem sinal em bits
//declara displayMask e desloca 31 bits à esquerda
unsigned displayMask = 1 << 31;printf(“%10u = ”, value);//percorre os bitsfor( c=1; c<=32; c++) {
putchar(value & displayMask ? ‘1’ : ‘0’);value <<= 1; //desloca valor à esquerda
em 1if( c%8 == 0) { //gera espaço após 8 bitsputchar(‘ ’);}
}putchar(‘ \n ’);
}
Exibição de um inteiro sem sinal em bits
Exibição de um inteiro sem sinal em bits
• A função displayBits usa o operador AND sobre bits para combinar a variável VALUE com a variável DISPLAYMASK.
• Frequentemente, o operador AND sobre bits é usado como um operando chamado MÁSCARA – um valor inteiro com bits específicos definidos como 1.
• As máscaras são usadas para ocultar alguns bits em um valor enquanto seleciona outros bits.
• Na função DISPLAYBITS, a variável máscara DISPLAYMASK recebe o valor 1 << 31 (10000000 00000000 00000000 00000000)
Exibição de um inteiro sem sinal em bits
• O operador de deslocamento à esquerda desloca o valor 1 a partir do bit de baixa ordem – mais à direita – para o bit de alta ordem – mais à esquerda – em DISPLAYMASK, e preenche bits 0 a partir da direita.
• A linha putchar(value & displayMask ? ‘1’ : ‘0’); determina se 1 ou 0 deve ser impresso para o bit mais à esquerda da variável VALUE.
• Quando VALUE e DISPLAYMASK são combinados usando &, todos os bits, exceto o bit de alta ordem na variável VALUE, são mascarados – ocultados – pois qualquer bit que passe por AND com 0 gera 0.
Exibição de um inteiro sem sinal em bits
• O operador de deslocamento à esquerda desloca o valor 1 a partir do bit de baixa ordem – mais à direita – para o bit de alta ordem – mais à esquerda – em DISPLAYMASK, e preenche bits 0 a partir da direita.
• A linha putchar(value & displayMask ? ‘1’ : ‘0’); determina se 1 ou 0 deve ser impresso para o bit mais à esquerda da variável VALUE.
• Quando VALUE e DISPLAYMASK são combinados usando &, todos os bits, exceto o bit de alta ordem na variável VALUE, são mascarados – ocultados – pois qualquer bit que passe por AND com 0 gera 0.
Exibição de um inteiro sem sinal em bits
• Se o bit mais à esquerda for 1, VALUE & DISPLAYMASK será avaliado como um valor diferente de zero – verdadeiro – e 1 será impresso – caso contrário, 0 será impresso.
• A variável VALUE é, então, deslocada um bit à esquerda pela expressão VALUE <<= 1 – isso equivale a VALUE = VALUE << 1.
• Essas etapas são repetidas para cada bit na variável UNSIGNED VALUE.
• Cuidado: usar o operador lógico AND (&&) para o operador AND SOBRE BITS (&) e vice-versa consiste em um erro.
Imprimindo um caracter em binário
#include <stdio.h>#include <stdlib.h>
typedef struct {unsigned char bit0: 1;unsigned char bit1: 1;unsigned char bit2: 1;unsigned char bit3: 1;unsigned char bit4: 1;unsigned char bit5: 1;unsigned char bit6: 1;unsigned char bit7: 1;
} Bits;
typedef union {unsigned char ch;Bits x;
} Binario;
int main (void){Binario B;printf("Digite um caractere: ");fflush(stdout);B.ch = getchar();printf("O caractere digitado é: %c \
n", B.ch);printf("O valor em binário
correspondente é: ");printf("%d", B.x.bit7);printf("%d", B.x.bit6);printf("%d", B.x.bit5);printf("%d", B.x.bit4);printf("%d", B.x.bit3);printf("%d", B.x.bit2);printf("%d", B.x.bit1);printf("%d", B.x.bit0);//system("PAUSE");return 0;
}
Imprimindo um caracter em binário
Operador and: & e &=
• É um operador binário que executa um AND com cada par de bits dos operandos.
• Cada bit do resultado é 1 somente quando os dois bits operandos são 1; em qualquer situação, o resultado é zero.
• O operador bit a bit AND é normalmente usado para testar se um bit particular está ligado ou desligado.
• O processo de teste funciona, pois se operarmos o bit a ser testado com 1, o resultado será verdadeiro somente se esse bit estiver ligado.
BIT 1 BIT 2 BIT & BIT2
0 0 0
1 0 0
0 1 0
1 1 1
Operador or: | e |=
• É um operador binário que executa um OR com cada par de bits dos operandos.
• Cada bit do resultado é zero somente quando os dois bits operandos são zero; em qualquer outra situação, o resultado é um.
• O operador bit a bit OR é normalmente usado para ligar um bit particular.
• O processo funciona, pois, se operarmos o bit a ser ligado com 1, o resultado será verdadeiro sempre.
BIT 1 BIT 2 BIT 1 | BIT 2
0 0 0
1 0 1
0 1 1
1 1 1
Operador xor: ^ e ^=
• É um operador binário que executa um XOR com cada par de bits dos operandos.
• Cada bit do resultado é 1 somente quando os dois bits operandos são diferentes; quando são iguais, o resultado é zero.
• O operador bit a bit XOR é normalmente usado para inverter o status de um bit.
BIT 1 BIT 2 BIT 1 | BIT 2
0 0 0
1 0 1
0 1 1
1 1 0
Operador de complemento: ~ e ~=
• O operador de complemento opera um único operando; resulta um valor com todos os bits invertidos.
• A aplicação do operador ~ duas vezes no mesmo operando resulta sempre o número original.
• Exemplo: int main (){
unsigned char ch;while((ch=getch()) != ‘X’)printf(“%c”, ~ch);system(“PAUSE”);return 0;
}
Operador de deslocamento esquerdo: << e <<=
• Trata-se de um operador binário, mas que age somente no operando da esquerda.
• Executa um deslocamento para a esquerda, conforme o número de posições especificado no segundo operando.
• Toda vez que empurramos um bit à esquerda estaremos multiplicando o número por dois.
X <<= 1; //é o mesmo que x*=2;X <<= 2; //é o mesmo que x*=4;
• Exemplo:
Operador de deslocamento esquerdo: << e <<=
int palavra () {unsigned int n = ~0;int i;for( i=0; n; i++)
n <<= 1;return i;
}int main(){
int t = palavra();printf(“O tamanho da palvra dessa máquina é %d
bits. \n”, t);system(“PAUSE”);return 0;
}
Operador de deslocamento esquerdo: >> e >>=
• É um operador binário, mas que age somente no operando da esquerda.
• Executa um deslocamento para a direita, conforme o número de posições especificado no segundo operando.
• Toda vez que empurramos um bit à direita estaremos dividindo o número por 2.
X >>= 1; //é o mesmo que x /= 2X >>= 2; //é o mesmo que x /= 4
Operadores de atribuição sobre bits
&= Operador de atribuição sobre bits AND.
|= Operador de atribuição sobre bits OR inclusivo.
^= Operador de atribuição sobre bits OR exclusivo.
<<= Operador de alinhamento à esquerda com atribuição.
>>= Operador de alinhamento à direita com atribuição.
Precedência e associatividade de operadores
Operadores Associatividade Tipo
() [] . Esquerda para a direita Mais alto
+ - ++ -- | & * ~sizeof (tipo) Direita para a direita Unário
* / % Esquerda para a direita Multiplicativo
+ - Esquerda para a direita Aditivo
<< >> Esquerda para a direita Deslocamento
< <= > >= Esquerda para a direita Relacional
== != Esquerda para a direita Igualdade
& Esquerda para a direita AND sobre bits
^ Esquerda para a direita OR sobre bits
| Esquerda para a direita OR sobre bits
&& Esquerda para a direita AND lógico
|| Esquerda para a direita OR lógico
?: Direita para a direita Condicional
= += -= *= /= |= ^= <<= >>= %= Direita para a direita Atribuição
, Esquerda para a direita vírgula
Campos de Bits
• C permite que o número de bits de um membro UNSIGNED ou INT de uma estrutura ou união armazenado, seja especificado pelo programador.
• Campos de bits permitem uma utilização da memória mais competente, armazenando dados no número mínimo de bits exigido.
• Os membros de campo de bit DEVEM ser declarados como INT ou UNSIGNED.
Campos de Bits
struct bitCar {unsigned face : 4;unsigned suit : 2;unsigned color : 1;
}; //jogo de cartas
• Um campo de bit é declarado ao se colocar um nome de membro UNSIGNED ou INT seguido por um sinal de dois-pontos ( : ) e uma constante inteira representando a largura do campo.
• A constante que representa a largura precisa ser um inteiro entre 0 e o número total de bits usados para armazenar um INT inclusive em seu sistema.
Campos de Bits
• O membro face é armazenado em 4 bits, o membro suit é armazenado em 2 bits e o membro color é armazenado em 1 bit.
• O número de bits é baseado no intervalo de valores desejado para cada membro da estrutura.
• 4 bits podem armazenar valores no intervalo de 0 a 15;
• 2 bits podem armazenar valores no intervalo 0 a 3;
• 1 bit pode armazenar um valor apenas, ou 0 ou 1.
Campos de Bits
• O membro face armazena as cartas de ÁS até Rei;
• O membro suit armazena as cartas:– Ouros = 0– Copas = 1 – Paus = 2– Espadas = 3
• O membro color armazena as cartas vermelho ou preto.
Campos de Bits
• Membros de campo de bit das estruturas são acessados exatamente como qualquer outro membro da estrutura.
• É possível especificar um campo de bit não nomeado para ser usado como preenchimento na estrutura.
Exemplo 1
//converte hexadecimal para binário
#include <stdio.h>#include <stdlib.h>#include <math.h>
int palavra();
int main(){int t, j, num, bit;unsigned int mask;while(1){
t = palavra();//1 no bit mais
significativo e zero nos outrosmask = pow(2, t-1);printf(" \n Digite um
número em hexadecimal: ");fflush(stdout);scanf("%x", &num);printf("Binário de %04x
é: ", num);fflush(stdout);for( j=0; j<t; j++){
Exemplo 1
bit = (mask & num) ? 1 : 0;printf("%d", bit);fflush(stdout);if(((j+1)%8) == 0){
printf("--");fflush(stdout);
}mask >>= 1;
}}system("PAUSE");return 0;
}
int palavra(){unsigned int n=~0;int i;for( i=0; n; i++){
n <<= 1;}return i;
}