Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中通过引用传递和C中通过指针传递有什么区别?_Java_C_Pointers_Pass By Reference - Fatal编程技术网

Java中通过引用传递和C中通过指针传递有什么区别?

Java中通过引用传递和C中通过指针传递有什么区别?,java,c,pointers,pass-by-reference,Java,C,Pointers,Pass By Reference,我已经学习Java几个月了,现在开始学习C 我有点困惑,我的印象是,通过引用传递对象和传递指向该对象的指针是一样的:我认为区别在于,在Java中,所有对象的传递都是通过指针自动完成的,而在C中,实际上必须在这里和那里撒上小星号和符号。最近,在谈话中,我确信这是不同的 通过引用传递和传递指针之间有什么区别?区别很细微。在程序集级别,在这两种情况下,对象的地址都传递给函数。但是,在指针情况下,参数是一个独立的指针,可用于修改目标对象(*pch='x')或用于访问不同的对象(pch=“newstr”)

我已经学习Java几个月了,现在开始学习C

我有点困惑,我的印象是,通过引用传递对象和传递指向该对象的指针是一样的:我认为区别在于,在Java中,所有对象的传递都是通过指针自动完成的,而在C中,实际上必须在这里和那里撒上小星号和符号。最近,在谈话中,我确信这是不同的


通过引用传递和传递指针之间有什么区别?

区别很细微。在程序集级别,在这两种情况下,对象的地址都传递给函数。但是,在指针情况下,参数是一个独立的指针,可用于修改目标对象(*pch='x')或用于访问不同的对象(pch=“newstr”)。在引用情况下,参数将自动间接指向目标对象。

如果您正在学习C(而不是C++),则没有引用

C中的术语“passbyreference”只是指传递一个指针作为存储值的地址,以便函数可以更改其值。 否则,您将通过值传递,这意味着在堆栈上生成变量的副本,修改不会产生任何影响

在许多方面,这与您在Java中看到的类似,只是在Java中,您不必显式地将对象转换为指针或取消对它们的引用。换句话说,当您传递一个指针时,地址会复制到堆栈上,因此如果您的函数更改指针(而不是它指向的数据),则更改会在您使用该函数后消失。类似地,在Java中传递对象引用时,可以更改对象的内容(例如,通过调用函数),但将变量be更改为指向另一个对象将在离开后无效

如果你使用C++(看起来像C),那么你可以通过引用,在这种情况下,你不需要处理指针,函数中变量的改变实际上会直接改变外部值(除了你不能使它指向其他东西)。

  • C没有引用(尽管有C++)
  • Java没有指针
  • 指针和引用之间的区别在于,指针实际上是可以用来计算的内存地址。无法使用计算引用
  • Java和C按值传递(在Java中传递对象时,将引用复制到函数)

    • 我相信指针是一个包含引用的变量。 使用&可以获得内存方向(参考),使用*可以访问内存方向的内容。 我推荐这本书

      “关于”

      True意味着您可以为引用分配一个新值,这个新值将在调用上下文中可见,就像在被调用方法中一样


      在Java中,这是不可能的,因为Eric Lippert最近发表了一篇关于这一点的文章。他是C#编译器的程序员,但无论他说什么,都有足够的通用性,可以扩展到其他GC语言,如Java:

      文章引述:

      指针严格来说比引用“更强大”;任何可以使用引用的操作都可以使用指针。[……]

      指针通常实现为地址。地址是一个数字,它是“字节数组”的偏移量,字节数组是进程的整个虚拟地址空间。[……]

      出于所有这些原因,我们在规范中不将引用描述为地址。规范只是说引用类型的变量“存储了一个引用”到一个对象,并且对于如何实现它完全不清楚。类似地,指针变量存储一个对象的“地址”,这同样是非常模糊的。在任何地方我们都不能说引用和地址是一样的

      所以,在C#中,引用是一种模糊的东西,可以让你引用一个对象。除了取消引用并将其与另一个引用进行相等比较外,您不能对引用执行任何操作。在C#中,指针被标识为地址

      与引用相比,使用包含地址的指针可以做得更多。地址可以用数学方法处理;你可以从一个减去另一个,你可以给它们加整数,等等。它们的合法操作表明它们是索引到“数组”的“花式数字”,数组是进程的虚拟地址空间

      Java和C都没有按引用传递。它们都是严格按价值传递的

      按引用传递语义意味着,当您更改方法中参数的值时,调用方将在参数中看到该更改

      现在,您可能会想:“但Java就是这样!如果我在方法中更改了一个对象,调用方就会看到该更改。”对象不是参数。参数就是变量——如果更改该变量的值,调用者将看不到这一点。例如:

      public void foo(Object x)
      {
          x = null;
      }
      
      public void caller()
      {
          Object y = new Object();
          foo(y);
          // y is still not null!
      }
      
      如果参数确实是通过引用传递的,
      y
      之后将为null。相反,
      y
      的值只是一个引用,该引用由值传递。这很令人困惑,因为“参考”这个词在两个术语中都有,但它们是不同的东西

      您可能想看看,如果Java确实具有引用传递语义,那么可能会发生什么,就像C#在(并且仅在)使用
      ref
      关键字时所做的那样

      您可能还想查看与主题相关的评论

      我认为区别在于,在Java中,所有对象的传递都是通过指针自动完成的,就像在C中一样,实际上必须在各处撒上星号和符号 static void Main(string[] args) { int x = 1; Foo(ref x); Console.WriteLine(x.ToString());//this will print 2 } private static void Foo(ref int x) { x++; }