0

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

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

提前致谢。

}

4

1 回答 1

1

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

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

  1. 调用 test() 分别计算表达式ia[0]a[i]to0和。1010
  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

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

于 2013-06-18T13:42:26.403 回答