#include<stdio.h>
#include<stdlib.h>
void f(int x, int* y, int **z)
{
*z = malloc(sizeof(int));
**z = 4;
**z += 1;
x += 2;
*y += 3;
}
int main()
{
int x = 5;
int *y = &x;
int **z = &y;
f(x, y, z);
printf("%d, %d, %d", x, *y, **z);
return 0;
}
所以,这是我对这个问题的看法-
首先在main中z和y指向x,x是5。当函数被调用时,新的变量x,y,z被创建为它们的类型,函数中的y,z最终指向main中的x。现在z被指向堆中的一个int空间。这里指向堆的z的值变为5。然后函数中的x变为7,在函数的最后一行 *y+=3使main中的x值递增(使其变为8)。
现在控制流返回到主控制器
并且x应该是main中的x,也就是8,y应该是8,因为它指向main中的x。并且z应该是5,因为它指向堆。
我哪里做错了?
2条答案
按热度按时间icnyk63a1#
f
的z
指向main
的y
,而不是f
的y
。main
的y
和f
的y
是不同的变量,即使它们在某个时间具有相同的值。改变一个不会改变另一个。我将说明当我们一行一行地(或多或少地)执行程序时发生了什么。但首先,我将重命名
f
的参数以避免混淆。1.之后
我们有
(All发明的地址确切的数字是不相关的)。
1.我们称之为
f
。这会将main
的x
、y
和z
复制到f
的a
、b
和c
。1.之后
我们有
记住
c
指向main
的y
。1.之后
我们有
1.然后,回到
main
,我们打印x
、*y
(anon块)和**z
(同样,通过*y
的anon块)。ni65a41a2#
首先,
f
中的x += 2
由于按值传递语义而毫无意义,并且永远不会再次使用,所以让我们摆脱它。z
是指向y
的指针。当我们解引用它并赋值时,我们正在赋值给main
* 中的y
*。Thaty
现在指向某个大小适合int
的内存块。我们的函数参数y
没有被改变。我们现在将
4
分配给该内存块,然后将其递增1
。main
中的y
现在是5
。y
函数参数仍然指向main
中的x
,所以当我们解引用它并添加3
时,它现在是8
。main
中的z
仍然指向y
,因此也是5
。因此,
8, 5, 5
被打印。C中的按值传递语义是这里真实的的关键。我想如果我们看一下,这是否会更容易理解: