Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.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_Reference - Fatal编程技术网

Java 在C#中,交换方法在内存级别如何工作?

Java 在C#中,交换方法在内存级别如何工作?,java,c#,pointers,reference,Java,C#,Pointers,Reference,我是一名Java程序员。我对C#知之甚少。但是从我读到的内容来看,Java只支持按引用值传递,而在C#中,默认值是按引用值传递,但是程序员可以在需要时使用按引用传递 我已经写下了我对交换函数如何工作的理解。我想把这个概念弄清楚是至关重要的,因为它是编程概念的基础 在C#: 步骤1:在堆上创建一个值为one的字符串对象,并将其位置的地址存储在变量one中。运行时环境在堆上分配一块内存,并返回指向该内存块开头的指针。该变量ONE存储在堆栈上,该堆栈是指向在内存中定位实际对象的参考指针 步骤2:调用

我是一名Java程序员。我对C#知之甚少。但是从我读到的内容来看,Java只支持按引用值传递,而在C#中,默认值是按引用值传递,但是程序员可以在需要时使用按引用传递

我已经写下了我对交换函数如何工作的理解。我想把这个概念弄清楚是至关重要的,因为它是编程概念的基础

C#:

  • 步骤1:在堆上创建一个值为
    one
    的字符串对象,并将其位置的地址存储在变量
    one
    中。运行时环境在堆上分配一块内存,并返回指向该内存块开头的指针。该变量
    ONE
    存储在堆栈上,该堆栈是指向在内存中定位实际对象的参考指针

  • 步骤2:调用方法
    changeString
    。指针(或内存地址位置)的副本分配给变量字。此变量是方法的局部变量,这意味着当方法调用结束时,它将从堆栈帧中删除,并且超出垃圾收集的范围。 在方法调用中,变量字被重新分配,以指向
    TWO
    对象位于内存中的新位置。方法返回

  • 步骤3:在控制台上打印应该打印一个,因为在上一步中更改的只是一个局部变量

  • 步骤4:重新分配变量1,以指向对象
    one
    所在的内存位置

  • 步骤5:调用方法
    changeString
    。此时传递对
    ONE
    的引用。这意味着本地方法变量word是主范围中变量word的别名。因此,没有复制参考文献。因此,将同一个变量传递给方法调用是等效的。该方法重新分配变量以指向另一个内存位置,该位置恰好包含两个。该方法返回

  • 步骤6:现在,外部范围(即主方法中)上的变量
    one
    通过方法调用更改,因此它打印
    TWO

Java
中,步骤5是不可能的。也就是说,您不能通过引用传递

请更正我上面描述的编程流程是否正确


我读过的文章,还有。

您对通过引用/值传递的语义的理解是正确的。

您似乎正确理解了语义。只是想用其他语言做一些类比

在C#中,默认值是对象引用(一级间接寻址),值类型除外。按引用传递本质上是向对象引用传递指针,这是双重间接寻址

最接近的是C或C++类比。

C++

C(忽略常数等问题)

但Java类比可能必须是一个具有字符串成员的类:

public class StringRef
{
   public string val;
}

public static void ChangeString(string word)
{
  word = "TWO";
}

public static void SeedCounter(StringRef strRefWord)
{
  strRefWord.val = "TWO";
}
详细说明每个请求


在C#(或者更具体地说是CLR)中,字符串变量是指针,但我们将其称为对象引用。该变量包含一个指向字符串对象的地址,通常位于堆的某个位置。变量本身通常是一个类字段(可能存在于堆上),或者是一个局部变量或参数,因此它存在于堆栈或局部变量槽(也存在于堆栈上)。通过引用传递时,传递的是指向变量的指针,而不是指向最终对象的指针。您的“ref”参数是A,A指向B,B是您的局部变量或对象字段,B指向C,即内存中某个字符串对象。按ref传递传递a,a是指向B的指针,您现在可以更改B。

不要假设“…是在堆上创建的”,编译器可以在堆、堆栈或任何地方自由分配它。。。。这只是一个实施细节…@L.B:谢谢你指出。我不知道编译器会分配它。在我上面引用的文章中,它被称为heap。所以我认为这是真的,你可能也想读这篇@L.B:谢谢你的精彩文章。我是一名Java开发人员,但总是很想知道如何在C#中实现。在Java中,如果我没有记错的话,对象总是在堆上。你想看的是语言所说的发生了什么(而不是语言是如何在“机器代码”中实现的)。谢谢你!这是对meThis的一个提升,但它并不能回答这个问题。若要评论或要求作者澄清,请在其帖子下方留下评论。@Barranka它以何种方式不回答问题?问题是他的陈述是否正确。他们是。这就回答了问题。你能在你的陈述中详细说明这意味着什么吗“通过引用传递本质上就是传递指向对象引用的指针,这是双重间接的。”
void ChangeString(std::string word)
{
  word = "TWO";
}

void SeedCounter(std::string &word)
{
  word = "TWO";
}
void ChangeString(char * word)
{
  word = strdup("TWO");
}

void SeedCounter(char ** word)
{
  *word = strdup("TWO");
}
public class StringRef
{
   public string val;
}

public static void ChangeString(string word)
{
  word = "TWO";
}

public static void SeedCounter(StringRef strRefWord)
{
  strRefWord.val = "TWO";
}