[ Utilidade | Memória | Variáveis | Expressões | Contexto ]

Introdução às variáveis e expressões aritméticas

Nesta seção apresentarei o conceito de variáveis e de expressões aritméticas. Esses são conceitos essenciais para a construção de algoritmos, sem eles seria inviável produzir um algoritmo flexível, que pudesse ser aplicado sobre dados distintos (e.g., o algoritmo da soma é flexível no sentido de podermos somar diferentes valores, não apenas 2 valores fixados).

O que é uma variável?

Uma explicação simples, para não especialistas em programação, é que uma variável é um nome quer pode ser associado à diferentes valores. Esse nome usualmente começa com uma letra, sendo composto por letras e números.

Usualmente, em qualquer linguagem de programação, sempre que usamos em um código uma variável, significa que deve-se pegar o valor armazenado nesta variável. Assim, um trecho com `10*b`, implica em pegar o valor corrente armazenado na variável `b` e multiplicá-lo por `10`.

Mas como o nome sugere, deve ser possível alterar o valor armazenado em uma variável, isso é feito por uma instrução de atribuição. Pode-se atribuir um valor à uma variável, como nos exemplos:

- <codigo1>i = 0</codigo1> significa que a variável de nome i (neste ponto do código) estará guardando o valor inteiro 0;
- <codigo1>fat = i*fat</codigo1> é exemplo mais "sofisticado", significa que a variável de nome fat deve receber o valor que anteriormente (à este comando) era guardado em fat multiplicado pelo valor guardado na variável i.

Fig. 1. Variáveis i e fat recebendo valores (constante e expressão).
Note que o símbolo "=" não tem o sentido usual da Matemática, em boa parte das linguagens de programação "`var = EXPRESSAO`" significa que deve-se computar o valor da expressão no lado direito da atribuição e depois atribuir este valor à variável de nome var. Isso fica mais claro no segundo exemplo "`fat = i*fat`".
Por isso diz-se que var recebe EXPRESSAO.

As linguagens que usam = como atribuição, usam == (dois símbolos de igualdade) para comparar valores. Um exceção é a linguagem Pascal que usa := para atribuição e = para comparações.

Sabendo um pouco mais sobre o que é uma variável

Uma variável um conceito comum na Matemática e presente em todas as linguagens de programação, que de uma forma implementa o conceito. Variável é a associação de uma posição específica de memória do computador a um nome, que geralmente não pode ser um nome de comando da linguagem (palavra reservada).

Existem vários tipos de variáveis, como variável inteira ou flutuante. O que as difere é o número de bits necessário para representar e como esses bits são interpretados. Por exemplo, se houver um tipo natural (ou inteiro positivo), que use 16 bits, poderia-se representar 216=65526 naturais distintos, ou seja, desde 0 até 65525. Se tentar representar o valor 65526 ocorreria um erro e algum número "estranho" apareceria na tela.

Fig. 2. Representação da memória com agrupamentos em bytes (8 bits).

Na figura 2 está ilustrado a associação de 16 bits à uma variável inteira de nome n, seguido de 32 bits correspondentes à uma variável float, usando o padrão IEEE 754 (o primeiro bit é o sinal s; os 8 bits seguintes correspondente ao expoente e e os últimos 23 à mantissa m - valor de x é s * m * 10e, sendo m entre 0 e 1). Por exemplo, se x=-102.003, então s=-1, m=102003 e e=-3, pois -102.003=-1 * 102003 * 10-3.

Para que serve variáveis

Ilustraremos a ideia e necessidade de variáveis a partir de um exemplo simples: como realizar o cálculo de gastos usando uma calculadora muito elementar.

