MC102 |
VARIÁVEIS LOCAIS E GLOBAIS |
Se em seu programa você tem procedimentos, é possível declarar variáveis dentro de cada um deles, bem como dentro do programa em si. As constantes e variáveis declaradas após PROGRAM e fora dos procedimentos são chamadas de globais. Constantes e variáveis declaradas após PROCEDURE, ou seja, dentro do procedimento, são chamadas locais. Então, no programa abaixo:
PROGRAM exemplo; CONST c1 = 3; c2 = 4; VAR v1 : integer; v2,v3 : real; PROCEDURE P; CONST c3 = 5; VAR v4,v5 : real; BEGIN ... END; BEGIN ... END. |
c1 e c2 são constantes globais, enquanto que c3 é local, e v1, v2 e v3 são variáveis globais, enquanto que v4 e v5 são locais.
O que essa diferença significa? Variáveis globais são visíveis de todo o programa, as locais somente de dentro do procedimento onde foram declaradas.
Assim, c3, v4 e v5 só são vistas em P, enquanto que c1, c2, v1, v2 e v3 podem ser acessadas de qualquer lugar no programa.
Mas, o que acontece se tenho variáveis locais e globais com o mesmo nome?
PROGRAM P; VAR v1,v2,v3 : integer; PROCEDURE Q; VAR v1,v2 : real; BEGIN ... END; BEGIN ... END. |
Dentro de Q, qualquer referência a v1 e v2 se tratará da v1 e v2 de Q. As globais não são visíveis, ou seja, as globais foram eclipsadas pelas locais de mesmo nome.
Quando, de dentro de Q, você chama v1, o compilador entende que é v1 de Q. Talvez seja mais fácil de entender assim: v1 é João, assim, v1 de P é João Silva, enquanto que v1 de Q é João Souza. Ambos são João, mas são diferentes. Como o compilador aceita conhecer no máximo um João, ele escolhe o mais próximo do lugar onde João foi chamado (na hierarquia).
Mas isso não é tudo! Podemos ter procedimentos dentro de procedimentos:
PROGRAM A; PROCEDURE B; PROCEDURE D; BEGIN ... END; {D} BEGIN ... END;{B} PROCEDURE C; PROCEDURE E; BEGIN ... END; {E} PROCEDURE F; BEGIN ... END; {F} BEGIN ... END; {C} BEGIN ... END. {A} |
Aqui, E e F estão dentro de C; D está dentro de B e B e C dentro de A. E agora? de onde posso chamar cada procedimento?
Procedimento: | Pode ser chamado por comandos em: |
---|---|
B | A, C, E, F, B |
C | A, C |
D | B, D |
E | C, F, E |
F | C, F |
Obs: O caso de chamar um procedimento de dentro dele mesmo será visto mais tarde no curso.
Esteja seguro de ter entendido isso! Considere, se ajudar, cada procedimento como um micro-programa que, por sua vez, pode ter dentro dele novos procedimentos.
Note que um procedimento pode ser chamado de dentro daqueles que estão no mesmo nível, mas abaixo dele na definição. Assim, apesar de B e C estarem no mesmo nível, B é visto de C, mas C não é visto de B, pois B foi declarado antes e, quando B é lido, C não é conhecido ainda. Assim, como quando chegamos em B C não foi declarado ainda, fazer uma chamada a ele de B causará um erro.
E as variáveis, como ficam? Onde posso referenciá-las?
Variáveis declaradas em: | Podem ser referenciadas em: |
---|---|
A | A, B, C, D, E, F |
B | B, D |
C | C, E, F |
D | D |
E | E |
F | F |
Viu? As variáveis de um nível são vistas em todos os níveis abaixo. E se, agora, tivermos variáveis de mesmo nome (repare que os tipos podem ser diferentes):
PROGRAM P; VAR a : tipo1; PROCEDURE Q1(a : tipo1); PROCEDURE Q2; VAR b : tipo2; PROCEDURE Q3; VAR a : tipo3; BEGIN ... END; {Q3} BEGIN ... END; {Q2} BEGIN ... END;{Q1} PROCEDURE Q4; VAR b : tipo2; PROCEDURE Q5; VAR a : tipo1; BEGIN ... END; {Q5} BEGIN ... END; {Q4} BEGIN ... END. {P} |
Se eu fizer a:=5 dentro de cada procedimento, qual "a" modifico?
Dentro de: | Modifico "a" de: |
---|---|
Q1 | Q1 |
Q2 | Q1 (não há "a" em Q2) |
Q3 | Q3 |
Q4 | P (não há declaracção de "a" em Q4) |
Q5 | Q5 |
P | P |
Note que, em Q1, "a" é parâmetro. Parâmetros são variáveis locais também.
Então, como o compilador, ao encontrar uma referência a uma variável, acha essa variável?