Introdução
Em qualquer programa de computador, do famoso “Hello World!” ao mais complexo sistema de piloto automático de aviões, é preciso dar nome aos objetos criados no código para que se possa manipulá-los. A estes elementos do programa que atribuímos nomes e damos tipos (isto é, que declaramos) chamamos variáveis. Compreender o que são as variáveis, como é feita a declaração de variáveis em C++ e como elas funcionam torna-se portanto uma habilidade importante e necessária a qualquer um que se aventure no domínio da programação: desta ninguém escapa; nem web devs (desenvolvedores de aplicações para a internet), nem desenvolvedores de sistemas embarcados, nem tampouco desenvolvedores que trabalhem com C++.
Dada a importância das variáveis para todos os programas de computador, planejo tratar dos principais pontos acerca delas em uma série de artigos , da qual este aqui é o primeiro.
Começarei falando da declaração e da definição de variáveis em C++, e de como às variáveis se associam os tipos (explicados no artigo Tipos em C++, se você precisar refrescar a memória). Em seguida, tratarei das convenções existentes para se nomear variáveis. Nos artigos que se seguirão, então, tornarei à definição de variáveis para falar do conceito de inicialização, e explicarei como se utiliza a palavra-chave const para criar variáveis cujos valores são imutáveis após a inicialização.
Pronto? Vamos lá!
Referências
Tomei como base para escrever esse artigo a primeira metade do Capítulo 1 do livro C++ Profissional, de Marc Gregoire (que recomendo bastante) e o Capítulo 2.2 do livro C++ Primer, de Stanley B. Lippman (este é um pouco mais simples, mas também excelente – recomendo-o para iniciantes).
Declaração de variáveis em C++ – como funciona?
Ao se criar uma variável qualquer, diz-se que a variável foi declarada. A declaração de uma variável é necessária na primeira vez que tal variável aparece no código. Como se, faz, então, essa declaração? É muito simples: basta escrever o tipo da variável, seguido do nome que se lhe deseja dar, e então finalizar a instrução com um ponto-e-vírgula (;). Vejamos abaixo um exemplo de declaração de uma variável de tipo inteiro (int) chamada saldoEmConta.
// Declaração de uma variável chamada saldoEmConta de tipo int int saldoEmConta;
No exemplo anterior, a variável foi declarada, mas ela também foi definida. Agora, se assim como eu você já teve dificuldade de entender a diferença entre os dois, tentarei ajudá-lo e explicar a diferença de um modo simples: a declaração de uma variável apenas “informa” ao programa que aquele nome está reservado para aquela variável; a definição de uma variável, por sua vez, além de reservar o nome da variável no programa, também reserva a memória necessária para armezar um objeto do tipo da variável. Veja desta forma: se você fosse o computador e o programa rodasse no seu cérebro, declarar uma variável contendo o nome de uma pessoa seria apenas isto: lembrar-se de um nome, sem rosto ou qualquer outra coisa (não custa nada, certo? na verdade até isto pode ser difícil para alguns de nós!); definir uma variável contendo o nome da pessoa, contudo, seria guardar aquele nome em sua memória, mas também conhecer as características físicas daquela pessoa e saber quais são suas aptidões, que tarefas ela pode realizar no dia-a-dia – um pouco mais trabalhoso, não? É mais ou menos assim que funciona no programa do computador.
A questão parece mais clara agora? Ajuda ainda mais saber que declaração e definição de variáveis quase sempre são sinônimos, ou seja: toda definição de variável também é uma declaração, e – quase – toda declaração também é um definição. Espere um momento, quase? Como assim quase? Isso mesmo, quase. Há um caso especial em que uma declaração não é uma definição: quando se usa a palavra-chave extern. O que a palavra-chave extern permite fazer é reservar o nome da variável no programa sem alocar a memória para o tipo em questão, mas isso é assunto para um outro artigo (escreverei assim que puder um pequeno post sobre esse tema); para a maioria das situações, uma declaração também é uma definição, então daqui em diante utilizarei os dois termos como sinônimos.
A título de curiosidade, um último ponto a se saber sobre declaração e definição é o seguinte: uma variável pode ter várias declarações, mas apenas uma definição. Se quiser saber mais sobre isso, acesse o artigo sobre a palavra-chave extern (quando ele estiver disponível).
Declarações múltiplas
Um outro ponto importante acerca das declaracões de variáveis é que elas podem aparecer agrupadas em uma única linha – a única condição limitante é que elas tenham todas o mesmo tipo de base. Vejamos então alguns exemplos de declarações múltiplas válidas e inválidas.
// Declaração das variáveis a, b e c, todas com o mesmo tipo de base (int) int a, b, c; // Declaração inválida das variáveis x, y e z - o seu tipo deve ser o mesmo. double x, y, int z; // Erro - o compilador espera um ; antes da palavra int (pois dois tipos de variável não podem aparecer em uma única declaraçao)
Apesar de ser possível declarar várias variáveis em uma mesma linha, normalmente não se faz isso por uma questão simples: o código torna-se menos legível muito rapidamente quando se utiliza desse artifício. Assim sendo, é melhor declarar cada variável em uma declaração independente.
Agora que tratamos desse ponto que é por vezes negligenciado, o próximo passo para compreender melhor as variáveis em C++ é entender para que servem os seus tipos.
Tipos das variáveis em C++
Como vimos anteriormente, para fazer a declaração de variáveis em C++ é preciso preceder o nome da variável declarada pelo seu tipo (se quiser relembrar quais são os tipos em C++, veja o artigo sobre tipos). Isto se dá por ser o C++ uma linguagem com tipificação (ou tipagem) estática de variáveis (do inglês statically typed, cuja tradução mais comum é estaticamente tipada, o que me parece uma má adaptação para o português, por isso não a utilizarei (•‿•)), o que significa que as variáveis precisam ter seus tipos especificados durante a declaração, e os tipos não podem ser alterados posteriormente. Sim, tudo bem, mas e o que isso quer dizer na prática? Bem, quer dizer que os dois exemplos abaixo são inválidos.
using namespace std; // Exemplo 1 - Conversão inválida int salarioDev = 100000; salarioDev = "Demitido"; // Erro - conversão inválida de "const char *" para "int" // Exemplo 2 - Declaração conflitante int salarioDev = 100000; string salarioDev = "Demitido"; // Erro - declaração conflitante "std::string salarioDev"; declaração prévia como "int salarioDev"
O efeito buscado no exemplo anterior é possível de se obter facilmente em linguagens com tipagem dinâmica de variáveis (tradução livre de dynamically typed, do inglês), como mostrado a seguir tomando a linguagem Python como exemplo. A variável que inicialmente contém um inteiro, no instante seguinte passa a armazenar um tipo de ponto flutuante. Note que o tipo da variável não é informado no código (como em C++), mas sim deduzido a partir do conteúdo da variável durante a execução do programa.
# Exemplo de código válido em Python salarioDev = 100000 # salarioDev é uma variável de "tipo int" salarioDev = 0.0 # salarioDev é modificada para uma variável de "tipo double" (entre aspas pois a correspondência não é exata com os tipos em C++)
Assim, em C++ é preciso preceder o nome das variáveis declaradas pelo seu tipo (ou pelas palavras chave auto e decltype, que são ferramentas para dedução automática de tipos – mas falaremos disso na sequência desses artigos sobre variáveis). Em seguida vem o nome da variável; vejamos, então, quais são as regras para a declaração de variáveis em C++ e quais são as principais convenções existentes para fazê-lo.
Como nomear variáveis em C++?
Os nomes das variáveis em C++ seguem regras muito simples. A primeira delas é a seguinte: (1) apenas são aceitos nos nomes de variáveis letras, números e o símbolo _ (underscore); a segunda diz que (2) nomes de variáveis devem começar com letras ou _, e não com dígitos; por fim, a última regra é que (3) nomes que diferem entre si apenas por terem letras minúsculas ou maiúsculas em posições correspondentes são considerados como nomes diferentes, e, portanto nomeiam variáveis diferentes (essa definição é condensada a expressão case-sensitive, em inglês). Essas regras ficarão mais claras observando os exemplos abaixo. Neles pus comentários indicando qual das regras (1, 2 ou 3) foi desrespeitada ou é relevante em cada uma das declarações.
int salarioDev = 100000; // OK: nenhum problema aqui. int SalarioDev = 200000; // OK: primeira letra é maiúscula, logo não há redeclaração da variável anterior (regra #3) int $alarioDev = 0; // Erro (regra #1) - caractere inválido : $ std::string _atributoPrivado = "segredo"; // OK: _ é aceito no início do nome double 1000Grau = 1000.00; // Erro (regra #2) - nome começado por um dígito bool ESTOURICO = false; // OK: letras maiúsculas também são aceitas bool estourico = true; // OK (regra #3): maiúsculas e minúsculas diferem entre si criando um novo nome válido
Agora que sabemos quais são as regras para se nomear variáveis, é importante conhecer também quais são as convenções utilizadas para fazê-lo. Entre as convenções existentes, ou seja, as “regras de boa conduta” para se criar nomes de variáveis (estas regras são gerais, e não apenas aplicáveis ao C++), as mais famosas e utilizadas são as chamadas camelCase e snake_case.
Como você deve ter percebido, desde o princípio venho escrevendo o nome das variáveis de acordo com o seguinte formato: primeiraSegundaTerceira
– este é o camelCase. A primeira letra do nome é sempre minúscula, e para cada palavra seguinte no nome da variável sua primeira letra é maiúscula. Desta forma, é possível distinguir facilmente quais são as palavras que constituem o nome inteiro do objeto. Veja abaixo alguns exemplos.
double temperaturaEmGrausCelsius = 36.0; int diaDeNascimento = 15; std::string melhorLinguagemDeProgramacao = "C++"; // Brincadeira, haters; calma.
O snake_case, por sua vez, determina utilizar um _ para separar cada uma das palavras presentes no nome em questão. Assim sendo, a variável que criei antes como exemplo para o camelCase, em snake_case seria escrita assim: primeira_segunda_terceira
. Note que as palavras começam todas com letras minúsculas, mesmo para as palavras que seguem a primeira. A seguir há as mesmas variáveis que declarei antes, mas agora usando snake_case.
double temperatura_em_graus_celsius = 36.0; int dia_de_nascimento = 15; std::string melhor_linguagem_de_programacao = "C++";
Agora que você conhece as duas convenções de nomes mais comuns, uma pergunta surge naturalmente: qual das duas é a melhor? Naturalmente, não há resposta correta para essa pergunta. O importante, ao invés de se perguntar qual é a melhor das convenções, é escolher uma convenção e seguí-la de modo consistente. Trocar de formato no nome das suas variáveis ao longo de um programa pode causar muita confusão e dificultar a legibilidade do código.
Nomes de variáveis – resumo das regras e convenções
- Use nomes que falam sobre o intuito da variável que você está criando. Por exemplo,
salarioDev
é melhor do quevalorInteiro
para armazenar um salário de desenvolvedor. - Escolha uma convenção para o nome das suas variáveis e utilize-a até o fim.
- Nomes de variáveis normalmente começam com letra minúscula, como dataDeNascimento ou salario_dev.
- Nomes começam com letras maiúsculas quando se referem a nomes de classes, por exemplo: ModeloDeCarro.
- Nomes inteiros em letras maiúsculas são normalmenete utilizados para macros (veremos o que estas são em um artigo posterior), como por exemplo
#define PI 3.1415
ou#define PASSWORD "123456"
.
Próximos assuntos
Aqui chegamos ao fim deste artigo, mas a sequência de posts sobre variáveis continuará. Fique de olho na parte 2 para saber mais sobre inicialização de variáveis, escopos de nomes e a palavra-chave const.
Gostou do artigo? Então inscreva-se na nossa newsletter para não perder nenhum dos nossos artigos 🙂
Sou apaixonado por tecnologia, literatura e também filosofia. O cultivo dessas paixões ao longo da minha trajetória me inspiraram a compartilhar aquilo que aprendo com os outros da maneira mais clara que eu possa. Sou formado em Engenharia Elétrica no Brasil, e também sou engenheiro formado na França. Trabalho atualmente como programador C++ em uma multinacional francesa, uma das maiores empresas de TI do mundo.
Muito esclarecedor e compreensível. Estou ansiosa pela parte 2 !!
Obrigado, Júlia! Que bom saber que você gostou. Fique atenta que logo mais sairá a parte 2 dessa série 🙂
ótimo trabalho, obrigado. Parte 2?
Fico feliz que tenhas gostado! Já estou trabalhando na parte 2. Fique de olho que logo mais ela estará disponível 🙂