• Nenhum resultado encontrado

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

N/A
N/A
Protected

Academic year: 2021

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

Copied!
6
0
0

Texto

(1)

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.

(2)

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

(3)

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 ? ⁞ ⁞

(4)

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.

(5)

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

(6)

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 ⁞ ⁞

Referências

Documentos relacionados

ABSTRACT: The toxicological effects of crude ethanolic extracts (CEE) of the seed and bark of Persea americana have been analyzed on larvae and pupae of

Esta ressignificação do conceito de paisagem se desenvolve com base nas proposições de Augustin Berque e Jean-Marc Besse, e a partir dos diálogos com o debate que se

• O estudante que realizar as leituras e as atividades propostas no ava e a avaliação presencial, mas não apresentar desempenho satisfatório na compreensão do conteúdo

Para avaliar o teste melhor indicado em visão subnormal, aplicou-se o teste de significância qui-quadrado, aceitando-se o teste de significância de 5% (alfa = 0,05),

remeteu para fiscalização prévia do Tribunal de Contas um contrato de aquisição de serviços técnicos de desenvolvimento aplicacional e administração de

PDE Integração dos programas da área da educação com os de outras áreas Transformação da escola num espaço comunitário Parcerias externas à comunidade escolar, visando a

I6 Os instrumentos e procedimentos de recolha de dados, consensualizados com os stakeholders internos e externos, são aplicados no quadro do processo de autoavaliação

Baseado na utilidade que pode ter o conhecimento adquirido, aliado as informações que são possíveis extrair da base de dados, foi proposto o desenvolvimento de um algoritmo