Variáveis e constantes

  1. Declaração e atribuição
  2. Identificadores
  3. Tipos de dados
  4. Tipos de dados escalares
  5. Tipos de dados compostos
  6. Tipagem
  7. Constantes

Declaração e atribuição

Em muitas linguagens de programação, antes que você possa usar qualquer variável, você deve declará-la. No entanto, isso não é necessário em todas as linguagens, e a cada dia mais aumenta o número de linguagens onde isso não é necessário.

Uma declaração é uma instrução que fornece um identificador para uma variável, precedido em muitas linguagens, mas não em todas, pelo tipo da variável. É o tipo que determina o conjunto de valores que a variável pode assumir. O identificador é simplesmente o nome da variável.

Exemplo de declarações em Portugol Studio:

real altura
real peso = 74.4
inteiro prestacoes_financiamento_casa, animais_estimacao

Note que esse exemplo tem 3 tipos de declarações:

  • Declaração de uma variável sem valor (o valor da variável é atribuído posteriormente).
  • Declaração de uma variável com valor (ou seja, declaração e atribuição ao mesmo tempo, num processo chamado de inicialização).
  • Declaração de múltiplas variáveis (todas sem valor, porém eu poderia ter declarado as duas variáveis com valor, se eu quisesse).

Essa é a sintaxe de declarações de variáveis do Portugol Studio. Linguagens de programação tem suas próprias sintaxes, mas geralmente também tem esses mesmos conceitos, porém com diferenças de sintaxe. Veja exemplos de declarações similares em C++:

double altura;
double peso = 74.4;
int prestacoesFinanciamentoCasa = 300, animaisEstimacao = 2;

Agora, veja exemplos de declarações similares em PHP:

$altura;
$peso = 74.4;
$prestacoesFinanciamentoCasa = 300;
$animaisEstimacao = 2;

Veja como os exemplos do PHP não tem declarações de múltiplas variáveis com atribuição de valores diferentes a cada variável. Essa funcionalidade não é suportada no PHP. Viu como cada linguagem tem suas particularidades?

Identificadores

O identificador de uma variável nada mais é do que o seu nome.

Restrições

Cada linguagem de programação tem as suas próprias regras para criar identificadores. Geralmente, as linguagens costumam ter palavras-chaves reservadas, que não podem ser usadas como nomes de variáveis, porque elas são parte da sintaxe da linguagem. Alguns exemplos de palavras-chaves reservadas são nomes de tipos de dados e nomes de estruturas de controle.

Diferentemente das palavras do mundo real, na programação não se pode separar as palavras que fazem parte do identificador de uma variável com espaço. Ao invés disso, usa-se outras maneiras para indicar o fim de uma palavra e o começo de outra no identificador de uma variável. Algumas dessas maneiras são:

  • Usar o underline (snake_case). Exemplo: inteiro jogos_perdidos_selecao = 10.
  • Usar uma letra maiúscula no começo de cada palavra, exceto a primeira (camelCase). Exemplo: inteiro jogosGanhosSelecao = 20.

Além disso, existem outras restrições aos identificadores de variáveis. A documentação do Portugol Studio não cita essas restrições, mas eu fiz alguns testes e vi que não é possível começar um nome de variável com um dígito, mas é possível iniciá-la com um underline ou uma letra.

De uma maneira geral, letras, dígitos e underlines geralmente são permitidos no identificador de uma variável, mas dígitos não costumam são permitidos na primeira letra. Isso não é válido para todas as linguagens, mas muitas delas seguem essas regras.

Os identificadores não permitem que se use letras com acentos, cedilhas, tremas, crases ou caracteres desse tipo. Exemplo:

real aceleracao = 7.1 // aceleracao ao invés de aceleração

Guias de estilo e naming conventions

