通过引用传递C中的指针

时间:2016-02-11 22:16:52

标签: c pointers

我试图理解通过引用传递的概念。当我这样做时,

#include<stdio.h>
int recent (int *a)
{
    *a = 20;
    return 0;
}
int main()
{
   int bee;
   bee=5;
   int *val = &bee;
   printf("Value is %d\n", *val);
   recent(val);
   printf("Now Value is %d\n", *val);
   return 0;
}

基本上我将指针val指向bee的内存位置,然后当我将它传递给最近的函数并更改值时,该更改会反映在调用函数中,所以值会更改为20。但是当我这样做时,

#include<stdio.h>

int check = 20;

int recent (int *a)
{
    a = &check;
    return 0;
}
int main()
{
   int bee;
   bee=5;
   int *val = NULL;
   recent(val);
   printf("Now Value is %d\n", *val);
   return 0;
}

我得到分段错误。

  

是不是因为我没有初始化指针指向任何位置,然后我将值传递给最近的函数,即使我把它指向一个内存位置(检查变量),调用函数也没有捕获因为我的价值超过了?

这是完全正确的还是我误解了一些事情并且幸运得到了答案?

6 个答案:

答案 0 :(得分:2)

您的问题是您正在打印主函数中取消引用指针val的输出。 main函数中指针val的值为NULL。因此,程序试图在内存位置0处打印该内容,这是程序无法访问的,并导致分段错误。

首先创建val指针并为其赋值NULL。

  

int * val = NULL;

然后你调用最近的,传递指针val,它仍然保持NULL。

  

最近(VAL);

最后你打印* val。 val仍然保持NULL,并且*运算符告诉编译器&#34; dereference&#34; val,意思是使用val指向的东西的值。

  

printf(&#34;现在值为%d \ n&#34;,* val);

在回答你的描述是否正确的问题时,答案是有点的,但你的描述是不精确的。你使函数的指针副本指向某个东西。当您使用指针在C中实现pass-by-reference函数时,您仍然按值传递指针:指针的副本被生成,被压入堆栈并发送到函数。如果更新被调用函数中指针的值,则不会更改调用函数中指针的值。

答案 1 :(得分:1)

离开函数后,

val仍然是一个空指针。指针本身(正如您猜测的那样)仅通过值传递,而不是通过引用传递。在函数内部,你只修改指针(它只存在于函数内部),而不是指针目标。

除此之外,请小心将内存位置传递给自动堆栈变量。至少来自C ++背景,它被认为是糟糕的风格。由于您没有自己显式控制堆栈变量的生命周期(就像使用malloc / free一样),因此您可以通过意外地解除引用已从堆栈中清除的指针来轻松地将自己射入脚中。

答案 2 :(得分:1)

原因与你的函数recent()有关。当你传入“a”时,你传入一个int *(即int指针),它是一个地址到内存中的一个位置。但是,“a”就像你拥有它一样,是这个函数的本地函数(指针是按值传递的)。

因此,当您设置“a =&amp; check”时,您只是更改本地指针值。一旦recent()返回,“a”就会超出范围。在这种情况下,你永远不会改变“a”实际指向的内容。

因此,你是段错误,因为val仍为null,并且你试图取消引用NULL指针。

答案 3 :(得分:1)

  

是因为我没有将指针初始化为指向任何位置,

代码已使用int *val = NULL;初始化,但NULL不是有效位置。 NULL不是一个位置。 NULL空指针常量。作为空指针,它&#34;保证比较不等于指向任何对象或函数的指针。&#34;

  

...即使我把它指向一个内存位置(检查变量),调用函数也没有捕到它,因为我传递了值?

是。使用a = &check;时,只有本地a受到影响,而val被复制为a 实际扩充 val }被值传递(复制)到形式参数 a

  

这是完全正确的......

IMO:是的

  

......我误解了一些事情并且幸运得到了答案?

似乎没有误解。幸运 - 很难评价。

答案 4 :(得分:0)

以下是您的代码中发生的事情:

#include<stdio.h>

int check = 20;

int recent (int *a)
{
    a = &check;
    return 0;
}
int main()
{
   // memory is allocated to hold an integer
   int bee;

   // the number 5 is written into that memory space
   bee = 5; 

   // memory is allocated to hold a memory address
   // the value of null (which is a invalid address) is written into it
   int *val = NULL;

   // more memory is allocated to hold a memory address (int* a)
   // the address in val (which is null) is written into it
   // the new memory address (a) now points to the address of check
   recent(val);

   // val is still NULL
   // BOOOM!
   printf("Now Value is %d\n", *val);

   return 0;
}

长话短说,你是对的! :)

答案 5 :(得分:0)

基本上所有人都回答了这个问题。这是因为您使用a方法传递指针Pass By Value指向的地址。那是你发送的地址副本。如果您希望第二个代码工作,则需要将代码更改为以下代码,

#include<stdio.h>

int check = 20;

int recent(int **a)
{
   *a = &check;
    return 0;
}
int main()
{
  int bee;
  bee = 5;
  int *val = NULL;
  recent(&val);
  printf("Now Value is %d\n", *val);

  return 0;
}

那就是你必须使用C版“Pass By Reference”传递a指向的地址。