Java和C / C ++中的变量是存储位置还是该存储位置中保存的值?

时间:2018-06-27 10:46:44

标签: variables pass-by-reference

我知道如何使用变量并对其进行处理。但是,由于那里给出了许多不同的定义,因此很难理解真正的变量是什么。真正让我困惑的是,即使按值传递,Java的对象的行为也像按引用传递一样。 因此,按引用传递是在被调用函数创建指向其自变量的指针并且指针指向变量地址的时候,对吗? 但是在Java中,对象的地址被传递给函数,这使其行为类似于按引用传递。 这是否意味着变量和值不是同一件事?从上面的解释看来,它们具有不同的内存地址。 当指向变量的指针被传递时,它被引用传递。但是,当传递对象的内存地址时,它将按值传递。

int obj = new SomeObject(); // do obj and SomeObject have the same memory address...confused

我知道按值传递和按引用传递之间的区别。我只想知道变量是否实际映射到内存位置,内存地址或该内存位置/地址中存储的值?

1 个答案:

答案 0 :(得分:0)

C和Java通过值传递所有内容,没有其他方法。这也是C ++的默认设置,但是对于将参数作为引用进行传递,它具有额外的表示法。

通过值传递某些内容意味着将创建一个新变量,并且该变量在方法/函数内部:

// C/C++, Java
void something(int x){
  x=10;
  // printf/cout/System.out.println x here, and it will be 10
}

void usesSomething(){
  int y=5;
  // printf/cout/System.out.println y here, and it will be 5
  something(y);
  // printf/cout/System.out.println y here, and it will be 5, x was just a copy
}

与Java对象没有什么不同:

void something(String x){
  x=new String("something");
  System.out.println("In something: "+x);
}

void usesSomething(){
  String y=new String("Hello!");
  System.out.println(y); // "Hello!"
  something(y);
  System.out.println(y); // again "Hello!", x was just a copy
}

令人困惑的部分仅是措辞,因为变量本身在Java中称为“对象引用”(在C / C ++中为“指针”)。但是它们(对象引用)是按值传递的,在此代码中y不会发生任何事情。

通过引用传递内容意味着对引用执行 任何 会直接影响原始变量。

// C++ only
void something(int &x){
  x=10;
}

void usesSomething(){
  int y=5;
  std::cout << y << std::endl; // it is 5
  something(y);
  std::cout << y << std::endl; // it is 10, x was the same variable as y
}


可能值得一提的是,对象和变量在Java中从来都不是同一件事。对象驻留在堆上(如故意夸大的“ Hello!”和“ something”),而这些对象(x和y)的引用变量可以驻留在任何位置(它们驻留在堆栈上),并且具有自己的内存用于存储对这些对象的引用(在C / C ++中,它非常类似于指针,指针也具有大小,例如4-8字节)。
因此,在一般情况下,这就是对象可以“感觉”通过引用传递的方式:实际上是通过值传递对象引用,最终引用了同一对象。如果对象是可变的(不是字符串),则可以通过引用同一对象的任何其他变量从外部看到更改。但是引用变量本身是您自己的,如果您对其进行更改(并引用另一个对象,可能为null),则没有其他人会注意到。