Avançar para o conteúdo
Imagem com logotipo, contendo link para a página inicial
  • United Stated of America flag, representing the option for the English language.
  • Bandeira do Brasil, simbolizando a opção pelo idioma Português do Brasil.

Aprenda Programação: Variáveis e Constantes

Exemplos de declaração e inicialização de variáveis nas linguagens de programação Python, Lua, GDScript e JavaScript.

Créditos para a imagem: Imagem criada pelo autor usando o programa Spectacle.

Pré-Requisitos

Na introdução sobre ambientes de desenvolvimento, indiquei Python, Lua e JavaScript como boas escolhas de linguagens de programação para iniciantes. Posteriormente, comentei sobre GDScript como opção para pessoas que tenham interesse em programar jogos digitais ou simulações. Para as atividades de introdução a programação, você precisará de, no mínimo, um ambiente de desenvolvimento configurado em uma das linguagens anteriores.

Caso queira experimentar programação sem configurar um ambiente, você pode usar um dos editores online que criei:

Contudo, eles não possuem todos os recursos dos interpretadores para as linguagens. Assim, cedo ou tarde, você precisará configurar um ambiente de desenvolvimento. Caso precise configurar um, confira os recursos a seguir.

Assim, se você tem um Ambiente Integrado de Desenvolvimento (em inglês, Integrated Development Environment ou IDE) ou a combinação de editor de texto com interpretador, você está pronto para começar. Os exemplos assumem que você saiba executar código em sua linguagem escolhida, como apresentado nas páginas de configuração.

Caso queira usar outra linguagem, a introdução provê links para configuração de ambientes para as linguagens C, C++, Java, LISP, Prolog e SQL (com SQLite). Em muitas linguagens, basta seguir os modelos da seção de experimentação para adaptar sintaxe, comandos e funções dos trechos de código. C e C++ são exceções, por requerem o uso de ponteiros para acesso à memória.

Memória

No último tópico, definiu-se o que são tipos de dados. Tipos de dados abstraem valores codificados. Em arquiteturas de computador, valores precisam existir em algum lugar. Este lugar chama-se memória.

Atividades de programação normalmente utilizam dois tipos de memória: memória primária e memória secundária.

Memória Primária

Em programação, memória primária é, normalmente, sinônimo da memória de acesso aleatório (do inglês, random-access memory ou RAM). A memória RAM é uma memória de acesso rápido, de quantidade pequena a média (dependendo do dispositivo, a quantidade pode variar de Kilobytes a Gigabytes) e volátil. Uma memória volátil é aquela que não persiste dados quando se cessa o fornecimento de energia. Em outras palavras, o conteúdo armazenado é perdido toda vez que o aparelho é desligado. Seja pela ação de uma pessoa, seja por um problema (como queda de energia ou falha de componente eletrônico), perde-se todos os dados armazenados em memória primária quando se termina o fornecimento de energia.

Caso você tenha, em algum momento, perdido dados porque um programa travou ou por falta de energia, a razão é que os dados estavam armazenados apenas em memória primária. Por isso a importância de usar funcionalidades para salvar dados (por exemplo, documentos). O ato de salvar copia dados de memória primária para memória secundária, usada como armazenamento persistente. Memória secundária é persistente, termo que é antonino de volátil.

Existem outros tipos de memória primária. Por exemplo, registradores constituem a memória usada que para um processador realize instruções. Registradores compartilham muitas das características principais da memória primária, mas são mais rápidos e com capacidade ainda mais limitada (da ordem de Kilobytes a poucos Megabytes.) Dependendo da arquitetura de computador, pode-se considerar registradores como memória primária ou como uma categoria própria.

Contudo, para fins práticos, o termo memória primária normalmente relaciona-se ao uso de RAM. Exceto em linguagens que permitem programar em nível muito baixo (como C ou C++) ou em linguagem de máquina (como assembly), a linguagem de programação abstrai o uso de registradores, permitindo apenas o uso de variáveis para codificação em nível de abstração mais alto.

Memória Secundária

Memória secundária é uma memória auxiliar à memória primária. Ela é, muitas vezes, o que o conhecimento popular denomina "memória": a memória para armazenamento persistente de dados.

A memória secundária é mais lenta que a memória primária, mas possui capacidade maior de armazenamento (por exemplo, da ordem de Terabytes) e é persistente. Como adiantado, memória persistente é o contrário de memória volátil. Quando se salva dados em memória persistente, eles persistem (isto é, continuam a existir) mesmo na ausência de energia. Isso é feito por meio de tecnologias como eletromagnetismo.

Quando se diz que a memória secundária é mais lenta que a memória primária, deve-se saber que ela realmente é muito mais lenta. O tempo de acesso, de leitura e de escrita em memória secundária é muito maior que o em memória primária. Dependendo do hardware e da quantidade de dados, a razão pode ficar na ordem de centenas, milhares ou milhões de vezes mais lenta.

Por isso programas operaram com memória primária ao invés de memória secundária. O uso de memória secundária é, comumente, um gargalo para o desempenho de programas. É por isso que, quando se abre um programa, normalmente é necessário esperar algum tempo para poder usá-lo. Esse tempo decorre da transferência de dados de memória secundária para a memória primária, contendo dados necessários para uso do programa. Depois de carregados, a execução do programa tende a ser mais rápida.

Exemplos de memória secundária incluem discos rígidos (hard disk drives ou HDs), discos solid slate drives (SSD), memória flash (como de pen-drives), compact disks (CDs) e digital video disks (DVD). Dependendo de sua idade, talvez você tenha usado disquetes em algum momento da vida. Eles são outro exemplo de memória secundária.

Em programação, utiliza-se memória secundária com abstrações como arquivos ou banco de dados. Por exemplo, na configuração ambiente usando SQLite como exemplo de SQL, criou-se e salvou-se dados em um banco de dados SQLite.

O uso de memória secundária é um pouco mais complexo que o de memória primária. Ele será descrito no futuro, após a introdução de outros recursos de programação.

Variáveis

Programação em assembly utiliza registradores. Programação em linguagens de programação utiliza variáveis.

Pode-se pensar em variáveis como caixinhas que armazenam dados. Cada caixinha possui uma capacidade e um endereço de memória.

A capacidade é medida em bytes e corresponde ao tamanho do tipo de dado que ela pode armazenar. O endereço é o local em que a variável está na memória RAM.

Em um computador, as caixinhas de variável ficam na memória RAM. Você pode imaginar a memória RAM como uma prateleira ou armário com as caixinhas enfileiradas.

Quando um programa precisa acessar (ler ou escrever) o valor de uma variável, ele acessa o endereço de memória e faz a operação necessária (leitura ou escrita). Dados lidos são armazenados em registradores para uso.

Retomando a metáfora de caixinha e prateleiras, é como se o computador pegasse a caixinha para deixá-la em um local de fácil acesso (o registrador). Como o número de registradores é limitado, um programa deve escolher quais valores estarão em registradores e quais valores estarão na RAM (ou, ainda, em memória secundária). Valores são carregados conforme a necessidade.

Se quiser, você pode pensar na memória secundária da metáfora como um armazém. Ele é maior, mas requer um tempo maior para obter ou armazenar uma caixinha nele.

Ainda é possível aumentar a metáfora. Além de memória secundária, é possível pensar em armazenamento externo ou mesmo remoto (por exemplo, com arquivos na Internet ou na "nuvem"). Quanto mais distante o dado e mais lenta a velocidade acesso, maior será o tempo necessário para se obter um dado.

Variáveis em Linguagens de Programação

Em linguagens de programação de níveis mais altos, o compilador ou interpretador é o responsável por gerenciar os dados que estarão em registradores ou na RAM. Como programadora ou programador, sua tarefa é definir uma variável e usá-la sempre que precisar.

Para isso, você fará duas operações principais: declaração e atribuição. Além disso, você comumente precisará decidir escopos para uso de variáveis.

Declaração

Antes de usar uma variável, é preciso declará-la. Em geral, a declaração mapeia um nome escolhido pela programadora ou pelo programador a um endereço de memória no computador. Ao invés de escrever um valor binário ou inteiro para acessar um endereço, usa-se o nome definido toda vez que se desejar acessar o endereço.

A título de curiosidade, algumas linguagens de programação mapeiam um nome a um valor ao invés de um endereço. Isso pode ocorrer, por exemplo, em Python. Na prática, o uso da variável normalmente é idêntico ao que ocorre em linguagens de programação que mapeiam endereços a nomes.

O termo genérico dado para um nome escolhido para uma variável é identificador. Linguagens de programação definem regras que designam caracteres válidos para identificadores. Em geral, um identificador deve começar com uma letra ou underscore (underline, _). O identificador não pode ter espaços ou símbolos especiais. Após o primeiro caractere, pode-se usar números.

Existem linguagens que impõe restrições adicionais. Por exemplo, em Prolog, um identificador para variável deve começar um nova letra maiúscula. Outras podem impor menos restrições. Por exemplo, LISP permite o uso de alguns caracteres como hífens (-) em nomes de variáveis.

Declaração de Tipos

Na metáfora da caixinha, a declaração serve como um rótulo que combina um nome a uma caixa do tamanho necessário para armazenar valores do tipo desejado.

Em linguagens com tipagem estática, deve-se explicitar o tipo desejado para a variável na declaração. Em linguagens com tipagem dinâmica, o compilador ou interpretador infere o tipo da variável a partir do valor atribuído a ela.

Algumas linguagens de programação adotam uma estratégia híbrida, na qual a declaração do tipo é opcional. Caso se forneça o tipo, ele será utilizado. Caso contrário, o interpretador ou compilador fará a inferência baseada no valor armazenado.

A declaração de tipo é interessante por evitar ambigüidades sobre o tipo de uma variável ou inferências incorretas por parte do compilador ou interpretador. Ela também permite criar variáveis com a quantidade de memória exata para armazenar valores do tipo definido.

Em linguagens com inferência de tipos, a declaração de números inteiros e números reais requer atenção. 0 é um número inteiro, mas 0.0 é um número real. Quando se desejar declarar um número real exato, é importante acrescentar o .0 após o valor. Por exemplo, -123456.0 ou 7.0. Caso se escreva -123456 ou 7, as variáveis serão do tipo inteiro.

Estilos para Identificadores

Existem alguns estilos para a escrita de nomes de variáveis. Alguns dos mais populares são:

  • PascalCase, na qual a inicial de cada palavra de um nome usa letra maiúscula;
  • snake_case, na qual se separa palavras com um underscore;
  • camelCase, na qual a letra inicial é minúscula, mas iniciais de outras palavras no mesmo nome são maiúsculas;
  • kebab-case, na qual se separa palavras com um hífen.

