Variáveis e Tipos de Dados
Armazenamento de informações para uso do programa.
Memória
A memória do computador é uma sequência de bilhões de espaços para guardar informação, cada um, necessariamente, preenchido ou com 0 ou com 1. Números, palavras e até imagens podem ser armazenados apenas com sequências de 0's e 1's. Um valor binário (0 ou 1) da memória é chamado de bit e 8 bits formam um byte.
Nome | Símbolo | Tamanho |
---|---|---|
Bit | b | 1 bit |
Byte | B | 8b |
KiloByte | KB | 1024B |
MegaByte | MB | 1024KB |
GigaByte | GB | 1024MB |
TeraByte | TB | 1024GB |
Uma das capacidades mais fundamentais de um programa é reservar um espaço da memória para o programa usar.
Variáveis
Uma variável é um espaço de memória que seu programa reserva e nomeia para uso.
Em algumas linguagens, não é preciso especificar o tipo de informação que será armazenada na variável (número, caractere, etc.). Porém, o C++ é uma linguagem fortemente tipada, isto é, os tipos das informações armazenadas nas variáveis devem ser conhecidos em tempo de compilação.
Portanto, uma variável em C++ sempre tem um tipo, um nome e um valor.
Criar uma variável é chamado de declarar uma variável, e pode ser feito com um comando da forma:
Para armazenar o número de estados brasileiros, por exemplo, pode-se escrever:
Acima, declaramos uma variável do tipo int
, que armazena números inteiros, cujo nome é estados_brasileiros
e atribuímos um valor inicial de 26 a ela.
Note que em momento algum temos de lidar com valores binários. Os nomes e valores são todos traduzidos para linguagem de máquina no momento da compilação. Essa é a razão de existência das linguagens de programação.
Podemos, também, declarar múltiplas variáveis do mesmo tipo. Seus nomes devem ser separados por vírgula, como abaixo:
Ou como comandos separados:
Os códigos acima têm o mesmo efeito.
Inicialização
A inicialização de uma variável é o armazenamento de um valor nela no momento de sua criação.
É possível declarar uma variável e não inicializá-la:
Porém, uma variável sempre contém um valor. O valor armazenado na variável, nesse caso, é o valor que estava naquele espaço da memória antes de sua declaração. Esse valor pode ser diferente a cada execução do programa, já que nem sempre o mesmo espaço de memória é reservado.
A valores obtidos dessa maneira damos o nome de lixo. Bugs cuja causa são variáveis não inicializadas podem ser difíceis de encontrar; deixar variáveis não inicializadas é uma má prática de programação.
Nomes de Variáveis
Existem algumas restrições quanto à nomenclatura de variáveis. Nomes de variáveis:
- devem conter apenas letras, números e
_
; - não podem começar com um número;
- não podem ser palavras reservadas da linguagem, como
if
, por exemplo.
Duas variáveis não podem ter o mesmo nome dentro do mesmo escopo. Por enquanto, o escopo é tudo o que está dentro da main
. Além disso, letras maiúsculas e minúsculas identificam variáveis únicas, isto é, a variável minha_variavel
é diferente da variável Minha_variavel
.
Por convenção, nomes de variáveis com mais de uma palavra são nomeados, por todo o programa, de uma de duas formas:
- snake_case: letras minúsculas com palavras separadas por
_
- camelCase: letras maiúsculas no início de cada palavra exceto a primeira
Tipos de dados
O tipo de uma variável determina:
- quanta memória é reservada para a variável;
- quais operações podem ser realizadas na variável (soma, concatenação, etc.).
Seguem os tipos de dados mais simples do C++, os tipos primitivos.
int
O tipo int
serve para o armazenamento de números inteiros. Seguem alguns exemplos de declarações de int
:
float
e double
Os tipos float
e double
servem para o armazenamento de números decimais. Seguem alguns exemplos de declarações de float
e double
:
float pi = 3.14;
double altura = 1.7012345;
double planetas = -8;
float distancia = 2e9; // podem ser declarados em notação científica
char
O tipo char
serve para o armazenamento de caracteres. Seguem alguns exemplos de declarações de char
:
Note que caracteres são escritos entre aspas simples ' '
.
Internamente, o tipo char
é armazenado similar a um int
. Na prática, um char
é um int
que tem um símbolo associado ao ser lido e escrito. Qual inteiro é associado a qual caractere é determinado pela tabela ASCII.
Esse comportamento, dentre outras coisas, permite que se inicialize caracteres de acordo com seus respectivos números:
bool
O tipo bool
armazena um estado que pode ser true
(verdadeiro) ou false
(falso):
void
O tipo void
indica a ausência de tipo. Ele será útil apenas na seção de funções.
Modificadores de sinal
Os modificadores signed
e unsigned
se aplicam aos tipos int
e char
e servem para tirar ou manter o sinal dos números.
Sua função é estender um pouco o intervalo de números que pode ser armazenado por um tipo, ao retirar a necessidade de armazenar um bit de sinal. Porém, pode causar resultados inesperados com uso descuidado.
Por padrão, o modificador signed
é usado na omissão de modificador de sinal:
signed int i = -2;
unsigned int ui = 10;
unsigned char c = 'a';
unsigned char uc = '2';
unsigned int cuidado = -10; // armazena 4294967286
Modificadores de tamanho
Como a memória do computador não é infinita, o espaço reservado para guardar cada variável também não é infinito. Consequentemente, os tipos int
, double
, char
e qualquer outro tipo que represente valores numéricos não podem representar números infinitamente grandes, uma vez que não há espaço para guardar infinitos dígitos.
A fim de não usar memória demais, mas também não impossibilitar a representação de números maiores, foram criados modificadores para os tipos int
e char
, que modificam a quantidade de memória reservada. Para números decimais, o tipo double
foi criado com o mesmo propósito.
Modificadores de tamanho do int
podem ser omitidos:
Segue uma tabela com os tipos primitivos e modificadores mais comuns, seus tamanhos e números que podem representar. Uma tabela completa pode ser encontrada aqui.
Tipo | Tamanho em bits | Intervalo (Aproximado) | Intervalo (Exato) |
---|---|---|---|
char |
8 | -128 a 127 | |
short int |
16 | ± 3 × 10⁴ | -32768 a 32767 |
int |
32 | ± 2 × 10⁹ | -2 147 483 648 a 2 147 483 647 |
long long int |
64 | ± 9 × 10¹⁸ | -9 223 372 036 854 775 808 a 9 223 372 036 854 775 807 |
double |
64 | ± 1.7 × 10⁻³⁰⁸ |
Modificadores de mutabilidade
Toda variável pode ter o modificador const
, que impede que ela seja modificada no futuro. Naturalmente, variáveis const
necessariamente devem ser inicializadas:
string
O tipo string
é o tipo do C++ dedicado ao tratamento de cadeias de caracteres. Ele já não é um tipo primitivo, mas é construído em cima do tipo char
. Seguem exemplos de declarações de strings:
Note que o conteúdo de strings sempre está entre aspas duplas " "
.
O tamanho de uma string
pode ser obtido com o comando .size()
:
Os caracteres de uma string são numerados, da esquerda para a direita, de 0 até string.size()-1
. Pode-se acessar um caractere específico com colchetes []
indicando a posição do caractere desejado:
Literais
Note que em diversos momentos escreve-se valores no código. Esses valores recebem o nome de literais.
short si = 1s; // literal de short
int i = 2; // literal de int
long l = 3l; // literal de long
long long ll = 4ll; // literal de long long
float f = 5f; // literal de float
double d = 6.0; // literal de double
char c = 'b'; // literal de char
string s = "Bla"; // literal de string
Caso uma variável seja inicializada com o literal de um tipo diferente, o compilador tentará converter de um tipo para outro. Tipos numéricos podem ser convertidos entre si:
Conversões de tipos
Existem dois tipos de conversões de tipos, explícitas e implícitas.
Conversões implícitas
Conversões implícitas ocorrem na presença de um tipo onde deveria haver outro. O compilador converte o tipo para o adequado automaticamente:
-
Conversões entre os tipos inteiros (
char
,int
e seus modificadores) funcionam bem desde que o valor esteja dentro do limite que o novo tipo consegue armazenar. -
Conversões de tipos inteiros para tipos decimais (
float
edouble
) sempre funcionam. -
Conversões de tipos decimais para tipos inteiros podem perder informação:
Os dígitos após a vírgula são truncados.
- Conversões de outros tipos para
bool
sãofalse
apenas se o valor for o valor nulo daquele tipo:
bool int_to_bool = 0; // false
bool char_to_bool = '\0';// false
bool double_to_bool = 0.0; // false
Conversões explícitas
Conversões explícitas são conversões solicitadas pelo programa:
Para converter entre tipos primitivos, basta o comando:
Para converter tipos primitivos para strings, a função to_string()
é utilizada:
Para converter de string
a tipos primitivos, uma vez que a string é compatível com o tipo a ser convertido, utiliza-se:
int i = stoi("4"); // string -> int
long l = stol("5"); // string -> long
long long ll = stoll("1000000000000"); // string -> long long
float f = stof("3.14"); // string -> float
double d = stod("4.6565323"); // string -> double
Outras funções de conversão numérica de string menos comuns podem ser encontradas na documentação de strings do C++.
A conversão de caracteres para int
e vice-versa é feita de acordo com o caractere na tabela ASCII. Mas isso pode não ser o desejado:
Para obter o valor desejado, pode-se operar com os valores da tabela ASCII: