int main()
{
  /* Values */
            int i = 4;  // not constant, can be modified: 
                i = 5;

     const int ci = 6;  // constant, must be initialized
               ci = 7;  // syntax error, cannot be modified

  /* References */
         int &ir1 = i;  // reference, must be initialized
              ir1 = 6;

         int &ir2 = ci; // syntax error, const correctness would be flawed

  const int &cir1 = ci; // constant reference to a constant value
             cir1 = 7;  // syntax error

  const int &cir2 = i;  // const reference to a non-const value, still ok
             cir2 = 7;  // syntax error, cir2 is const reference

  /* Pointers */
         int *ip;
              ip = &i;
             *ip = 5;   // ok

              ip = &ci; // syntax error, const correctness would be flawed

  const int *cip = &ci; // ok 
            *cip = 7;   // syntax error


              ip = cip; // syntax error, C++ keeps constness
             cip = ip;  // ok, but now:
            *cip = 5;   // syntax error, wherever cip points is const 

  int const *icp;       // same as const int *
             icp = &i;  // ok, can assign to, icp is NOT const, *icp IS
            *icp = 5;   // syntax error, wherever icp points is const

  /* Can a pointer be constant? */
         int * const ipc = &i;  // ipc IS const, must be initialized         
                    *ipc = 5;   // OK, where ipc points to is NOT a const

        int * const ipc2 = &ci; // syntax error, ipc2 is NOT pointer to const
  const int * const cipc = &ci; // const pointer to a const

  return 0;
}