Exceto caso a linguagem de programação imponha restrições, você pode escolher o estilo que preferir. Embora também seja possível misturá-los, eu recomendaria escolher um e sempre utilizá-lo em um mesmo projeto, para criar um padrão.

Nomenclatura

Exceto palavras reservadas e palavras que não respeitem as regras de nomenclatura, você pode escolher os nomes que quiser para suas variáveis. Existem pessoas que gostam de nomes curtos para variáveis, como x ou i. Embora certamente práticos para escrever, código costuma ser lido mais vezes que escrito. Portanto, minha recomendação é que você tente escolher nomes representativos para suas variáveis ao invés de nomes genéricos.

Por exemplo, n ou nome_completo podem ser variáveis do tipo string para armazenar um nome completo. A segunda opção, entretanto, permite identificar o que está armazenado com maior clareza.

Também existem pessoas que gostam de adicionar informações sobre o tipo de uma variável em seu nome. Um dos exemplos mais extremos é o da notação húngara. Embora eles possam ser úteis, IDEs comumente fornecem dicas sobre o tipo de uma variável (por exemplo, ao se deixar o cursor do mouse ou teclado sobre uma variável), o que pode tornar a notação redundante. Entretanto, caso o tipo de dado seja importante para um determinado problema (por exemplo, problemas de precisão em números reais), pode ser interessante adicioná-lo à variável como um alerta ou lembrete.

Atribuição

Para ler o valor de uma variável, normalmente basta usar o nome definido para ela. Para modificar o valor de uma variação, realiza-se uma atribuição.

A operação de designar um valor a uma variável chama-se atribuição. Na metáfora da caixinha, a atribuição é o processo que troca o valor armazenado dentro da caixa. O valor anterior deixa de existir, e a variável assume o novo valor informado.

O nome ou símbolo do operador de atribuição varia de acordo com a linguagem de programação. Opções comuns são o uso de um igual (=), dois pontos seguido de igual (:=), ou de uma combinação de menor e hífen (<-), simbolizando uma flecha.

Por exemplo, minha_variavel = 1, minha_variavel := 1 ou minha_variavel <- 1 poderiam significar que se armazenou o valor 1 na variável minha_variavel. Ao acessar o valor usando o nome minha_variavel, o valor informado será 1.

Inicialização

A primeira atribuição de valor a uma variável tem um nome especial: inicialização. Muitas linguagens permitem inicializar um valor diretamente na declaração da variável, algo que eu recomendo fazer.

Existem linguagens que inicializam variáveis com um valor padrão, como um valor considerado zero. Normalmente, os valores são zero para números (0 e 0.0), falso para valores lógicos, e a cadeia de caracteres vazia ("") para cadeias de caracteres. Entretanto, nem toda linguagem faz isso.

Em linguagens que não inicializarem um valor padrão, o valor inicial será desconhecido (também chamado de lixo). Simplificadamente, quaisquer dados que estivessem na memória antes da declaração da variável poderão servir como valor inicial da variável.

Assim, nunca assuma um valor inicial para uma variável antes de consultar a documentação da linguagem para descobrir qual o comportamento padrão. De forma geral, inicializar variáveis com valores iniciais apropriados para seu programa é uma boa prática.

Cópia de Variáveis

Caso se atribua o valor de uma variável a outra, o valor da primeira é copiado na segunda. A cópia pode ser uma cópia rasa ou uma cópia profunda, dependendo do tipo da variável e da linguagem de programação.

Cópias profundas duplicam os valores, fazendo com que as variáveis armazenem valores independentes. Ou seja, a posterior alteração de uma das variáveis não afeta a outra.

Cópias rasas são feitas usando referências. Ao invés de duplicatas, os valores são compartilhados. Em outras palavras, a posterior alteração de valor de uma das variáveis também afetará a outra.

Para tipos primitivos de dados, é comum que cópias sempre sejam profundas, gerando valores duplicados.

Escopo

Um escopo é uma região na qual um nome ou valor é válido. Em programação, normalmente utiliza-se dois escopos: escopo global e escopo local. Existem outros escopos (como escopo estático), mas eles são mais avançados.

Um nome definido com escopo global é válido em qualquer parte do programa. Um nome definido com escopo local é válido apenas dentro de um bloco com início e fim específicos.

De forma geral, deve-se optar pelo uso de escopo local sempre que possível. Isso ocorre porque identificadores devem ser únicos. Por exemplo, se você declarar uma variável chamada x, nenhuma outra variável no mesmo escopo poderá ter o nome x. Em outras palavras, caso o escopo de x seja global, nenhuma outra variável do programa poderá usar o nome x.

Tecnicamente, algumas linguagens de programação definem regras que permitem ocultar escopos mais externos em escopos mais internos. Isso é comumente chamado de shadowing (algo como sombreamento em inglês). Em linguagens assim, o valor usado será sempre o da variável definida no escopo mais interno quando houver conflitos de nomes.

Neste momento, a escolha entre escopo global ou local não fará diferença. Contudo, quando da introdução de subrotinas (funções, procedimentos ou métodos), o uso incorreto de escopo global pode acarretar em erros (potencialmente difíceis de depurar). Portanto, novamente, tente criar o hábito de usar escopo local sempre que possível.

O uso de escopo global tem aplicações mais avançadas válidas, como compartilhamento de memória. Ainda assim, normalmente pode-se evitá-lo criando-se abstrações de escopos locais.

Estado