Imagine uma calculadora simples, como ilustrado ao lado, dispondo de apenas um mostrador e apenas 4 operações (somar, subtrair, multiplicar e dividir). Se desejamos computar o gasto mensal com a padaria, devemos digitar sequencialmente os valores gastos, um a um, seguido do operador de soma `+`, sendo que ao final teclamos `=`. Vamos supor que os valores dos gastos foram `5`, `2`, `3`, `5` e `3`. Mas como foi possível obter a soma de todos os valores? Isso só foi possível por existir um "acumulador" (`AC`) para armazenar o primeiro valor digitado e depois disso, esse mesmo "acumulador" teve um novo valor a ele adicionado (ou acumulado): `AC := 5`, depois `AC := 5+2 = 7`. depois `AC := 7+3 = 10`. depois `AC := 10+5 = 15` e por último `AC := 15+3 = 18`.

Podemos pensar que calculadora está fazendo o papel da Unidade Lógico Aritmética (Arithmetic logic unit (ALU) em Inglês) de um computador. O recurso da calculadora que armazena os valores computados (que denotamos por `AC`) seria o equivalente a um registrador ou a uma posição de memória em um computador. Para se ter uma noção da diferença, deve-se notar que um computador moderno dispõe de vários registradores e o que tem sido denominado memória, ordens de grandeza maiores que os registradores, hoje compra-se computadores com ao menos 2 Gb de memória RAM (Gb = giga bytes = 1 bilhão de bytes)

Deve-se destacar que o valor armazenado em um registrador ou na memória pode ser alterado, podendo-se dizer que esses valores variam, vindo dai seu nome de variável. Para nomear as variáveis, pode-se usar qualquer combinação de letras e números (iniciando por uma letra). Por exemplo, uma instrução alterando o valor da variável de nome `discriminante` em uma linguagem de programação qualquer:

`discriminante = b*b - 4 * a * c`
que significa que a variável de nome `discriminante` recebe o resultado da expressão "o quadrado do valor armazenado em `b` menos `4` vezes o conteúdo em `a` vezes o conteúdo em `c`".

Voltando aos tipos de variáveis, existe a necessidade de declarar qual é o tipo da variável, em uma linguagem de programação como C isso deve ser feito de modo explicito, por exemplo, podemos declarar e iniciar uma variável inteira e uma flutuante com o valor 5 da seguinte forma:
`<verm>int</verm> AC = 5; <verm>float</verm> ac = 5; <cyan>// em C, "AC" NAO e' a mesma coisa que "ac"!</cyan>`.
Por outro lado, a linguagem Python não dispõe de um mecanismo para indicar o tipo de variável explicitamente, a primeira atribuição usando um nome funciona como declaração:
`AC = 5; ac = 5.0; <cyan>#</cyan> em Python, "AC" NAO e' a mesma coisa que "ac"!`.

Portanto, variável é essencial para que possamos fazer com que o programa receba algum dado de nosso interesse. Mesmo em um editor de texto isso ocorre, o texto que digitamos é armazenado (de alguma forma, em variáveis!).

Se você estiver interessado em saber um pouco mais sobre o que é o conceito de variável, estude o restante desse texto.

Memória, bits e bytes

O conceito de variável foi introduzido com o surgimento as linguagens de programação, antes disso era necessário fazer um acesso direto às posições de memória. Portanto, variável está associada às linguagens de programação (em um compilador ou via um interpretador), tendo sido definido para facilitar o armazenamento e recuperação de valores em determinada posição de memória (para facilitar a programação).

Em última análise, os dados presentes na memória do computador são uma sequência de bits e um bit corresponde a uma posição de memória que pode armazenar o valor 0 ou o valor 1. No início da computação moderna a menor quantidade de bits que podia ser acessada eram 8 bits, que foi denominado por byte.

Fig. 3. Representação da memória com agrupamentos em bytes (8 bits).

Desse modo, toda informação armazenada no computador é uma sequência de bytes e o tratamento de cada que se dá para cada uma dessas sequências pode variar, por exmeplo, pode considerar a sequência `0010` com uma letra ou como um inteiro. Ou seja, de acordo com o contexto, se ela estiver associada a uma variável do tipo inteiro pode-se interpretar a sequência como um número inteiro, se for uma variável do tipo caractere, como um caractere.

