按值和指针传递
Pass by value and pointers
你能解释一下为什么输出是 3
吗?
我试图追踪答案,结果显示
行
i+=(a==b?1:0)
给出 1
,但 fun1()
没有按值 传递 ,因此 q
和 p
被复制到不同的变量?
int fun1(int* a, int* b)
{
int i = 0;
i += (&a == &b ? 1 : 0);
i += (a == b ? 1 : 0);
i += (*a == *b ? 1 : 0);
return i;
}
int fun2(int** a, int* b)
{
int i = 0;
i += (a == &b ? 1 : 0);
i += (*a == b ? 1 : 0);
return i;
}
int main(void)
{
int i = 0;
int* p = &i;
int* q = &i;
printf("%d\n", fun1(p, q) + fun2(&p, q));
return 0;
}
a==b
实际上是在测试 a
和 b
是否指向相同的内存位置。在函数 fun1
中,a
和 b
都指向相同的内存位置,因此 a==b
结果是 true
.
int fun1(int *a, int*b)
{
int i=0;
i+=(&a==&b?1:0); // 0. &a is the memory where a stands. it's different from &b.
i+=(a==b?1:0); // 1. Both pointers point to the same memory.
i+=(*a==*b?1:0); // 1. *a is the value where it points to, and that's the same as *b.
return i; // returns 2
}
int fun2(int **a, int*b)
{
int i=0;
i+=(a==&b?1:0); // 0
i+=(*a==b?1:0); // 1. *a is the value where it points to, and this is a memory value that is the same as b.
return i; // returns 1
}
这就是为什么 returns 3.
顺便提一下,问得好。
在fun1
中:
(&a==&b?1:0)
这得到 0
。它们是fun1
的两个不同参数,基本上是两个不同的局部变量,所以它们不能有相同的地址。
(a==b?1:0)
这得到 1
。这些值都是 &i
来自 main
.
(*a==*b?1:0)
这得到 1
。由于 a
和 b
相等,所以它们指向相同的东西。
在fun2
中:
(a==&b?1:0)
这得到 0
。 a
和 b
都是参数,所以 a
不能等于 b
的地址(事实上,它等于来自 main 的 &p
)。
(*a==b?1:0)
这得到 1
。 a
等于 &p
from main,所以 *a
等于 p
from main,也就是 &i
from main。 b
等于来自 main 的 q
,这又是来自 main 的 &i
。
因此总数是 3
。
我们先来看第一个函数
int fun1(int *a, int*b)
{
int i=0;
i+=(&a==&b?1:0);
i+=(a==b?1:0);
i+=(*a==*b?1:0);
return i;
}
它被称为
fun1(p,q)
两个指针指向同一个变量
int *p=&i;
int *q=&i;
所以这个函数得到了两个相等的值作为它的参数。是变量i
.
的地址
函数参数是它的局部变量。你可以想象被调用的函数像
int fun1( /*int *a, int*b */)
{
int *a = p;
int *b = q;
//...
}
这些局部变量占用不同程度的内存。所以 &a
不等于 &b
.
因此,表达式 (&a==&b?1:0)
的值将等于 0,下面语句中的变量 i
i+=(&a==&b?1:0);
不会改变
变量a
和b
中存储的值是main
中变量i
的地址。如前所述,这两个变量包含相同的值。
所以表达式 (a==b?1:0)
将在下面的语句
中产生 1 和变量 i
i+=(a==b?1:0);
会增加。
由于两个指针都指向同一个对象,因此表达式 (*a==*b?1:0)
也将产生 1。结果变量 i
将增加/
i+=(*a==*b?1:0);
该函数将 return 值 2。
现在让我们考虑第二个函数
int fun2(int **a, int*b)
{
int i=0;
i+=(a==&b?1:0);
i+=(*a==b?1:0);
return i;
}
上面说了参数b
是函数的局部变量。它的地址不等于参数p
的地址
所以表达式 (a==&b?1:0)
产生 0。
表达式 *a
是参数中存储的值 p
相同的值存储在参数中 b
所以表达式 (*a==b?1:0)
产生 1。
函数的 return 个值的总和将等于 3。
你能解释一下为什么输出是 3
吗?
我试图追踪答案,结果显示
i+=(a==b?1:0)
给出 1
,但 fun1()
没有按值 传递 ,因此 q
和 p
被复制到不同的变量?
int fun1(int* a, int* b)
{
int i = 0;
i += (&a == &b ? 1 : 0);
i += (a == b ? 1 : 0);
i += (*a == *b ? 1 : 0);
return i;
}
int fun2(int** a, int* b)
{
int i = 0;
i += (a == &b ? 1 : 0);
i += (*a == b ? 1 : 0);
return i;
}
int main(void)
{
int i = 0;
int* p = &i;
int* q = &i;
printf("%d\n", fun1(p, q) + fun2(&p, q));
return 0;
}
a==b
实际上是在测试 a
和 b
是否指向相同的内存位置。在函数 fun1
中,a
和 b
都指向相同的内存位置,因此 a==b
结果是 true
.
int fun1(int *a, int*b)
{
int i=0;
i+=(&a==&b?1:0); // 0. &a is the memory where a stands. it's different from &b.
i+=(a==b?1:0); // 1. Both pointers point to the same memory.
i+=(*a==*b?1:0); // 1. *a is the value where it points to, and that's the same as *b.
return i; // returns 2
}
int fun2(int **a, int*b)
{
int i=0;
i+=(a==&b?1:0); // 0
i+=(*a==b?1:0); // 1. *a is the value where it points to, and this is a memory value that is the same as b.
return i; // returns 1
}
这就是为什么 returns 3.
顺便提一下,问得好。
在fun1
中:
(&a==&b?1:0)
这得到
0
。它们是fun1
的两个不同参数,基本上是两个不同的局部变量,所以它们不能有相同的地址。(a==b?1:0)
这得到
1
。这些值都是&i
来自main
.(*a==*b?1:0)
这得到
1
。由于a
和b
相等,所以它们指向相同的东西。
在fun2
中:
(a==&b?1:0)
这得到
0
。a
和b
都是参数,所以a
不能等于b
的地址(事实上,它等于来自 main 的&p
)。(*a==b?1:0)
这得到
1
。a
等于&p
from main,所以*a
等于p
from main,也就是&i
from main。b
等于来自 main 的q
,这又是来自 main 的&i
。
因此总数是 3
。
我们先来看第一个函数
int fun1(int *a, int*b)
{
int i=0;
i+=(&a==&b?1:0);
i+=(a==b?1:0);
i+=(*a==*b?1:0);
return i;
}
它被称为
fun1(p,q)
两个指针指向同一个变量
int *p=&i;
int *q=&i;
所以这个函数得到了两个相等的值作为它的参数。是变量i
.
函数参数是它的局部变量。你可以想象被调用的函数像
int fun1( /*int *a, int*b */)
{
int *a = p;
int *b = q;
//...
}
这些局部变量占用不同程度的内存。所以 &a
不等于 &b
.
因此,表达式 (&a==&b?1:0)
的值将等于 0,下面语句中的变量 i
i+=(&a==&b?1:0);
不会改变
变量a
和b
中存储的值是main
中变量i
的地址。如前所述,这两个变量包含相同的值。
所以表达式 (a==b?1:0)
将在下面的语句
i
i+=(a==b?1:0);
会增加。
由于两个指针都指向同一个对象,因此表达式 (*a==*b?1:0)
也将产生 1。结果变量 i
将增加/
i+=(*a==*b?1:0);
该函数将 return 值 2。
现在让我们考虑第二个函数
int fun2(int **a, int*b)
{
int i=0;
i+=(a==&b?1:0);
i+=(*a==b?1:0);
return i;
}
上面说了参数b
是函数的局部变量。它的地址不等于参数p
所以表达式 (a==&b?1:0)
产生 0。
表达式 *a
是参数中存储的值 p
相同的值存储在参数中 b
所以表达式 (*a==b?1:0)
产生 1。
函数的 return 个值的总和将等于 3。