mirror of
https://gitlab.com/blau_araujo/cblc.git
synced 2025-11-13 02:11:17 -03:00
Alvaro: Resolução dos exercícios da aula 3 #13
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Exercícios da aula 3: Tipos de dados
1. Pesquise e demonstre
No programa
quadrado-long.c, da aula 2, encontre uma forma de demonstrar o tipo do valor avaliado pela expressãobase * basenesta função:Solução
Saída:
Explicação
No programa
quadrado-long.c, a expressãobase * baseé avaliada como um valor do tipolong, porque ambos os operandos (base) são do tipolong.Podemos usar o operador
sizeofe_Generic(disponível em C11) para inspecionar o tipo em tempo de compilação.Como
baseélong, o resultado é o produto delongporlong, portantolong.O retorno
unsigned longda funçãoquadradosó ocorre após a multiplicação, caso em que o tipo da expressão é convertido paraunsigned long.Se
basefor muito grande (ex: 2.000.000.000),base * basepode estourar (já quelongtem limite). Nesse caso, mesmo retornandounsigned long, o cálculo intermediário (long * long) já terá ocorrido com overflow.2. Desafio: conversão de Fahrenheit para Celsius
Criar um programa que converta valores inteiros de -100ºF a 100ºF para Celsius e apresente os resultados no terminal.
Fórmula da conversão:
C = 5 × (F - 32) / 9Os valores em Fahrenheit serão expressos pela variável
i, declarada no loopfor.Por exemplo:
Solução
3. Pesquise e responda
O operador
sizeof(TIPO)expressa o tamanho em bytes deTIPOcom o tiposize_t.O que é o tipo
size_t?size_té um tipo de dado inteiro sem sinal (unsigned) definido pela linguagem C para representar tamanhos de objetos em bytes. Ele é usado principalmente para retornar o resultado desizeof(), representar índices e tamanhos em funções de manipulação de memória (malloc,memcpy, etc) e evitar problemas de portabilidade, já que seu tamanho varia conforme a arquitetura (32-bit ou 64-bit).Como utilizá-lo no seu programa sem incluir cabeçalhos?
Se você não quiser incluir
<stddef.h>ou<stdio.h>, pode declararsize_tmanualmente no seu programa, mas isso não é recomendado, pois o tamanho exato desize_tdepende do compilador e do sistema. Sem os cabeçalhos padrão perde-se a portabilidade.Em quais cabeçalhos ele é definido?
size_té definido nos seguintes cabeçalhos padrão:<stddef.h>(Definição principal)<stdio.h>(Para funções de I/O comoprintf)<stdlib.h>(Para funções comomalloc)<string.h>(Para funções comostrlen)Exemplo de uso recomendado:
Qual é o especificador de formatos para ele no
printf?O especificador correto para
size_tnoprintfé%zu(recomendado, portável e seguro).Exemplo de uso recomendado:
Alternativas (não portáveis e não recomendadas):
%lu(sesize_tforunsigned long)%u(sesize_tforunsigned int)Essas alternativas devem ser evitadas, pois elas podem causar comportamento indefinido em sistemas onde
size_tnão corresponde ao tipo assumido.4. Compile, corrija e responda
O programa abaixo deveria imprimir 0.25 no terminal…
Responda:
Depois de compilado e executado, qual foi o valor impresso?
O programa imprime 0 e não 0.25 como esperado.
Por que isso aconteceu?
O problema está na linha
"int valor = 1 / 4;", pois ocorre uma divisão inteira, já queint / int = int.Quando ambos os operandos são inteiros (1 e 4), o C realiza uma divisão inteira, descartando a parte fracionária.
1 / 4resulta em quociente 0 e resto 1, por isso o resultado foi 0.Como solucionar?
Existem pelo menos 2 formas de corrigir.
Solução 1. Usar
floatoudoubleem pelo menos um operando decimal, pois se um dos operandos é de ponto flutuante (float/double), a divisão será de ponto flutuante.Exemplo:
Solução 2. Converter explicitamente um operando para
float/doubleusando casting.Exemplo:
5. Analise, pesquise e comente o código
Programa dump.c:
Solução
Saída:
Observações:
Em
"(unsigned long)num * num;"o cast força a multiplicação a ser feita emunsigned long(64 bits), evitando overflow.A função
print_bytesconverteaddrparaunsigned char*(byte a byte).Saídas esperadas para
num = 100000(little-endian):num(int, 4 bytes):0x000186a0→ Bytes:a0 86 01 00a0 86 01 00 00 00 00 00sqr_int(overflow):10.000.000.000em 32 bits é truncado para0x540BE400e vira o decimal1.410.065.408. Bem menor que o valor esperado.00 e4 0b 54 00 00 00 00sqr_long(64 bits):10.000.000.000em 64 bits é representado integralmente como0x00000002540BE40000 e4 0b 54 02 00 00 00Problemas e soluções:
Overflow em
sqr_int:int(32 bits) não consegue armazenar10.000.000.000long longouunsigned longdesde o inícioPortabilidade:
longvaria (32/64 bits)uint64_t(do<stdint.h>) para precisãoSugestões de Melhoria
1. Adicionar Verificação de Overflow:
2. Usar Tipos de Tamanho Fixo: