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 !
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.
staticvoid foo(int x)
{
x = x + 42;
}
staticvoid bar(int &x)
{
x = x + 42;
}
staticvoid 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.
#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.
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)
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(constint& i); flags as an error if i is modified in the function.