C++ logo

The ‘Pointer’ in C++, demystified. [Part-2]

In Part 1 of this series we explored the conceptual landscape of Pointer in C++. We discussed Pointer definition, how a Pointer variable declare, reference and some primary concepts on Pointer .  In this article I’ll share a some additional intermediate level examples from the Docker ecosystem that you need to know. At first write following program  in your editor and run:

#include <bits/stdc++.h>

using namespace std;

int main()
{
    double pi = 3.141592655358;
    int *ptr;
    ptr=&pi;

    cout<< " Value of pi " << pi << "\n";
    cout << "Value of pi :" << *ptr << "\n";

    return 0;
}

While compiling above program you got following error! right?

error: assigning to 'int *' from incompatible type 'double *'
    ptr=&pi;

The error is quite self-explanatory. Here we referenced  double type variable to integer type pointer. However, we know that type of reference variable and type of Pointer variable must be same.

Now, we put the address of Integer type variable into Integer type pointer. After that, we will  change the value of Pointer. Then we would see that the Integer type variable value has changed.

 

#include <bits/stdc++.h>

using namespace std;

int main()
{
    int x = 10;
    int *p = &x;
    cout << "Value of x: " << x << "\n";
    *p = 20; //content of pointer p changed
    cout << "Value of x: " << x << "\n";
    cout << "Address of x: " << &x << "\n";
    cout << "Address of p: " << p << "\n";

    return 0;
}

Output:

Value of x: 10
Value of x: 20
Address of x: 0x7ffee55351b8 
Address of p: 0x7ffee55351b8

Notice the output of  program we found x and p memory address are same. Here x variable’s address has putted into p pointer variable.In other word, p point x variable’s memory address. So,  *p=20;  actually means assigning new value to variable x which memory address hold by p pointer.

Another one example on pointer’s value change and it’s effects:

#include <bits/stdc++.h>

using namespace std;

int main()
{    
    int x = 10;
    int *p;
    cout << "Value of x: " << x << endl;
    p = &x;
    *p = 20;
    cout << "Value of x: " << x << endl;
    x = 15;
    cout << "Value of x: " << x << endl;
    cout << "Value stored at location: " << p << " is " << *p << "\n";
    cout << "Address of x: " << &x << endl;
    cout << "value of p: " << p << endl;
    return 0;
}

Output:

Value of x: 10
Value of x: 20
Value of x: 15
Value stored at location: 0x7ffeec1bf168 is 15
Address of x: 0x7ffeec1bf168
value of p: 0x7ffeec1bf168

If we put address of x into p, then we can access x using *p.  When we assign any other value to *p , value of x is also changed. *p means the value of variable(x) which address hold by p Pointer. So, If we change *p is value of x will also change.

References and Pointers

There are 3 ways to pass C++ arguments to a function:

  • call-by-value
  • call-by-reference with pointer argument
  • call-by-reference with reference argument

Bellow I am giving a program to illustrate call-by-methods in C++  using all 3 ways of pass agruments in function:

#include <bits/stdc++.h> 
using namespace std; 
//Pass-by-Value 
int square1(int n) 
{ 
  //Address of n in square1() is not the same as n1 in main() 
  cout << "address of n1 in square1(): " << &n << "\n"; 
  
  // clone modified inside the function 
  n *= n; 
  return n; 
} 
//Pass-by-Reference with Pointer Arguments 
void square2(int *n) 
{ 
  //Address of n in square2() is the same as n2 in main() 
  cout << "address of n2 in square2(): " << n << "\n"; 
  
  // Explicit de-referencing to get the value pointed-to 
  *n *= *n; 
} 
//Pass-by-Reference with Reference Arguments 
void square3(int &n) 
{ 
  //Address of n in square3() is the same as n3 in main() 
  cout << "address of n3 in square3(): " << &n << "\n"; 
  
  // Implicit de-referencing (without '*') 
  n *= n; 
} 
void tests() 
{ 
  //Call-by-Value 
  int n1=8; 
  cout << "address of n1 in main(): " << &n1 << "\n"; 
  cout << "Square of n1: " << square1(n1) << "\n"; 
  cout << "No change in n1: " << n1 << "\n"; 
  
  //Call-by-Reference with Pointer Arguments 
  int n2=8; 
  cout << "address of n2 in main(): " << &n2 << "\n"; 
  square2(&n2); 
  cout << "Square of n2: " << n2 << "\n"; 
  cout << "Change reflected in n2: " << n2 << "\n"; 
  
  //Call-by-Reference with Reference Arguments 
  int n3=8; 
  cout << "address of n3 in main(): " << &n3 << "\n"; 
  square3(n3); 
  cout << "Square of n3: " << n3 << "\n"; 
  cout << "Change reflected in n3: " << n3 << "\n"; 
  
  
} 
//Driver program 
int main() 
{ 
  tests(); 
} 

Output:

address of n1 in main(): 0x7ffcdb2b4a44
address of n1 in square1(): 0x7ffcdb2b4a2c
Square of n1: 64
No change in n1: 8
address of n2 in main(): 0x7ffcdb2b4a48
address of n2 in square2(): 0x7ffcdb2b4a48
Square of n2: 64
Change reflected in n2: 64
address of n3 in main(): 0x7ffcdb2b4a4c
address of n3 in square3(): 0x7ffcdb2b4a4c
Square of n3: 64
Change reflected in n3: 64

Till now in Part-2 we have learnt about some beginner to intermediate level pointer concept. In Part-3 we will know about more topics like Null Pointer, String & Pointer , Pointer inside pointer and so on. If you found this series useful please stick with it. Thank you and Good-bye.

 

 

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *