Fundamentos de Programação ET42G Aula 5 Prof. Daniel Cavalcanti Jeronymo Tipos básicos de dados. Modificadores de tipos. Operadores aritméticos. Operadores lógicos. Operadores binários. Universidade Tecnológica Federal do Paraná (UTFPR) Engenharia Eletrônica 2º Período 2015.1 1/42
Tipos básicos de dados Plano de Aula int, char, float, double, void Tipos definidos pelo usuário struct, union, enum, typedef Tipos derivados [ponteiros, vetores, funções] Modificadores de tipos Tamanho, sinal, constante, volatilidade, armazenamento [ponteiros, funções e interrupções] Literais limits.h 2/42
Caractere (char) Tamanho: tipicamente, porém não restrito, a um byte (8 bits) número de bits da arquitetura é encontrado na macro CHAR_BIT (limits.h) Tipos básicos de dados Restrição: maior ou igual a 8 bits Uso: representação de valores de caracteres utilizando alguma codificação (e.g. ASCII) sizeof retorna o tamanho da unidade em chars 3/42
sizeof Não é uma função! é uma palavra chave Tipos básicos de dados Retorna o tamanho, em chars, da variável ou do tipo Uso: sizeof(int); sizeof int; int x; sizeof(x); 4/42
Inteiro (int) Tamanho: igual a unidade natural da arquitetura (word) Tipos básicos de dados Restrição de tamanho: maior ou igual a 16 bits Armazenamento mínimo: valores entre -32767 ~ 32767 Armazenamento depende da endianness 5/42
Inteiro (int) Endianness sequência de armazenamento de valores maiores que um byte (não se aplica a registradores!) Tipos básicos de dados Origem do termo: Jonathan Swift e a sátiar As Viagens de Gulliver, guerra centenária entre o reinado de Lilliput e o reinado de Blefuscu Motivo: habitantes de Lilliput comiam ovos cozidos primeiro pela parte pequena (little endian) enquanto em Blefuscu os ovos eram iniciados pela parte grande (big endian) 6/42
Inteiro (int) Tipos básicos de dados Endianness Valor 90AB12CD 16 big endian byte mais significante little endian byte menos significante 7/42
Inteiro (int) Endianness Importância na transferência de informação entre arquiteturas Tipos básicos de dados #include <stdio.h> #include <string.h> int main() { int valor = 0x1A2B3C4D; int byte = 0; memcpy(&byte, ((char*)&valor) + 0, sizeof(char)); printf("%x %X\n", valor, byte); } return 0; 8/42
Ponto flutuante (float/double) Como representar números reais em binário? Tipos básicos de dados Pense em decimal: 14.75 1*10^1 + 4*10^0 + 7*10^-1 + 5*10^-2 9/42
Ponto flutuante (float/double) Lembrete de aulas passadas: a operação de multiplicar por dois é equivalente, em binário, a deslocar bits para a esquerda (SHL) Tipos básicos de dados 14.75 * 2^2 * 2^-2 (SHL) = 59.0 * 2^-2 Deslocamos todo o conteúdo decimal para antes do ponto! 10/42
Ponto flutuante (float/double) Continuando, traduzimos o valor pra binário Mantendo a notação de base para binário e ignorando para decimal (afim de simplificar) Tipos básicos de dados = 59.0 * 2^-2 = 111011 2 * 2^-2 11/42
Ponto flutuante (float/double) Agora deslocando os bits para a direita (SHR),dividindo por 2, e utilizando a notação científica Tipos básicos de dados = 111011 2 * 2^-2 = 111011 2 * 2^-2 * 2^5 * 2^-5 (SHR) = 1.11011 2 * 2^-2 * 2^5 = 1.11011 2 * 2^3expoente mantissa 12/42
Ponto flutuante (float/double) Passando 1.11011 2 para decimal 2 0. 2-1 2-2 2-3 2-4 2-5 1. 1 1 0 1 1 Tipos básicos de dados = 1*2^0 + 1*2^-1 + 1*2^-2 + 0*2^-3 + 1*2^-4 + 1*2^-5 = 1.84375 mantissa 13/42
Ponto flutuante (float/double) = 1.11011 2 * 2^3 = 1.84375 * 2^3 Tipos básicos de dados Verificando a conta acima: = 1.84375 * 2^3 = 14.75 14/42
Ponto flutuante (float/double) Representação padronizada IEEE 754 Tipos básicos de dados float double Expoente representado com bias 127 (variação -127 ~ +128 para float) 15/42
Ponto flutuante (float/double) Exemplo anterior = 1.11011 2 * 2^3 Tipos básicos de dados Bits da fração: 11011 Expoente com bias = 127 + 3 = 130 = 10000010 2 Sinal = 0 (positivo) 16/42
Ponto flutuante (float/double) Verificando o exemplo em código #include <stdio.h> #include <string.h> #include <assert.h> int main() { float f_valor = 14.75; int i_valor = 0; assert(sizeof(int) == sizeof(float)); memcpy(&i_valor, &f_valor, sizeof(int)); printf("%x \n", i_valor); Tipos básicos de dados } return 0; 17/42
Ponto flutuante (float/double) Esperado: 0x416C0000 Tipos básicos de dados 18/42
Vazio (void) Usado pra definir ausência de tipo em parâmetros, retornos ou ponteiros Tipos básicos de dados void func(...); int func(void); void *p; 19/42
Tipos definidos pelo usuário Tipos derivados Tipos básicos de dados Aula específica no futuro! 20/42
Tamanho Modificadores de tipos short int maior ou igual a 16 bits, maior ou igual a char long int maior ou igual a 32 bits, maior ou igual a int long double maior ou igual a double 21/42
Sinal Modificadores de tipos signed Permite valores negativos (padrão) unsigned Apenas valores positivos 22/42
Sinal (signed/unsigned) Como representar valores negativos? Modificadores de tipos Magnitude assinalada Complemento de um Complemento de dois 23/42
Sinal (signed/unsigned) Complemento de dois amplamente utilizado em várias arquiteturas Modificadores de tipos Para representar -1, considera-se o valor como positivo, considerando uma palavra de 4 bits: 0001, aplica-se a negação lógica: 1110, em seguida soma-se um: 1111 ^ O primeiro bit representa o sinal 24/42
Constante (const) Variáveis cujo conteúdo não pode ser alterado após a declaração Modificadores de tipos const int A = 10; const unsigned B = 20; 25/42
Armazenamento Define o escopo (visibibilidade) e duração das variáveis Modificadores de tipos auto variáveis na pilha. (padrão) register variáveis em registradores. static variável é mantida durante toda a existência do programa, ao contrário de ser criada e destruída cada vez que o escopo é acessado. nomes simbólicos globais são limitados ao escopo do arquivo. extern nomes simbólicos são visíveis a todos os arquivos de código. (padrão) Ponteiros, funções e interrupções aula futura. 26/42
0x... hexadecimal 0... octal 5u unsigned 5l - long 5ul unsigned long 314159E-5L notação exponencial Literais 27/42
Macros que definem limites dos tipos #include <stdio.h> #include <limits.h> int main() { printf("numero de bits em um byte %d\n", CHAR_BIT); printf("valor mínimo de SIGNED CHAR = %d\n", SCHAR_MIN); printf("valor máximo de SIGNED CHAR = %d\n", SCHAR_MAX); printf("valor máximo de UNSIGNED CHAR = %d\n", UCHAR_MAX); printf("valor mínimo de SHORT INT = %d\n", SHRT_MIN); printf("valor mínimo de SHORT INT = %d\n", SHRT_MAX); printf("valor mínimo de INT = %d\n", INT_MIN); printf("valor mínimo de INT = %d\n", INT_MAX); printf("valor mínimo de CHAR = %d\n", CHAR_MIN); printf("valor máximo de CHAR = %d\n", CHAR_MAX); printf("valor mínimo de LONG = %ld\n", LONG_MIN); printf("valor máximo de LONG = %ld\n", LONG_MAX); return(0); } limits.h 28/42
Operadores aritméticos Plano de Aula soma, subtração, multiplicação, divisão, módulo, incremento e decremento Operadores lógicos not, and, or Operadores binários Not, and, or, xor, shift left, shift right 29/42
Aritméticos Promoção Inc/Dec Lógicos Binários Operadores aritméticos Operadores aritméticos Considere A = 10 e B = 20 Operador Descrição Exemplo + Adiciona dois operandos A + B = 30 - Subtrai o Segundo operando do primeiro A - B = -10 * Multiplica dois operandos A * B = 200 / Divide o primeiro operando pelo Segundo B / A = 2 % Resto de uma divisão de inteiros B % A = 0 ++ Incremento por um A++ = 11 -- Decremento por um A-- = 9 30/42
Aritméticos Promoção Inc/Dec Lógicos Binários Operadores aritméticos Unários utilizam apenas um operando Operadores aritméticos +a promoção de inteiro -a aditiva inversa ++a e a++ são diferentes --a e a-- também 31/42
Aritméticos Promoção Inc/Dec Lógicos Binários Operadores aritméticos Promoção de inteiro Operadores aritméticos Se um int pode representar todos os valores de um tipo, o valor é convertido para int; caso contrário, é convertido para unsigned int. signed char: -127 a 127 unsigned char: 0 a 255 signed short: -32767 a 32767 unsigned short: 0 a 65535 signed int: -2147483647 a 2147483647 unsigned int: 0 a 4294967295 32/42
Aritméticos Promoção Inc/Dec Lógicos Binários Operadores aritméticos Promoção de inteiro em +a Operadores aritméticos #include <stdio.h> int main(void) { char ch; short sh; int i; } /* saida: 1 2 4 */ printf("%d %d %d\n", sizeof(ch), sizeof(sh), sizeof(i)); /* saida: 4 4 4 */ printf("%d %d %d\n", sizeof(+ch), sizeof(+sh), sizeof(i)); 33/42
Aritméticos Promoção Inc/Dec Lógicos Binários Operadores aritméticos Promoção de inteiro abaixo, a*b = 1200 que é maior que um inteiro, o código funciona? Operadores aritméticos #include <stdio.h> int main() { char a = 30, b = 40, c = 10; char d = (a * b) / c; printf ("%d ", d); return 0; } 34/42
Aritméticos Promoção Inc/Dec Lógicos Binários Operadores aritméticos Conversão de lvalue para rvalue o código abaixo funciona? Operadores aritméticos #include <stdio.h> int main(void) { char a = 10; char b = (+a)++; } 35/42
Aritméticos Promoção Inc/Dec Lógicos Binários Operadores aritméticos Ordem de incremento ou decremento Operadores aritméticos #include <stdio.h> int main(void) { char a = 10; char b = 20; } printf("a: %d b: %d\n", ++a, b++); printf("a: %d b: %d\n", a, b); 36/42
Aritméticos Promoção Inc/Dec Lógicos Binários Operadores lógicos A = 1 e B = 0 Operadores lógicos Operador Descrição Exemple && AND lógico. Se ambos os operandos forem não-zero, então a condição é verdadeira. (A && B) é falso. OR lógico. Se qualquer um dos operandos for não-zero, então a condição é verdadeira. (A B) é verdade.! NOT lógico. Reverte o estado lógico do operando.called Logical NOT Operator. Use to reverses the logical state of its operand. If a condition is true then Logical NOT operator will make false.!(a && B) é verdade. 37/42
Aritméticos Promoção Inc/Dec Lógicos Binários Operadores lógicos Operadores lógicos Tabela verdade P Q p && q T T T T F F F T F F F F P Q p q T T T T F T F T T F F T P!P T F F T 38/42
Aritméticos Promoção Inc/Dec Lógicos Binários Operadores lógicos Avalie as seguintes condições Operadores lógicos 1) (true && true) false 2) (false && true) true 3) (false && true) false true 39/42
Aritméticos Promoção Inc/Dec Lógicos Binários Operadores lógicos Avalie as seguintes condições Operadores lógicos 1) (true && true) false = true 2) (false && true) true = true 3) (false && true) false true = true 40/42
Aritméticos Promoção Inc/Dec Lógicos Binários Operadores binários A = 0xF0 e B = 0x0F Operador Descrição Exemplo & AND binário. Copia um bit para o resultado caso (A & B) = 0x00 exista em ambos operandos. OR binário. Copia um bit para o resultado caso exista em qualquer um dos operandos. (A B) = 0xFF ^ XOR binário. Copia um bit para o resultado caso (A ^ B) = 0xFF seja diferente entre os operandos. ~ Negação ou complement. Operador unário para inversão de bits. (~A ) = 0x0F Operadores binários << Operador de deslocamento à esquerda. O valor do operando a esquerda é movido pela quantidade de bits especificada pelo operando a direita. >> Operador de deslocamento à direita. O valor do operando a esquerda é movido pela quantidade de bits especificada pelo operando a direita. A << 1 = 0x1E0 A >> 1 = 0x78 41/42
Aritméticos Promoção Inc/Dec Lógicos Binários Operadores binários Utilidades: Operadores binários Bit Twiddling Hacks http://graphics.stanford.edu/~seander/bithacks.html Exemplo: XOR swap 42/42