1

我正在尝试了解如何在 C 语言中通过引用传递参数。所以我写了这段代码来测试参数传递的行为:

#include <stdio.h>
#include <stdlib.h>

void alocar(int* n){
   n = (int*) malloc( sizeof(int));
   if( n == NULL )
      exit(-1);
   *n = 12;
   printf("%d.\n", *n);
}
int main()
{
   int* n;
   alocar( n );
   printf("%d.\n", *n);
   return 0;
}

这里打印:

12.
0。

示例 2:

#include <stdio.h>
#include <stdlib.h>

void alocar(int* n){
   *n = 12;
   printf("%d.\n", *n);
}

int main()
{
   int* n;
   n = (int*) malloc(sizeof(int));
   if( n == NULL )
      exit(-1);
   alocar( n );
   printf("%d.\n", *n);
   return 0;
}

它打印:

12.
12.

这两个程序有什么区别?

4

5 回答 5

6

C 是按值传递,它不提供按引用传递。在您的情况下,指针(不是它指向的内容)被复制到函数参数(指针按值传递 - 指针的值是地址)

void alocar(int* n){
   //n is just a local variable here.
   n = (int*) malloc( sizeof(int));
  //assigning to n just assigns to the local
  //n variable, the caller is not affected.

你会想要这样的东西:

int *alocar(void){
   int *n = malloc( sizeof(int));
   if( n == NULL )
      exit(-1);
   *n = 12;
   printf("%d.\n", *n);
   return n;
}
int main()
{
   int* n;
   n = alocar();
   printf("%d.\n", *n);
   return 0;
}

或者:

void alocar(int** n){
   *n =  malloc( sizeof(int));
   if( *n == NULL )
      exit(-1);
   **n = 12;
   printf("%d.\n", **n);
}
int main()
{
   int* n;
   alocar( &n );
   printf("%d.\n", *n);
   return 0;
}
于 2010-11-11T20:36:51.583 回答
3

Actually not really much a difference, except the first one is broken. :) (Well, both are, but the first is broken more).

Let me explain what happens in the second case:

  • variable n of type pointer-to-int is allocated on the stack
  • a new variable of type int is allocated to the stack, it's address is stored in variable n
  • function alocar is called, being passed the copy of variable n, which is the copy of the address of our variable of type int
  • the function sets the int variable being pointed by n to 12
  • the function prints the value of the variable being pointed by n (12)
  • the function returns

The first case:

  • variable n of type pointer-to-int is allocated on the stack
  • the function alocar is called with a copy of the variable n (which is still uninitialized - contains an unknown value)
  • a new variable of type int is created in memory and the local copy of variable n in function alocar is set to point to that new variable
  • the variable (pointed by the function's local copy of n) is set to 12 and printed
  • the function returns, again in the main() function:
  • since the original n variable in main is still uninitialized, it points to a random place in memory. So the value in random place in memory is printed (which is likely to crash your program).

Also, both programs are broken because they don't free the memory allocated by malloc().

于 2010-11-11T20:40:48.937 回答
1

您想修改 in 的值nmain而不是n 指向的值,因此您需要将指针传递给它。由于nin的类型mainint *,所以参数 toalocar需要是 type int **

void alocar(int **n)
{
  *n = malloc(sizeof **n); // note no cast, operand of sizeof
  if (!*n)
    exit(-1);

  **n = 12;
  printf("%d\n", **n);
}

int main(void)
{
  int *n;
  alocar(&n);
  printf("%d\n", *n);  // we've already tested against n being NULL in alocar
  free(n);             // always clean up after yourself
  return 0;
}
于 2010-11-11T21:15:24.413 回答
0

看,第一个程序中发生了什么。

在调用 alocar 之前,我们在 main 中只有变量 n,指向一些未定义的地方:

 main()::n [  X--]--->(?)

(方括号中有值,未定义,标记为X)。然后我们调用 alocar,我们在 alocar 的作用域中有另一个变量,它有一个 origianl var 的副本。

 main()::n   [  X--]--->(?)
 alocar()::n [  X--]-----^

现在,分配一些内存:

 main()::n   [  X--]--->(?)
 alocar()::n [  *--]--->[   Y  ]

为分配的 var 赋值:

 main()::n   [  X--]--->(?)
 alocar()::n [  *--]--->[  12  ]

返回。alocar()::n 被删除,因为它仅在执行 alocar() 时才存在。

 main()::n   [  X--]--->(?)
                        [  12  ]

main()::n 仍然指向某个未定义的位置...(可能存储值 0)并且没有人指向分配的位置。

于 2010-11-11T21:48:49.220 回答
0

The answer posted by nos is correct.

Also note that the first of the two posted programs will actually crash on many systems, when the printf line in main() tries to dereference main's pointer n, which was never set:

   printf("%d.\n", *n);
于 2010-11-11T20:42:40.960 回答