sobre variáveis, ponteiros, arrays, parâmetros e alocação ...lucas.frucht/variaveis.pdf ·...

6

Click here to load reader

Upload: tranquynh

Post on 26-Jan-2019

212 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Sobre Variáveis, Ponteiros, Arrays, Parâmetros e Alocação ...lucas.frucht/variaveis.pdf · program variavel; var a : integer; b : char; c : real; begin end. Rotulos Endereço

Sobre Variáveis, Ponteiros, Arrays, Parâmetros e Alocação de Memória

Queridos,

Este texto ainda não está terminado. Ainda vou mudar alguns trechos e ajeitar a

formatação, principalmente dos exemplos. Ainda assim, preferi divulgar essa versão

temporária para que vocês possam estudar para a prova de terça-feira.

O texto trata também de alguns assuntos que vocês ainda não aprenderam. Por ora,

podem pular as partes que falam de linguagens forte e fracamente tipadas, ponteiros e

alocação de memória.

Como sempre, fico a disposição para tirar qualquer dúvida que possa surgir sobre o

texto.

Boa prova!

Cordialmente,

Lucas Frucht

Variáveis

Por trás de todos os demais conceitos que serão abordados nesse texto está o conceito de variável.

Embora seja um conceito relativamente simples (ou talvez, justamente, por ser simples), ele não costuma

ser explorado em profundidade. Dominar este conceito é a chave para entender os demais.

Declarar uma variável em seu código-fonte é dizer ao compilador que ele deve reservar um espaço na

memória com um determinado tamanho (que depende do tipo da variável) e interpretar o conteúdo

daquele espaço como sendo de um determinado tipo. A segunda é mais importante nas linguagens

fortemente tipadas. O nome que damos à variável é um rótulo com o qual a identificamos para o

compilador.

program variavel;

var

a : integer;

b : char;

c : real;

begin

end.

Rotulos Endereço Conteúdo

0000 0000

a 00c4 5d00

00c4 5d01

b 00c4 5d02

c 00c4 5d03

00c4 5d04

00c4 5d05

00c4 5d06

00c4 5d07

Uma vez que o espaço é reservado, ele poderá ser usado para armazenar diferentes valores ao longo da

execução do programa. Sempre que usamos uma variável o compilador acessa a posição da memória

associada àquele rotulo para obter seu conteúdo atual. Quando atribuímos um novo valor a ela, o

compilador armazena o valor na posição de memória associada ao rotulo.

Page 2: Sobre Variáveis, Ponteiros, Arrays, Parâmetros e Alocação ...lucas.frucht/variaveis.pdf · program variavel; var a : integer; b : char; c : real; begin end. Rotulos Endereço

Vale lembrar que não existe posição de memória vazia. Quando o compilador reserva o espaço na

memória ele continuará com a informação que estava lá antes do programa ser executado. Por esse

motivo, nunca podemos assumir que uma variável guarda um determinado valor sem antes inicializá-la

(dar a ela um valor inicial).

program variavel;

var

a : integer;

b : char;

c : real;

begin

a := 20;

end.

Rotulos Endereço Conteúdo

0000 0000 ?

⁞ ⁞

a 00c4 5d00 20

00c4 5d01

b 00c4 5d02 ?

c 00c4 5d03

? 00c4 5d04

00c4 5d05

00c4 5d06

00c4 5d07 ?

⁞ ⁞

Pascal é uma linguagem fortemente tipada. Suas variáveis dos tipos byte e char, por exemplo, têm o

mesmo tamanho, mas seus conteúdos são interpretados de forma distinta. O tipo byte é usado para

armazenar números, enquanto o tipo char é usado para armazenar caracteres. A linguagem não permite

que variáveis do tipo byte sejam usadas em funções (e procedimentos) criadas para manipular caracteres.

Da mesma forma, não é permitido que variáveis do tipo char sejam usadas em funções (e procedimentos)

criadas para manipular números, nem em expressões aritméticas. Qualquer um desses usos inadequados

irá resultar em um erro de compilação.

C é uma linguagem fracamente tipada. Não há nenhum outro tipo nativo cujas variáveis tenham o mesmo

