Являются ли переменные в Java и C / C ++ местом памяти или значением, сохраненным в этом месте памяти? - PullRequest
0 голосов
/ 27 июня 2018

Я знаю, как использовать переменные и работать с ними. Тем не менее, очень сложно понять, что же такое переменные из-за множества различных определений. Что меня действительно смутило, так это то, как объекты java ведут себя как передача по ссылке, даже если это передача по значению. Так что передача по ссылке - это когда вызываемая функция создает указатели на свои аргументы, а указатели указывают на переменный адрес, верно? Но в Java адрес объекта передается функции, которая заставляет его вести себя как передача по ссылке. Означает ли это, что переменные и и значение не одно и то же? Судя по приведенному выше объяснению, они имеют разные адреса памяти. когда передается указатель на переменную, он передается по ссылке. но когда адрес памяти объекта передается по значению.

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

Я знаю разницу между передачей по значению и передачей по ссылке. Я просто хочу знать, действительно ли переменная отображается на ячейку памяти или адрес памяти, или на значение, сохраненное в этой ячейке памяти / адресе?

1 Ответ

0 голосов
/ 27 июня 2018

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!» И «что-то»), в то время как ссылочные переменные для этих объектов (x и y) могут находиться где угодно (здесь они находятся в стеке), и у них есть собственная память для хранения ссылки на эти объекты (в C / C ++ это было бы очень похоже на указатель, который также имеет размер, примерно 4-8 байт).
Таким образом, в общем случае это то, как объект может «чувствовать» передачу по ссылке: вы фактически передаете ссылку на объект по значению, в итоге ссылаясь на тот же объект. Если объект изменчив (строки не являются), изменения будут видны извне, через любую другую переменную, ссылающуюся на тот же объект. Но сама переменная-ссылка является вашей собственной, если вы измените ее (и обратитесь к другому объекту, возможно, к нулевому значению), никто больше не заметит.
...