Curso de ScriptVox Intermediário - Aula 4 - Prof. Oswaldo Vernet - iNCE/UFRJ



Na aula passada, aprendemos a criar nossas próprias funções, que podem receber

parâmetros, retornar valores e manipular variáveis locais. Nesta quarta aula,

vamos introduzir, através de exemplos, o conceito de ESCOPO, que se aplica, 

em princípio, a variáveis e rótulos. 



Execute todos os scripts apresentados neste texto no ScriptVox versão 6.0,

analise atentamente o que acontecer e vá respondendo ao que for perguntado.



Primeiro script:



* início do primeiro script

frase := "Boa noite"

teste ("Olá", 3)

escreve "A variável frase armazena o valor " frase

termina



função teste (frase, vezes) : contador

repete contador vezes

escreve frase

fim repete

fim função

* fim do primeiro script



Perguntas sobre o primeiro script:

1)  Quantas vezes o comando ESCREVE, interno ao bloco do comando REPETE é executado?

    Que variável determina esta quantidade de vezes? Que cadeia é escrita na tela

    por este comando.  

2)  Como você chamaria a função "teste" para escrever dez vezes a cadeia "Socorro!" ?

3)  Que cadeia é escrita na tela pelo comando ESCREVE que está na linha seguinte 

    à linha onde a função "teste" é chamada?

4)  Há uma variável global chamada "frase" e o nome da variável que guarda o primeiro

    parâmetro para a função "teste" também é frase. São a mesma variável ou elas têm

    apenas o mesmo nome? Justifique.

5)  Enquanto a função "teste" está sendo executada, o nome "frase" se refere a qual

    das duas variáveis?

6)  Antes de chamar a função "teste", houve uma atribuição à variável global "frase".

    Que valor foi atribuído?

7)  Este valor mudou após a chamada da função "teste" ?

8)  A função teste retorna algum valor ?



Moral da história: se tivermos um parâmetro com o mesmo nome de uma variável global

e usarmos o nome dessa variável dentro da função, estaremos nos referindo ao parâmetro

e não à variável global. É como se, temporariamente, essa variável global fosse esquecida

enquanto a função está sendo executada. Mas quando a função termina, a variável global está

lá, intacta, com o mesmo valor que possuía antes da chamada.



Vamos ao segundo script:



* início do segundo script

frase := "Bom dia"

teste ()

escreve frase

termina



função teste ()

escreve frase

frase := "Boa noite"

fim função

* fim do segundo script 



Perguntas sobre o segundo script:



1) O que é escrito na tela durante a execução do script?

2) A função "teste" recebe algum parâmetro?  Ela retorna algum valor?

3) Durante a execução do comando "escreve frase", que pertence ao bloco 

   da função "teste", qual o valor da variável frase ?

4) Durante a execução do comando "escreve frase", fora da função "teste",

   qual o valor da variável "frase"?  Onde ele foi mudado?



Moral da história: Uma variável global pode ser usada ou modificada no bloco

de uma função, desde que não haja um parâmetro ou uma variável local à função

com o mesmo nome da variável global.



Vamos ao terceiro script:



* início do terceiro script

frase := teste ()

escreve frase



função teste () : frase

frase := "Uma frase curta"

escreve frase

frase := "Uma frase longa"

retorna frase

fim função

* fim do terceiro script



1)  A função "teste" recebe algum parâmetro?  Ela possui variáveis locais?  Quais?

    Ela retorna algum valor?  Qual?  Em que momento (linha) este valor é retornado?

2)  O que faz exatamente a primeira atribuição do script "frase := teste()" ?

    Explique passo a passo o seu funcionamento.

3)  No comando "escreve frase", pertencente ao bloco da função "teste", a qual

    variável "frase" estamos nos referindo: à variável global ou à variável local?

4)  No comando "frase := teste()", que é a primeira atribuição do script, a qual

    variável "frase" estamos nos referindo: à variável global ou à variável local?

5)  A atribuição frase := "Uma frase longa", no bloco da função "teste" irá modificar

    o valor da variável frase local ou da variável frase global?