tamanho das variáveis do tipo char. Variáveis desse tipo podem ser usadas tanto para armazenar

caracteres quanto números e cabe ao desenvolvedor garantir que as funções que manipularão essas

variáveis interpretarão seu conteúdo de forma adequada. É possível, inclusive, somar o caractere ‘1’ com

o caractere ‘2’; e o resultado não será o caractere ‘3’ (tipicamente será o caractere ‘c’). Já se o caractere

‘a’ for somado com o número 1 o resultado, tipicamente, será ‘b’1.

Ponteiros

Embora exista uma grande mítica em torno deles, os ponteiros não são nada além de mais um tipo de

variável. A única diferença está no modo como o compilador interpreta o conteúdo de variáveis desse

tipo. Ao invés de interpretar como um caractere, um número inteiro ou um decimal, o conteúdo de

ponteiros será interpretado como um endereço de memória2. Por isso, que se diz que um ponteiro

“aponta” para uma posição de memória.

As linguagens que possuem ponteiros oferecem operadores para permitir que seja acessado o conteúdo da

posição de memória que está armazenada em um ponteiro. Adicionalmente, o tipo do ponteiro indica o

1 Foram considerados resultados típicos os que são obtidos quando é usada uma tabela de codificação baseada no ASCII, como

é a maioria das utilizadas atualmente. 2 Em linguagens fracamente tipadas um número inteiro ou real pode ser interpretado com um ponteiro e vice-versa.

Page 3: Sobre Variáveis, Ponteiros, Arrays, Parâmetros e Alocação ...lucas.frucht/variaveis.pdf · program variavel; var a : integer; b : char; c : real; begin end. Rotulos Endereço

tamanho e como deve ser interpretado este conteúdo. Essas linguagens oferecem também operadores que

indicam o endereço de uma variável.

program ponteiros;

var

a, b, c : integer;

ptrB, ptrC : ^integer;

begin

a := 2;

ptrA := @a;

ptrB := @b;

^ptrB := 3;

c := ^ptrA;

end.

Rotulos Endereço Conteúdo

0000 0000 ?

⁞ ⁞

a 00c4 5d00 2

00c4 5d01

b 00c4 5d02 3

00c4 5d03

c 00c4 5d04 2

00c4 5d05

ptrA 00c4 5d06

00ca 5d00 00c4 5d07

00c4 5d08

00c4 5d09

ptrB 00c4 5d0a

00c4 5d02 00c4 5d0b

00c4 5d0c

00c4 5d0d

⁞ ⁞

Arrays

Um array é um conjunto de variáveis de um mesmo tipo. Geralmente elas são dispostas seqüencialmente

na memória. Desta forma, supondo que um inteiro ocupe 4 bytes, quando se declara um array de 10

inteiros, se está indicando que o compilador deve reservar 40 bytes de memória e interpretar cada 4 bytes

como um número inteiro. O nome dado ao array é um rotulo para o endereço da primeira posição do

array, ou de um ponteiro para sua primeira posição. O operador que indica as posições dentro do array

indica, na verdade, um deslocamento a partir do endereço inicial.

program ponteiros;

var

a : array [1..5] of integer;

b : integer;

begin

for b := 1 to 5 do

a[b] := b * 2;

end.

Rotulos Endereço Conteúdo

0000 0000 ?

⁞ ⁞

a 00c4 5d00 2

00c4 5d01

00c4 5d02 4

00c4 5d03

00c4 5d04 6

00c4 5d05

00c4 5d06 8

00c4 5d07

00c4 5d08 10

00c4 5d09

b 00c4 5d0a 1 2 3 4 5

00c4 5d0b

00c4 5d0c ?

00c4 5d0d ?

⁞ ⁞

Page 4: Sobre Variáveis, Ponteiros, Arrays, Parâmetros e Alocação ...lucas.frucht/variaveis.pdf · program variavel; var a : integer; b : char; c : real; begin end. Rotulos Endereço

Alocação de Memória

Como já foi visto, para toda variável e todo array declarado no seu programa o compilador separa um

espaço na memória onde o conteúdo será armazenado. O tamanho total desse espaço deve ser conhecido

