按值和指针传递

Pass by value and pointers

你能解释一下为什么输出是 3 吗? 我试图追踪答案,结果显示

i+=(a==b?1:0)

给出 1,但 fun1() 没有按值 传递 ,因此 qp 被复制到不同的变量?

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 实际上是在测试 ab 是否指向相同的内存位置。在函数 fun1 中,ab 都指向相同的内存位置,因此 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中:

  1. (&a==&b?1:0)

    这得到 0。它们是fun1的两个不同参数,基本上是两个不同的局部变量,所以它们不能有相同的地址。

  2. (a==b?1:0)

    这得到 1。这些值都是 &i 来自 main.

  3. (*a==*b?1:0)

    这得到 1。由于 ab 相等,所以它们指向相同的东西。

fun2中:

  1. (a==&b?1:0)

    这得到 0ab 都是参数,所以 a 不能等于 b 的地址(事实上,它等于来自 main 的 &p)。

  2. (*a==b?1:0)

    这得到 1a 等于 &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);

不会改变

变量ab中存储的值是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。