静态与动态作用域代码输出验证及动态作用域逻辑解析求助
静态与动态作用域的代码输出验证分析
现有一段C语言代码,需分别基于**静态作用域(Static scoping)和动态作用域(Dynamic scoping)**分析输出结果。已知老师给出的两类输出,静态作用域的输出逻辑已理解,但动态作用域的输出存疑,现验证老师给出的动态作用域输出是否正确,并说明逻辑。
待分析代码
#include <stdio.h> int a = 1, b = 2; void C() { int a = 50; printf("%d, %d\n", a, b); D(); printf("%d, %d\n", a, b); } void D() { printf("%d, %d\n", a, b); a = 3; b = 4; printf("%d, %d\n", a, b); E(); } void E() { int b = 6; printf("%d, %d\n", a, b); a = 7; b = 8; } int main() { int a = 20, b = 30; printf("%d, %d\n", a, b); C(); printf("%d, %d\n", a, b); D(); return 0; }
老师给出的输出结果
静态作用域
20,30 50,2 1,2 3,4 3,6 50,4 20,30 7,4 3,4 3,6
动态作用域
20,30 50,30 50,30 3,4 3,6 7,4 20,4 20,4 3,4 3,6
动态作用域输出验证(核心规则:变量引用优先从调用栈的上层作用域查找)
动态作用域的核心逻辑是:变量使用时,不从定义位置的词法作用域找,而是从当前函数的调用者(调用栈)的作用域逐层向上查找。以下是逐行输出的逻辑验证:
main()初始执行:- 定义局部
a=20、b=30,直接输出20,30,与老师结果一致。 - 调用
C(),调用栈变为main → C。
- 定义局部
C()执行:- 定义局部
a=50,查找b时,从调用栈上层main的作用域找到b=30,输出50,30,老师结果正确。 - 调用
D(),调用栈变为main → C → D。
- 定义局部
D()执行:- 查找
a时,从调用栈上层C的作用域找到a=50;查找b时,从main的作用域找到b=30,输出50,30,老师结果正确。 - 修改
a=3(实际修改的是C作用域内的a)、b=4(实际修改的是main作用域内的b),输出3,4,老师结果正确。 - 调用
E(),调用栈变为main → C → D → E。
- 查找
E()执行:- 定义局部
b=6,查找a时,从调用栈上层C的作用域找到已被修改为3的a,输出3,6,老师结果正确。 - 修改
a=7(修改C作用域内的a)、b=8(仅修改自身局部b,不影响外部),执行完毕返回D(),再返回C()。
- 定义局部
C()继续执行:- 此时
a是C作用域内的变量,已被D()修改为7;b是main作用域内的变量,已被修改为4,输出7,4,老师结果正确。
- 此时
回到
main()继续执行:main的局部a未被修改,仍为20;b已被修改为4,输出20,4,老师结果正确。- 调用
D(),调用栈变为main → D。
D()执行:- 查找
a时,从调用栈上层main的作用域找到a=20;查找b时找到main作用域内的b=4,输出20,4,老师结果正确。 - 修改
a=3(修改main作用域内的a)、b=4(main的b值不变),输出3,4,老师结果正确。 - 调用
E(),调用栈变为main → D → E。
- 查找
E()执行:- 定义局部
b=6,查找a时,从调用栈上层main的作用域找到已被修改为3的a,输出3,6,老师结果正确。 - 修改
a=7(修改main作用域内的a)、b=8(仅修改自身局部b),执行完毕返回D(),再返回main(),程序结束。
- 定义局部
综上,老师给出的动态作用域输出完全符合动态作用域的规则,是正确的。
内容的提问来源于stack exchange,提问作者sumit dhiman
相关产品推荐
相关产品推荐

