Tipos de Dados em C++

Introdução ao Tipos de Dados em C++

Por Fábio dos Reis

A linguagem C++ é uma linguagem fortemente tipada. Isso significa que cada variável no programa possui um tipo associado a ela, que define o que ela pode armazenar. O compilador realiza verificação rígida dos tipos ao compilar um programa em C++ para assegurar que o tipo correto esteja sendo usado e que os tipos sejam compatíveis quando combinados entre si (por exemplo, em cálculos).

Existem sete tipos de dados básicos ou fundamentais em C++, chamados de Tipos Primitivos. A tabela a seguir mostra os tipos básicos primitivos em C++, com a palavra-chave usada em sua declaração e o tamanho em bytes ocupado por cada elemento do tipo na memória RAM:

Tipo Descrição Faixa de valores Tamanho (bytes)
int Inteiro -2.147.483.648 a -2.147.483.647 2 ou 4
float Ponto Flutuante, 7 dígitos de precisão -3,4 x 1038 a 3,4 x 1038 4
double Ponto Flutuante Duplo, 15 dígitos de precisão -1,7 x 10308 a 1,7 x 10308 8
char Caractere caracteres 1
wchar_t Caractere Ampliado
bool Lógico true | false 1
void Sem Valor (usado em funções que não retornam valores)

Os tipos numéricos ou aritméticos que usamos em C++ são divididos em duas grandes categorias: tipos inteiros (números inteiros) e tipos de ponto flutuante (números fracionários). Existem diversos tipos de dados em cada uma dessas categorias, cada um com uma faixa de valores permitida (quantidade de valores possíveis) que o tipo pode armazenar.

Modificadores de Tipo

Um modificador é uma palavra-chave acrescentada ao nome de um tipo em sua declaração, que permite modificar seu comportamento de duas formas:

  • Estendendo a faixa de valores suportada pelo tipo
  • Permitindo ou não o emprego de números negativos (com sinal).

Alguns dos tipos básicos podem ser estendidos usando os seguintes modificadores e suas combinações:

  • Long
  • Short
  • Unsigned
  • Signed

Basicamente, esses modificadores expandem os valores mínimo e máximo da faixa de valores de cada tipo e determinam se os valores podem ser negativos ou somente positivos.

Tipos com sinal – signed

Um tipo com sinal (“signed”) é um tipo que permite a representação de valores positivos e negativos. É empregado quando precisamos armazenar valores negativos em um programa.

Um exemplo é o armazenamento de temperaturas – podemos armazenar tanto valores positivos como +32°C (temperatura real no momento em que escrevo esse artigo!) quanto temperaturas negativas como -15°C.

Por exemplo, o tipo int permite a faixa de valores de –2.147.483.648 a +2.147.483.647. A tabela a seguir mostra os tipos inteiros disponíveis em C++ incluindo a aplicação dos modificadores:

Tipo Faixa de Valores Tamanho em bytes (típico)

char

-128 a +127 1

short
short int
signed short
signed short int

-32768 a +32767 2

int
signed int

-2.147.483.648 a +2.147.483.647 4
long
long int
signed long
signed long int
igual a int ou long long
(depende da implementação)
4 ou 8
(a partir do C++11)
long long
long long int
signed long long
signed long long int
-9223372036854775808 a +9223372036854775807 8

Na tabela acima, temos os nomes de tipos na coluna à esquerda e, como podemos ver, alguns nomes são compostos por mais de uma palavra. Sempre que possível usamos o nome mais curto disponível para o tipo em questão.

Assim, é muito comum usar, por exemplo, “long” do que “signed long int”, que representa o mesmo tipo (porém de forma mais explícita e melhor documentada).

O modificador signed para números inteiros é, na verdade, opcional. Se for omitido, o valor terá sinal por padrão.

Tipos sem sinal – unsigned

Já um tipo sem sinal (“unsigned”) somente permite a representação de números positivos, no mesmo espaço de armazenamento, tendo portanto uma faixa de valores positivos estendida. É usado, como podemos imaginar, quando não há a necessidade de armazenar números negativos no programa.

Um exemplo é o armazenamento da idade de uma pessoa – as idades são sempre números positivos; você pode ter 30 anos de idade, mas nunca -30 anos!

A tabela a seguir mostra os tipos inteiros em C++ sem sinal:

Tipo Faixa de Valores Tamanho em bytes (típico)
unsigned char 0 a 255 1
unsigned short 0 a 65535 2
unsigned int 0 a 4294967295 4
unsigned long
unsigned long int
igual a unsigned int ou unsigned long long
(depende da implementação)
4 ou 8
unsigned long long
unsigned long long int
0 a 18446744073709551615 8

Para criar um tipo sem sinal devemos obrigatoriamente usar a palavra-chave unsigned antes do nome do tipo em si, como no exemplo a seguir:

unsigned short int // Tipo inteiro curto sem sinal

Números de Ponto Flutuante

Números de ponto flutuante permitem representar valores fracionários, positivos e negativos, como 3.1415 ou -9.345464576, além de permitirem o armazenamento de valores muito grandes (ou muito pequenos), em faixas de valores bem maiores que as possíveis com números inteiros.

