Chapter 9: Data Structures: Arrays and Structs The variables used so far have all had common characteristics: Each variable could only store one value at a time; Each was defined using a simple data type. Frequently, we may have a set of values, all of the same data type, that form a logical group. It is more efficient to store these values together in main memory than to allocate a separate variable for each item. A simple list containing individual items of the same scalar data type is called an array. In this chapter, we will study two structured data types: the array and the struct. 9.1 The Array Data Type A one-dimensional array (or a list, or a vector) is a group of related values with the same data type that is stored using a group name. The group name is referred to as the array name. The items in the list can be declared as a single unit and stored under a common variable name called the array name. For example, suppose that we would like to store five exam grades in an array, named grade. Then the declaration statement will be: int grade[5]; Other examples: char code[4]; //an array of four character values float prices[6]; double amount[100]; Page 1 of 16 Chapter 9: Data Structures: Arrays and Structs Each element in an array is called an element or component of the array. The individual elements stored in the array are stored sequentially. The first array element is stored in the first reserved location, the second element, in the second reserved location, and so on. To access individual elements in an array, you use the name of the array and the element's position. This position is called the element's subscript or index value. For a single-dimensioned array the first element has a subscript of 0. The indices of an array are said to be zero relative. For example: int grade[5]; grade[0] refers to the first grade stored in the grade array. grade[1] refers to the second grade stored in the grade array. grade[0] grade[1] grade[2] grade[3] grade[4] an integer an integer an integer an integer an integer element 1 element 2 element 3 element 4 element 5 Internally, the computer uses the index as an offset from the array's starting position. The index tells the computer how Page 2 of 16 Chapter 9: Data Structures: Arrays and Structs many elements to skip over, starting from the beginning of the array, to get to the desired element. In-Class Exercise: 1. Write array declarations for the following: a. a list of 100 floating-point prices b. a list of 30 characters, each representing a code c. a list of 100 integers Using Subscripted Variables Subscript variables can be used anywhere scalar variables are valid. For example: grade[0] = 98; grade[1] = grade[0] - 11; The subscript contained within the brackets need not be an integer constant. Any expression that evaluates to an integer may be used as a subscript. For example: grade[i] grade[2 * i] grade[j - 1] A for loop can be used to access the elements in an array. Page 3 of 16 Chapter 9: Data Structures: Arrays and Structs Array Initialization Array elements can be initialized within their declaration statements, enclosing their values within braces. For example: int grade[5] = { 95, 87, 92, 100, 80 }; If the number of initializers is less than the declared number of elements listed in square brackets, the initializers are applied starting with array element zero. For example: int grade[5] = { 98, 100, 80 }; will only initialize the first three elements. A unique feature of initializers is that the size of an array may be omitted when initializing values are included in the declaration statement. For example: int gallons [ ] = { 16, 12, 10, 15, 19 }; char code [4] ={ 'a', 'b', 'c', 'd' }; char code [ ] ={ 'a', 'b', 'c', 'd' }; string kidNames[ ] = { “Richard”, “Debbie”, “Robin”, “Shelley”, “Dara” }; Page 4 of 16 Chapter 9: Data Structures: Arrays and Structs 9.2 Sequential Access to Array Elements Most programs process the elements of an array in sequential order, starting with element 0 (the first). A for loop lends itself well to the processing of an array to accomplish the following: Entering data into an array. Displaying the contents of an array. Performing any other sequential processing tasks. Example: Determine the maximum value in an array int prices [1000]; : maximum = prices[0]; for (int i = 1; i < 1000; i++) if (prices[i] > maximum) maximum = prices [i]; In-Class Exercise: Write a for loop that can be used to display values for the complete array declared as: int grades [25]; Page 5 of 16 Chapter 9: Data Structures: Arrays and Structs Input and Output of Array Values Individual array elements can be assigned values interactively using cin object. For example: cin >> grade[0]; cin >> grade[1] >> grade[2] >> grade[3]; A for loop can also be used to cycle through the array for interactive data input. For example: for (int i = 0; i < 5; i++) { cout << "Enter a grade: "; cin >> grade[i]; } Caution: C++ does not check the value of the index being used. For example, if an array has been declared as consisting of 10 elements, and you use an index of 12, C++ will not notify you of the error when the program is compiled. You will get a runtime error. During output, individual array elements can be displayed using the cout object. Again, a for loop can be used to display an array. for (int n = 5; n < 20; n++) cout << n << " " << amount[n]; Page 6 of 16 Chapter 9: Data Structures: Arrays and Structs Example: Program 9-1 #include <iostream> using namespace std; int main( ) { int grade[5]; for (int i = 0; i < 5; ++i) // Enter five grades { cout << "Enter a grade: "; cin >> grade[i]; } for (i = 0; i < 5; i++) // Print five grades cout << "\ngrade[" << i << "] is " << grade[i]; cout << endl; return 0; } Sample Run: Enter a grade: 94 Enter a grade: 95 Enter a grade: 96 Enter a grade: 97 Enter a grade: 98 grade[0] is 94 grade[1] is 95 grade[2] is 96 grade[3] is 97 grade[4] is 98 Page 7 of 16 Chapter 9: Data Structures: Arrays and Structs Example: Program 9-2 #include <iostream> using namespace std; int main( ) { int grade[5], total = 0; for (int i = 0; i < 5; ++i) // Enter five grades { cout << "Enter a grade: "; cin >> grade[i]; } cout << "\nThe total of the grades "; for (i = 0; i < 5; i++) // Print five grades { cout << grade[i] << " "; total = total + grade[i]; } cout << "is " << total; return 0; } In-Class Exercise: Write a program to input eight integer numbers into an array named temp. As each number is input, add the numbers into a total (accumulator). After all numbers are input, display the numbers and their average. Page 8 of 16 Chapter 9: Data Structures: Arrays and Structs Strings and Arrays of Characters In C and C++, an array of characters can be used to store a single string value. Another method of initializing a character array: char code [ ] = "sample"; // no braces or commas This uses the string "sample" to initialize the char array, code. This creates an array named code with seven elements stored in it. (Why seven?) A string object uses an array whose elements are type char to store a character string. That is why the position of the first character of a string object is 0, not 1. If we declare a variable as: string name = "mary"; we can use either of the following to access the ith character of name: name[i] name.at(i) In-Class Exercise: Write a declaration to store the string “This is a test” into a string named strtest. Include the declaration in a program to display the message using the following loop: for (int i = 0; i < strtest.length(); i++) cout << strtest[i]; Page 9 of 16 Chapter 9: Data Structures: Arrays and Structs Enumeration Type: (From 7.5) In many programming situations, the int, char and float data types are inadequate to provide the desired degree of program readability and understandability. The enumeration type can be used to improve program readability. FORM: enum Name {Enumerator-list} Enumerator-list: ConstIntExpression Examples: enum class_id {freshman, sophomore, junior, senior}; enum day {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday}; enum months {jan = 1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec}; Portion of Program 9-3: enum Drink {Orange, Cola, Root_beer, Cherry, Lemon}; float salesAmt[ ] = {0.5, 0.6, 0.5, 0.55, 0.50}; Drink flavor; //variable of the index type for (int n, flavor = Orange; flavor <= Lemon; flavor = Drink(++n)) cout << salesAmt[flavor]<<endl; Page 10 of 16 Chapter 9: Data Structures: Arrays and Structs 9.3 Arrays as Arguments to Functions Individual array elements are passed to a called function in the same manner as individual scalar variables. For example: find_min(grades[2], grades[6]); The function find_min( ) would be defined as accepting two integer values: int find_min(int, int); Passing a copy of the whole array to the function would be wasteful of computer storage, especially for larger arrays. To avoid this, the called function is given direct access to the array. find_max(grades) On the receiving side, the called function must be alerted that an array is being passed. Let's look at an example: Page 11 of 16 Chapter 9: Data Structures: Arrays and Structs Program 9-4: #include <iostream> using namespace std; int find_max(int [5]); // function prototype int main( ) { int nums[5] = {2, 18, 1, 27, 16}; cout << "\nThe maximum value is " << find_max(nums) << endl; return 0; } int find_max(int vals[5]) { int i, max = vals[0]; // find the maximum value for (i = 1; i < 5; i++) if (max < vals[i]) max = vals[i]; return max; } Page 12 of 16 Chapter 9: Data Structures: Arrays and Structs The parameter declaration in find_max( ) header line actually contains extra information that is not required by the function. All that find_max( ) must know is that the parameter vals references an array of integers. Since the array has been created in main( ) and no additional storage space is needed in find_max( ), the declaration for vals can omit the size of the array. Thus, an alternative function header line is: int find_max(int vals[ ]) Note: When this array is being passed, only the address of the first element in the array is actually passed. You are passing a reference or pointer to the array. Once the function has the address of the first element, it calculates the location of the other elements based on the data type of the array. The more general form of the previous example follows: Program 9-5: #include <iostream> using namespace std; int find_max(int [], int); // function prototype int main( ) { int nums[5] = {2, 18, 1, 27, 16}; cout << "\nThe maximum value is " << find_max(nums, 5) << endl; return 0; } Page 13 of 16 Chapter 9: Data Structures: Arrays and Structs int find_max(int vals[], int num_els) { int i, max = vals[0]; for (i = 1; i < num_els; i++) if (max < vals[i]) max = vals[i]; return max; } In-Class Exercise: Given the following function definition: #include <iostream> using namespace std; bool sameArray(float a[], // IN: arrays to be compared float b[], const int size)// IN: size of the arrays { int i = 0; // Loop control variable/array subscript while ((i < size – 1) && (a[i] == b[i])) i++; return (a[i] == b[i]); } Write a main( ) function that declares and initializes two float arrays, then uses the above function to determine if the arrays are equal or not. Page 14 of 16 Chapter 9: Data Structures: Arrays and Structs 9.4 Reading Part of an Array Sometimes the programmer does not know what the exact size of a particular array will be, because it is unknown how many values the user needs to enter. For example, if you are writing a program to process grades, one class section may have 15 students and another may have 25 students. As a programmer, you need to allocate enough storage to handle the maximum number of scores so that the program can process the largest expected array without error. When you read the array data into memory, you should begin filling the array starting at element 0 and keep track of the number of data items that are actually being stored in the array. The portion of the array that contains actual data is called the filled subarray. Page 15 of 16 Chapter 9: Data Structures: Arrays and Structs In-Class Exercise: Given the following code: #include <iostream> using namespace std; const int MAXSIZE = 14; // Add function prototypes here int main() { int grades[MAXSIZE]; int total; // Accumulates the total grades int numGrades; // Counts the number of grades entered float average; // Use reference parameter here for total and numGrades readGrades(grades, total, numGrades); displayGrades(grades, numGrades); // Add code to calculate and display the average. return (0); } // Define functions here Complete the program so that it allows the user to enter the grades (use a sentinel to stop entry or stop at MAXSIZE), then display those grades, calculate, and display the average. Page 16 of 16