6)  O comando retorna frase, na última linha do bloco da função "teste", irá retornar

    que cadeia?  Esta cadeia será atribuída a qual variável?



Moral da história: Através do comando RETORNA, podemos modificar indiretamente uma

variável global, atribuindo a ela o valor retornado por uma função.



A palavra ESCOPO quer dizer alcance, amplitude e, em linguagens de programação, significa 

exatamente em que pontos do programa uma variável pode ser usada.



Uma variável local, portanto, tem seu escopo restrito à função onde ela é

declarada. Ela só pode ser usada no bloco desta função. O mesmo acontece com uma

variável que armazena um parâmetro passado para função. 



Já uma variável global, como o próprio nome diz, é visível em todo o script,

seu valor pode ser usado em qualquer lugar. Mas se houver uma variável local ou

parâmetro com o mesmo nome da variável global, a global fica temporariamente inacessível

no bloco da função e, assim que a função termina, a variável global volta a ser

visível. Chamamos isto de SOMBREAMENTO de uma variável global por uma variável local.



O escopo também funciona para os rótulos. Quando um rótulo é definido dentro do

bloco de uma função, qualquer comando "desvia" para este rótulo tem que pertencer

ao bloco da função. Em outras palavras: não é possível desviar de uma linha

do script fora do bloco de uma função para um rótulo definido no bloco da função.

O contrário também não é permitido: um comando desvia pertencente ao bloco de

uma função não pode desviar para um rótulo situado fora da função. Ou seja,

não é possível, através de um comando Desvia, desviar para dentro ou para fora

de uma função.



Apesar de ser possível ter variáveis globais e locais com o mesmo nome, não é

aconselhável adotar esta prática, pois ela só prejudica a legibilidade do programa.

Portanto, aqui no nosso curso, vamos sempre procurar batizar as variáveis com

nomes diferentes, de modo a evitar confusões. Afinal de contas, há tantos nomes

que podemos inventar para as variáveis! Para que repetir?



Exercícios de programação (use e abuse de variáveis locais, sempre que apropriado):



1)  Escreva a função "conta_brancos", que recebe como parâmetro uma cadeia de caracteres e retorna

    quantas vezes o caractere branco ocorre na cadeia. Teste sua função com os seguintes

    comandos:



    escreve conta_brancos ("Uma pequena frase")

    escreve conta_brancos ("Uma frase enorme, cheia de letras e que não diz nada")



2)  Generalize a função "conta_brancos", chamando-a de "conta_caracteres". Esta nova função receberá

    dois parâmetros: uma cadeia e um caractere. A função deve retornar o número de ocorrências do 

    caractere na cadeia.  Teste com os seguintes comandos:



    escreve conta_caracteres ("Quero ver contar qualquer caractere", "a")

    escreve conta_caracteres ("xxxyyyyyyyyyyzyzyzyz", "y")



3)  Escreva a função "repete_caracteres", que recebe como parâmetro um número inteiro e um caractere 

    e retorna uma cadeia onde o caractere é repetido tantas vezes quanto o número inteiro que foi passado.

    Assim:



    escreve repete_caractere (5, "b")



    deverá escrever na tela a cadeia "bbbbb".



Atenção em todos os exercícios para um detalhe: em ScriptVox, quando nos referimos a um caractere,

queremos dizer, na verdade, uma cadeia unitária, formada por apenas um caractere. 





Exercício de avaliação (enviar para scriptvox@gmail.com até o meio-dia de 30 de janeiro de 2012)



Escreva uma função (pode escolher o nome) que recebe dois parâmetros: o nome de um arquivo a ser lido

e o nome de um arquivo a ser criado. A função deverá ler o primeiro arquivo e

transcrever todas as suas linhas convertidas para maiúsculas no segundo arquivo

e retornar o número de linhas que foram processadas.



Faça também o programa principal que pergunta ao usuário e lê do teclado os nomes dos arquivos, 

chama a sua função e, para finalizar, escreve uma mensagem de despedida informando o número

de linhas.



Não precisa mais avisar que a extensão agora é ".PRO", certo?

    

Bom estudo!



Oswaldo Vernet