Estado é um termo relacionado ao uso de variáveis. Estado significa algo cujo comportamento ou funcionamento pode variar de acordo com os valores atualmente armazenados.

Um programa com estado pode se recordar do que aconteceu em momentos anteriores, pois os valores passados são salvos em variáveis. Programas com estado são ditos stateful. O resultado de programas stateful pode variar de acordo com entradas e o estado atual.

Para uma analogia, pode-se considerar uma pessoa em dois dias distintos. Em uma dia que ela esteja feliz, um cumprimento pode resultar em uma resposta positiva. Em uma dia em que ela esteja muito brava, o cumprimento pode ser ignorado ou ter uma resposta negativa. Em ambos os casos, a entrada foi a mesma (um cumprimento), mas a reposta variou de acordo com o estado interno da pessoa.

Outro exemplo seria a pessoa reagir de forma diferente para cumprimentos de alguém que ela conheça ou não. A existência de estado permite que a pessoa recorde-se de interações prévias com outras pessoas.

Um programa sem estado não é, necessariamente, um programa sem variáveis, mas é um programa cujas variáveis internas não interferem nos processamentos internos de forma a alterar um resultado; ele não registra o que aconteceu no passado. Um programa sem estado é dito stateless. O resultado de um programa stateless depende apenas das entradas.

Para o exemplo anterior, a pessoa reagiria sempre da mesma forma para todo cumprimento. Ela também não lembraria de nenhuma outra pessoa; todo cumprimento seria como a primeira interação.

Variáveis em Programação

Usar variáveis em linguagens de programação é algo simples. Os conceitos podem parecer mais difíceis do que realmente são. Hora de exemplos práticos.

Fluxogramas: Flowgorithm

Variáveis em Flowgorithm utilizam ambos os conceitos de declaração e atribuição.

Para criar uma variável, clique com o botão direito em uma flecha, depois escolha o bloco Definição (Declare). Clique duas vezes no novo bloco. Escolha um nome para a variável e um tipo. Nomes de variáveis em Flowgorithm devem começar com uma letra; após a primeira letra, eles podem ter apenas letras e números. Neste momento, mantenha a opção Arranjo (vetor ou Array) inativa. Depois confirme a criação em OK.

Para realizar uma atribuição, clique com o botão direito em uma flecha (ela deve estar após a declaração de uma variável) e escolha a opção Atribuição (Assign). Digite o nome da variável, o valor desejado e confirme. Cadeias de caracteres devem ser escritas entre aspas duplas; valores lógicos devem ter os valores true (verdadeiro) ou false (falso).

Para escrever um valor no console, crie um bloco de saída Output e digite o nome da variável. Caso queira combinar texto e o valor da variável, você pode escrever a mensagem entre aspas duplas, adicionar uma letra e comercial (&) para concatenar os valores (que significa escrever um texto após o primeiro), e digitar o nome da variável em seguida. Por exemplo, para uma variável chamada numeroInteiro, você poderia escrever "Valor: " & numeroInteiro. Para continuar o texto, bastaria fazer novas concatenações. Por exemplo, "Valor: " & numeroInteiro & ". Texto continua aqui.".

Exemplo de declaração e atribuição de variáveis em Flowgorithm.

Como pode ser difícil de visualizar o imagem anterior, a próxima imagem ilustra o fluxograma ampliado.

Fluxograma completo em Flowgorithm.

Flowgorithm também permite gerar e visualizar implementações do fluxograma em diferentes linguagens de programação. Para isso, clique em Ferramentas (Tools), depois em Exibir código fonte (Source Code Viewer). A opção padrão utiliza um tipo de pseudocódigo (Pseudocódigo Automático ou Auto Pseudocode). Você pode alterá-la para uma linguagem de programação disponível na lista, para comparar diferentes sintaxes.

Exemplo de algoritmo gerado a partir do fluxograma por Flowgorithm.

É interessante notar que as cores do código ilustrado seguem as cores do fluxograma. Assim, você pode comparar a estrutura do programa em cada representação.

Linguagens de Programação Visual: Scratch

Em Scratch, opções para uso de variáveis estão no menu lateral Variáveis (Variables).

Para declarar uma variável, clique em Criar uma Variável (Make a Variable). Escolha um nome (por exemplo, meu_nome) e, opcionalmente, um ator. Para começar, você pode manter a opção padrão (Para todos os atores / _For all sprites). Em seguida, confirme.

Uma elipse (uma forma com cantos arrendondados) aparecerá com o nome da variável. Quando quiser utilizá-la, você deverá selecioná-la.

Para fazer uma atribuição, você usará o bloco mude nome da variável para valor (set nome da variável to value). Você pode clicar em nome da variável para escolher a variável declarada que você quiser. Em valor, você pode definir o valor da variável.

Caso você queira que o valor da variável sempre apareça no painel com a saída programa, marque o checkbox ao lado da elipse com a variável.

Para escrever o valor de uma variável, adicione um bloco diga Olá! (say Hello!). Em seguida, troque o valor Olá! pelo bloco com a variável desejada. Para isso, arraste a elipse com a variável até Olá e solte-a.

Para facilitar a visualização dos valores, é conveniente adicionar um intervalo de tempo entre blocos. Para isso, acesse Controle (Control) e escolha o bloco Espere 1 seg (_Wait 1 seconds). Outra opção é usar o bloco diga Olá! por 2 segundos (say Hello! for 2 seconds). Você pode alterar o valor 1 ou 2 para outro número que quiser. O número, inclusive, pode estar armazenado em uma variável numérica.

