Tipos fundamentais
Anteriormente vimos que funções, parâmetros e variáveis podem representar diferentes tipos de dados. Alguns tipos já estão embutidos na linguagem, e serão chamados de tipos fundamentais. Esse grupo inclui os tipos inteiros e os tipos flutuantes, que podem ser vistos abaixo.
Tipos inteiros
Tipo int
Representa um número inteiro, como -30
ou 529
. O menor e maior número
representável em um int
não está definido no padrão C, mas um int
representará, no mínimo, qualquer número inteiro no intervalo [-32767,32767].
Tipo char
Representa um caractere, como ' '
(espaço em branco), 's'
(letra "s") ou ?
(ponto de interrogação). Os caracteres em C devem estar dentro de aspas simples;
"a"
é uma string.
char foo = 'a'; // Okay
char bar = "a"; // Erro
Sequências de escape
Alguns caracteres não podem ser simplesmente digitados, portanto são
representados utilizando sequências de escape, nesse caso uma barra
invertida \
seguida de um caractere. Na tabela abaixo estão algumas sequências
de escape.
Sequência | Descrição |
---|---|
\a | Produz um alerta audível ou visual |
\n | Produz uma quebra de linha |
\' | Produz uma aspa simples |
Tentar armazenar uma aspa simples em um char
pode ser complicado, pois em
char ch = ''';
o compilador procura um caractere contido entre o primeiro par
de aspas, porém não há nada dentro. Nesse caso devemos utilizar a sequência de
escape \'
: char ch = '\'';
.
char ch = '''; // Erro
char ch = '\''; // Okay
Conversões para outros tipos inteiros
Valores char
são internamente representados por valores inteiros, e o valor de
cada caractere depende do sistema. Muitos sistemas utilizam o conjunto de
caracteres ASCII, parcialmente mostrado na tabela abaixo.
Valor | Caractere | Valor | Caractere | Valor | Caractere |
---|---|---|---|---|---|
32 | (espaço) | 65 | A | 97 | a |
48 | 0 | 66 | B | 98 | b |
49 | 1 | 67 | C | 99 | c |
50 | 2 | 68 | D | 100 | d |
51 | 3 | 69 | E | 101 | e |
52 | 4 | 70 | F | 102 | f |
53 | 5 | 71 | G | 103 | g |
54 | 6 | 72 | H | 104 | h |
55 | 7 | 73 | I | 105 | i |
56 | 8 | 74 | J | 106 | j |
57 | 9 | 75 | K | 107 | k |
Quando um valor char
é convertido para outro tipo inteiro (e.g. int
), o
resultado é o valor inteiro que representa o caractere no conjunto de caracteres
utilizado. Quando um tipo inteiro é convertido para char
, o resultado é o
caractere que representa o valor inteiro no conjunto de caracteres utilizado.
char ch = 65; // ch é igual a 'A' se o conjunto de caracteres for ASCII
int i = 'A'; // i é igual a 65 se o conjunto de caracteres for ASCII
Caracteres entre aspas simples, como 'a'
, possuem tipo int
. Esse detalhe não
costuma ser problemático pois um valor int
pode ser implicitamente convertido
para char
.
Tipo _Bool
Em C, _Bool
é equivalente ao bool
de outras linguagens de programação, mas
possui outro nome pois esse tipo foi adicionado no padrão C99 e usar o nome
bool
poderia quebrar programas antigos.
O tipo _Bool
serve para armazenar um de dois valores: verdadeiro ou falso.
Aqui está um exemplo de duas variáveis _Bool
, com valores que indicam,
respectivamente, verdade e falsidade:
_Bool verdadeiro = 1;
_Bool falso = 0;
Utilizar a palavra-chave _Bool
pode não ser intuitivo. Por conveniência, é
recomendado incluir o arquivo <stdbool.h>
, que faz com que bool
se refira a
_Bool
e permite utilizar as palavras true
(verdadeiro) e false
(falso).
Veja o mesmo código que no exemplo anterior acima porém utilizando
<stdbool.h>
:
bool verdadeiro = true;
bool falso = false;
Sempre que bool
, true
ou false
forem utilizados neste livro, considere que
a diretiva #include <stdbool.h>
está presente mesmo que em alguns exemplos ela
possa estar omitida por conveniência. É útil lembrar, também, que true
se
refere ao valor 1
e false
ao valor 0
.
Um exemplo do uso de bool
são predicados (termo comum para funções que
retornam true
ou false
). Suponhamos que a função Paridade
seja um
predicado que verifica a paridade de um número, retornando true
caso ele seja
par e false
caso contrário.
Paridade(1); // false
Paridade(3); // false
Paridade(5); // false
Paridade(2); // true
Paridade(4); // true
Paridade(6); // true
Tipos flutuantes
Tipo double
Representa um número real, como -30.52
ou 529.0023
. Ao ser convertido para
um inteiro a parte fracionária é descartada, portanto 15.89
se torna 15
. Se
o valor for alto/baixo demais para ser representado por um int
, o
comportamento é indefinido.
double d = 2.5; // d é igual a 2.5
int i = 2.5; // i é igual a 2
Tipo float
Representa um número real assim como double
, mas os valores representáveis em
um float
são um subconjunto dos valores representáveis em um double
. Isso
significa que um float
pode ter menos precisão e/ou não conseguir representar
valores da mesma magnitude que um double
.
Um f
ou F
após um valor flutuante (e.g. 1.5f
) especifica que o valor é do
tipo float
.
float f = 2.5f; // f é igual a 2.5
Tipo long double
Representa um número real assim como double
, mas os valores representáveis em
um long double
são um superconjunto dos valores representáveis em um double
.
Isso significa que um long double
pode ter mais precisão e/ou conseguir
representar valores de maior magnitude que um double
.
Um l
ou L
após um valor flutuante (e.g. 1.5l
) especifica que o valor é do
tipo long double
.
long double ld = 2.5l; // ld é igual a 2.5
Tipos flutuantes podem não representar todos os valores com precisão, mesmo que estejam entre o valor mínimo e o valor máximo permitidos.
Em geral, quanto mais dígitos um valor possuir, menos precisa será sua
representação. O valor 1.00000001f
, por exemplo, pode se tornar 1.f
em
algumas implementações.