傻瓜评估订单

时间:2013-06-18 12:42:08

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

无论我阅读多少主题,我都无法理解评估策略。你能用一个例子向我解释三个评估订单吗?我正在编写下面的代码。您能否按需要解释呼叫(懒惰评估),按名称呼叫(正常订单评估),使用下面的代码通过引用进行调用。你也可以用你的例子来解释它们。我想要的只是理解它们,但我无法理解。

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);
}

提前致谢。

}

1 个答案:

答案 0 :(得分:1)

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

编程行为,使用与调试器监视列表中显示的相应表达式的值。请注意*p是一个表达式,而不是变量:调试器会懒惰地评估它,但它不是真正存在于内存中的东西。

  1. 调用test()分别评估表达式ia[0]a[i]01010
  2. 测试(0,10,10)开始 - > {x,y,z,p,* p} = {0,10,10,(未初始化),(无效)}
  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
  13. 事实上,指针实际上并不用于演示指针在这里是如何工作的:它有很多浪费的潜力。就指针而言,这是一个糟糕的示例代码。