Na maioria das linguagens, os identificadores são case-sensitive (sensíveis à caixa), então nomeJogador é diferente de NOMEJOGADOR e de nomejogador. No Portugol Studio também é assim. Além disso, as linguagens costumam permitir a colocação de um underline no identificador de uma variável como já foi falado. Exatamente por causa dessa liberdade enorme de nomear as variáveis, existem algumas naming conventions (convenções de nomenclatura) para nomear variáveis. Para quem não sabe, naming conventions são uma coisa muito ampla, são convenções para se nomear alguma coisa, que pode ser de diversas áreas de conhecimento diferentes.

Algumas naming conventions são snake_case e camelCase, que foram brevemente citadas na seção anterior. A popularidade de cada naming convention varia de acordo com cada linguagem. Muitas linguagens tem guias de estilo (style guides), que definem regras para a programação na linguagem e estabelecem quais naming conventions devem ser seguidas e quando elas devem ser aplicadas. Isso mesmo: um guia de estilo de uma linguagem pode seguir mais de uma naming convention. Ele pode, por exemplo, usar camelCase para nomear variáveis e StudlyCaps para nomear classes (não se preocupe se você não sabe o que são classes, você aprenderá quando trabalhar com uma linguagem de programação que tenha classes).

Seguir guias de estilos é bom, porque aumenta a consistência entre o modo de programar de diferentes programadores da mesma linguagem. Quando se trabalha com outros programadores, tudo fica mais fácil quando todos seguem o mesmo guia de estilos.

Há linguagens onde os guias de estilos são mais adotados e populares do que outras. Quando você for programar em alguma linguagem, independentemente de qual seja, eu recomendo que você sempre procure saber se há guias de estilo da sua linguagem. Muitas vezes, pode haver mais de um, então sugiro que você procure saber qual é o mais adotado.

Enfim, tenha uma coisa em mente: seguir um guia de estilo vai ajudar a tornar os seus programas mais fáceis de ler e entender.

Tipos de dados

O tipo de dado de uma variável está associado ao conjunto de valores que a variável pode assumir. Exemplo: o tipo inteiro está associado a um conjunto de valores inteiros, que é limitado pelo número de bytes que podem ser usados para representar o valor.

Os tipos de dados podem ser classificados em várias categorias, de acordo com as características deles. Por exemplo, eles podem ser escalares, que são aqueles que são representados por um único valor (pense no conceito de grandeza escalar da Física, que explica que grandeza escalar é aquela que contém apenas um valor), ou compostos, que podem ser representados por múltiplos valores.

Tipos de dados escalares

Os tipos de dados escalares, que também são chamados de básicos ou de primitivos, se encaixam em três categorias: numérica (gue engloba números, sejam eles inteiros ou reais), lógica/booleana (que guarda true/false, ou seja verdadeiro/falso) e caractere (que guarda um caractere, que pode ser uma letra, um número, um símbolo, etc...).

A categoria lógica pode também ser considerada uma subcategoria da categoria numérica, já que na verdade, ela usa números. Mesmo assim, alguns, como eu, deixam ela em uma categoria separada. Isso também não está errado, já que o propósito dela é diferente do propósito da categoria numérica e ela é bem mais restrita quanto aos valores permitidos.

É importante lembrar que essas são categorias. Por serem categorias, elas podem englobar vários tipos de dados. Por exemplo, dentro da categoria numérica, a maioria das linguagens de programação tem tipos de dados diferentes para armazenar números inteiros e números reais. Muitas até tem subtipos para armazenar números reais com precisões diferentes (geralmente são os subtipos float e double). A categoria lógica é mais restrita e as linguagens contém apenas um tipo dentro dela.

Veja como é a declaração de variáveis com tipos de dados escalares no Portugol Studio:

inteiro x = 3
real y = 2.5
logico lampadaAcesa = falso
caracter c = 'K'

Atribuição de valores

Valores numéricos

Valores numéricos são escritos sem símbolos especiais. Nada de cifrão, mesmo se a variável que você estiver utilizando guardar algum preço de alguma coisa ou o lucro de uma empresa qualquer. Da mesma forma, se a sua variável representar alguma grandeza, como velocidade, você não deve colocar m/s após o número que representar o valor da variável.

Números inteiros devem ser escritos apenas com os dígitos dele. Números reais devem ser escritos com um ponto separando a parte inteira da parte decimal. Os detalhes extras (nos exemplos que eu citei, o $ e o m/s) devem ser adicionados quando você for imprimir esses valores para o usuário. Eles não fazem parte do valor da variável.

Exemplo de atribuição de valores numéricos em Portugol:

inteiro x = 3
real y = 7.4

A única situação onde um número, seja inteiro ou real, é escrito com alguma coisa a mais do que o número em si é quando se deseja expressar o número em uma notação diferente da padrão, que é a decimal. Essas notações diferentes não são suportadas por todas as linguagens. O Portugol suporta:

inteiro x = 0x7a84fb // número inteiro expresso em notação hexadecimal

Valores lógicos

Podem assumir apenas dois valores: verdadeiro ou falso. Veja o exemplo abaixo:

logico lampada_acesa = verdadeiro

Chars

Quando você atribuir um char a uma variável, coloque aspas simples. Um char representa apenas um caractere. Um caractere não precisa ser uma letra. Pode ser um dígito ou algum outro caractere, como uma vírgula. Exemplos:

caractere c = 'K'
caractere d = '9'

Tipos de dados compostos

Tipos de dados compostos são mais amplos do que os simples e armazenam vários valores. Eles podem ser arrays, strings, tipos definidos pelo usuário, dentre outros. Vamos ver apenas arrays e strings. Os demais tipos compostos variam de acordo com a linguagem, portanto não devem ser abordados aqui, senão os tutoriais ficariam presos a uma linguagem X ou Y, o que não é o propósito dos tutoriais.

Algumas linguagens (tais como PHP) permitem que o número de elementos que uma array pode armazenar seja alterado durante a execução e outras não permitem essa alteração (tais como C++).

Array

Uma array é um tipo de dado que armazena vários valores. Exemplos: uma lista de fornecedores de uma empresa ou uma lista com o número de vendas de um determinado produto em cada mês. Em algumas linguagens, esses valores precisam ser do mesmo tipo, como C++, e em outras, esses valores podem ser de tipos diferentes, como PHP.

Vetor

Uma array pode ter várias dimensões. Uma array unidimensional é chamada de vetor. Exemplos de declarações de vetores no Portugol Studio:

inteiro fotos[10]
inteiro vitorias_equipes[] = {3, 1, 2, 1, 1}
real precos_produtos[3] = {10.30, 3.45, 2.10}

No Portugol Studio, um vetor é declarado da seguinte forma: primeiro, informa-se o tipo da variável, seguido pelo identificador dela. Depois, coloca-se colchetes, que é o que indica que a variável é uma array. Se você quiser indicar o tamanho do vetor, basta informá-lo nos colchetes. O tamanho do vetor é obrigatório se os elementos do vetor não forem inicializados.

Se os elementos do vetor forem informados, o tamanho se torna opcional, porque ele pode ser inferido. Quando os elementos do vetor são definidos, eles devem ser colocados entre chaves e separados por vírgulas.

Matrizes

Como eu falei, arrays podem ter várias dimensões. Uma array unidimensional é chamada de vetor. Já uma array bidimensional é chamada de matriz. Pense que você pode querer armazenar a altura e o peso de um grupo de 10 pessoas. Fazer isso em vetores não seria bom. Ficaria bagunçado, estranho. O mais recomendado seria usar uma matriz (considerando apenas essas duas opções).

Seguindo o exemplo de usar uma matriz para armazenar a altura e o peso das 10 pessoas, a primeira dimensão da matriz poderia ter 10 elementos para armazenar os dados das 10 pessoas, e a segunda dimensão poderia ter 2 elementos, para armazenar o peso e a altura de cada uma das 10 pessoas. Ou seja, cada um dos elementos da primeira dimensão da array vai poder guardar dois dados, em cada uma das duas posições da segunda dimensão.

