// ==========================================================================
// $Id: array_pointer.cpp,v 1.2 2015/09/14 19:35:25 jlang Exp $
// CSI2372 example Code for lecture 2
// ==========================================================================
// (C)opyright:
//
//   Jochen Lang
//   EECS, University of Ottawa
//   800 King Edward Ave.
//   Ottawa, On., K1N 6N5
//   Canada. 
//   http://www.eecs.uottawa.ca
// 
// Creator: jlang (Jochen Lang)
// Email:   jlang@eecs.uottawa.ca
// ==========================================================================
// $Log: array_pointer.cpp,v $
// Revision 1.2  2015/09/14 19:35:25  jlang
// formatting fixed
//
// Revision 1.1  2015/09/14 18:21:18  jlang
// Added pointer to array and C++14 auto type inference.
//
// ==========================================================================
#include <iostream>
#include <iomanip>

using std::cout;
using std::endl;
using std::setw;



int main() {
  // Initialization: size is inferred from number of elements
  int numbers[]{ 0, 1, 2, 3, 4, 5, 6, 7};
  // Sizes known at compile time!
  cout << "Size of array: " << sizeof(numbers) << endl;
  cout << "Size of type: " << sizeof(int) << endl;
  cout << "No. of elements: " << sizeof(numbers)/sizeof(int) << endl;
  const int aSz = sizeof(numbers)/sizeof(int);

  // Pointer to array
  int (*ptrArray)[aSz] = &numbers;
  cout << "Access through pointer to Array" << endl;
  for (int i=0;i<aSz;++i) {
    cout << setw(10) << (*ptrArray)[i] << '\t';
  }
  cout << endl;

  // Pointer to first element
  int* firstE = &numbers[0];
  cout << "Access through pointer to elements" << endl;
  for (int i=0;i<aSz;++i) {
    cout << setw(10) << firstE[i] << '\t';
  }
  cout << endl;

  const int sm = 5;

  // Pointer to smaller array -- needs cast
  // int(*)[8] not the same type as int(*)[3]
  int (*ptrSmall)[aSz-sm] = reinterpret_cast<int(*)[aSz-sm]>(numbers);
  cout << "Access through pointer to small Array" << endl;
  for (int i=0;i<aSz-sm;++i) {
    cout << setw(10) << (*ptrSmall)[i] << '\t';
  }
  cout << endl;

  // Pointer to any element
  int* anyE = &numbers[sm];
  cout << "Access through pointer to any element" << endl;
  for (int i=0;i<aSz-sm;++i) {
    cout << setw(10) << anyE[i] << '\t';
  }
  cout << endl;



  return 0;
}
