Difference between pass by value and pass by reference

I'm having a hard time understanding the difference between pass by value and pass by reference. I know that by value means program make a copy of original input data then do calculations on that copied and by reference means program do calculations on the original input data, but while I'm working on the problems, I don't see any difference since both have the same outputs. Can you give me a simple example of these two concepts that have different output? Thanks for your help !
Last edited on
If you modify the content of a variable that was passed "by value" inside of a function, then is will only effect the local copy, but not the original variable at the caller's site. If, instead, you pass a reference or a pointer to a variable into a function, then you can change the content of the original variable from inside the function.

Here is an example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
static void foo(int x)
{
    x = x + 42;
}

static void bar(int &x)
{
    x = x + 42;
}

static void baz(int *x)
{
    *x = *x + 42;
}

int main(void)
{
    test = 0;
    printf("%d\n", test);
    foo(test);   // <-- pass by value
    printf("%d\n", test);
    bar(test);   // <-- pass by reference
    printf("%d\n", test);
    baz(&test);  // <-- pass a pointer
    printf("%d\n", test);
}

0
0
42
84


Note: Another reasons to pass data "by reference" is because it can be way more efficient than having to create a copy! Suppose you have a struct that is several kilobytes in size. If you pass it "by value", then a copy of the whole struct (i.e. several kilobytes) needs to be created on the stack. If, instead, you pass it "by reference", then effectively only a pointer (4 or 8 bytes) will need to be passed around.
Last edited on
https://stackoverflow.com/questions/2564873/how-do-i-use-reference-parameters-in-c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>

void plus_five(int);
void plus_five_ref(int&);

int main()
{
   int value { 10 };

   std::cout << "Before calling plus_five function, value: " << value << '\n';

   plus_five(value);

   std::cout << "After calling plus_five function, value: " << value << '\n';

   // let's reset the value
   value = 10;

   std::cout << "\nBefore calling plus_five_ref function, value: " << value << '\n';

   plus_five_ref(value);

   std::cout << "After calling plus_five_ref function, value: " << value << '\n';
}

void plus_five(int value)
{
   std::cout << "\tIn plus_five, value: " << value << '\n';

   value += 5;

   std::cout << "\tNow in plus_five: value: " << value << '\n';
}

void plus_five_ref(int& value)
{
   std::cout << "\tIn plus_five_ref, value: " << value << '\n';

   value += 5;

   std::cout << "\tNow in plus_five_ref: value: " << value << '\n';
}
Before calling plus_five function, value: 10
        In plus_five, value: 10
        Now in plus_five: value: 15
After calling plus_five function, value: 10

Before calling plus_five_ref function, value: 10
        In plus_five_ref, value: 10
        Now in plus_five_ref: value: 15
After calling plus_five_ref function, value: 15

plus_five makes a local copy of the variable, so any changes made are not reflected back in the caller.

plus_five_ref uses a reference so the variable in the function is the same* as in main. So......any changes made in the function are reflected by the variable in main.

*What actually happens is up to the implementation of the compiler, but the result is still the same. Modify a variable sent to a function via a reference (or pointer) in the function changes the value of the variable outside the function.
If you want the function modified value to show up back in main you'd have to change the function to return the value and assign it to the variable:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>

int plus_five(int);

int main()
{
   int value { 10 };

   std::cout << "Before calling plus_five function, value: " << value << '\n';

   value = plus_five(value);

   std::cout << "After calling plus_five function, value: " << value << '\n';
}

int plus_five(int value)
{
   std::cout << "\tIn plus_five, value: " << value << '\n';

   value += 5;

   std::cout << "\tNow in plus_five: value: " << value << '\n';

   return value;
}
Before calling plus_five function, value: 10
        In plus_five, value: 10
        Now in plus_five: value: 15
After calling plus_five function, value: 15
@OP

George and Kigar have shown you examples of usage. If you understand pointers and how objects are laid out in memory, it's also a bit insightful to see what's actually being passed by examining the address of the object passed into those functions.

Wherever address values are equal, they refer to the same object (and where they aren't, you're dealing with a copy of an object)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>

using std::cout;
using std::hex;

void Func1(int val)
{
    cout << "Inside Func1 (pass-by-value). Address of val: " << hex << &val << "\n";
}

void Func2(int &val)
{
    cout << "Inside Func2 (pass-by-reference). Address of val: " << hex << &val << "\n";
}

void Func3(int *val)
{
    cout << "Inside Func3 (pass-by-pointer). Address of val: " << hex << val << "\n";
}

int main()
{
  int testVal = 100;
  cout << "In main(). Address of testVal: " << hex << &testVal << "\n";
  Func1(testVal); // Pass by value
  Func2(testVal); // Pass by reference
  Func3(&testVal); // Pass by pointer
}



In main(). Address of testVal: 0x7787b0f27d6c
Inside Func1 (pass-by-value). Address of val: 0x7787b0f27d4c
Inside Func2 (pass-by-reference). Address of val: 0x7787b0f27d6c
Inside Func3 (pass-by-pointer). Address of val: 0x7787b0f27d6c
Last edited on
GeorgeP wrote:
If you want the function modified value to show up back in main you'd have to change the function to return the value and assign it to the variable


That's exactly what I did, so I guess passing reference or value doesn't matter if I do it in this way.
Last edited on
There are reasons why passing by pointer or reference is preferred vs. passing by value and returning the possibly modified value.

Objects can be very costly to copy, passing by pointer/reference doesn't incur the copy cost.

Passing Plain Old Data (POD) like an int is cheap no matter what.

There is also the idea of declaring the passed object as const if you don't want the object to be modified in the function. void F1(const int& i); flags as an error if i is modified in the function.
Topic archived. No new replies allowed.