javac++pass-by-referencecall-by-value

Java vs C++ (Call-By-Reference?)


I am not sure if this topic is about Call-By-Reference but I have a question about these 2 snippets:

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);
.
.
.
}

So if I print out the array in the main method, why is it in Java that my array at position [0][0] is 5 but in C++ it's not? I learned that in C++ it's a copy only in the scope. What exactly is the difference?


Solution

  • As noted above, the main problem here is that by default, the parameters are passed as values and not references. It is true in Java as well, however, whatever passed in the java snippet is the pointer to the array, and not the array itself, making it seem as "pass by reference", however, Java is always passing by value!

    In C++ it is possible to pass both by value and by reference. You can pass a pointer to an object, which is a new section in the program's memory, which contains the location to the wanted value, or you can pass the reference to the specific position in the memory in which the value is stored. Notice the memory addresses of the pointer in the following code snippet:

    #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 output of this snippet is:

    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
    

    In foo we pass the value of the integer, therefore, we get a different address than the original.

    In foo1, we pass the value of a pointer to num. The pointer has its own memory location, and its value is the memory address of num.

    In foo2, we pass the reference to the integer num, and its memory address is exactly the memory address of the original, and this is a true pass-by-reference.

    In order to edit such an object, you need to pass it by-pointer, or by-reference (generally, pass-by-reference is preferred over pointers whenever possible).