C++ Pointers

For a C++ program, the memory of a computer is like a succession of memory cells, each one byte in size, and each with a unique address. These single-byte memory cells are ordered in a way that allows data representations larger than one byte to occupy memory cells that have consecutive addresses.

When a variable is declared, its value is assigned to a specific location in memory (its memory address)

With pointers you can use dynamic memory (heap) instead of static memory (stack) only. Using pointers the visibility of a variable will be position indipendent.

(&) address of… – (*) dereference operator

...
myvar = 25;  // the value of this var is 25
foo = &myvar;// example: the address of myvar is memory address 1776
bar = myvar; // bar is 25
baz = *foo;  // baz equal to value pointed to by foo (25) 
...

Workink example:


// my first pointer
#include <iostream>
using namespace std;

int main ()
{
  int firstvalue, secondvalue; // declaring variables
  int * mypointer;             // declaring pointer wuth asterisk

  mypointer = &firstvalue;
  *mypointer = 10;

  mypointer = &secondvalue;
  *mypointer = 20;

  cout << "firstvalue is " << firstvalue << '\n';
  cout << "secondvalue is " << secondvalue << '\n';
  return 0;
}

Ther result is:
10
20

For italian people: come funziona?
1. dichiaro le variabili firstvalue, secondvalue; -> il sistema operativo assegna loro un indirizzo di memoria
2. dichiaro il puntatore usando *mypointer
3. il puntatore ‘punta’ all’indirizzo di firstvalue e gli assegna un valore di 10
4. LO STESSO PUNTATORE ‘punta’ all’indirizzo di secondvalue e gli assegna un valore di 20
5. Ora firstvalue=10 e secondvalue=20

Example:


// more pointers
#include <iostream>
using namespace std;

int main ()
{
  int firstvalue = 5, secondvalue = 15;
  int * p1, * p2;

  p1 = &firstvalue;  // p1 = address of firstvalue
  p2 = &secondvalue; // p2 = address of secondvalue
  *p1 = 10;          // value pointed to by p1 = 10
  *p2 = *p1;         // value pointed to by p2 = value pointed by p1
  p1 = p2;           // p1 = p2 (value of pointer is copied)
  *p1 = 20;          // value pointed by p1 = 20
  
  cout << "firstvalue is " << firstvalue << '\n';
  cout << "secondvalue is " << secondvalue << '\n';
  return 0;
}

The result is:
firstvalue is 10
secondvalue is 20

Arrays and Pointers

Example with an array:


// more pointers
#include <iostream>
using namespace std;

int main ()
{
  int numbers[5];
  int * p;
  p = numbers;  *p = 10;
  p++;  *p = 20;
  p = &numbers[2];  *p = 30;
  p = numbers + 3;  *p = 40;
  p = numbers;  *(p+4) = 50;
  for (int n=0; n<5; n++)
    cout << numbers[n] << ", ";
  return 0;
}

The result is:
10, 20, 30, 40, 50,

Const

Keyword ‘const’ declares pointers that can access the pointed value to read it, but not to modify it.

...
int x;
int y = 10;
const int * p = &y;
x = *p;          // ok: reading p
*p = x;          // error: modifying p, which is const-qualified 
...

Working example:


// pointers as arguments:
#include <iostream>
using namespace std;

void increment_all (int* start, int* stop)
{
  int * current = start;
  while (current != stop) {
    ++(*current);  // increment value pointed
    ++current;     // increment pointer
  }
}

void print_all (const int* start, const int* stop)
{
  const int * current = start;
  while (current != stop) {
    cout << *current << '\n';
    ++current;     // increment pointer
  }
}

int main ()
{
  int numbers[] = {10,20,30};
  increment_all (numbers,numbers+3);
  print_all (numbers,numbers+3);
  return 0;
}

The result is:
11
21
31

Pointers can also be themselves const:

...
int x;
      int *       p1 = &x;  // non-const pointer to non-const int
const int *       p2 = &x;  // non-const pointer to const int
      int * const p3 = &x;  // const pointer to non-const int
const int * const p4 = &x;  // const pointer to const int 
...
const int * p2a = &x;  //      non-const pointer to const int
int const * p2b = &x;  // also non-const pointer to const int 
...

Pointers and string literals

const char * foo = "hello"; 

Address Value
1702 h
1703 e
1704 l
1705 l
1706 o
1707 \0

Pointers to Pointers

C++ allows the use of pointers that point to pointers, the syntax simply requires an asterisk (*) for each level of indirection in the declaration of the pointer:


char a;
char * b;  // pointer to variable, one asterisk
char ** c; // pointer to pointer , two asterisk
a = 'z';
b = &a;
c = &b;

Void (privo) Pointers

Void pointers are pointers that point to a value that has no type.


// increaser
#include <iostream>
using namespace std;

void increase (void* data, int psize)
{
  if ( psize == sizeof(char) )
  { char* pchar; pchar=(char*)data; ++(*pchar); }
  else if (psize == sizeof(int) )
  { int* pint; pint=(int*)data; ++(*pint); }
}

int main ()
{
  char a = 'x';
  int b = 1602;
  increase (&a,sizeof(a)); // sizeof: the number of bytes required to represent the type.
  increase (&b,sizeof(b));
  cout << a << ", " << b << '\n';
  return 0;
}

The result is:
y, 1603

Null Pointers

Sometimes, a pointer really needs to explicitly point to nowhere, and not just an invalid address.


// null pointers
int * p = 0;
int * q = nullptr;

Pointers to Functions

The typical use of this is for passing a function as an argument to another function.
The name of the function is enclosed between parentheses () and an asterisk (*) is inserted before the name.


// pointer to functions
#include <iostream>
using namespace std;

int addition (int a, int b)
{ return (a+b); }

int subtraction (int a, int b)
{ return (a-b); }

int operation (int x, int y, int (*functocall)(int,int))
{
  int g;
  g = (*functocall)(x,y);
  return (g);
}

int main ()
{
  int m,n;

  // passing a function as an argument to another function
  int (*minus)(int,int) = subtraction;

  m = operation (7, 5, addition);
  n = operation (20, m, minus);
  cout <<n;
  return 0;
}

The result is: 8

For italian peolple: come funziona?
1. m = operation (7, 5, addition); -> int operation (int x, int y, int (*functocall)(int,int))
passiamo i valori 7, 5 e la funzione da richiamare

2. g = (*functocall)(x,y);
richiama la funzione addition inviando i valori 7 e 5 -> il valore sarà m= 12

3. n = operation (20, m, minus); dove -> int (*minus)(int,int) = subtraction;
passiamo i valori 20, 12 e la funzione substraction -> il valore sarà 20-8= 12

My website: http://www.lucedigitale.com

Reference: http://en.wikipedia.org/wiki/Sizeof
Reference: http://www.cplusplus.com/doc/tutorial/pointers/