Variáveis inteiras e reais

Mas qual a relação entre bytes e variáveis?
Primeiro, deve-se saber a priori quanto "espaço" cada tipo de variável ocupará na memória. Esse "tamanho" também determinará quanto valores distintos tal tipo de variável poderá armazenar. Por exemplo, suponha que determinado computador (muito, muito antigo) utilize apenas um byte para armazenar inteiros, como em um byte existem oito (8) bits, então nesse computador poderia existir 28 (ou seja, 256) inteiros distintos (mas como existem negativos e positivos um deles ficaria com 27=128 valores e o outro com 27-1=127).
Desse modo, nesse computador de inteiros com 8 bits, uma variável inteira na verdade guardaria o endereço inicial (a posição de seu primeiro bit) e onde tiver referencia a ela, o computador estaria programado para pegar os 8 bits a partir dessa posição e interpretá-lo como um valor inteiro.
Exemplos: a sequência de bits `00000101` seria interpretado como 5 (pois 1*22+1*20=5) e a sequência de bits `00010101` seria interpretado como 5 (pois 1*24+1*22+1*20=21).

Existe uma regra para sintática para a construção de nomes de variáveis, por exemplo, em linguagens de programação como C ou Python, uma variável é uma sequência de letras, dígitos e do caractere "barra baixa" ('`_`'), devendo começar com letra, mas não pode coincidir com nome de algum comando da linguaguem (que são denominados palavra reservada).

Existem outros tipos de variáveis como os valores "reais", que devido à técnica de implementação (vide figura 2) é denominado flutuante (float).

Do ponto de vista prático, vejamos como se usa variáveis do tipo int e do tipo float nas linguagens C e Python.

| C | Python
1 | <verm>int</verm> n1,n2; | <cyan># desnecessário declarar em Python</cyan>
2 | n1 = 1; | n1 = 1 <cyan># primeira atribuicao equivale `a declarar em Python</cyan>
3 | <verd>scanf</verd>("%d", &n2); | n2 = int(<verd>input</verd>())
4 | <verd>printf</verd>("n1=%d e n2=%d\n", n1, n2); | <verd>print</verd> "n1=", n1, " e n2=", n2 <cyan>#</cyan> Python 2
5 |  | <verd>print</verd>("n1=", n1, " e n2=", n2) <cyan>#</cyan> Python 3

Note as diferenças entre C e Python:

- De modo geral, todo comando em C precisa de ';' como finalizador.
- Na linha 1 percebe-se que em C é obrigatório declarar as variáveis, enquanto que em Python não.
- Na linha 3 nota-se que C utiliza a função pré-definida de nome <verd>scanf</verd> para pegar valores digitados pelo usuário enquanto Python usa o input. O <verd>scanf</verd> usa o formatador especial '%d' para forçar o computador a interpretar os bytes como um inteiro, enquanto o input pega os bytes digitados e o submete à outra função pré-definida Python, o int(...), que converte os bytes lidos para um inteiro.
- Na linha 4 nota-se o mesmo tipo de diferença, C utiliza a função <verd>printf</verd> para imprimir também com o formatador para inteiro '%d', além de separar em 2 blocos, o primeiro para formatar a saída, que é cercado por aspas dupla e o segunda, uma lista de variáveis compatíveis com o formatador. Já em Python, usa-se os caracteres entre aspas e as variáveis misturados, separador por vírgula.
- Vale destacar que a linha 4 apresenta a sintaxe do Python antes da versão 3, enquanto que a linha 5 apresenta o mesmo resultado mas para o Python a partir da sua versão 3.

Expressões aritméticas

Do mesmo modo que em matemática é essencial efetuarmos operações aritméticas com valores numéricos, o mesmo ocorre com o computador, na verdade efetuar contas de modo rápido e "sem erro" (na verdade existem erros numéricos, mas este é outro assunto) foi a grande motivação para se construir os computadores.

