Home Previous Next

CSC100 :: Lecture Note :: Week 9
Assignments | Code | Handouts | Resources | Email Thurman {Twitter::@compufoo Facebook::CSzero}
{GDT::Bits:: Time  |  Weather  |  Populations  |  Special Dates}

Overview Assignment(s): Code: arrays0.cpp | arrays1.cpp | random.cpp | arrays2.cpp | BingoCard.cpp | bingo.cpp

Arrays

An array is a collection of individual data values with two characteristics: it is ordered and homogeneous.

The following are some terms commonly used when talking about arrays:

An array is homogeneous because each element must be of the same type. For example, an array of int's, an array of float's, an array of char's.

An array is ordered -- it has a 1st element, a 2nd element, a 3rd element, and so on. Array elements are stored in contiguous memory locations.

Just like any other variable, an array must be defined before it is used.

   Syntax:  element-data-type array-name [ length ];

      int intArray[10]; 
         name:  intArray
         type:  int
         length:  10
         size:  10 * sizeof(int)

      char someString[32];
         name:  someString
         type: char
         length: 32
         size:  32 * sizeof(char)

Each element of the array is identified by a numeric value called its index (index numbers always start at 0).

When defining an array, its length must be specified at compile-time. In addition, the specification of the length must be a constant integral EXPR.

   
   int i = 10;
   /* double salaries[i];   // illegal (not a constant) */
   /* char name[15.5];      // illegal (not an integral type) */
   const int MAX_ELEMENTS = 10;
   short scores[MAX_ELEMENTS];  /* okay in C++, not C */
   #define LENGTH 5
   float someArrayOfFloats[LENGTH];

Typically, array lengths are defined to be manifest constants.

Array Initialization

Arrays can be initialized at the time they are defined.

   int evenNumbers[5] = { 2, 4, 6, 8, 10 };

   note:  it is a syntax error if the # of initializers is
          greater than the array length (i.e. # of elements)

   The elements of the initializer list must be constant
   EXPRs.  If the number of initializers is less than the
   array length, then remaining elements are set to zero.

If an array is initialized when defined, then the length is not needed -- the compiler will set the length depending on the number of initializers. If the length of the array needs to be greater than the number of initializers specified, then the length must be specified.

   float radioStations[] = { 103.1, 93.3, 100.7 };

   radioStations  has a length of 3; to figure out the length
   of the array using code:

      sizeof(radioStations) / sizeof(radioStations[0])

   sizeof(radiostations)  evaluates to the size of the array
   and  sizeof(radioStations[0])  evaluates to the size of a
   single element of the array (recall, an array size is equal 
   to the length of the array times the size of the array type)

   the following EXPR also works to determine the length of
   an array    sizeof(radioStations) / sizeof(float)    but could 
   result in the defect if the type of the array is changed and
   the EXPR is not

There is not a convenient mechanism for initializing all elements of an array to a single value (exception: it is easy to set all elements of an array to zero -- int a[10] = { 0 };).

For efficiency, locally declared arrays that are initialized at definition may be declared to be static.

   static short tvStations[99] = { 3, 10, 12, 61 };

   tvStations  is an array of length 99; elements 0, 1, 2, 3
   have non-zero values, whereas elements 4 through 98 equal 0;
   the array is initialized once -- at program load time

Once an array has been defined, its length (i.e. number of elements) cannot be altered.

Elements of the array are accessed using the unary array operator [].

   const int LEN = 10;
   int a[LEN];

   a[3] = 150;  /* set element #4 to 150 */
   a[1] = 200;  /* assign the value 200 to element #2 */

   if (a[1] == a[3]) /* compare the value of element #2 with element #4*/

Array indicies must be integral values, but they are not restricted to being constants.

   int i, j, k;

   a[0] = 100;
   a[i] = 150;
   a[i * j - k] = 210;
   a[a[a[i]]] = 250;
   a[rand() % LEN] = 178;

The language does not protect against indexing beyond the ends of an array. Typically, if this happens, then a run-time error is encountered.

   a[-1] = 100;
   a[sizeof(a)/sizeof(a[0]) + 2] = 200;

Array 'a' cannot be copied to array 'b' using simple assignment.

   #define LEN 5 
   int a[LEN] = { 100, 200, 210, 120, 240 }, b[LEN];

   /* b = a;   //syntax error -- array name not a lvalue */
   for (int i = 0; i < LEN; i++)
      b[i] = a[i];
Arrays and Functions

Arrays are passed to functions "by reference." (Think about the overhead if arrays were passed by value.)

A function that receives an array as a parameter, obtains a constant pointer to the first element of the array.

Unless specifically qualified to be const, the function can modify the content of the array.

When a function receives an array as a parameter, it does not know, nor can it figure out, the length or size of the array. In many cases, the caller passes the array length (size_t) to the function.

   void func1(int[]);         //do *not* specify the array length
   void func2(const int[]);   //func2() not allowed to modify the array
   void func3(int [], int);
   #define A_LEN 10
   int a[A_LEN];
   
   func1(a);  //using array name w/o [] operator "decays" into a
              //constant pointer to the 1st element of the array
   func2(a);
   func3(a, A_LEN);  //pass the array length to the function
   ...
   
   void func1(int i[]) {  //again, array length not specified
      int len = sizeof(i) / sizeof(i[0]);
         // does not work -- sizeof(i) evaluates to the size
         // allocated for pointer variables, which is typically
         // the sizeof(int)...
      ...
   }
   
   void func2(const int i[]) {
      //! i[0] = 100;    //use of  const  implies the content of the
                         //array cannot be changed...
   }
   
   void func3(int i[], int len) {
      for (int i = 0; i < len; i++)
         //loop through each element of the array
       ...
    }

Pointer notation can be used when prototyping and defining functions that receive arrays as parameters.

   void func1(int*);  //this syntax indicates that the function receives
                      //a pointer to an array
   void func2(const int*);  //array content cannot be modified

A Tutorial on Pointers and Arrays in C

{TopOfPage} {Tutorial} {CodingGround (online IDE)} {CPP.sh (online IDE)} {C at MIT} {GDT::C/C++ Resource}


Home Previous Next