mirror of
https://gitlab.com/blau_araujo/cblc.git
synced 2025-05-09 10:16:35 -03:00
conteúdo da aula 3
This commit is contained in:
parent
f8cccca463
commit
d85cf6d346
7 changed files with 321 additions and 1 deletions
|
@ -15,10 +15,11 @@ qualquer distribuição.
|
|||
- [[./aulas][Exemplos utilizados nas aulas]].
|
||||
- [[./c17/iso-iec-9899-2017.pdf][Especificações C17]] (PDF em inglês).
|
||||
- [[./c23/iso-iec-9899-2024.pdf][Especificações C23]] (PDF em inglês).
|
||||
- [[https://fiorix.wordpress.com/wp-content/uploads/2014/04/o-fantc3a1stico-mundo-da-linguagem-c.pdf][O Fantástico Mundo da Linguagem C - Alexandre Firori]] (PDF).
|
||||
|
||||
** Anotações e vídeos
|
||||
|
||||
- 10.03.2025 [[./aulas/00-intro/README.org][Aula 0: Sobre o curso]] ([[https://youtu.be/RZmfuuABTHY][vídeo]])
|
||||
- 12.03.2025 [[./aulas/01-historia/README.org][Aula 1: História]] ([[https://youtu.be/wqJQL5W9FIw][vídeo]]) ([[./exercicios/01/README.org][exercícios]])
|
||||
- 14.03.2025 [[./aulas/02-dados-e-instrucoes/README.org][Aula 2: Dados e instruções]] ([[https://youtu.be/2KsvRJjshQ0][vídeo]]) ([[./exercicios/02/README.org][exercícios]])
|
||||
|
||||
- 17.03.2025 [[./aulas/03-tipos-de-dados/README.org][Aula 3: Tipos de dados]] ([[https://youtu.be/iMiRzZCU7hE][vídeo]]) ([[./exercicios/03/README.org][exercícios]])
|
||||
|
|
235
aulas/03-tipos-de-dados/README.org
Normal file
235
aulas/03-tipos-de-dados/README.org
Normal file
|
@ -0,0 +1,235 @@
|
|||
#+title: Curso Básico da Linguagem C
|
||||
#+subtitle: Aula 3: Tipos de dados
|
||||
#+author: Blau Araujo
|
||||
#+startup: show2levels
|
||||
#+options: toc:3
|
||||
|
||||
* Aula 3: Tipos de dados
|
||||
|
||||
- [[https://youtu.be/iMiRzZCU7hE][Vídeo desta aula]]
|
||||
- [[https://fiorix.wordpress.com/wp-content/uploads/2014/04/o-fantc3a1stico-mundo-da-linguagem-c.pdf][O Fantástico Mundo da Linguagem C - Alexandre Firori]]
|
||||
|
||||
** Exemplo da última aula (=quadrado.c=)
|
||||
|
||||
#+begin_src c
|
||||
#include <stdio.h>
|
||||
|
||||
int quadrado(int base) {
|
||||
return base * base;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int num = 100000;
|
||||
|
||||
printf("%d^2 = %d\n", num, quadrado(num));
|
||||
return 0;
|
||||
}
|
||||
#+end_src
|
||||
|
||||
O que há de novo:
|
||||
|
||||
~int num = 100000;~ → A base será 100.000
|
||||
|
||||
Compilando e executando...
|
||||
|
||||
#+begin_example
|
||||
:~$ gcc quadrado.c
|
||||
:~$ ./a.out
|
||||
100000^2 = 1410065408
|
||||
#+end_example
|
||||
|
||||
O resultado está obviamente errado!
|
||||
|
||||
** Tipos são tamanhos de dados na memória
|
||||
|
||||
- Bit: algarismos 0 ou 1;
|
||||
- Byte: 8 bits;
|
||||
- Tipo =int=: 32 bits == 4 bytes (arquitetura x86_64).
|
||||
|
||||
*** Maior número que se pode escrever com 4 bytes (32bits):
|
||||
|
||||
#+begin_example
|
||||
(2^32) - 1 = 4.294.967.295
|
||||
#+end_example
|
||||
|
||||
Quadrado de 100.000:
|
||||
|
||||
#+begin_example
|
||||
100.000^2 = 10.000.000.000
|
||||
#+end_example
|
||||
|
||||
*** O que aconteceu?
|
||||
|
||||
Bytes necessários para escrever 10.000.000.000:
|
||||
|
||||
#+begin_example
|
||||
:~$ printf '0x%016x\n' 10000000000
|
||||
0x00000002540be400
|
||||
↑
|
||||
5 bytes
|
||||
#+end_example
|
||||
|
||||
Bytes truncados pelo limite do tipo =int= (4 bytes):
|
||||
|
||||
#+begin_example
|
||||
:~$ printf '0x%016x\n' 1410065408
|
||||
0x00000000540be400
|
||||
↑
|
||||
4 bytes
|
||||
#+end_example
|
||||
|
||||
Precisamos de mais espaço para escrever o resultado:
|
||||
|
||||
| Tipo | Tamanho | Faixa de valores |
|
||||
|-------+---------+--------------------------------------------------------|
|
||||
| =char= | 1 byte | -128 a 127 |
|
||||
| =short= | 2 bytes | -32.768 a 32.767 |
|
||||
| =int= | 4 bytes | -2.147.483.648 a 2.147.483.647 |
|
||||
| =long= | 8 bytes | -9.223.372.036.854.775.808 a 9.223.372.036.854.775.807 |
|
||||
|
||||
Todos esses tipos consideram o uso de valores com sinal!
|
||||
|
||||
** Exemplo corrigido (=quadrado-long.c=)
|
||||
|
||||
#+begin_src c
|
||||
#include <stdio.h>
|
||||
|
||||
unsigned long quadrado(long base) {
|
||||
return base * base; /* Qual é o tipo dessa expressão? */
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
long num = 100000;
|
||||
|
||||
printf("%ld^2 = %lu\n", num, quadrado(num));
|
||||
return 0;
|
||||
}
|
||||
#+end_src
|
||||
|
||||
## Compilando e executando...
|
||||
|
||||
#+begin_example
|
||||
:~$ gcc quadrado-long.c
|
||||
:~$ ./a.out
|
||||
100000^2 = 10000000000
|
||||
#+end_example
|
||||
|
||||
** Tipos primitivos
|
||||
|
||||
| Tipo | Tamanho | Faixa de valores (x86_64) |
|
||||
|--------+---------+--------------------------------|
|
||||
| =char= | 1 byte | -128 a 127 |
|
||||
| =short= | 2 bytes | -32.768 a 32.767 |
|
||||
| =int= | 4 bytes | -2.147.483.648 a 2.147.483.647 |
|
||||
| =float= | 4 bytes | 1,18E-38 a 3,40E+38 |
|
||||
| =double= | 8 bytes | 2,23E-308 a 1,80E+308 |
|
||||
|
||||
*** Qualificador =unsigned= (sem sinal):
|
||||
|
||||
| Tipo | Tamanho | Faixa de valores (x86_64) |
|
||||
|----------------+---------+---------------------------|
|
||||
| =unsigned char= | 1 byte | 0 a 255 |
|
||||
| =unsigned short= | 2 bytes | 0 a 65.535 |
|
||||
| =unsigned int= | 4 bytes | 0 a 4.294.967.295 |
|
||||
|
||||
*** Qualificador =long=:
|
||||
|
||||
| Tipo | Tamanho | Faixa de valores (x86_64) |
|
||||
|---------------+----------+--------------------------------------------|
|
||||
| =long= | 8 bytes | -9223372036854775808 a 9223372036854775807 |
|
||||
| =unsigned long= | 8 bytes | 0 a 18446744073709551615 |
|
||||
| =long double= | 16 bytes | 3,36E-4932 a 1,19E+4932 |
|
||||
|
||||
** Tipos customizados
|
||||
|
||||
Nós podemos criar apelidos para tipos:
|
||||
|
||||
#+begin_example
|
||||
typedef [QUALIFICADORES] TIPO NOME;
|
||||
#+end_example
|
||||
|
||||
*** Exemplos:
|
||||
|
||||
#+begin_src c
|
||||
typedef int i32;
|
||||
typedef unsigned int u32;
|
||||
typedef long int i64;
|
||||
typedef unsigned long int u64;
|
||||
#+end_src
|
||||
|
||||
Para diferenciar de nomes de variáveis, é comum utilizar o sufixo =_t= (de /type/):
|
||||
|
||||
#+begin_src c
|
||||
typedef int i32_t;
|
||||
typedef unsigned int u32_t;
|
||||
typedef long int i64_t;
|
||||
typedef unsigned long int u64_t;
|
||||
#+end_src
|
||||
|
||||
** Expressões constantes (valores literais)
|
||||
|
||||
| EXPRESSÃO | TIPO |
|
||||
|-----------+--------------------------|
|
||||
| =42= | =int= |
|
||||
| =42U= | =unsigned int= |
|
||||
| =42L= | =long int= |
|
||||
| =42UL= | =unsigned long int= |
|
||||
| =42LL= | =long long int= |
|
||||
| =42ULL= | =unsigned long long int= |
|
||||
| ='a'= | =int= |
|
||||
| =12.3= | =double= |
|
||||
| =1e16= | =double= |
|
||||
| =12.3F= | =float= |
|
||||
| =1e16F= | =float= |
|
||||
| =12.3L= | =long double= |
|
||||
| =1e16L= | =long double= |
|
||||
| ="salve"= | =unsigned long= (endereço) |
|
||||
|
||||
** O tipo =void=
|
||||
|
||||
No contexto de declarações de funções, =void= representa a ausência de tipo,
|
||||
mas pode ter outros significados.
|
||||
|
||||
*** Funções sem valor de retorno:
|
||||
|
||||
#+begin_src c
|
||||
void func(int num) {
|
||||
printf("num x 2 = %d\n", num * 2);
|
||||
}
|
||||
#+end_src
|
||||
|
||||
#+begin_quote
|
||||
Retorno não é o que a função imprime, mas o valor que ela expressa!
|
||||
#+end_quote
|
||||
|
||||
*** Funções que não recebem argumentos:
|
||||
|
||||
#+begin_src c
|
||||
int func(void) {
|
||||
puts("Nada a fazer...");
|
||||
return 42;
|
||||
}
|
||||
#+end_src
|
||||
|
||||
*** Ponteiros de dados de tipo indeterminado:
|
||||
|
||||
#+begin_src c
|
||||
void *ptr;
|
||||
#+end_src
|
||||
|
||||
#+begin_quote
|
||||
Ponteiros são variáveis que recebem endereços da memória (aula 5).
|
||||
#+end_quote
|
||||
|
||||
** Modelagem de tipos (type casting)
|
||||
|
||||
/Type casting/ é a conversão explícita de um tipo de dado para outro, utilizando
|
||||
a sintaxe =(TIPO)= antes de um valor ou de uma variável:
|
||||
|
||||
Exemplo:
|
||||
|
||||
#+begin_src c
|
||||
(double)5 /* O inteiro '5' será compilado como 'double'. */
|
||||
#+end_src
|
||||
|
||||
|
33
aulas/03-tipos-de-dados/dump.c
Normal file
33
aulas/03-tipos-de-dados/dump.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
#include <stdio.h>
|
||||
|
||||
void print_bytes(char *label, void *addr, size_t size);
|
||||
|
||||
int main(void) {
|
||||
|
||||
int num = 100000;
|
||||
|
||||
int sqr_int = num * num;
|
||||
unsigned long sqr_long = (unsigned long)num * num;
|
||||
|
||||
print_bytes("num ", &num, sizeof(num));
|
||||
printf("-> %d\n", num);
|
||||
|
||||
print_bytes("sqr_int ", &sqr_int, sizeof(sqr_int));
|
||||
printf("-> %d\n", sqr_int);
|
||||
|
||||
print_bytes("sqr_long", &sqr_long, sizeof(sqr_long));
|
||||
printf("-> %lu\n", sqr_long);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void print_bytes(char *label, void *addr, size_t size) {
|
||||
|
||||
unsigned char *bytes = (unsigned char *)addr;
|
||||
|
||||
printf("%p - %s - ", bytes, label);
|
||||
|
||||
for (size_t i = 0; i < 8; i++)
|
||||
printf("%02x ", i > (size - 1) ? 0 : bytes[i]);
|
||||
}
|
27
aulas/03-tipos-de-dados/limites.c
Normal file
27
aulas/03-tipos-de-dados/limites.c
Normal file
|
@ -0,0 +1,27 @@
|
|||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <float.h>
|
||||
#include <locale.h>
|
||||
|
||||
int main(void) {
|
||||
|
||||
setlocale(LC_NUMERIC, "");
|
||||
|
||||
puts("Tipo Bytes Limites");
|
||||
puts("========================================================================");
|
||||
printf("char (%zu) %d a %d\n", sizeof(char), SCHAR_MIN, SCHAR_MAX);
|
||||
printf("unsigned char (%zu) %d a %d\n", sizeof(unsigned char), 0, UCHAR_MAX);
|
||||
printf("short (%zu) %'d a %'d\n", sizeof(short), SHRT_MIN, SHRT_MAX);
|
||||
printf("unsigned short (%zu) %d a %'d\n", sizeof(unsigned short), 0, USHRT_MAX);
|
||||
printf("int (%zu) %'d a %'d\n", sizeof(int), INT_MIN, INT_MAX);
|
||||
printf("unsigned int (%zu) %d a %'u\n", sizeof(unsigned int), 0, UINT_MAX);
|
||||
printf("long int (%zu) %'ld a %'ld\n", sizeof(long int), LONG_MIN, LONG_MAX);
|
||||
printf("unsigned long int (%zu) %d a %'lu\n", sizeof(long unsigned int), 0, ULONG_MAX);
|
||||
printf("long long (%zu) %'ld a %'ld\n", sizeof(long long int), LLONG_MIN, LLONG_MAX);
|
||||
printf("unsigned long long (%zu) %d a %'llu\n", sizeof(unsigned long long int), 0, ULLONG_MAX);
|
||||
printf("float (%zu) %.2E a %.2E\n", sizeof(float), FLT_MIN, FLT_MAX);
|
||||
printf("double (%zu) %.2E a %.2E\n", sizeof(double), DBL_MIN, DBL_MAX);
|
||||
printf("long double (%zu) %.2LE a %.2LE\n", sizeof(long double), LDBL_MIN, LDBL_MAX);
|
||||
|
||||
return 0;
|
||||
}
|
12
aulas/03-tipos-de-dados/quadrado-long.c
Normal file
12
aulas/03-tipos-de-dados/quadrado-long.c
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include <stdio.h>
|
||||
|
||||
unsigned long quadrado(long base) {
|
||||
return base * base; /* Qual é o tipo desse expressão? */
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
long num = 100000;
|
||||
|
||||
printf("%ld^2 = %lu\n", num, quadrado(num));
|
||||
return 0;
|
||||
}
|
12
aulas/03-tipos-de-dados/quadrado.c
Normal file
12
aulas/03-tipos-de-dados/quadrado.c
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int quadrado(int base) {
|
||||
return base * base;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int num = 100000;
|
||||
|
||||
printf("%d^2 = %d\n", num, quadrado(num));
|
||||
return 0;
|
||||
}
|
0
exercicios/03/README.org
Normal file
0
exercicios/03/README.org
Normal file
Loading…
Add table
Reference in a new issue