no momento que o código for compilado. Sempre que o programa for carregado na memória esse espaço

será reservado. Esta alocação é chamada estática.

Passagem de Parâmetros

Os parâmetros passados para uma função (ou procedimento)3 são a comunicação de quem está chamando

a função para a função. Devem estar na lista de parâmetros todas as informações que a função deve

receber para funcionar de forma genérica. Embora, em teoria, essa comunicação possa se dar através de

variáveis globais, essa não é considerada uma boa prática pois deixa o código mais confuso e dificulta o

reaproveitamento de código.

Variáveis locais, que são usadas internamente para a operação da função e não tem sentido fora dela, não

devem estar na lista de parâmetros. Por outro lado, os parâmetros declarados já são variáveis locais da sua

função e não podem ser redeclarados no corpo dela.

A comunicação de volta da função para quem a chamou costuma se dar através de um valor de retorno.

No Pascal, este valor é definido em uma variável com o mesmo nome da função.

3 Diferentemente de Pascal, a maioria das linguagens não faz distinção entre funções e procedimentos, considerando um

procedimento como uma função que não retorna valor algum. Por esse motivo, as explicações serão dadas com base em

funções, mas, com exceção do valor de retorno, tudo se aplica de forma idêntica aos procedimentos.

Page 5: Sobre Variáveis, Ponteiros, Arrays, Parâmetros e Alocação ...lucas.frucht/variaveis.pdf · program variavel; var a : integer; b : char; c : real; begin end. Rotulos Endereço

program ponteiros;

function somatorio(

a : array of integer;

i : integer;

limite : integer) : integer;

var

i : integer;

limite : integer;

begin

somatorio := 0;

for i := 0 to limite -1 do

somatorio := somatorio + a[i];

end;

var

a : array[0..2] of integer;

b : integer;

begin

a[0] := 4;

a[1] := 7;

a[2] := 2;

b := 3;

b := somatorio(a, b);

end.

Existem duas formas de passagem de parâmetros. A passagem por valor consiste em copiar o valor de

uma variável (ou constante) para o parâmetro correspondente na função. Esta correspondência costuma se

dar pela ordem dos parâmetros na declaração e na chamada da função.4 Caso a função altere o valor dos

parâmetros ela estará manipulando uma variável completamente diferente, logo, essa alteração não terá

reflexo em quem chamou a função.

Já na passagem por referência a função não recebe o valor da variável, mas sua referência, ou seja o local

onde ela está armazenada. Desta forma, ao invés de se criar uma variável nova, se está dando apenas um

novo nome para a variável que já existe. Esse nome é válido apenas dentro da função, mas permite que

ela manipule diretamente a variável original. Caso a função altere o valor de um parâmetro passado por

referência, a alteração acontece também onde a função foi chamada. Desta forma a passagem por

referência serve também como uma comunicação “indireta” da função para quem a chamou.

4 Algumas linguagens trabalham com parâmetros nomeados, não importando a ordem com que eles são passados.

Page 6: Sobre Variáveis, Ponteiros, Arrays, Parâmetros e Alocação ...lucas.frucht/variaveis.pdf · program variavel; var a : integer; b : char; c : real; begin end. Rotulos Endereço

program ponteiros;

procedure s1(x, y, z : integer);

begin

z := x + y;

end;

procedure s2(x, y : integer;

var z : integer);

begin

z := x + y;

end;

var

a, b, c, d : integer;

begin

a := 2;

b := 3;

s1(a, b, c);

s2(a, b, d);

end.

Rotulos Endereço Conteúdo

0000 0000 ?

⁞ ⁞

s1.x 00c4 5d00 2

00c4 5d01

s1.y 00c4 5d02 3

00c4 5d03

s1.z 00c4 5d04 5

00c4 5d05

s2.x 00c4 5d06 2

00c4 5d07

s2.y 00c4 5d08 3

00c4 5d09

a 00c4 5d0a 2

00c4 5d0b

b 00c4 5d0c 3

00c4 5d0d

c 00c4 5d0e ?

00c4 5d0f

d s2.z 00c4 5d10 5

00c4 5d11

⁞ ⁞