Changing address of variables using reference - c++

in below code why its displaying 2,3 though we change the address. why not 3,2.
#include <iostream>
using namespace std;
void Addresschange(int *a, int *b)
{
int *t;
t = a;
a = b;
b = t;
cout << *a<<endl<< *b<<endl;//here its displaying 3,2
}
int main ()
{
int a = 2 ,b = 3;
Addresschange(&a ,&b);
cout << a<<endl<< b;//why its displaying 2,3 here
return 0;
}
So after going out of this function the addresses of the actual parameters (a and b) would be changed. Is it possible at all?

In the Addresschange function, a and b are local variables. When you change their values, that only changes their values inside the function. So your code just swaps the values of a and b inside the Addresschange function. It doesn't use any pointer operations, so even though the values happen to be pointers. that doesn't change the fact that they're passed by value and that means that changing the value won't propagate out of the function.
If you want to change something's value using a pointer, you have to pass a pointer to it and change the value the pointer points to. So if you want to change the value of an int *, you need to pass the function an int **.
Your function passes an int * (pointer to int), which lets you change the value of an int. For example, *a = 3; will make a equal to 3 instead of 2 in the caller, using the pointer that was passed by value to change the value of the thing it points to.
(You can also use references in C++. You still can't "reseat" a reference to make it refer to something else unless you use something like std::reference_wrapper.)

Related

Why does the address of pointer changes while passing?

while implementing the BST by my own using struct, I got confused on how the pointer works.
here’s my simple code
#include <iostream>
#include <vector>
using namespace std;
void ptr_change(int* p){
cout<<&p<<endl;
/*
*address changes. why ? */
return ;
}
int main(){
//4. Pointer address integrity
cout<<"4. Pointer address integrity"<<endl;
int* p1;
cout<<&p1<<endl;
ptr_change(p1);
}
Why does the address changes when after passing it to the function as parameter??
Thank U!
The address didn't change. You're looking at two separate variables.
In the main function, you define a variable called p1. This variable has a particular address. You then pass the value of p1 to the function ptr_change.
In ptr_change, it has a parameter called p. This variable has its own address separate from p1 in main, although it contains the same value as p1.
You may be confused because the parameter in question is a pointer. It's no different than a non-pointer parameter. For example:
void foo(int x)
{
cout << &x << end;
}
int main()
{
int y = 0;
cout << &y << end;
foo(y);
return 0;
}
Here, x in foo and y in main are different variables each with their own address, but they both contain the value 0.
You are passing a copy of the pointer to the function. It's like when you pass a -say- int variable, you pass a copy of it's value. When you pass a pointer to int, you are copying the pointer itself, which also points to the same memory location, but pointer itself can be stored at another random location.

C++ pointers and addresses

i was just playing with pointers as function arguments and i know this.
#include <iostream>
using namespace std;
void func(int *a)
{
*a+=1;
return;
}
int main()
{
int a=1;
cout<<a<<endl;//prints 1
func(&a);
cout<<a;//prints 2
return 0;
}
My question is why does below code act similar to the one above, more precisely
when we call func(&a) from main function in above case
// starting address of that 4 bytes(size of int) of data gets passed and in our function(func) this address is stored in local pointer 'a' and when we write *(a) our compiler knows to read 4 bytes of data because its an integer pointer.
in short, my question is
what exactly are we passing to 'func'
when we call func(a) where 'a' is a variable which stores an integer value
and what exactly func(int &a) means
#include <iostream>
using namespace std;
void func(int &a)
{
//cout<<*a;// error
a+=1;
// cout<<a<<endl;
}
int main()
{
int a=1;
cout<<a<<endl;// prints 1
func(a);
cout<<a;// prints 2
return 0;
}
sorry for bad english
One way to read pointers and references is that during declarations, the '*' can be replaced by "something that points to".
So:
int* a;
Means that 'a' is something that points to an integer (i.e. 'a' is a pointer).
In other places in the code (not declarations), the '*' can be replaced by "the thing pointed to by".
So:
*a = 5;
Means that "thing pointed to by 'a' becomes equal to 5". I.e. the integer which a points to is now 5.
In your first block of code, 'a' is just an integer type. when you write func(&a);, you are passing the address of 'a' (i.e. the name of the memory location which stores the value of 'a') to the function. The function is expecting an int* type, (something which points to an int), which is exactly what you've given it.
Within the function, 'a' is just the address of your variable. The function then takes this address, and says "increment the thing that 'a' points to".
In your secondblock of code, 'a' is again just an integer type. This time however, the function is expecting a reference variable (because the function definition is expecting an int& type.
So within the function, 'a' is the original variable - not a copy or a pointer to the original variable. The function says "increment the actual integer that was sent".
Read more
The two cases work similarly:
Case 1: func expects some pointer to some direction of an integer (int *a) which is, as you said, the first byte of a sizeof (int) bytes block according to the OS. When func is called you passed correctly that direction func(&a), so the compiler considers that call as something like: int p = &a; func(p); anyway a pointer to that direction is actually what is being passed.
Case 2: func expects some direction of some integer (int &a). When func is called you just passed correctly the value func(a), as all C++ compilers support reference paramenters, the compiler passes internally the direction of the passed value, func (&a). Notice if you try to call func like func (&a) an error will occur because it would be passed something like func (&&a) while the compiler is just waiting for (&a).
OBS: We can also look to the second case void func(int &a) as a reference which is different from a pointer with an example:
int a = 10;
int &b = a;
cout<<a; //10 is printed
cout<<b; //10 is printed
b = 20;
cout<<a; //20 is printed
cout<<b; //20 is printed
Whether you modify a reference to a (i.e b) or you modify a directly, you are modifying the same value beacause they stand at the same direction of a.

How is C++ function's default parameter passed?

Say I have the following code:
#include <iostream>
using namespace std;
int defaultvalue[] = {1,2};
int fun(int * arg = defaultvalue)
{
arg[0] += 1;
return arg[0];
}
int main()
{
cout << fun() << endl;
cout << fun() << endl;
return 0;
}
and the result is:
2
3
which make sense because the pointer *arg manipulated the array defaultvalue. However, if I changed the code into:
#include <iostream>
using namespace std;
int defaultvalue[] = {1,2};
int fun(int arg[] = defaultvalue)
{
arg[0] += 1;
return arg[0];
}
int main()
{
cout << fun() << endl;
cout << fun() << endl;
return 0;
}
but the result is still:
2
3
Moreover, when I print out the defaultvalue:
cout << defaultvalue[0] <<endl;
It turn out to be 3.
My question is, in the second example, should the function parameter be passed by value, so that change of arg will have no effect on defaultvalue?
My question is, in the second example, should the function parameter be passed by value, so that change of arg will have no effect on defaultvalue?
No.
It is impossible to pass an array by value (thanks a lot, C!) so, as a "compromise" (read: design failure), int[] in a function parameter list actually means int*. So your two programs are identical. Even writing int[5] or int[24] or int[999] would actually mean int*. Ridiculous, isn't it?!
In C++ we prefer to use std::array for arrays: it's an array wrapper class, which has proper object semantics, including being copyable. You can pass those into a function by value just fine.
Indeed, std::array was primarily introduced for the very purpose of making these silly and surprising native array semantics obsolete.
When we declare a function like this
int func(int* arg);
or this
int (func(int arg[])
They're technically the same. It's a matter of expressiveness. In the first case, it's suggested by the API author that the function should receive a pointer to a single value; whereas in the second case, it suggests that it wants an array (of some unspecified length, possibly ending in nullptr, for instance).
You could've also written
int (func(int arg[3])
which would again be technically identical, only it would hint to the API user that they're supposed to pass in an int array of at least 3 elements. The compiler doesn't enforce any of these added modifiers in these cases.
If you wanted to copy the array into the function (in a non-hacked way), you would first create a copy of it in the calling code, and then pass that one onwards. Or, as a better alternative, use std::array (as suggested by #LightnessRacesinOrbit).
As others have explained, when you put
int arg[] as a function parameter, whatever is inside those brackets doesn't really matter (you could even do int arg[5234234] and it would still work] since it won't change the fact that it's still just a plain int * pointer.
If you really want to make sure a function takes an array[] , its best to pass it like
template<size_t size>
void func (const int (&in_arr)[size])
{
int modifyme_arr[100];
memcpy(modifyme_arr, in_arr, size);
//now you can work on your local copied array
}
int arr[100];
func(arr);
or if you want 100 elements exactly
void func (const int (&arr)[100])
{
}
func(arr);
These are the proper ways to pass a simple array, because it will give you the guaranty that what you are getting is an array, and not just a random int * pointer, which the function doesn't know the size of. Of course you can pass a "count" value, but what if you make a mistake and it's not the right one? then you get buffer overflow.

Why is void returning a value?

I can't understand one weird thing. Here is my program :
#include <iostream>
using namespace std;
void Swap(int *a , int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
int main()
{
int a=0;
int b=0;
cout<<"Please enter integer A: ";
cin>>a;
cout<<"Please enter integer B: ";
cin>>b;
cout<<endl;
cout<<"************Before Swap************\n";
cout<<"Value of A ="<<a<<endl;
cout<<"Value of B ="<<b<<endl;
Swap (&a , &b);
cout<<endl;
cout<<"************After Swap*************\n";
cout<<"Value of A ="<<a<<endl;
cout<<"Value of B ="<<b<<endl;
return 0;
}
Now if you look at the function "Swap", I have used "void Swap". Therefore it must not return any value to main function (only "int" returns a value (at least that's what my teacher has taught me)). But if you execute it, the values are swaped in main function! How come ? Can anyone tell me how its possible ?
Swap function in your example just swaps two integers, but does NOT return anything.
In order to check what function has retuned, you have to assign it to some variable, like this
int a = swap(&a, &b);
but this piece of code has an error because swap function doesn't return anything.
Another example:
int func() {
return 18;
}
int main() {
int a = func();
cout << a;
}
Is fine, cause variable a is int and function func returns an int.
Swap may not return any values, but it can still modify them. You're passing in pointers to two variables into the function. If you change the value the pointer maps to in the Swap function, that change persists throughout the program.
Actually, the function is NOT returning the value. It is just accessing the values through the variables' addresses and swapping them from their reference. Your code is right and now I have cleared your concept without any long explanation. That's all.
This is correct.
Your Swap method does work with pointers, not real values.
In your main your are calling this method and tell it to swap the values in the variables. They are in the sme context at this point.
Your code looks very similar to this:
http://www.tutorialspoint.com/cplusplus/cpp_function_call_by_pointer.htm
What it does it uses pointers addresses. You use them as parameters and then you use them to access the information stored at that location, which is the values of a and b, and then change them.
I think you are misunderstand what your teacher said.
What he/she said might be Swap() will not return value, but change value by passing address is still valid.
like this:
int Swap();
int GetReturnValue = Swap(); // Get return value from Swap()
Let's look the second one:
void Swap();
int GetReturnValue = Swap();
Though the second one might really get value, but this value is meaningless.
Sometimes, you will get a compiler warning if you do like the second one, GCC Compiler will report warnings about casting
Swap procedure can only modify your variables because you've passed them by reference.
Remember procedures, unlike functions, cannot return a value.

Understand Reference and Dereferencing Operators?

Can someone please help me understand Reference and Dereference Operators?
Here is what I read/understand so far:
int myNum = 30;
int a = &myNum; // a equals the address where myNum is storing 30,
int *a = &myNum; // *a equals the value of myNum.
When I saw the code below I was confused:
void myFunc(int &c) // Don't understand this. shouldn't this be int *c?
{
c += 10;
cout<< c;
}
int main()
{
int myNum = 30;
myFunc(myNum);
cout<< myNum ;
}
int &c has the address to what's being passed in right? It's not the value of what's being passed in.
So when I do c+=10 it's going to add 10 to the memory address and not the value 30. Is that correct?
BUT... when I run this...of course with all the correct includes and stuff...it works. it prints 40.
Actually the ampersand in the function parameter list for myFunc is not an address operator, nor a bitwise and operator. It is a reference indicator. It means that within myFunc, the parameter c will be an alias of whatever argument is passed to it.
You have a few issues here.
your second line of code int a = &myNum; // a equals the address where myNum is storing 30 is wrong;
you can combine it with line 3 like so:
int *a = &myNum; // a equals the address where myNum is stored;
*a == myNum.
The type int & is read as "reference-to-int". Perhaps the Wikipedia article can help you understand what this means.
Both pieces of code are valid and your understanding of pointers in the first piece of code is correct. However, the ampersand (&) in the two pieces of code are actually different things. (Like how * is both the dereference and multiplication operator)
The second piece of code shows how the & can be used to pass variables to a function by reference. Normally if you had code like this:
int a;
void foo(int bar) {
bar = 3;
}
int main() {
a = 5;
foo(a);
// a still equals 5
}
The call to 'foo()' does not affect the variable you passed to it (bar or in this case, a). However if you changed this line:
void foo(int bar) {
to
void foo(int &bar) {
then it would affect the variable and at the end of the program above, the value of a would be 3.
In C++ when you pass things by reference using int &c you don't need to dereference. You only need to dereference pointers. If it was int *c then it would be necessary. Just remember in both cases you change the value of what was passed in the original caller so myNum is now 40.
Let's have a look at the assumptions first:
int myNum = 30;
// this won't compile. &myNum is the address of an int (an int *), not an int:
int a = &myNum;
// *a is a pointer to an int. It received the address of myNum (which is &myNum),
// and not its value
int *a = &myNum;
About the code:
void myFunc(int &c)
// c is passed by reference. This is a kind of "hidden pointer" that
// allows using the variable as if it was not a pointer but the pointed variable.
// But as this reference and the variable that was passed by the caller (myNum
// in your example) share the same address (this is the property of a reference),
// any modification of the value of c inside myFunc modifies it in the
// caller's scope too (so here, it modifies myNum).
{
c += 10;
cout<< c;
}
int main()
{
int myNum = 30;
myFunc(myNum); // displays 40
// What follows displays 40 as well, due to the fact
// c was passed by reference to myFunc that added 10 to it
cout<< myNum ;
}
So when I do c+=10 it's going to add 10 to the memory address and not
the value 30. Is that correct?
No, 10 was added to the value of c by myFunc.
As c is a reference (a "hidden pointer to") that received myNum, myNum was modified as well.