0

I know call by pointers in which we pass address of variables.Something like this:

void swap(int *x, int *y)
{
   int temp;
   temp = *x; /* save the value at address x */
   *x = *y; /* put y into x */
   *y = temp; /* put x into y */

   return;
}

  swap(&a, &b);

And also call by reference,in both of these methods the changes made in the function are reflected in actual arguments' variable.
But why are actual parameters passed in this case of call not changed:

#include <iostream>
using namespace std;
void foo(int* c){
c=c+1;
}
int main()
{
    int a=5;
    int *c=&a;
    cout<<&c<<endl; //0x7ffe1a74f3b0
    foo(c);        
    cout<<*c<<endl;//5
    cout<<&c<<endl;//0x7ffe1a74f3b0
}

Here c passed to foo() is address of a.So how this is call by value.
Here c should have printed garbage value according to me.Please explain what has happened here.

user7098526
  • 235
  • 3
  • 8
  • 5
    `foo()`'s parameter is passed by value. Which means that `c=c+1` modifies foo's parameter. That's it. It does nothing to the completely different variable named `c` in `main()`. The End. – Sam Varshavchik Jun 16 '17 at 02:16
  • How come it is value? c contains the addr of a. – user7098526 Jun 16 '17 at 02:19
  • 1
    A pointer is part of the type of something. An `int*` is not the same as an `int**` which is not the same as an `int***`. You passed the pointer by value. If you assign to it with `*c = value`, obviously that will be reflected in the caller, but changing the value of *c* will not have any effect. There is a distinction between changing the value of `c` and changing the value of what `c` *points* to. – Millie Smith Jun 16 '17 at 02:24
  • When you call `foo`, its parameter `c` is set to the address of `a`. Then the line `c=c+1;` sets `c` to be equal to an address that is one past the address of `a`. When `foo` returns, its parameter `c` is discarded and the different variable `c` that is defined within `main` is not affected in any way. Perhaps you meant to write `*c = *c + 1;` instead? – David Scarlett Jun 16 '17 at 02:25
  • @DavidScarlett no,i meant c=c+1; and i was thinking it should change the address of c in main – user7098526 Jun 16 '17 at 02:30
  • @user7098526 Then you need to pass the variable `c` that is defined in main by reference, otherwise the parameter `c` will merely be a copy of it. I'll post an answer to illustrate. – David Scarlett Jun 16 '17 at 02:39

3 Answers3

2

And also call by reference, in both of these methods the changes made in the function are reflected in actual arguments' variable.

There is an important difference, though: the changes are always made to whatever is referenced/pointed to, never to the reference/pointer itself (modifying a reference is impossible in general).

That is why assigning c a new value inside foo has no effect on c outside foo: the pointer passed to a function is copied.

If you need to modify the pointer, you need to add another level of dereference by passing a pointer reference or a pointer to a pointer.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
0

Following on from comments, the variable c defined in function main is a different variable to the parameter c of function foo. If you want foo to be able to modify main's c, that is modify the address that c's pointer type holds, then you need to pass either a reference or pointer to c to the function instead.

Here is an example that shows the difference between passing c by value (as int *), or by reference (as int ** or int *&). Don't be fooled by the fact that int * is a pointer type, that means that it can receive an int by reference or an int * by value. And since main's c is int * rather than int, main c is being passed by value.

Note the differences in how the functions are called (whether c needs the address operator & in the function call) and the outcome of each function.

#include <iostream>
using namespace std;

void foo_int_ptr(int* c)
{
    c=c+1;
}

void foo_int_ptr_ptr(int** c)
{
    *c=*c+1;
}

void foo_int_ptr_ref(int*& c)
{
    c=c+1;
}

int main()
{
    int a=5;
    int *c=&a;
    cout << "&c=" << &c << ", c=" << c << ", *c=" << (c==&a ? std::to_string(*c) : std::string("INVALID PTR")) << endl;
    foo_int_ptr(c);
    cout << "&c=" << &c << ", c=" << c << ", *c=" << (c==&a ? std::to_string(*c) : std::string("INVALID PTR")) << endl;
    foo_int_ptr_ptr(&c);
    cout << "&c=" << &c << ", c=" << c << ", *c=" << (c==&a ? std::to_string(*c) : std::string("INVALID PTR")) << endl;
    foo_int_ptr_ref(c);
    cout << "&c=" << &c << ", c=" << c << ", *c=" << (c==&a ? std::to_string(*c) : std::string("INVALID PTR")) << endl;
}

Output:

&c=0x7e02d81808b8, c=0x7e02d81808ac, *c=5
&c=0x7e02d81808b8, c=0x7e02d81808ac, *c=5
&c=0x7e02d81808b8, c=0x7e02d81808b0, *c=INVALID PTR
&c=0x7e02d81808b8, c=0x7e02d81808b4, *c=INVALID PTR
David Scarlett
  • 3,171
  • 2
  • 12
  • 28
0

there is a mistake in your thinking about this ..

int *c = &a; 

this doesn't mean that c "contains" address of a, this means that c is a pointer TO the address of a. Passing a pointer to foo() will not do anything.

Kattie.S
  • 117
  • 1
  • 11
  • Actually, `c` does contain the address of `a`, and `c` *is* a pointer to `a`. But when passed to `foo`, `foo` receives a *copy* of the address of `a` in a new pointer variable. – David Scarlett Jun 16 '17 at 08:30