Exemplo de uso de variável em Scratch com a interface em Português.
Exemplo de uso de variável em Scratch com a interface em Inglês.

Para alterar o nome de uma variável ou apagá-la, você pode clicar com o botão direito do mouse da elipse da variável e escolher a opção correspondente.

Deve-se notar que Scratch não possui um tipo para valores lógicos. Caso queira usá-los, você pode usar Verdadeiro e Falso como texto, ou 1 para Verdadeiro e 0 para Falso. O problema é que, posteriormente, o uso de operações lógicas será difícil sem valores lógicos reais.

Uma alternativa é usar o bloco Not (vazio) para Verdadeiro, e o bloco And (vazio) para Falso. Quando vazios, os blocos anteriores, retornam, respectivamente, true e false, servindo aos propósitos (embora de forma desnecessariamente obscura).

Por fim, caso queira adicionar um comentário a um bloco, você pode clicar em um bloco com o botão direito e escolher a opção Comentar (Add Comment).

Exemplo de uso de valor lógico e comentário em Scratch com a interface em Português.
Exemplo de uso de valor lógico e comentário em Scratch com a interface em Inglês.

O comentário adiciona uma nota ao bloco selecionado. Você pode escrever o texto que quiser.

Linguagens de Programação Textual: JavaScript, Python, Lua, GDScript e C++

JavaScript, Python, Lua e GDScript são linguagens com tipagem dinâmica, ou seja, nas quais o interpretador é capaz de inferir o tipo da variável após a inicialização ou atribuição de um valor.

As quatro linguagens anteriores definem o tipo da variável de acordo com o valor fornecido. Em outras palavras, caso se atribua um valor de tipo diferente, o tipo da variável mudará para corresponder ao novo valor.

Nem toda linguagem de programação permite fazer isso. Em linguagens como C, C++ e Java, normalmente não se pode atribuir um valor de um tipo que não corresponda ao tipo da variável.

Pessoalmente, eu prefiro seguir a convenção de que toda variável tem um tipo, e que ele nunca deve ser alterado para a mesma variável. Isso facilita entender o código-fonte, pois o tipo sempre será sempre o adotado na inicialização.

GDScript opcionalmente permite a declaração de um tipo desejado para a variável. Caso fornecido, ele será adotado para a variável. Python também permite a sugestão de tipos em algumas circunstâncias. JavaScript possui uma implementação alternativa chamada TypeScript, que adiciona suporte a tipos explícitos.

Como as declarações e usos de variáveis em JavaScript, Python, Lua e GDScript serão similares, o exemplo a seguir também declara variáveis em C++. Além disso, a versão em GDScript fornece exemplos da tipagem opcional após a declaração padrão. Isso é feito de duas formas: com a sugestão de tipo, e com um operador especial, :=, que adota o tipo do valor inicializado como o tipo da variável. Quando programar, você pode escolher uma das três maneiras para declarar as variáveis de seu programa.

let numero_inteiro = -1
let numero_real = -1.0
let valor_logico = true
let cadeia_caracteres = "Olá, meu nome é Franco"

console.log(numero_inteiro, ": ", typeof(numero_inteiro))
console.log(numero_real, ": ", typeof(numero_real))
console.log(valor_logico, ": ", typeof(valor_logico))
console.log(cadeia_caracteres, ": ", typeof(cadeia_caracteres))

numero_inteiro = 123
numero_real = 123.456
valor_logico = false
cadeia_caracteres = "Tchau!"

console.log(numero_inteiro)
console.log(numero_real)
console.log(valor_logico)
console.log(cadeia_caracteres)
numero_inteiro = -1
numero_real = -1.0
valor_logico = True
cadeia_caracteres = "Olá, meu nome é Franco"

print(numero_inteiro, ": ", type(numero_inteiro))
print(numero_real, ": ", type(numero_real))
print(valor_logico, ": ", type(valor_logico))
print(cadeia_caracteres, ": ", type(cadeia_caracteres))

numero_inteiro = 123
numero_real = 123.456
valor_logico = False
cadeia_caracteres = "Tchau!"

print(numero_inteiro)
print(numero_real)
print(valor_logico)
print(cadeia_caracteres)
local numero_inteiro = -1
local numero_real = -1.0
local valor_logico = true
local cadeia_caracteres = "Olá, meu nome é Franco"

print(numero_inteiro, ": ", type(numero_inteiro))
print(numero_real, ": ", type(numero_real))
print(valor_logico, ": ", type(valor_logico))
print(cadeia_caracteres, ": ", type(cadeia_caracteres))

numero_inteiro = 123
numero_real = 123.456
valor_logico = false
cadeia_caracteres = "Tchau!"

print(numero_inteiro)
print(numero_real)
print(valor_logico)
print(cadeia_caracteres)
extends Node