Exemplos de declarações de matrizes:

real dados_pessoas[3][2]
real dados_pessoas[3][2] = {{1.77, 78.0}, {1.54, 52.0}, {1.65, 57.0}}
real dados_pessoas[][] = {{1.77, 78.0}, {1.54, 52.0}, {1.65, 57.0}}

Veja que a declaração de uma matriz segue a mesma lógica da declaração de um vetor. Basicamente, se adiciona um colchete a mais, para indicar a segunda dimensão. E, na definição dos elementos da matriz, cada dimensão é definida dentro de suas próprias chaves. E as chaves são separadas por vírgulas. São chaves dentro de chaves. Note também que os tamanhos das dimensões da matriz podem ser inferidos, como acontece na terceira declaração.

Índices

Depois que uma array foi declarada e você definiu os elementos dela, você pode usar os elementos da array da mesma forma que você usuaria variáveis simples. Ou seja, você pode atribuir valores a elementos da array, imprimi-las, etc.

Cada elemento de uma array é diferenciado dos outros por um índice único, que é usado para acessar o elemento da array. Na maioria das linguagens, o índice é obrigatoriamente numérico (em outras, como PHP, também pode ser uma string).

Em linguagens onde o índice deve ser numérico, ele quase sempre indica a posição de um item particular dentro de uma matriz, pois os itens quase sempre começam do 0 e aumentam de 1 em 1. Uma das exceções é Pascal. Porém, em quase todas as linguagens, você começará com o índice 0. Isso é o mais comum.

Veja como definir e consultar elementos de vetores e matrizes:

inteiro vitorias_equipes[] = {3, 1, 2, 1, 1}
real dados_pessoas[3][2] = {{1.77, 78.0}, {1.54, 52.0}, {1.65, 57.0}}
escreva(vitorias_equipes[0])
vitorias_equipes[1] = 2
escreva(vitorias_equipes[1])
dados_pessoas[1][0] = 1.52
escreva(dados_pessoas[1][0])

Perceba como a sintaxe para definir e para acessar o valor de um elemento de uma array é a mesma. Se for um vetor, apenas informe o nome da array e coloque o índice entre colchetes. Se for uma matriz, adicione o índice da segunda dimensão também.

Convenções

Quando se nomeia arrays, programadores seguem as mesmas regras que eles seguem quando nomeiam variáveis. Muitos usam algumas convenções ao nomear arrays, como apenas usar o plural, (exemplo: velocidades_carros), ou usar uma palavra que implica um grupo, tais como lista_compras ou grupo_estudantes. Esse primeiro deve ser evitado, porque ele pode gerar confusão, já que lista é o nome de uma estrutura de dados.

Strings

Enquanto o tipo caractere serve para armazenar apenas um caractere, o tipo string armazena um conjunto de caracteres. Por isso, ele pode ser usado para armazenar desde uma palavra ou uma frase até o conteúdo de um arquivo de texto completo.

No Portugol Studio, o tipo string é chamado de cadeia (porque remete à cadeia de caracteres):

cadeia nome = "Lorraine"

Perceba que é bem semelhante às declarações dos tipos de dados escalares. A diferença é que o valor é um texto especificado entre aspas. A diferença é portanto conceitual: o tipo string é composto porque ele é uma cadeia de caracteres.

É importante ressaltar que uma string também pode conter apenas dígitos. Ou também exclamações. Ainda assim seria uma string. Uma string é uma cadeia de caracteres, e não de letras.

Tipagem

Assim como alguns outros temas cobertos nos tutoriais, esse não é um tema tradicional de Lógica de Programação, mas eu decidi colocá-lo porque eu acho que falar sobre tipagem vai te ajudar quando você aprender a sua primeira linguagem de programação.

Inferência de tipo

O que é inferir? É deduzir. Então, a inferência de tipo nada mais é do que a dedução do tipo de uma variável. Então, em linguagens onde há inferência de tipo, o tipo da variável não é informado. Exemplos: PHP e Python. Exemplos onde isso não acontece: C++ e Java.

