Please send questions to st10@humboldt.edu .

CIS 130 - Week 13, Wednesday, 04-21-10

Intro to C++ ARRAYS

*   the most basic "collection" of data in C++ is the array
    ...it's called a composite data type;
    (int, double, bool -- types where an instance's value
    are just "one" value -- are called scalar data types)

    *   we also talk a lot about how to organize, or structure,
        collections of data -- often called data structures;

	an array is a basic data structure, often used as
	one of several possible means of building other
	data structures;

*   in C++, the basic static array has its restrictions,
    but those restrictions help it to be quite fast and
    efficient in execution...

*   you can think of an array as a 1-column table
    (that's a 1-dimensional array)

    *   in C++, a static array has a set size, that you have
        to specify in advance;

        ...an array's size is how many THINGS are in it;

	...the compiler then requests a chunk of memory
	capable of holding that many things;

    *   and, every element must be of the same type;

        (so the compiler can request enough memory to
	hold the specified number of things where each
	thing is of that type;)

*   So, to declare an array in C++, you need to tell the
    compiler 3 things:
    *   the NAME you want for the array,
    *   the TYPE of each of the elements in the array, and
    *   how many elements are in the array

    Here's the syntax for that:

    type name[size]; 

    ...note that, IF you know if advance the size of an array,
       you could certainly use a named constant for that...

    const int NUM_STUDENTS = 37;
    int quiz_grades[NUM_STUDENTS]; // I now have a collection of memory
                                   //    able to hold 37 ints,
				   //    named quiz_grades

    ...note that you really don't know what's in those 37 int-sized
       holes or slots -- and you shouldn't assume what's in them --
       UNTIL you put something in;

    const num NUM_CITIES = 42;
    string cities_to_visit[NUM_CITIES]; // I now have a collection of
                                        //    memory able to hold
					//    42 strings, named
                                        //    cities_to_visit
*   to refer to the whole collection,
    just use the name of the array;
    (like when you pass it as an argument)

    cities_to_visit
    quiz_grades

*   but what if I just want ONE thing from that collection?
    ...you give an INDEX specifying HOW MANY "STEPS" from
       the beginning of the array the element you want is;

       the first element is 0 steps from the beginning,
       so its index is 0

       you write array_name[index] to indicate a SINGLE
           element within the array

       cities_to_visit[0] is the string at the beginning
       (0 steps from the beginning)

       cities_to_visit[5] is the 6th string in the set
       (5 steps from the beginning)

*   really, C++ just keeps track of WHERE the array begins,
    and what type its elements are;

    when you say
    cities_to_visit[5]

    ...the computer multiplies the index (5) by the size of the
       type (here, string) and ADDS that to the beginning
       of the array to know right where to jump to reach
       the desired element;

    And now,
    cities_to_visit[5] is an expression,
    its value is THAT string within the array;
    (you can SET it using this expression,
     you can USE it using this expression)

    quiz_grades[7] is an expression,
    its value is THAT double (the 8th double, 7 steps from the beginning)
       within the array

    the type of cities_to_visit --> array of string
    the type of cities_to_visit[3] --> string

    the type of quiz_grades --> array of double
    the type of quiz_grades[7] --> double

    These are all now fine:

    quiz_grades[3] = 99.5;

    // once it is set to something!

    cout << quiz_grades[3] >> endl;

    // would print 99.5 to the screen
99.5

    cities_to_visit[5] = "Paris";

    // once it is set to something!

    cout << cities_to_visit[5] >> endl;

    // would print Paris to the screen:
Paris

*   Notice, then: 
    if an array has 5 elements, the range of its indices is 0 to 4
    if it has 10 elements, the range of its indices is 0 to 9
    ...if it has SIZE elements, the range of its indices is 0 to (SIZE-1)

*   Also notice:
    If you are doing something involving every element in an array,
    you'll OFTEN want to use a count-controlled loop to do it;

    // assume cities_to_visit has been filled with cities

    // you could print the cities in that array:

    int index = 0;
    
    while (index < NUM_CITIES)
    {
        cout << cities_to_visit[index] << endl;
        index++;
    }

    // assume quiz_grades has been filled with quiz grades

    // you could add up all those grades like this:

    int index = 0;
    double sum_grades = 0;
   
    while (index < NUM_STUDENTS)
    {
        sum_grades += quiz_grades[index];
        index++;
    }

    // and after the loop I could return the average of those grades
    //    like this

    return sum_grades / NUM_STUDENTS;

*   C++ does provide a shortcut for INITIALIZING an array
    to values -- this ONLY works within an array declaration,
    darn it!

    type array_name[size] = {first_element, second_element, ...};

    const int NUM_GRADES = 5;
    int final_grades[NUM_GRADES] = {95, 98, 87, 70, 99};

*   If I'd like to write a function that expects an array and
    does something to it ...
    NOTE: a C++ array does not "know" its size!
    (C++ keeps track of its type and where it starts,
       but that's it!)

       ...so ALL functions that expect an array should ALSO
          expect the SIZE of that array as an additional parameter!!

*   Let's write a function that expects an array of double and its
    size, and it returns the sum of the doubles in that array;

// contract: sum_array: double[] int -> double

                        ^ NOTE how you indicate, for a function,
			  that the type of a parameter is an array!
			  you put the type of the element in the
			  array, followed by []

// purpose: expects any array of numbers and how many numbers
//          are in it, and returns the sum of those numbers

double sum_array(double values[], int num_values)

/* examples:
   consider this array:

   const int NUM_WTS = 5;
   double fish_wts[NUM_WTS] = {10, 20.5, 3, 4, 100};

   sum_array(fish_wts, NUM_WTS) == 137.5
*/

double sum_array(double values[], int num_values)
{
    int index = 0;
    double sum_so_far = 0.0;

    while (index < num_values)
    {
        sum_so_far = sum_so_far + values[index];
        index++;
    }

    return sum_so_far;
}

*   count-countrolled loops are so common --
    and it is SO easy to forget to increment the counter,
    or set it originally --
    that C++ provides a special-purpose loop that's especially
    good for THIS kind of loop;

    the for-loop

    syntax:

    for (initialize_steps; bool_cond; update_steps)
        statement;

    often is:

    for (initialize_steps; bool_cond; update_steps)
    {
        statement;
	...
	statement;
    }

    semantics:
    1. DO the initialize_steps
    2. see if bool_cond is true. if so,
       do the body (its statement(s))
       then do update_steps
  
       if false, go to 3.
    3. ...

    THESE 2 loops do the SAME THING:
----------------------------
    double sum_so_far = 0.0;    

    for (int index=0; index < num_values; index++)
    {
        sum_so_far = sum_so_far + values[index];
    }
    return sum_so_far;
----------------------------
    double sum_so_far = 0.0;
    int index = 0;

    while (index < num_values)
    {
        sum_so_far = sum_so_far + values[index];
        index++;
    }
    return sum_so_far;
----------------------------

*   FEEL FREE to use a for-loop for any count-controlled loop;
    (but it is POOR STYLE to use it for a NON-count-controlled loop)

----------------------------
Another example:
*   I want a function that accepts an array of strings,
    and its size, and a desired title, and it returns
    nothing, but it prints to the screen that title,
    then a blank line, and then the strings within
    that array, one string per line

    see: function show_strings