该程序的输出使用不同的作用域/绑定规则和参数传递?
对于我的下一次考试来说,这是一个(非常)艰难的练习。它旨在用于理解范围、绑定和参数传递规则。我什至无法弄清楚输出的前 3 个数字,这让我发疯。
这个具有动态作用域、浅层绑定和从左到右表达式求值的类 C 程序的输出是什么?
1 A : {
2
3 int x = 5;
4 int y = 7;
5
6 proc P(ref int y, valueresult int z, int R(name int)) {
7 z = y-- + R(++x + ++y);
8 write(x, y, z);
9 z = R(z++);
10 }
11
12 B : {
13
14 int x = 3;
15
16 int Q(name int w) {
17 return (w + x++ + y++);
18 }
19
20 P(x, y, Q); // start here
21 write(y++, x++);
22 }
23
24 write(y, x);
25
26 }
This is a (really) hard exercise for my next exam. It's intended for scoping, binding and parameter-passing rules undestanding. I can't figure out even the first 3 numbers outputted, this is driving me crazy.
What is the output of this C-like program with dynamic scope, shallow binding and expression evaluation from left to right?
1 A : {
2
3 int x = 5;
4 int y = 7;
5
6 proc P(ref int y, valueresult int z, int R(name int)) {
7 z = y-- + R(++x + ++y);
8 write(x, y, z);
9 z = R(z++);
10 }
11
12 B : {
13
14 int x = 3;
15
16 int Q(name int w) {
17 return (w + x++ + y++);
18 }
19
20 P(x, y, Q); // start here
21 write(y++, x++);
22 }
23
24 write(y, x);
25
26 }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Ax = 5
A.y = 7
B.x = 3
调用 P(3, 7, Q) - 在 P 内部,y 是 Bx 的引用,其值为 3,z 为 7。由于动态作用域,在 P 内部,x 是 Bx
内部P,在第一条指令中,我们首先计算后递减 y--,因此计算值将为 3,Bx 将更改为 2。
R 是按名称调用的,因此返回 (w + x++ + y++)变为返回 ++x + ++y + x++ + y++。整个第一个表达式被展开为等价于 z = y-- + (++x + ++y + x++ + y++)。
在表达式 ++x + ++y + x++ + y++ 中,我们有一个预增量 ++x,它将 Bx 更改为 3,并给出 3 作为结果。 ++y 会将 Bx 更改为 4 并计算 4。x++ 将计算结果为 4 并更改为 5,y++ 将计算结果为 5 并更改为 6。
因此 Q 的返回值为 3 + 4 + 4 + 5 = 16. 这将添加到之前的 z-- 值 3 中,因此 19 将分配给 z,Bx 将为 6。
写入将打印 x,这是由于动态范围 Bx,因此将打印 6。y是对同一个 Bx 的引用,因此将打印 6。z 是 19。因此它将打印 6, 6, 19。
在 P 的第三条指令中,我们有 z = R(z++),由于按名称调用,它将扩展为相当于 z = (z++ + x++ + y++) 的值。
这样我们就得到了 z 值,即 19 并增量到 20(后增量)。将其与 Bx (6) 的值相加,并将 Bx 更改为 7。将 y 加上 7,并将 y(即 Bx)增加到 8。
所以 z = 19 + 6 + 7 = 32。Bx 为 8。
由于 z 的值结果,Ay 将变为 32。
在 P 之外,write(y++, x++) 将得到 Ay 值,即 32,打印它。然后Ay将更改为33。Bx即8将被打印并更改为9。因此它将打印32, 8。
最后,将打印 Ay(其值为 33)。将打印 Axe,即 5。因此它将打印 33, 5。
最后,程序打印 6, 6, 19, 32, 8, 33, 5。
A.x = 5
A.y = 7
B.x = 3
Calls P(3, 7, Q) - Inside P, y is a ref to B.x, which value is 3, z is 7. Due to dynamic scope, inside P, x is B.x.
Inside P, in the first instruction, we have the post-decrement y-- evaluated first, so the evaluated value would be 3 and B.x will change to 2.
R is called by name, so the return (w + x++ + y++) will become return ++x + ++y + x++ + y++. The entire first expression is expanded to something equivalent to z = y-- + (++x + ++y + x++ + y++).
In the expression ++x + ++y + x++ + y++, we have a pre-increment ++x, which will change B.x to 3 and give 3 as result. The ++y will change B.x to 4 and evaluate 4. The x++ will evaluate to 4 and change to 5 and the y++ will evaluate to 5 and change to 6.
So the returned value from Q is 3 + 4 + 4 + 5 = 16. This will be added to the previous z-- value which is 3, so 19 will be assigned to z and B.x will be 6.
The write will print x which is due to dynamic scope B.x, so will print 6. The y is a reference to the same B.x, so will print 6. The z is 19. So it will print 6, 6, 19.
In the third instruction of the P, we have z = R(z++) which due to call by name will expand to something equivalent to z = (z++ + x++ + y++).
So we get the z value, which is 19 and increment to 20 (post-increment). Add it to the value of B.x (6) and change B.x to 7. Add the 7 from y and increment y (which is B.x) to 8.
So z = 19 + 6 + 7 = 32. B.x is 8.
Due to the valueresult of z, the A.y will be changed to 32.
Outside P, the write(y++, x++) will get the A.y value, which is 32 and print it. Then A.y will change to 33. B.x which is 8 will be printed and changed to 9. So it will print 32, 8.
Finally, the A.y will be printed (its value is 33). The A.x will be printed, which is 5. So it will print 33, 5.
Concluding, the program prints 6, 6, 19, 32, 8, 33, 5.
这是我想出的 - 逐行跟踪:
6 4 22
34 5
35 6
Here's what I've come up with - in a line-by-line trace:
6 4 22
34 5
35 6