Neste, os agrupamentos de valores, variáveis e operadores aritméticos recebem o nome de expressão aritmética. De modo geral, podemos conceituar uma expressão aritmética EA como:

1. EA := K: uma constante numérica é uma expressão aritmética
2. EA := EA + EA | EA - EA | EA * EA | EA / EA: uma expressão aritmética seguida de um operador binário (com 2 itens) e seguida por outra expressão aritmética é uma expressão aritmética

Os operadores artiméticos binários, tanto em C quanto em Python são:

Operação | Operador | Exemplo
soma | + | 2 + 4
subtração | - | n1 + 1
multiplicação | * | 3 * n2
divisão | / | n1 / n2

Note que foi usado espaço em branco entre os operando e operadores, mas isso não é obrigatório.

O resultado de uma expressão aritmética depende do contexto

É importante observar que dependendo do contexto o resultado de uma expressão é um ou outro, quer dizer, se os valores envolvidos forem todos eles inteiros, o resultado será inteiro, entretanto havendo um valor real, a resposta final será real.

A importância disso fica clara ao examinar dois exemplos simples: 3 / 2 * 2 e 3.0 / 2 * 2. Em várias linguagens de programação a primeira expressão resulta o valor 2, enquanto a segunda 3.0. A razão é que no primeiro caso todos valores são inteiros, então o cômputo é realizado com aritmética de precisão inteira, ou seja, ao realizar o primeiro cômputo 3/2, o resultado é 1 (e não 1.5 como no segundo caso), daí o segundo operador é feito com os valores 1 * 2 resultando o valor 2.

Por exemplo, na linguagem C, a sintaxe e o resultado para as expressões acima está indicada no código abaixo:

    <incl1>#include</incl1> <stdio.h>
    <verm>void</verm> main (<verm>void</verm>) {
      <cyan>//                                                Resultados</cyan>
      <verd>printf</verd>("3 / 2 * 2 = %d\n",    3 / 2 * 2);     <cyan>//  3 / 2 * 2 = 2</cyan>
      <verd>printf</verd>("3.0 / 2 * 2 = %f\n",  3.0 / 2 * 2);   <cyan>//  3.0 / 2 * 2 = 3.000000</cyan>
      }

Entretanto existe exceção, na versão 3 do Python, ao usar o operador de divisão `/`, ele automaticamente converte o resultado para número real. O bloco de comandos abaixo ilustra a diferença entre o Python 2 e o Python 3:

    <cyan># Resultados em :                       Python 2</cyan>                | <cyan># Python 3/cyan>
    <verd>print</verd>("3 / 2 * 2=", 3 / 2 * 2);       <cyan># ('3 / 2 * 2=', 2)       | 3 / 2 * 2= 3.0/cyan>
    <verd>print</verd>("3.0 / 2 * 2=", 3.0 / 2 * 2);   <cyan># ('3.0 / 2 * 2=', 3.0)   | 3.0 / 2 * 2= 3.0/cyan>
    <verd>print</verd>("3 // 2 * 2=", 3 // 2 * 2);     <cyan># ('3 // 2 * 2=', 2)      | 3 // 2 * 2= 2/cyan>
    <verd>print</verd>("3.0 // 2 * 2=", 3.0 // 2 * 2); <cyan># ('3.0 // 2 * 2=', 2.0)  | 3.0 // 2 * 2= 2.0/cyan>

Leônidas de Oliveira Brandão
http://line.ime.usp.br

Alterações:
2020/10/23: acerto vírgulo faltante
2020/10/16: cor include
2020/08/15: novo formato, pequenas revisões
2020/07/06: nova seção inicial (" O que é uma variável?");
2019/06/05: as seções inicial ("Ideia de variável") e final ("O resultado de uma expressão aritmética depende do contexto") foram estendidas;
2019/06/04: adicionada nova seção (inicial) "Ideia de variável";
2017/04/14: adicionados novos itens (como explicação adicional sobre expressões aritméticas).