C中指针的按引用传递

C中指针的按引用传递,c,pointers,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); r

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

#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;
}
#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;
}
我犯了一个错误

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


这完全是真的,还是我误解了什么,幸运地得到了答案?

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

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

int*val=NULL

然后调用recent,将指针val传递给它,它仍然保持NULL

近期(val)

最后打印*val.val仍然保持NULL,*运算符告诉编译器“取消引用”val,这意味着使用val指向的对象的值

printf(“现在值为%d\n”,*val)


在回答你的描述是否正确的问题时,答案有点像,但你的描述不准确。您使函数的指针副本指向某个对象。当您使用指针在C中实现一个按引用传递函数时,仍然是按值传递指针本身:创建指针的副本,推送到堆栈上,然后发送到函数。如果更新被调用函数中指针的值,调用函数中指针的值将不会更改。

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

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

int*val=NULL

然后调用recent,将指针val传递给它,它仍然保持NULL

近期(val)

最后打印*val.val仍然保持NULL,*运算符告诉编译器“取消引用”val,这意味着使用val指向的对象的值

printf(“现在值为%d\n”,*val)


在回答你的描述是否正确的问题时,答案有点像,但你的描述不准确。您使函数的指针副本指向某个对象。当您使用指针在C中实现一个按引用传递函数时,仍然是按值传递指针本身:创建指针的副本,推送到堆栈上,然后发送到函数。如果更新被调用函数中指针的值,则调用函数中指针的值不会更改。

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


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

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


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

原因与函数recent()有关。当您传入“a”时,您正在传入一个int*(即int指针),它是指向内存中某个位置的地址。但是,正如您所说,“a”是该函数的局部变量(指针是按值传递的)

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


因此,您可能会因为val仍然为null而出错,并且您正在尝试取消对null指针的引用。

原因与您的函数recent()有关。当您传入“a”时,您正在传入一个int*(即int指针),它是指向内存中某个位置的地址。但是,正如您所说,“a”是该函数的局部变量(指针是按值传递的)

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


因此,您可能会因为val仍然为null而出错,并且您正在尝试取消对null指针的引用。

下面是代码中发生的情况:

#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;
}
#包括
整数校验=20;
近期整数(整数*a)
{
a=&检查;
返回0;
}
int main()
{
//内存被分配用来保存一个整数
蜜蜂;
//数字5被写入该内存空间
bee=5;
//内存被分配用来保存一个内存地址
//null值(无效地址)写入其中
int*val=NULL
#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;
}