// pointers1.cpp

#include <iostream>
#include <cstdio>
using namespace std;

int main() {

  int x, y;	// declare two ints
  int *px;	// declare a pointer to an int

  x = 3;	// initialize x

  px = &x;	// set px to the value of the address of x; i.e., to point to x

  y = *px;	// set y to the value stored at the address pointed
		// to by px; in other words, the value of x

  cout << "step 0: here is what we start with: ";
  cout << "x=" << x;
  cout << " px=" << px;
  cout << " y=" << y;
  cout << endl;
  // printing them (above) produces something like:
  // x=3 px=0xbffffce0 y=3
  // note that the precise value of px will depend on the machine
  // and may change each time the program is run, because its value
  // depends on what portion of memory is allocated to the program
  // by the operating system at the time that the program is run

  x++;		// increment x

  cout << "step 1: after incrementing x:       ";
  cout << "x=" << x;
  cout << " px=" << px;
  cout << " y=" << y;
  cout << endl;
  // printing them (above) produces something like:
  // x=4 px=0xbffffce0 y=3
  // note that the value of x changes, but not px or y

  (*px)++;	// increment the value stored at the address pointed
		// to by px

  cout << "step 2: after incrementing (*px):   ";
  cout << "x=" << x;
  cout << " px=" << px;
  cout << " y=" << y;
  cout << endl;
  // printing them (above) produces something like:
  // x=5 px=0xbffffce0 y=3
  // note that the value of x changes, because px contains the
  // address of x

  // what happens if we take away the parens?
  *px++;

  cout << "step 3: after incrementing *px:     ";
  cout << "x=" << x;
  cout << " px=" << px;
  cout << " y=" << y;
  cout << endl;
  // printing them (above) produces something like:
  // x=5 px=0xbffffce4 y=3
  // the value of px changes -- is that what you expected?
  // also note that it goes up by 4 -- because it is an integer pointer
  // and integers take up 4 bytes

  // since px has changed, what does it point to now?
  cout << "        and *px=" << *px << endl;
  // the output is:
  // *px=3
  // because px now points to y's address -- this is because y was
  // declared right after x was declared. note that this is usually
  // the case, but not necessarily. use an array to ensure contiguity of
  // addresses.

}
