Statique (Lexicale) Délimitation vs Dynamique de Portée (Pseudo-code)
Program A()
{
x, y, z: integer;
procedure B()
{
y: integer;
y=0;
x=z+1;
z=y+2;
}
procedure C()
{
z: integer;
procedure D()
{
x: integer;
x = z + 1;
y = x + 1;
call B();
}
z = 5;
call D();
}
x = 10;
y = 11;
z = 12;
call C();
print x, y, z;
}
À partir de ma compréhension, le résultat de ce programme lors de l'exécution à l'aide de statique portée est: x=13, y=7 et z=2.
Toutefois, lorsqu'il est exécuté à l'aide de dynamique de portée, le résultat est: x=10, y=7 et z=12.
Ces résultats sont ceux que notre professeur nous a donné. Cependant, je ne comprends pas pour la vie de moi, comment il a atteint ces résultats. Quelqu'un pourrait éventuellement marcher à travers le pseudocode et d'expliquer leurs valeurs dans les deux différents types de champs?
- Quelle est la signification exacte de ces
z: integer;
dans votre pseudo? Si ils définissent une nouvelle variable, ils ont déterminé la valeur par défaut? - Il serait équivalent à
int z;
- Aussi loin que je peux voir aucune des variables sont accessibles à l'avant ils sont initialisés.
- i.imgur.com/f6wT7pB.png Pas sûr si ça va aider, il a été inclus dans la solution.
- Vous avez raison, j'ai mal lu le code.
- Quelle langue est-ce la question?
- double possible de Ce qui est portée lexicale?
Vous devez vous connecter pour publier un commentaire.
Avec statique (lexicale) délimitation, la structure du code source du programme détermine les variables que vous faites allusion. Avec dynamique de portée, l'état d'exécution de la pile du programme détermine quelle variable on se réfère. Cela est probablement très mal le concept, depuis le fond, chaque langage de programmation largement utilisé de nos jours (à l'exception peut-être emacs lisp) utilise une portée lexicale, qui tend à être beaucoup plus facile pour les humains et les outils d'analyse de raisonner sur.
Considérer ce beaucoup plus simple programme d'exemple (il est écrit dans le pseudo-code de la syntaxe):
Le programme et le compilateur se référer à ces deux variables comme
x
, mais j'ai marqué leurx1
etx2
pour faciliter la discussion ci-dessous.Avec une portée lexicale, on détermine, au moment de la compilation
x
nous nous référons à la statique, lexical de la structure du code source du programme. Le plus profond de la définition dex
dans la portée lorsque définitionb
estx1
, et l'écriture en question décide dex1
, et c'est là quex = 2
écrit, nous avons donc l'impression2
lors de l'exécution de ce programme.Avec dynamique de la portée des projets, nous avons une pile de définitions de variables suivies à l'exécution -- alors, qui
x
nous écrire à dépend de ce qui est exactement dans le champ d'application et a été défini de façon dynamique à l' runtime. Début d'exécutera
poussex => x1
sur la pile, l'appel dec
poussex => x2
sur la pile, et puis quand on arrive àb
, le sommet de la pile estx => x2
, et ainsi de nous écrire enx2
. Cela laissex1
intacte, et nous avons donc l'impression1
à la fin du programme.En outre, considérez ce qui est légèrement différent du programme:
Note
b
est appelé à deux reprises: la première fois viac
, la deuxième fois directement. Avec une portée lexicale, l'explication ci-dessus n'est pas changé, et nous l'avons écrit dansx1
les deux fois. Cependant, avec la dynamique de la portée, il dépend de la façon dontx
est lié à l'exécution. La première fois que nous appelonsb
, nous écrire enx2
comme expliqué ci-dessus, mais la deuxième fois, nous écrire enx1
, puisque c'est ce qui est en haut de la pile! (x => x2
est sauté quandc
retourne.)Donc, ici, c'est votre professeur de code, annoté avec laquelle exact de la variable est utilisée sur lequel écrire avec une portée lexicale. Écrit que l'extrémité imprimé à la fin du programme sont marqués avec un
*
:Et ici, il est avec dynamique de portée. Remarque le seulement changements sont en
B
, et à l'emplacement de la*
tags:this
mot clé de JavaScript peut aussi être considéré comme un exemple de la dynamique de la portée? Parce quethis
n'est pas lié à une portée lexicale.procedure B() { y: integer; // y2 y=0; // y2 = 0 x=z+1; // x2 = z2 + 1 = 5 + 1 = 6 z=y+2; // z2 = y2 + 2 = 0 + 2 = 2 }
Portée statique et Dynamique de la portée de différentes façons afin de trouver variable avec un nom unique dans un programme écrit dans n'importe quelle langue.
Son particulièrement utiles pour l'interpréteur ou compilateur de décider où et comment trouver la variable.
Envisager de code est comme ci-dessous,
Statique:
C'est essentiellement textuel, la première variable est définie ou non doit être vérifié en fonction locale(nom, il vous permet de f1()), si ce n'est dans les locaux de la fonction f1(), alors la variable sera recherché dans la fonction f2() qui joint ce fonction(par ce je veux dire f1()), ...cela continue...jusqu'à ce que la variable est trouvé.
Dynamique:
Ceci est différent de la statique, dans le sens, comme il est plus de temps d'exécution ou dynamique, la première variable est définie ou non doit être vérifié en fonction locale,si ce n'est dans les locaux de la fonction f1(),alors la variable sera recherché dans la fonction f3() qui appelle ce fonction(par ce je veux dire f1() encore une fois), ...cela continue...jusqu'à ce que la variable est trouvé.
Le point crucial est que le lexique graphique ressemble à ceci:
alors que le graphe d'appel ressemble à ceci:
La seule différence est que la lignée B a. Dans le lexique de l'image, B est défini directement dans le champ d'application de l'Une (la portée mondiale). Dans la dynamique de l'image, la pile à B dispose déjà D sur le dessus de C, puis A.
Cette différence représente la façon dont les mots-clés
x
etz
sont résolus dans B. Lexicalement, ils sont identifiés parA.x
etA.z
, mais de façon dynamique, ils sont identifiés parD.x
et (depuis pasD.z
existe) avecC.z
.Ci-dessus, j'ai essayé de représenter votre code plus clairement. Notez que D mute
A.y
selon les deux méthodes de résolution de nom, alors que B muteA.x
etA.z
si lexicale plutôt que de la dynamique de la portée est choisi.Noter que, si une fonction n'est jamais défini une fois*, il est commun d'appeler à partir de plusieurs endroits (et on peut même appeler récursivement). Ainsi, alors qu'il est assez trivial pour effectuer une portée lexicale en utilisant le code statique, la dynamique de la portée est plus compliqué parce que le même mot-clé (dans la même fonction) peut résoudre de différentes variables (à partir de différents espaces de nom) lors des différents appels à cette fonction (vous obligeant à parcourir le programme et de suivre la façon dont la pile d'appel des modifications en cours d'exécution).
*(À l'exception de template langues..)