Exemplos de inferência de tipo em PHP:

$salario = 8000; // infere-se o tipo int
$nome = "Max"; // infere-se o tipo string

Já em C++, o tipo não é inferido:

int salario = 8000;
string nome = "Max";

Tipagem estática

Em linguagens com tipagem estática, o tipo de uma variável não se modifica. Por isso, essa tipagem é chamada de estática. Geralmente, linguagens com tipagem estática requerem que o programador informe o tipo da variável quando ele declara as variáveis do programa. Mas isso nem sempre é necessário, pois uma linguagem pode ter tipagem estática e inferência de tipo ao mesmo tempo. Exemplos de linguagens com tipagem estática são C e C++.

Tipagem dinâmica

É o contrário da tipagem estática. Na tipagem dinâmica, o tipo de uma variável pode ser modificado durante o programa. Em linguagens que suportam esse tipo, não se indica o tipo da variável na declaração dela. Ao invés disso, usa-se apenas o identificador da variável e algum prefixo antes dela em alguns casos, como um $ no caso do PHP. Nele, eu posso inicializar uma variável com um número inteiro e depois mudar o valor dela para um texto tranquilamente:

$x = 30;
$x = "texto";

Isso é tipagem dinâmica. Em linguagens com tipagem estática, isso não é permitido.

Conclusão

Tipagem é um tema que gera muitas discussões nas comunidades de programadores. O objetivo foi introduzir o tema, explicando os conceitos de inferência de tipo e tipagem estática e dinâmica. Tem mais coisa para falar sobre tipagem, como tipagem fraca, tipagem forte e duck typing, mas não seria legal abordar nesses tutoriais. É melhor você ter uma experiência com uma linguagem de programação antes de entender esses conceitos.

Constantes

Além de variáveis, a maioria das linguagens de programação permite que você crie constantes. A única diferença entre uma constante e uma variável é que a constante não pode ter o valor dela alterado e geralmente precisa ter o valor dela definido no momento da sua declaração.

Casos de uso de constantes são quando você quer usar constantes matemáticas em um programa (como pi) ou quando você quer usar qualquer coisa que você sabe que não vai mudar durante o programa. Declarando essas coisas como constantes, há uma segurança a mais, porque se você tentar mudar o valor de uma constante, um erro vai ocorrer.

Em muitos guias de estilo, constantes seguem naming conventions diferentes de variáveis. Se o identificador de uma constante for uma palavra composta, geralmente as naming conventions determinam que seja usado o underline para separar as palavras e também é comum determinar que todas as letras da constante sejam maiúsculas. Basicamente, um snake_case com letras maiúsculas.

Declaração

No Portugol Studio, a declaração de uma constante é bem parecida com a declaração de uma variável. Basta colocar const no início:

const real PI = 3.14
const cadeia NOME_ABNT = "Associação Brasileira de Normas Técnicas"

Constantes anônimas

Existem também as constantes anônimas. Considere o pseudocódigo abaixo:

inteiro x = 9
real y = 8.2

Considere os números 9 e 8.2 de forma isolada. Esses números são chamados de constantes numéricas, ou constantes literais numéricas. Estou falando dos números isoladamente, não das variáveis às quais eles são atribuídos. O número isolado é uma constante literal, porque o valor dele é sempre o mesmo.

O mesmo ocorre com strings. Considere o pseudocódigo abaixo:

cadeia cpf = "999.999.999-99"

Da mesma forma que um valor numérico isolado é uma constante numérica, uma string olhada de forma isolada, esquecendo qualquer variável que possa estar ligada à ela, é uma constante de string.

Tanto a constante numérica como a constante de string são chamadas de constantes anônimas. Elas são chamadas assim porque não tem identificadores, mesmo que elas sejam atribuídas a uma variável. Olhadas de forma isolada, elas nunca contém identificadores.