Um número de ponto flutuante normalizado consiste em duas partes: uma mantissa e um expoente. A magnitude de um número é o valor da mantissa multiplicado por 10 elevado à potência do expoente.

Por exemplo, o número de dias em um ano típico, 365, pode ser escrito como um valor de ponto flutuante de precisão fixa em notação E (exponencial / científica) da seguinte forma:

3.650000E02

Aqui, a mantissa tem sete valores decimais (float – precisão fixa) e o expoente possui dois. A letra ‘E‘ significa “vezes dez elevado a“, significando que o valor 3.650000 multiplica 10 elevado a 02 (102). Ou seja:

3.650000 x 10 x 10 = 3.650000 x 100 = 365 (ignorando os zeros).

Note que o valor do expoente – 02 –  é um valor positivo. Por padrão, não precisamos especificar o sinal do expoente se for positivo, como fizemos no exemplo. Mas se o valor for negativo, é obrigatório indicar seu sinal – e podemos indicar se for positivo também, para maior clareza de representação. Veja os exemplos do mundo real:

Carga elementar (elétron): 1.602 × 10-19  = 1.602E-19

Constante de Avogadro: 6.022 x 1023 = 6.022E23

Podemos usar essa notação ao definir constantes de ponto flutuante ou ainda valores literais em um programa (diretamente no código-fonte). A letra E pode ser maiúscula ou minúscula, não importando seu caso.

Os tipos de ponto flutuante disponíveis em C++ são:

Tipo Faixa de Valores Tamanho em bytes
float 1.17549 x 10-38 a 3.40282 x 1038 4
double 2.22507 x 10-308 a 1.79769 x 10308 8
long double Depende da implementação. Em meu sistema (Win 10 64 bits), por exemplo, os limites são:
3.3621 x 10-4932 a 1.18973 x 104932
10, 12 ou 16

O tipo float possui 7 dígitos de precisão (tamanho da mantissa), ao passo que o tipo double possui 15 dígitos de precisão (ou seja, precisão dupla). O arquivo de cabeçalho float.h informa os valores de bytes, expoente e precisão para os tipos de ponto flutuante do sistema em particular que você está usando.

Para descobrir os limites das faixas de valores dos tipos float, double e long double em seu sistema, você pode rodar o seguinte programa C++:

#include <iostream>
#include <limits>
using namespace std;
int main()
{
cout << "Tipo\t\tValor Min\tValor Max\n\n"
 << "Float" << '\t' << '\t' << std::numeric_limits<float>::min() << '\t'
   << std::numeric_limits<float>::max() << '\n'
 << "Double" << '\t' << '\t' << std::numeric_limits<double>::min() << '\t'
   << std::numeric_limits<double>::max() << '\n'
 << "Long Double" << '\t'<< std::numeric_limits<long double>::min() << '\t'
   << std::numeric_limits<long double>::max() << '\n';
return 0;
}

Veja o resultado do código anterior em meu sistema:

Tipos de ponto flutuante em C++

A escolha do tipo correto de dados é importante em seus programas para garantir que seja possível representar os dados de maneira eficiente e correta. Alguns exemplos disso incluem:

  • usar o tipo short em vez de int se o intervalo de dados permitir
  • usar double em vez de float para obter maior precisão para valores monetários (que representam dinheiro)
  • usar um wchar_t para dados de caractere que não estão incluídos no conjunto de caracteres ASCII padrão, como por exemplo o Kanji japonês

Outros tipos de dados em C++ incluem os tipos de dados definidos pelo usuário (enum, structure, union e class) e tipos de dados derivados (array, ponteiro, referência), entre outros, que estudaremos em um momento oportuno.

Nas próximas lições vamos abordar de forma mais aprofundada conceitos como valores literais, os tipos char, wchar_t e bool, constantes, variáveis e outros.

Referências

  • HORTON, I.; VAN WEERT, P. Beginning C++ 17 From Novice to Professional. 5ª edição. 2018. Editora Apress.
  • PRATA, S. C++ Primer Plus. 6ª edição. 2012. Editora Addison-Wesley.

 

Sobre Fábio dos Reis (1207 Artigos)
Fábio dos Reis trabalha com tecnologias variadas há mais de 30 anos, tendo atuado nos campos de Eletrônica, Telecomunicações, Programação de Computadores e Redes de Dados. É um entusiasta de Ciência e Tecnologia em geral, adora Viagens e Música, e estuda idiomas, além de ministrar cursos e palestras sobre diversas tecnologias em São Paulo e outras cidades do Brasil.

1 Comentário em Tipos de Dados em C++

  1. Clóvis Adriano Vianna // 27/05/2021 em 9:06 // Responder

    Bom dia Fábio,
    Tudo bem?
    Será que na primeira tabela não há algo estranho? Os dados do tipo primitivo int têm apenas uma faixa negativa de “-2.147.483.648 a -2.147.483.647”.
    Até mais.

Escreva um comentário

Seu e-mail não será divulgado


*