CS 150 - Intro to Programming - Fall 2001
Lab Exercise 10

Topics:

Part 1 - Array Declaration and Initialization

Arrays are declared by giving their type, a name (identifier) , the left subscript operator [, a size expression, the right subscript operator ], followed by a ";" (semicolon). For example:

int a[10];           //declare an array of 10 integers
double scores[100];  //declare an array of 100 doubles


A.) The array size expression must be an integer literal (8, 100, etc) or a const expression. For example: When the program in part a below is compiled, the compiler will issue an error message because MAX is not a constant - even though it has been given a value. Part b shows the best way to declare an array - use a size expression that is declared in a constant statement - the use of literals for array indexes should be limited to test code and never used in a "production grade program" Also note that in part b MAX is declared a global variable - one case where globals are ok..

a.

#include <iostream>
using namespace std;

int main()
  {
  int MAX = 10;
  int foo[MAX];  //will cause an error
  //do nothing 
  return 0;
  }

b.

#include <iostream>
using namespace std;

const int MAX = 10;
int main()
  {
  int foo[MAX];  //constant ok
  //do nothing 
  return 0;
  }

Paste the code from part a into a C++ file. Compile the program and note the error. Nothing to be turned for this part - but make sure you can identify the above error!!!

B.) Arrays like all other variables we use must be initialized before we use them. For example: (Assume MAX = 10;)

An array may be initialized by a list of values.

1.)  int v1[] = {1, 2, 3, 4};               //integer array
2.)  char s1[] = {'a', 'b', 'c', '\0'};     //character array - cstring
3.)  char c1[] = {'a', 'b', 'c'};           //just a plain character array
4.)  char str[] = "Hello CS150";            //automatically appends the '\0'

When an array is declared without a specific size, but with an initializer list, the size is calculated by counting the elements of the initializer list. Therefore v1, s1, c1, and str are of type int[4], char[3], char[4], and char[12], respectively. If a size is explicitly specified, it is an error to give surplus elements in an initializer list. For example:

5.)  char s2[2] = {'a', 'b', '\0'};  //error: too many initializers
6.)  char s3[3] = {'a', 'b', '\0'};  //ok

If the initializer list supplies too few elements, 0 is assumed for the remaining elements. For example:

7.)  int v2[8] = {1, 2, 3, 4};  //equivalent to:  int v2[8] = {1, 2, 3, 4, 0, 0, 0, 0};
8.)  int v3[MAX] = {0};         //set all elements to zero;

If no initializer list is supplied, the array elements are not initialized to any value. For example:

9.)  double v4[5*MAX];          //declare array of 50 doubles- no initial values

Create a C++ program(yourLastNameLab10Part1). Paste the array declarations (1 - 9) into the program (be sure to define MAX). Run the program - line 5 should give an error - note the error - then comment out the line and recompile. Once the program compiles, enable the debugger, run the program and trace the execution as the array declarations are encountered. Note how the arrays are represented in the variable window and when the initial values given to the variables. What values does v4 have?

C.) The above method works well for small arrays when we know in advance the number and values of the data to be entered - for most programs this is not the case - we do not know ahead of time how many values will be entered - the best we can do here is declare an array that is "big enough" to hold all anticipated cases. And initialize all its element to some default value. For example an array size of 100 would be"big enough" to hold the test scores for a typical CS150 class since the enrollment limit is 80. Initial values could be set to 0.0.

D.) Add two for loops to the above program; one that will initialize all elements of v4 to 0.0 - and one to print each element of the array. Test your code until it compiles and runs (saveAs - yourLastNameLab10Part1).


Part 2 - Accessing and Processing Arrays elements.

A.) Accessing array elements - individual array elements can be accessed through their index to update or read the value at that memory location. Study the code sample below. Create a C++ program(yourLastNameLab10Part2a). Paste the following code into the program. Run the program and note how the elements of the array are changed as the program is executed..

/********************************************************/
// R. A. Hillyard
// Lab10Part2a
/********************************************************/

#include<iostream>
#include<iomanip>
using namespace std;
const int TEST_MAX = 10;
void printArray(int a[], int size);  //function to print array elements

