The difference between reference and non-reference variables

I do not understand the difference between
1
2
3
4
5
6
7
8
void change(int& x, int& y){ // with reference sign
int tmp = x; 
x=y; 
y=tmp;
}
int main(int argc, char *argv[]){ 
int a = 5, b = 10;
change(a, b);


and

1
2
3
4
5
6
7
8
void change(int x, int y){ // withoud the reference sign
int tmp = x; 
x=y; 
y=tmp;
}
int main(int argc, char *argv[]){
int a = 5, b = 10;
change(a, b);


Could someone explain?
The "reference sign" is the "Address Of" operator. Basically it retrieves the address of a variable as opposed to receiving a copy of the variable's value.

Using the address of operator you can successfully change the original variable's value from a function, such as the change() function in your example. If you omit the address of operator, then your change() function is useless to the caller because the values will not be exchanged, as the change() function operated on copies.

If you need more help understanding the topic, then I suggest that you first read about pointers.
@webJose
The "reference sign" is the "Address Of" operator.

No, they are both ampersands, but they have completely different purposes. You use the reference operator to declare a reference variable (similarly to the * for pointers).
1
2
3
int a = 10;
int *p = &a; //declaring a pointer to the address of a
int &r = a;  //declaring a reference to a 

You can change the value of a through both p and r. But p is a pointer whilst r is a reference.
1
2
*p = 11;
r = 12;

Pointers and reference are similar, but have different behavior, property and syntax.

@Rox
You can pass a variable three ways in C++.
By value, by reference and by pointer.

Passing by value means, the variable gets copied thus you can't change the original passed variable. (An example for this is your second code).
Passing by reference and by pointer means the variable you pass doesn't get copied, instead a pointer* is passed to the function, this way we save the cost of copying (for large objects), and we can modify the original variable. (Your first code is an example for passing by reference). References have simpler syntax, since one doesn't have to dereference it explicitly every time, but has stricter rules.

*a reference is basically a pointer too.

http://www.cplusplus.com/doc/tutorial/pointers/



Thanks for the answers!

So, given the main function:
1
2
3
4
5
6
7
int _tmain(int argc, _TCHAR* argv[])
{	
	int x = 5;
	int y = 10;	
	swap(x,y);
	return 0;
}
, the following functions give the same result but work with the variables in different ways?
1
2
3
4
5
void swap1(int x, int y){
	int tmp = x;
	x = y;
	y = tmp;
}

1
2
3
4
5
void swap2(int& x, int& y){
	int tmp = x;
	x = y;
	y = tmp;
}

1
2
3
4
5
void swap3(int* x, int* y){
	int tmp = *x;
	x = y;
	y = &tmp;
}

Is that the whole thing about pointers and references, that instead of copying the object, we can use a pointer or a reference to just point on a piece of an object that we want for the moment?

So, in theory, is it possible to solve everything in the same way using the three methods (values, references, pointers)?
Last edited on
swap1 won't affect the variables you have in main
not quite.

swap1 does absolutly nothing:

1
2
3
4
5
int a = 1;
int b = 0;
swap1(a,b);
cout << a;  // outputs '1' -- a didn't change
cout << b;  // outputs '0' -- b didn't change 


This is because the parameters are passed by value, so 'x' and 'y' are actually copies of the variable, and they do not refer to a,b.

---
swap2 works as expected. x "becomes" a and y "becomes" b.

swap3 is just coded incorrectly. This is how it should look:

1
2
3
4
5
void swap3(int* x, int* y){
    int tmp = *x;
    *x = *y;   // don't change the pointers, change the value they point to
    *y = tmp;  // same
}


with that fix, swap3 is the same as swap2.
Romai, thanks for the correction on the operator names. When I read about it a long time ago, I read it was called "address of", and stuck with that all this time.

At OP: Usually you can get something done either by reference or via pointers, but usually what you can do with them is incompatible with "by value".

The one way to make things work "by value" as if they were by reference would be to pass the pointer values as numbers and then casting to pointer types, but that is 110% UNNECESSARY and bad practice most of the time and plain WACKO.
Ah, now I figured out that I was using the std::swap() function and not my own, that explains why the values were swapped even when my swap function used address operator or pointers (because it was not used, it was still the std::swap() that was used). Haha! :-)

By the way,
1
2
3
4
5
void swap3(int* x, int* y){
	int tmp = *x;
	*x = *y;
	*y = tmp;
}

seems to not work properly since the call
swap3(x,y); gives this error:

Error 3 error C2664: 'swap3' : cannot convert parameter 1 from 'int' to 'int *'

What´s wrong?


I've gotten similar error messages when I have mistakenly declared 'int' twice for the same variable, perhaps its not in your code snippet posted, but in a previous entry where the variable has may have already been declared. I could be way off base, but that has been my experience with this type of error. The code snippet looks correct to me otherwise.
You need to pass an address if your parameter is a pointer: swap3(&x,&y);
Rox:

You have to pass a pointer to the function, not an int.

So your function call should look like this:

1
2
3
4
int a = 1;
int b = 0;

swap3(&a,&b);  // give it pointers to a,b 


Note that all these syntax things are partly the reason why references (swap2) should be preferred for something like this.
example of the code and output, non referenced and referenced
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

// non referenced

#include <iostream>
using namespace std;
void swap2(int i, int j);

int main()
{

	int i=10;
	int j=20;
		
	cout << "Original Value of i and j: " << i << ", " << j << "\n";
	swap2(i,j);
	cout << "Swapped Value of i and j: " << i << ", " << j << "\n";
	
	return 0;
	
}

void swap2(int i, int j)

{
	
	int *x, *y;
	x=&i;
	y=&j;
	
	
	
	int temp;
	temp = *x;
	*x   = *y;
	*y   = temp;
			
}




Original Value of i and j: 10, 20
Swapped Value of i and j: 10, 20




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
43

// referenced 

#include <iostream>
using namespace std;
void swap2(int &i, int &j);

int main()
{
	int i=10;
	int j=20;
	
	
	
	
	cout << "Original Value of i and j: " << i << ", " << j << "\n";
	swap2(i,j);
	cout << "Swapped Value of i and j: " << i << ", " << j << "\n";
	return 0;
	
}

void swap2(int &i, int &j)

{
	
	int *x, *y;
	x=&i;
	y=&j;
	
	
	
	int temp;
	temp = *x;
	*x   = *y;
	*y   = temp;
	
	
		
}







Original Value of i and j: 10, 20
Swapped Value of i and j: 20, 10



Topic archived. No new replies allowed.