Java против C ++ (Call-By-Reference?) - PullRequest
0 голосов
/ 16 марта 2020

Я не уверен, что эта топи c касается Call-By-Reference, но у меня есть вопрос по поводу этих 2 фрагментов:

Java

public static int calculateWinner(int[][] game){
        game[0][0] = 5; 
.
.
.
}


public static void main(String[] args) {

        int[][] game = {
            {1, 2, 2},
            {2, 1, 2},
            {1, 1, 1}
        };

        int winner = calculateWinner(game);
.
.
.
}

C ++

int calculateWinner(array<array<int, 3>, 3> field) {
    field[0][0] = 5;
.
.
.
}

int main(int argc, const char* argv[]) {

    array<array<int, 3>, 3> field;
    field[0] = { 2, 0, 1 };
    field[1] = { 0, 1, 0 };
    field[2] = { 1, 0, 2 };

    int winner = calculateWinner(field);
.
.
.
}

Итак, если я распечатываю массив в методе main, почему в Java мой массив находится в позиции [0] [0] это 5, но в C ++ это не так? Я узнал, что в C ++ это копия только в объеме. В чем именно разница?

Ответы [ 2 ]

3 голосов
/ 16 марта 2020

Как отмечалось выше, основная проблема здесь заключается в том, что по умолчанию параметры передаются как значения, а не как ссылки. Это верно и для Java, однако, все, что передано во фрагменте java, является указателем на массив, а не на сам массив, что делает его «передаваемым по ссылке», однако , Java всегда , передавая по значению !

В C ++ можно передавать как по значению, так и по ссылке. Вы можете передать указатель на объект, который является новым разделом в памяти программы, который содержит расположение к требуемому значению, или вы можете передать ссылку на указанную позицию c в памяти в котором значение сохраняется. Обратите внимание на адреса памяти указателя в следующем фрагменте кода:

#include <iostream>

void foo(int num)
{
    std::cout << "The location of pass-by-value num is: " << &num << std::endl;
}

void foo1(int* num)
{
    std::cout << "The location of num* is: " << &num << " But its value is :" << num << std::endl;
}

void foo2(int& num)
{
    std::cout << "The location of num& is: " << &num << std::endl;
}

int main()
{
    int num;

    std::cout << "The location of num is: " << &num << std::endl;

    foo(num);
    foo1(&num);
    foo2(num);
}

Вывод этого фрагмента:

The location of num is: 0x7ffce8cceccc

The location of pass-by-value num is: 0x7ffce8ccecac

The location of num* is: 0x7ffce8cceca8 But its value is :0x7ffce8cceccc

The location of num& is: 0x7ffce8cceccc

В foo мы передаем значение целого числа, поэтому мы получаем адрес, отличный от оригинала.

В foo1 мы передаем значение указателя в num. Указатель имеет свою собственную ячейку памяти, и его значение является адресом памяти num.

В foo2 мы передаем ссылку на целое число num, и его адрес памяти точно адрес памяти оригинала, и это true передача по ссылке.

Для редактирования такого объекта вам необходимо передать его по указателю или по ссылке (как правило, передача по ссылке предпочтительнее указателей, когда это возможно).

1 голос
/ 16 марта 2020

C ++ имеет передачу по ссылке и передачу по копии. Java имеет только проход за копией (но внутренние объекты объекта указывают на ту же ссылку, что и оригинал).

Итак:

static void nullReference(int a []){ 
   a = null; // the copy of the object points to null
}

static void update(int a []) { 
 a[0]=5; // [0] is from the original reference.

}

static void main (String args[]){ 
int a [] = {1,2,3}; 
nullReference(a); 
print(a == null); // false
update(a); 
print(a[0] == 5); // true
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...