int main()
  {
  int testArray[TEST_MAX] = {};
  int index;

  cout << "To start array contains the values:\n";
  printArray(testArray, TEST_MAX);
  
  while(true)
    {
    cout << "enter an index to change (-1 to quit): ";
    cin >> index;       //would be a good idea to check range of index here
    if(index == -1)
      break;
 
    cout << "enter new value: ";
    cin >> testArray[index];       //write value to array
 
    cout << "After update array contains the values:\n";
    printArray(testArray, TEST_MAX);
    }
  return 0;  
  }//end main
/********************************************************/
 void printArray(int a[], int size)
   {
   for(int i = 0; i < size; i++)  //write size elements to the screen
     cout << setw(5) << a[i];
     
   cout << endl;  
   }
/********************************************************/

B.) When processing arrays, we often want to do something to each element of the array, the best control structure for this task is the for loop. There are two main cases for filling arrays as noted in part one - one we will know ahead of time how many values are in the array. For example to initialize and print any array that holds the first eight powers of 2 we could use the following:

int a[8];
for(int i = 0; i < 8; i++)  //initialize array
  {a[i] = pow(2, i); }
for(int i = 0; i < 8; i++)  //print the results
  {cout <<a[i] << endl; }

A second and more general case is when we don't know how many elements will be in the array (partially filled arrays)- in this case we need to keep track of the actual number of elements using a counter of some type. The counter is incremented each time a new value is read into the array. Create a C++ program(yourLastNameLab10Part2b). Paste the reverse.cpp codeSample into the program. Run the program and note how the program keeps track of the actual number of elements in the array. The for loop is designed to limit the number of entries (numVals < MAXVAL) and keep track of the actual number of entries read (numVals++).

C.) Out of range errors - Most common error when programming with arrays. C++ provides no range checking when using arrays - you can read as well as write to elements that are not in the array. Even though this can be done it is the programmers job to keep track of the number of elements in an array and make sure this error never occurs - writing or accessing elements outside the array will produce unpredictable results and are very hard to debug. An out of range error quite often happens when processing each element of the array using a loop and are "off by one" (or more) due to an improper stopping condition. The following code illustrates this. Create a C++ program (yourLastNameLab10Part2c). Paste the following codeSample into the program. Run the program and note how the array nextArray gets values even though I did not directly access them.

/********************************************************/
// R. A. Hillyard
// Lab10Part2c
/********************************************************/

#include<iostream>
#include<iomanip>
using namespace std;
const int TEST_MAX = 10;
void printArray(int a[], int size);

int main()
  {
  int testArray[TEST_MAX] = {};
  int nextArray[TEST_MAX] = {9,9,9,9,9,9,9,9,9,9};
  //int index;

  cout << "To start testArray contains the values:\n";
  printArray(testArray, TEST_MAX);
  cout << "To start nextArray contains the values:\n";
  printArray(nextArray, TEST_MAX);
  cout << "************************\n";

  cout << "write 30 values to a 10 element testArray!!!\n";
  for(int i = 0; i < 3*TEST_MAX; i++)
    {
    testArray[i] = i;
    }
  printArray(testArray, 3*TEST_MAX);   //print results

  cout << "Change testArray index 15 to -666:\n";
  testArray[15] = -666;                //overwrite the 6th element of nextArray???
  cout << "\n************************\n";
  cout << "nextArray  now Contains\n";
  printArray(nextArray, TEST_MAX);     //how did this array get any values???
  return 0;
  }//end main

/*******************************************************************/
void printArray(int a[], int size)
  {
  for(int i = 0; i < size; i++)
    {
    cout << setw(5) << a[i];
    if( ((i+1)%10) == 0)     //print 10 per line
      cout << endl; 
    }
  cout << "\n************************\n";
  }
/*******************************************************************/

D.) Write a complete C++ (yourLastNameLab10Part2d) program that extracts an undetermined number of characters from the user (maximum of 100), stores them in an array and then displays them in reverse order. Input is terminated when the user presses the enter key('\n'). (use the cin.get(charVar) member function to read the data a character at a time - until the end of line ('\n') is read)


Part 3 - Arrays and File I/O

Write a C++ program (yourLastNameLab10Part3) that reads an undetermined number of doubles (maximum of 50) from a file (allow the user to enter the file name) and stores them in an array, then displays them to the screen in reverse order. You will have to create the input file (lab10Part3.dat) for the doubles - use a variety of values. Output the results using 2 decimal place precision.



What to turn in

Remember to: