【问题标题】:Evaluation Order for Dummies假人评估顺序
【发布时间】:2013-06-18 12:42:08
【问题描述】:

无论我阅读多少主题,我都无法理解评估策略。你能举个例子给我解释一下这三个评估顺序吗?我在下面写一个代码。您能否使用下面的代码解释按需要调用(惰性评估)、按名称调用(正常顺序评估)、按引用调用。你也可以用你的例子来解释它们。我只想了解他们,但我就是无法了解。

int a[4] = {10,20,30,40};
int i = 0;
int *p;
void test(int x, int y, int z)
{
    p = (int *)malloc(sizeof(int));
    *p=x;
    x++; y++; z++;
    p = &z;
    printf("%d %d %d\n",x,y,z);
    x++; y++; z++;
    p = &z;
    printf("%d %d %d\n",x,y,z);
}
main()
{
    test(i,a[0],a[i]);
    printf("%d %d %d %d %d\n", a[0],a[1],a[2],a[3],*p);
}

提前致谢。

}

【问题讨论】:

  • 我认为这些概念在 C 语言中没有作用,在 C 语言中,评估总是“正常”的,并且评估顺序问题只出现在具有副作用的语句中。我看到的最接近的是按值或按引用/指针调用函数之间的区别。 ...另一方面,如果你想要的只是对每一行代码的详细解释,我可以做到。

标签: c lazy-evaluation operator-precedence evaluation-strategy


【解决方案1】:

这里没有懒惰,因为所有受影响的东西都是按值传递的,并且全局指针永远不会被取消引用,直到它未定义的行为这样做(指向已经返回的函数的局部变量)。

程序行为,具有适当表达式的值,它们将出现在调试器的监视列表中。请注意,*p 是一个表达式,而不是一个变量:调试器会延迟计算它,但它并不是真正在内存中的东西。

  1. 调用 test() 将表达式 ia[0]a[i] 分别计算为 01010
  2. test(0, 10, 10) 开始 --> {x, y, z, p, *p} = {0, 10, 10, (uninitialized), (invalid)}
  3. p = (int *)malloc(sizeof(int)); --> {x, y, z, p, *p} = {0, 10, 10, (堆上某处), (未初始化)}
  4. *p=x; --> {x, y, z, p, *p} = {0, 10, 10,(堆上某处),0}
  5. x++; y++; z++; --> {x, y, z, p, *p} = {1, 11, 11, (堆上某处), 0}
  6. p = &z; --> {x, y, z, p, *p} = {1, 11, 11, &z, 11}(内存泄漏,malloc'd 内存的地址被“遗忘”而没有被释放)李>
  7. printf("%d %d %d\n",x,y,z); 显示 1 11 11
  8. x++; y++; z++; --> {x, y, z, p, *p} = {2, 12, 12, &z, 12}
  9. p = &z; 没有变化,p 已经指向 z。
  10. printf("%d %d %d\n",x,y,z); 显示 2 12 12
  11. 函数返回。 p 现在是一个悬空指针!当您取消引用它时,任何事情都可能发生。
  12. 大的 printf():第五个数字未定义(应用程序甚至可能在函数被调用之前崩溃),但如果星号正确,它可能是 12。 在这种情况下,它显示10 20 30 40 12

事实上,指针在这里并没有真正用来演示指针是如何工作的:这有点浪费了潜力。就指针而言,这是一个糟糕的示例代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    • 2016-08-25
    相关资源
    最近更新 更多