0

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?

Haidepzai
  • 764
  • 1
  • 9
  • 22
  • 7
    One `=` is assignment, two `==` is a boolean equality test. `field[0][0] == 5;` is **not** `field[0][0] = 5;` – Elliott Frisch Mar 16 '20 at 16:12
  • Sounds like you could use a [good C++ book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). In such a book they will discuss the difference between pass by value and pass by reference. – NathanOliver Mar 16 '20 at 16:13
  • Sorry that's a typo... It should be = but still my question is the same. – Haidepzai Mar 16 '20 at 16:13
  • Even with field[0][0] = 5; in C++ it doesn't change the value – Haidepzai Mar 16 '20 at 16:15
  • 2
    `int calculateWinner(array, 3> field)` is pass by value. If you wanted to pass by reference, you would do `int calculateWinner(array, 3>& field)`. It's unclear, to me, what, exactly, are you asking about. – Algirdas Preidžius Mar 16 '20 at 16:15
  • related/maybe dupe: https://stackoverflow.com/questions/166033/what-do-value-semantics-and-pointer-semantics-mean – NathanOliver Mar 16 '20 at 16:15
  • 3
    Sounds like you already know the answer? "*I learned that in C++ it's a copy only in the scope*" – Kevin Mar 16 '20 at 16:15
  • I'm not sure if that was correct though. I started to learn C++ last week and had not learn '&' yet. – Haidepzai Mar 16 '20 at 16:17
  • 1
    No matter how you slice it, both C and its variants and Java are call by value. The fact that you can pass addresses and references and pointers is irrelevant. – WJS Mar 16 '20 at 16:18
  • So Java is pass-by-reference and in my example with C++ it is pass-by-value? – Haidepzai Mar 16 '20 at 16:21
  • 1
    Related: [Is Java "pass-by-reference" or "pass-by-value"?](https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value) – Yksisarvinen Mar 16 '20 at 16:22
  • 1
    @Haidepzai No. java is always pass by value. If you pass a reference can you actually change the reference? Nope! You can only change what it refers too. – WJS Mar 16 '20 at 16:23
  • Thanks... This is still so complicated for me. If I pass by value, then why does the array in the main method in Java changed? – Haidepzai Mar 16 '20 at 16:29
  • 2
    Because you are passing in a reference to that. You are changing what it points to which is fine but you can't change the reference itself Even in C you can pass an address to a method via pointer and change what the address points to by, but you can't change the pointer unless you pass in its address. – WJS Mar 16 '20 at 16:35

2 Answers2

4

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

Kerek
  • 1,106
  • 1
  • 8
  • 18
1

C++ has pass by reference and pass by copy. Java has only pass by copy(But, the inner objects of the object point to the same reference as the original).

So:

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
sgtcortez
  • 407
  • 4
  • 15