英文:
Why is the output of the code 8,5,5 and not 8,8,5?
问题
你的代码有一些错误。让我帮你更正一下:
#include <stdio.h>
#include <stdlib.h>
void f(int x, int* y, int **z)
{
*z = (int*)malloc(sizeof(int)); // 改成 (int*)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;
}
主要的修正包括:
- 在
malloc
函数的返回值前添加了(int*)
强制类型转换,以确保它与int**
类型的指针匹配。 - 在
int *y = &x;
和int **z = &y;
中,去掉了&
,因为这是在初始化指针时不需要的。
这样修改后,你的代码应该能够按照你的预期工作,输出为 "8, 8, 5",表示 x
、*y
和 **z
的值分别为 8、8 和 5。
英文:
#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;
}
So,here is my take on the problem-
first in the main z and y point to x which is 5.When function is called new variables x,y,z are created of their types and y,z in the function beginning eventually point to the x in the main.Now z is made to point to a int space in heap.Here the value of z pointing to the heap becomes 5.then x in the function becomes 7 and in the last line of function *y+=3 makes an increment to x value in main (making it 8).
now the flow of control returns to main
and x should be x in main that is 8 y should be 8 since it points to x in main. and z should be 5 since it points in the heap.
where did I go wrong?
答案1
得分: 4
f
的z
指向main
的y
,而不是f
的y
。main
的y
和f
的y
是不同的变量,即使它们在某个时刻具有相同的值。改变一个不会影响另一个。
我将逐行解释程序的执行过程(或多或少)。但首先,我将重命名f
的参数以避免混淆。
void f(int a, int* b, int **c)
{
*c = malloc(sizeof(int));
**c = 4;
**c += 1;
a += 2;
*b += 3;
}
-
在
int x = 5; int *y = &x; int **z = &y;
之后,我们有
int **z @ 3000 int *y @ 2000 int x @ 1000 +-----------+ +-----------+ +-----------+ | 2000 --------->| 1000 --------->| 5 | +-----------+ +-----------+ +-----------+
(所有地址都是虚构的。确切的数字无关紧要。)
-
我们调用
f
。这将main
的x
、y
和z
复制到f
的a
、b
和c
中。int **z @ 3000 int *y @ 2000 int x @ 1000 +-----------+ +-----------+ +-----------+ | 2000 ------+-->| 1000 ------+-->| 5 | +-----------+ | +-----------+ | +-----------+ || | || | || || | || | || 复制 | 复制 | 复制 || | || | || VV | VV | VV int **c @ 6000 | int *b @ 5000 | int a @ 4000 +-----------+ | +-----------+ | +-----------+ | 2000 ------+ | 1000 ------+ | 5 | +-----------+ +-----------+ +-----------+
-
在
*c = malloc(sizeof(int));
之后,我们有
int @ 7000 +-----------+ +--->| ????????? | | +-----------+ | int **z @ 3000 int *y @ 2000 | int x @ 1000 +-----------+ +-----------+ | +-----------+ | 2000 ------+-->| 7000 -----+ +->| 5 | +-----------+ | +-----------+ | +-----------+ | | int **c @ 6000 | int *b @ 5000 | int a @ 4000 +-----------+ | +-----------+ | +-----------+ | 2000 ------+ | 1000 -------+ | 5 | +-----------+ +-----------+ +-----------+
请记住,
c
指向main
的y
。 -
在
**c = 4; **c += 1; a += 2; *b += 3;
之后,我们有
int @ 7000 +-----------+ +--->| 5 | (4+1) | +-----------+ | int **z @ 3000 int *y @ 2000 | int x @ 1000 +-----------+ +-----------+ | +-----------+ | 2000 ------+-->| 7000 -----+ +->| 8 | (5+3) +-----------+ | +-----------+ | +-----------+ | | int **c @ 6000 | int *b @ 5000 | int a @ 4000 +-----------+ | +-----------+ | +-----------+ | 2000 ------+ | 1000 -------+ | 7 | (5+2) +-----------+ +-----------+ +-----------+
-
然后,在
main
中,我们打印x
、*y
(匿名块)和**z
(再次通过*y
的匿名块)。
英文:
f
's z
points to main
's y
, not f
's y
. main
's y
and f
's y
are distinct variables, even if they have the same value for a time. Changing one doesn't change the other.
I'm going to illustrate what is happening as we step through the program line by line (more or less). But first, I'm going to rename f
's parameters to avoid confusion.
void f(int a, int* b, int **c)
{
*c = malloc(sizeof(int));
**c = 4;
**c += 1;
a += 2;
*b += 3;
}
-
After
int x = 5; int *y = &x; int **z = &y;
we have
int **z @ 3000 int *y @ 2000 int x @ 1000 +-----------+ +-----------+ +-----------+ | 2000 --------->| 1000 --------->| 5 | +-----------+ +-----------+ +-----------+
(All addresses invented. The exact numbers are irrelevant.)
-
We call
f
. This copiesmain
'sx
,y
andz
intof
'sa
,b
andc
.int **z @ 3000 int *y @ 2000 int x @ 1000 +-----------+ +-----------+ +-----------+ | 2000 ------+-->| 1000 ------+-->| 5 | +-----------+ | +-----------+ | +-----------+ || | || | || || | || | || copy | copy | copy || | || | || VV | VV | VV int **c @ 6000 | int *b @ 5000 | int a @ 4000 +-----------+ | +-----------+ | +-----------+ | 2000 ------+ | 1000 ------+ | 5 | +-----------+ +-----------+ +-----------+
-
After
*c = malloc(sizeof(int));
we have
int @ 7000 +-----------+ +--->| ????????? | | +-----------+ | int **z @ 3000 int *y @ 2000 | int x @ 1000 +-----------+ +-----------+ | +-----------+ | 2000 ------+-->| 7000 -----+ +->| 5 | +-----------+ | +-----------+ | +-----------+ | | int **c @ 6000 | int *b @ 5000 | int a @ 4000 +-----------+ | +-----------+ | +-----------+ | 2000 ------+ | 1000 -------+ | 5 | +-----------+ +-----------+ +-----------+
Remember that
c
points tomain
'sy
. -
After
**c = 4; **c += 1; a += 2; *b += 3;
we have
int @ 7000 +-----------+ +--->| 5 | (4+1) | +-----------+ | int **z @ 3000 int *y @ 2000 | int x @ 1000 +-----------+ +-----------+ | +-----------+ | 2000 ------+-->| 7000 -----+ +->| 8 | (5+3) +-----------+ | +-----------+ | +-----------+ | | int **c @ 6000 | int *b @ 5000 | int a @ 4000 +-----------+ | +-----------+ | +-----------+ | 2000 ------+ | 1000 -------+ | 7 | (5+2) +-----------+ +-----------+ +-----------+
-
Then, back in
main
, we printx
,*y
(the anon block), and**z
(again, the anon block via*y
).
答案2
得分: 3
First off, the x += 2
in f
means absolutely nothing because of pass-by-value semantics and it's never used again, so let's get rid of it.
void f(int x, int* y, int **z)
{
*z = malloc(sizeof(int));
**z = 4;
**z += 1;
*y += 3;
}
z
is a pointer to y
. When we dereference it and assign we're assigning to y
in main
. That y
now points to some block of memory the right size for an int
. The y
that's our function argument is unchanged by this.
We now assign 4
to that chunk of memory, and then we increment it by 1
. The y
in main
is now 5
.
The y
function argument still points to x
in main
, so when we dereference it and add 3
, it's now 8
.
The z
in main
still points to y
, so that's 5
as well.
Thus 8, 5, 5
is printed.
Pass-by-value semantics in C are the real kicker here. I wonder if this would be easier to understand if we were looking at:
#include <stdio.h>
#include <stdlib.h>
void f(int a, int* b, int **c)
{
*c = malloc(sizeof(int));
**c = 4;
**c += 1;
a += 2;
*b += 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;
}
英文:
First off, the x += 2
in f
means absolutely nothing because of pass-by-value semantics and it's never used again, so let's get rid of it.
void f(int x, int* y, int **z)
{
*z = malloc(sizeof(int));
**z = 4;
**z += 1;
*y += 3;
}
z
is a pointer to y
. When we dereference it and assign we're assigning to y
in main
. That y
now points to some block of memory the right size for an int
. The y
that's our function argument is unchanged by this.
We now assign 4
to that chunk of memory, and then we increment it by 1
. The y
in main
is now 5
.
The y
function argument still points to x
in main
, so when we dereference it and add 3
, it's now 8
.
The z
in main
still points to y
, so that's 5
as well.
Thus 8, 5, 5
is printed.
Pass-by-value semantics in C are the real kicker here. I wonder if this would be easier to understand if we were looking at:
#include <stdio.h>
#include <stdlib.h>
void f(int a, int* b, int **c)
{
*c = malloc(sizeof(int));
**c = 4;
**c += 1;
a += 2;
*b += 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;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论