func _init():
    var numero_inteiro = -1
    var numero_real = -1.0
    var valor_logico = true
    var cadeia_caracteres = "Olá, meu nome é Franco"

    print(numero_inteiro, ": ", typeof(numero_inteiro))
    print(numero_real, ": ", typeof(numero_real))
    print(valor_logico, ": ", typeof(valor_logico))
    print(cadeia_caracteres, ": ", typeof(cadeia_caracteres))

    numero_inteiro = 123
    numero_real = 123.456
    valor_logico = false
    cadeia_caracteres = "Tchau!"

    print(numero_inteiro)
    print(numero_real)
    print(valor_logico)
    print(cadeia_caracteres)

    ################################################################
    # Com tipo explícito.                                          #
    ################################################################

    var numero_inteiro_2: int = -1
    var numero_real_2: float = -1.0
    var valor_logico_2: bool = true
    var cadeia_caracteres_2: String = "Olá, meu nome é Franco"

    print(numero_inteiro_2, ": ", typeof(numero_inteiro_2))
    print(numero_real_2, ": ", typeof(numero_real_2))
    print(valor_logico_2, ": ", typeof(valor_logico_2))
    print(cadeia_caracteres_2, ": ", typeof(cadeia_caracteres_2))

    ################################################################
    # Com tipo fixo baseado na primeira atribuição.                #
    ################################################################

    var numero_inteiro_3 := -1
    var numero_real_3 := -1.0
    var valor_logico_3 := true
    var cadeia_caracteres_3 := "Olá, meu nome é Franco"

    print(numero_inteiro_3, ": ", typeof(numero_inteiro_3))
    print(numero_real_3, ": ", typeof(numero_real_3))
    print(valor_logico_3, ": ", typeof(valor_logico_3))
    print(cadeia_caracteres_3, ": ", typeof(cadeia_caracteres_3))
#include <iostream>
#include <string>

int main()
{
    int numero_inteiro = -1;
    double numero_real = -1.0;
    bool valor_logico = true;
    std::string cadeia_caracteres = "Olá, meu nome é Franco";

    std::cout << numero_inteiro << std::endl;
    std::cout << numero_real << std::endl;
    std::cout << valor_logico << std::endl;
    std::cout << cadeia_caracteres << std::endl;

    numero_inteiro = 123;
    numero_real = 123.456;
    valor_logico = false;
    cadeia_caracteres = "Tchau!";

    std::cout << numero_inteiro << std::endl;
    std::cout << numero_real << std::endl;
    std::cout << valor_logico << std::endl;
    std::cout << cadeia_caracteres << std::endl;

    return 0;
}
Exemplo de uso de variáveis nas linguagens de programação Python, Lua, GDScript e JavaScript utilizando os trechos de código anteriores.

Algumas notas para os exemplos:

  1. Todas as variáveis foram inicializadas com um valor na declaração;

  2. O valor de uma variável pode ser alterado após a declaração. Isso é algo permitido em praticamente toda linguagem de programação, embora existam exceções. Por exemplo, linguagens lógicas, como Prolog, podem definir unificações ao invés de atribuições, impedindo que o valor de uma variável altere-se após unificado.

  3. Em Lua, local permite a declaração de variáveis locais. O mesmo vale para let em JavaScript. Caso se omita a palavra reservada, a variável será global. JavaScript também permite usar var para declaração de variáveis, resultando em escopo de função, algo um pouco diferente das convenções de escopo para blocos usadas em muitas linguagens de programação. Assim, o uso de let costuma ser preferível.

  4. Em GDScript e C++, a declaração de variáveis dentro de _init() e main(), respectivamente, resulta em variáveis locais. Declarar as variáveis fora das funções resultaria em declarações de variáveis globais.

  5. Em Python, as variáveis são globais por padrão. Para declarar variáveis locais, seria necessário introduzir uma função, como main().

    def main():
        numero_inteiro = -1
        numero_real = -1.0
        valor_logico = True
        cadeia_caracteres = "Olá, meu nome é Franco"
    
        print(numero_inteiro, ": ", type(numero_inteiro))
        print(numero_real, ": ", type(numero_real))
        print(valor_logico, ": ", type(valor_logico))
        print(cadeia_caracteres, ": ", type(cadeia_caracteres))
    
        numero_inteiro = 123
        numero_real = 123.456
        valor_logico = False
        cadeia_caracteres = "Tchau!"
    
        print(numero_inteiro)
        print(numero_real)
        print(valor_logico)
        print(cadeia_caracteres)
    
    if (__name__ == "__main__"):
        main()

    Variáveis declaradas dentro de funções serão variáveis locais. A regra é a mesma usada para GDScript e C++. Ela também vale para muitas outras linguagens de programação. Exceções incluem linguagens como Lua e JavaScript, que utilizam palavras reservadas especiais para a declaração de variáveis locais.

Valores de variáveis são, como o nome sugerem, variáveis e passíveis de alteração. Para se declarar valores que não se pode alterar após a primeira atribuição (ou seja, após a inicialização), existem linguagens de programação que permitem a definição de constantes.

Por outro lado, muitas linguagens de programação não permitem redeclarar uma variável em um mesmo escopo. Como isso pode ocorrer usando os exemplos em JavaScript deste material, pode ser útil forçar a criação de um novo escopo usando chaves.

{
let x = 1
console.log(x)
}

O recurso é conveniente caso um exemplo resulte em erro de redeclaração de variável.

Cópias

Atribuições podem ser feitas de uma variável para outra. Nesse caso, o valor da esquerda do operador de atribuição receberá o valor resultante da direita do operador.

let x = 123
let y = x
console.log(x, y)

x = 456
console.log(x, y)

x = y
console.log(x, y)
x = 123
y = x

print(x, y)
x = 456
print(x, y)

x = y
print(x, y)
local x = 123
local y = x
print(x, y)

x = 456
print(x, y)

x = y
print(x, y)
extends Node

func _init():
    var x = 123
    var y = x
    print(x, y)

    x = 456
    print(x, y)

    x = y
    print(x, y)
#include <iostream>
#include <string>

int main()
{
    int x = 123;
    int y = x;
    std::cout << x << " " << y << std::endl;

    x = 456;
    std::cout << x << " " << y << std::endl;

    x = y;
    std::cout << x << " " << y << std::endl;

    return 0;
}

Inspeção de Variáveis Usando REPL

Convém destacar uma funcionalidade prática para programação usando Read, Evaluate, Print, Loop (REPL; leia, avalue, escreva, repita). Após declarar uma variável, muitos REPLs permitem inspecionar o valor armazenado digitando-se o nome da variável como comando.

>>> let x = "Franco"undefined
>>> x"Franco"
js78js> let x = "Franco"js> x"Franco"
nodeWelcome to Node.js v16.11.1.
Type ".help" for more information.
> let x = "Franco"undefined
> x'Franco'
pythonPython 3.9.7 (default, Oct 10 2021, 15:13:22)
[GCC 11.1.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> x = "Franco">>> x'Franco'
luaLua 5.4.3  Copyright (C) 1994-2021 Lua.org, PUC-Rio
> x = "Franco"> xFranco

Em ambientes gráficos, alguns IDEs fornecem painéis com depuradores ou opções para visualização de variáveis. Thonny (Python), ZeroBrane Studio (Lua), e Godot Engine (GDScript) possuem depuradores integrados para inspeção de variáveis.

Constantes

Variáveis são valores que podem ser alterados. Constantes são valores inalteráveis após inicialização. A tentativa de redefinir o valor de uma constante resulta em erro (na maioria das linguagens de programação, embora existam exceções).

O uso de constantes possui alguns benefícios:

  1. Pode facilitar a leitura e interpretação de um valor, evitando-se os chamados números mágicos (valores arbitrários que podem não fazer sentido de imediato);
  2. Permite redefinir todas as ocorrências de seu valor em um projeto de forma simplificada e com segurança. Desde que todas as ocorrências usem o nome da constante, basta alterar o valor definido na declaração da constante;
  3. Em linguagens nas quais a redefinição de valores para constantes resultam em erro, o uso evita alterações acidentais de valores que deveriam ser inalteráveis.

Nem toda linguagem de programação permite a definição de constantes. Em linguagens que não permitam a criação, uma alternativa é definir um estilo próprio para nomenclatura de constantes e assegurar-se de nunca mudar o valor após a inicialização de uma variável adotada como constante. Embora não seja o ideal, é uma alternativa possível.

Estilos para Constantes

É comum escolher um estilo para nomes de constantes que permita identificá-las como tal no código-fonte de um programa. Escolhas usuais são escrever todas as letras em maiúsculas, ou adotar um prefixo arbitrário, como k ou k_. Por exemplo, NOME_CONSTANTE, k_nome_constante ou kNomeConstante.

Linguagens de Programação Textual: JavaScript, Python, Lua, GDScript e C++

JavaScript, GDScript e C++ permitem a definição de constantes. Lua permite a partir da versão 5.4; caso esteja usando uma versão mais antiga, não será possível usar <const> para definir constantes. Python possui uma proposta para incorporação opcional de constantes à linguagem.

Os exemplos a seguir ilustram como usar constantes em cada uma das linguagens anteriores.

const NUMERO_INTEIRO = -1
const NUMERO_REAL = -1.0
const VALOR_LOGICO = true
const CADEIA_CARACTERES = "Olá, meu nome é Franco"

console.log(NUMERO_INTEIRO, ": ", typeof(NUMERO_INTEIRO))
console.log(NUMERO_REAL, ": ", typeof(NUMERO_REAL))
console.log(VALOR_LOGICO, ": ", typeof(VALOR_LOGICO))
console.log(CADEIA_CARACTERES, ": ", typeof(CADEIA_CARACTERES))
from typing import Final

NUMERO_INTEIRO: Final = -1
NUMERO_REAL: Final = -1.0
VALOR_LOGICO: Final = True
CADEIA_CARACTERES: Final = "Olá, meu nome é Franco"

print(NUMERO_INTEIRO, ": ", type(NUMERO_INTEIRO))
print(NUMERO_REAL, ": ", type(NUMERO_REAL))
print(VALOR_LOGICO, ": ", type(VALOR_LOGICO))
print(CADEIA_CARACTERES, ": ", type(CADEIA_CARACTERES))
local NUMERO_INTEIRO <const> = -1
local NUMERO_REAL <const> = -1.0
local VALOR_LOGICO <const> = true
local CADEIA_CARACTERES <const> = "Olá, meu nome é Franco"

print(NUMERO_INTEIRO, ": ", type(NUMERO_INTEIRO))
print(NUMERO_REAL, ": ", type(NUMERO_REAL))
print(VALOR_LOGICO, ": ", type(VALOR_LOGICO))
print(CADEIA_CARACTERES, ": ", type(CADEIA_CARACTERES))
extends Node

const NUMERO_INTEIRO = -1
const NUMERO_REAL = -1.0
const VALOR_LOGICO = true
const CADEIA_CARACTERES = "Olá, meu nome é Franco"

################################################################
# Com tipo explícito.                                          #
################################################################
const NUMERO_INTEIRO_2: int = -1
const NUMERO_REAL_2: float = -1.0
const VALOR_LOGICO_2: bool = true
const CADEIA_CARACTERES_2: String = "Olá, meu nome é Franco"

################################################################
# Com tipo fixo baseado na primeira atribuição.                #
################################################################
const NUMERO_INTEIRO_3 := -1
const NUMERO_REAL_3 := -1.0
const VALOR_LOGICO_3 := true
const CADEIA_CARACTERES_3 := "Olá, meu nome é Franco"

func _init():
    print(NUMERO_INTEIRO, ": ", typeof(NUMERO_INTEIRO))
    print(NUMERO_REAL, ": ", typeof(NUMERO_REAL))
    print(VALOR_LOGICO, ": ", typeof(VALOR_LOGICO))
    print(CADEIA_CARACTERES, ": ", typeof(CADEIA_CARACTERES))

    print(NUMERO_INTEIRO_2, ": ", typeof(NUMERO_INTEIRO_2))
    print(NUMERO_REAL_2, ": ", typeof(NUMERO_REAL_2))
    print(VALOR_LOGICO_2, ": ", typeof(VALOR_LOGICO_2))
    print(CADEIA_CARACTERES_2, ": ", typeof(CADEIA_CARACTERES_2))

    print(NUMERO_INTEIRO_3, ": ", typeof(NUMERO_INTEIRO_3))
    print(NUMERO_REAL_3, ": ", typeof(NUMERO_REAL_3))
    print(VALOR_LOGICO_3, ": ", typeof(VALOR_LOGICO_3))
    print(CADEIA_CARACTERES_3, ": ", typeof(CADEIA_CARACTERES_3))
#include <iostream>
#include <string>

int main()
{
    const int NUMERO_INTEIRO = -1;
    const double NUMERO_REAL = -1.0;
    const bool VALOR_LOGICO = true;
    const std::string CADEIA_CARACTERES = "Olá, meu nome é Franco";

    std::cout << NUMERO_INTEIRO << std::endl;
    std::cout << NUMERO_REAL << std::endl;
    std::cout << VALOR_LOGICO << std::endl;
    std::cout << CADEIA_CARACTERES << std::endl;

    return 0;
}
Exemplo de uso de constantes nas linguagens de programação Python, Lua, GDScript e JavaScript utilizando os trechos de código anteriores.

Algo a notar é que, tanto em Python quanto em Lua, existem casos em que é possível alterar o valor de constantes. Assim, deve-se tomar cuidado para não modificar o valor inadvertidamente após a declaração.

Novos Itens para Seu Inventário

Ferramentas:

  • Inspeção de variáveis em REPL.

Habilidades:

  • Manipulação de memória primária.

Conceitos:

  • Memória;
  • Memória primária;
  • Memória secundária;
  • Variáveis;
  • Declaração de variável;
  • Atribuição;
  • Cópia;
  • Cópia rasa;
  • Cópia profunda;
  • Inicialização de variável;
  • Escopo;
  • Estado;
  • Constantes.

Recursos de programação:

  • Declaração de variáveis;
  • Atribuição;
  • Uso de variáveis;
  • Declaração de constantes;
  • Uso de constantes.

Pratique

Escolha alguns dos tipos definidos para a seção Pratique de Tipos de Dados. Em seguida, declare variáveis em uma linguagem de sua escolha e faça atribuições a elas. Escreva os valores resultantes no console. Embora simples, a atividade exercitará todos os conceitos práticos estudados até o momento.

Para complementar a prática, declare algumas contantes para cada tipo de dado. Em seguida, tente redefinir o valor com uma nova atribuição. O que ocorre ao executar o programa?

Próximos Passos

Com variáveis, você pode armazenar valores em memória primária, consultá-los quando quiser, e modificá-los quando necessário. Com constantes, você pode simplificar a leitura do código e facilitar alterações posteriores de valores.

Contudo, todos os valores de variáveis até o momento precisaram ser definidos no código-fonte do programa. Em outras palavras, apenas pessoas que saibam programar poderiam alterar valores.

Para continuar sua jornada de desenvolvimento de software, como permitir que pessoas que, diferentemente de você, ainda não saibam programas, mais queiram usar seus sistemas, possam alterar valores de variáveis?

Se a saída permite a um sistema exibir valores internos, a entrada permitirá receber dados externos para processamento pelo programa. Aprender a utilizar entrada é um possível próximo passo.

  1. Introdução;
  2. Ponto de entrada e estrutura de programa;
  3. Saída (para console ou terminal);
  4. Tipos de dados;
  5. Variáveis e constantes;
  6. Entrada (para console ou terminal);
  7. Aritmética e Matemática básica;
  8. Operações relacionais e comparações;
  9. Operações lógicas e Álgebra Booleana;
  10. Estruturas de condição (ou condicionais ou de seleção);
  11. Subrotinas: funções e procedimentos;
  12. Estruturas de repetição (ou laços ou loops);
  13. Vetores (arrays), cadeias de caracteres (strings), coleções (collections) e estruturas de dados;
  14. Registros (structs ou records);
  15. Arquivos e serialização (serialization ou marshalling);
  16. Bibliotecas;
  17. Entrada em linha de comando;
  18. Operações bit-a-bit (bitwise operations);
  19. Testes e depuração.
  • Informática
  • Programação
  • Iniciante
  • Pensamento Computacional
  • Aprenda a Programar
  • Python
  • Lua
  • Javascript
  • Godot
  • Gdscript
  • CPP
  • Scratch
  • Flowgorithm