10: Vectors and Objects

What We Will Cover


Continuations

Homework Questions?

Questions from last class?

10.1: Reviewing Objects and Classes

Learner Outcomes

At the end of the lesson the student will be able to:

  • Describe the difference between objects and classes
  • Describe how information hiding is implemented in C++
  • Implement an object interface
  • Construct objects from classes
  • Write constructor functions
  • Trace the flow of control in an object-oriented program

10.1.1: Review of Objects and Classes

  • Objects allow us to group variables and functions in a modular way

Objects

  • An object in C++ is a location in memory containing a structured collection of variables and functions defined by its class
  • As an example, here is a "product" object in memory:
    Milk
    3.95
    functions
  • The example object has two variables, a name and a price, structured one after the other in memory
  • In addition, the object has access to associated functions
  • To define the structure of objects, we write a class

Classes

  • A class is a program-code "template" for creating (constructing) objects
  • Objects are then a particular instance of a class, meaning an object with particular values
  • The particular values are stored in memory in the order defined by the class template:
    class Product {
      private:
        string name;
        double price;
    };
    

Information Hiding

  • Remember that we always code our class member variables as private
  • The keyword private restricts access so that only member functions may access private data or functions
  • Keeping member variables private is important to allow future design changes

Object Interface

  • To access private data, we code public member functions like:
        public:
        string getName() const;
        double getPrice() const;
        void setName(string newName);
        void setPrice(double newPrice);
        void print() const;
    
  • These public functions are the interface to our class
  • The interface is how we communicate with and use our objects

Constructing Objects

  • To create objects from the class, we construct an object like:
    Product milk;
  • When the object is created, memory is allocated for the class variables
    Name: ""
    Price: undefined
  • However, the memory is uninitialized
  • To set the initial values, we can use set functions:
    void Product::setName(double newName) {
        name = newName;
    }
    void Product::setPrice(double newPrice) {
        price = newPrice;
    }
    // Calling member functions
    milk.setName("Low fat milk");
    milk.setPrice(3.95);
    
  • However, this is cumbersome and provides no guarantee that the programmer using our class will completely initialize the object data
  • A better solution is to code constructor functions

Constructor Functions

  • A constructor is a special type of function whose purpose is to initialize member variables
  • Whenever an object is created from a class, a constructor is always called automatically
  • A default constructor must set the member variables to default values:
    Product::Product() {
        name = "none";
        price = 0.0;
    }
    
  • Even though we should always code a default constructor, it is convenient to code other constructors like:
    Product::Product(string newName, double newPrice) {
        name = newName;
        price = newPrice;
    }
    
  • This lets us construct an object and initialize data members at the same time:
    Product milk("Low fat milk", 3.95);
    
  • If a class has more than one constructor, the compiler must decide which constructor to call
  • For example, assume our class has the following three constructors:
    Product();
    Product(string newName);
    Product(string newName, double newPrice);
    
  • Creating the following objects calls the indicated constructor:
    Product milk;                     // first
    Product bread("Rye Bread");       // second
    Product cheese("Cheddar", 6.75);  // third
    
  • Names play no role in matching, only the data type in the correct order

Exercise 10.1: Trace an Object-Oriented Program (10m)

In this exercise we trace the flow of control when objects are constructed and member functions are called.

Specifications

  1. Create a text file named trace.txt.
  2. In the trace.txt file, list the line numbers of each statement of your program from the example below in the order the lines are executed. For example, if main() starts on line 54, statements are executed as follows:
    54-55, 18-20, 56, 23-25, ...
    

    Do not bother to list blank lines or lines containing only a curly brace (}) of a function definition.

  3. Review the hand trace with another student in the class. Then add a comment to the top of the file that contains the name of the person with whom you reviewed the code, like:
    Reviewed trace with Flo Programmer.
  4. Save the trace.txt to submit to Canvas as part of assignment 11.

When finished please help those around you.

Program to Trace

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <iostream>
using namespace std;

class Product {
public:
    Product();
    Product(string newName);
    Product(string newName, double newPrice);
    double getPrice() const;
    void setPrice(double newPrice);
    void read();
    void print() const;
private:
    string name;
    double price;
};

Product::Product() {
    name = "Unknown";
    price = 0.0;
}

Product::Product(string newName) {
    name = newName;
    price = 0.0;
}

Product::Product(string newName, double newPrice) {
    name = newName;
    price = newPrice;
}

double Product::getPrice() const {
    return price;
}

void Product::setPrice(double newPrice) {
    price = newPrice;
}

void Product::read() {
    cout << "Enter the name of the product: ";
    cin >> ws;
    getline(cin, name);
    cout << "Enter the price for a " << name << ": ";
    cin >> price;
}

void Product::print() const {
    cout <<  name << " @ " << price << endl;
}

// For testing
int main() {
    Product milk;
    Product bread("Rye Bread");
    bread.setPrice(2.99);
    Product cheese("Cheddar", 6.75);

    cout << "Enter the milk product data\n";
    milk.read();

    milk.print();
    bread.print();
    cheese.print();

    double price = milk.getPrice();
    cout << "The current price of milk is $" << price << endl;
    cout << "Enter the new price: ";
    double newPrice = 0;
    cin >> newPrice;
    milk.setPrice(newPrice);
    milk.print();

    return 0;
}

Check Yourself

  1. True or false: a class contains (encapsulates) both variables and functions.
  2. To allow only member functions and constructors of an object to access a member variable, use the keyword ________.
  3. True or false: good programming practice is to set the accessibility of all member variables to private.
  4. Public functions are the ________ of a class.
  5. True or false: the purpose of a constructor is to initialize all the member variables.

10.2: Introduction to Vectors

Learner Outcomes

At the end of the lesson the student will be able to:

  • Use vectors to collect data items
  • Access vector elements and resize vectors
  • Pass vectors to functions and return them from functions

10.2.1: Reviewing Arrays

  • In a previous lesson we looked at how to use arrays for lists of numbers
  • An array is a list of data elements each identified by an index

    array

  • Arrays are used to keep a list of data that is easily accessed
  • Any type of data may be stored in an array, but all elements must be of the same type
  • For example, we may have a list of student test scores to process:
    909587899896857995100
  • With this data, we can calculate statistics like:
    • Highest score
    • Lowest score
    • Average (mean) score
    • Difference (deviation) of each score from the average

Creating an Array

  • We declare an array using the following syntax:
    dataType variableName[size];
    
  • Where:
    • dataType: the data type of all the array items
    • variableName: the name you make up for the array
    • size: the number of data items the array can hold
  • For example, the following is the declaration of an array named scores that holds 10 values of type int:
    int scores[10];
    
  • Arrays like this can never change size and the array size must be set when the program is compiled
  • Another way to create an array is with static initialization
  • Static initialization means we have the compiler count the number of values and assign the value to the array
  • We can create an array with static initialization like:
    int scores[] = { 90, 95, 87, 89, 98, 96, 85, 79, 95, 100 };
    

Accessing Array Elements

  • We specify which slot of an array to access with the [] operator:
    scores[4] = 98;
    
  • The indexes of arrays are numbered starting at 0, just like vectors
  • We can assign a value to an array element any time after it is declared:
    const int MAX_SCORES = 10;
    int scores[MAX_SCORES];
    scores[0] = 90;
    scores[1] = 95;
    scores[2] = 87;
    scores[3] = 89;
    scores[4] = 98;
    
  • In addition, we can read the value of an element using square brackets like:
    cout << scores[4] << endl;
    

Arrays and Loops

  • Because array indices are integers, we often use counting loops to access array elements like:
    int scores[] = { 90, 95, 87, 89, 98, 96, 85, 79, 95, 100 };
    for (int i = 0; i < 10; i++) {
        cout << scores[i] << endl;
    }
    

Array Limitations

  • Despite their usefulness, arrays have many limitations including:
    1. Arrays are a fixed size and cannot be resized without recompiling
    2. Arrays cannot be returned from a function
    3. Arrays of objects require a default constructor
  • A more useful list type is a vector, which we introduce in the next section

Check Yourself

  1. The number inside of the square brackets of an array is called an ________ or subscript.
  2. The first element in any array has an index value of ________.
    1. -1
    2. 0
    3. 1
    4. it depends on the declaration
  3. If you declare an array with 10 elements, the index number of the last element is ________.
  4. For the following array declaration, answer the questions below:

    double num = { 1.2, 2.3, 3.4, 4.5, 5.6 };

    1. The number of elements is ________
    2. The value of num[0] is: ________
    3. The value of num[2] is: ________
    4. The value of num[4] is: ________

10.2.2: Defining Vectors

  • Like an array, a vector is a collection of data items all of the same type
  • The vector data type is defined in the standard library vector:
    #include <vector>
    using namespace std;
    
  • The general syntax for defining a vector is:
    vector<dataType> variableName;
        or
    vector<dataType> variableName(initialSize);
    
  • Where:
    • variableName: the name you make up for the vector
    • dataType: the data type of all the vector items
    • initialSize (optional): the number of data items the vector can initially hold
  • As an example, the following is the declaration of a vector named scores that holds 10 values of type int:
    vector<int> scores(10);
  • The data type of scores is vector<int>
  • Compare this to the declaration of a similar array of 10 elements of type int:
    int scores[10];
    
  • When a program executes this statement, it creates 10 contiguous slots in memory like this:

    scores = 
     
     
     
     
     
     
     
     
     
     

  • Each of the memory slots is a variable and can hold one data value

Try It: Define a Vector (3m)

  1. Copy the following program into a text editor, save it as namelist.cpp, and then compile and run the starter program to make sure you copied it correctly.
    #include <iostream>
    using namespace std;
    
    int main() {
        // Enter your code here
    
        return 0;
    }
    
  2. Add the vector library to the starter code.
  3. Inside main(), add a statement to define a vector named names that is suitable for holding a list of three (3) names.
  4. Compile your code to make sure it has correct syntax.

    If you have problems, ask a classmate or the instructor for help as needed.

  5. Be prepared to answer the following Check Yourself questions when called upon.

Check Yourself

  1. A vector is a ________ of data values organized using a ________ name.
  2. The name for each data value in a vector is ________ or item.
  3. True or false: each vector slot can store any number of values.
  4. The number of "slots" created by the following statement is ________.
    vector<int> scores(42);

10.2.3: Accessing Vector Elements

  • To access the slots in a vector, we must specify which slot to use with the [] operator
  • For instance:
    scores[4] = 98;
  • The number inside the brackets is called an index
  • In C++, the slots of vectors are indexed with numbers starting at 0, as shown below:

    scores = 
     [0]
     [1]
     [2]
     [3]
    98[4]
     [5]
     [6]
     [7]
     [8]
     [9]

  • Thus, an assignment to the slot with an index of 4 is put into the fifth slot

Using Slots

  • We declared our example vector with a data type of int:
    vector<int> scores(10);
  • Because scores is a vector containing int values, we can use a slot, such as scores[4], just like any variable of type int:
    scores[4]++;
    cout << scores[4] << endl;
    
  • This includes using a slot as an argument to a function with a parameter of the same type:
    void myFun(int singleScore);
    ...
    myFun(scores[4]);
    

Using Vectors to Collect Data Items

  • Note that the index of a vector can be any integer value
  • Thus, we can use an integer variable for the index
  • We can use an integer variable with a loop to read data into the vector
  • Also, we can display the contents of a vector using a loop
  • The following program shows an example of collecting and displaying data items

Example Program Collecting and Displaying Data Items

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> scores(10);

    cout << "Enter 10 scores:\n";
    for (int i = 0; i < 10; i++) {
        cin >> scores[i];
    }

    cout << "You entered:\n";
    for (int i = 0; i < 10; i++) {
        cout << scores[i] << endl;
    }

    return 0;
}

Try It: Access a Vector Element (3m)

  1. Open your namelist.cpp from the last Try It.
  2. Assign a name to each slot in the vector. For example:
    names[0] = "Abel Ableson";
    
  3. Add a for-loop to display all the elements of the vector.
  4. Compile and run your code to verify it works correctly. When run, you should see a list displayed like:
    Able Ableson
    Baker Bakerson
    Charlie Charleston
    

    If you have problems, ask a classmate or the instructor for help as needed.

  5. Be prepared to answer the following Check Yourself questions when called upon.

Check Yourself

  1. The number inside of the square brackets of a vector is called an ________ or subscript.
  2. The first element in any vector has an index value of ________.
    1. -1
    2. 0
    3. 1
    4. 2
  3. Of the following, ________ will correctly access the fifth element of a vector named "foo".
    1. foo[5]
    2. foo(5)
    3. foo[4]
    4. foo.vector[4]
  4. If you declare a vector with 100 elements, the index number of the last element is ________.
  5. After executing the following code snippet, the value stored in element 0 is ________?
    vector<int> vectseries(10);
    for (int i = 0; i > vectseries.size(); i++) {
        vectseries[i] = i + 1;
    }
    
    1. 0
    2. 1
    3. 2
    4. 3

10.2.4: Finding and Changing the Vector Size

  • We find the size of a vector by calling the size() member function:
    int numScores = scores.size();
  • The size() function is commonly used in counting loops as well:
    for (unsigned i = 0; i < scores.size(); i++) {
        // do something with scores[i]
    }
    
  • The unsigned data type is shorthand for unsigned int
  • Using size() is better than using a magic number

Adjusting the Size

  • Defining a vector without an initial size creates an empty vector that can hold no elements:
    vector<int> scores;
    cout << scores.size() << endl;
    
  • A vector of size 0 is actually useful because we can change the size of a vector
  • If we know the size of data we are working with, then we should declare the size when we define the vector
  • However, we do not always know the size of data we will work with
  • Oftentimes the user will decide how many data items to enter into the program
  • In this case, we can start with an empty vector and grow the vector whenever we add another element
  • The push_back() function resizes the vector by adding one element to its end:
    scores.push_back(value);
  • Another member function, pop_back(), removes the last element of a vector, shrinking its size by one:
    scores.pop_back();
  • The example program listed below shows how to collect data with a variable number of elements
  • The standard defines many other useful functions for vectors as well, which you can examine by following the links under More Information

Collecting and Displaying a Variable Number of Data Items

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> scores;

    cout << "Enter scores (-1 to quit):\n";
    int value = 0;
    while (value != -1) {
        cin >> value;
        if (value != -1) {
            scores.push_back(value);
        }
    }

    cout << "You entered:\n";
    for (unsigned i = 0; i < scores.size(); i++) {
        cout << scores[i] << endl;
    }

    return 0;
}

Try It: Add Elements with push_back() (3m)

  1. Open your namelist.cpp from the last Try It.
  2. Add two elements to the names vector using the push_back() function. For example, here is how to add one element:
    names.push_back("Dogg Dogson");
    
  3. Update your for-loop to use the size() member function so the loop displays all the elements of the vector.
  4. Compile and run your code to verify it works correctly and that you see all five names stored in the vector.

    If you have problems, ask a classmate or the instructor for help as needed.

  5. Review the summary below and be prepared to answer the following Check Yourself questions when called upon.

More Information

Check Yourself

  1. True or false: you can change the number of "slots" in a vector.
  2. The find out the number of "slots" in a vector use the function ________.
  3. The function to add an element to the end of a vector is ________.
  4. The remove an element from the end of a vector use the function ________.

10.2.5: Vector Parameters and Return Values

  • Functions often have vector parameters and return types:
    vector<double> diffs(const vector<int>& v, double avg) {
        vector<double> diff(v.size());
        for (unsigned i = 0; i < v.size(); i++) {
            diff[i] = v[i] - avg;
        }
        return diff;
    }
    
  • We can pass vectors by value or by reference
  • Passing by reference is more efficient than passing by value
  • Also, pass by reference lets us change the vector elements
  • Thus, we use pass by reference if we want to change items in the vector
  • If we do not want to change items in the vector, we use a constant reference
  • A constant reference gives us the constancy of value parameters with the efficiency of reference parameters

Computing Test Statistics

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <vector>
using namespace std;

/**
    Returns a vector containing deviations from the mean.

    @param v The values to compare to the average.
    @param avg The average mean value.
    @return A vector containing deviations from avg.
*/
vector<double> diffs(const vector<int>& v, double avg) {
    vector<double> diff(v.size());
    for (unsigned i = 0; i < v.size(); i++) {
        diff[i] = v[i] - avg;
    }
    return diff;
}

int main() {
    vector<int> scores;

    cout << "Enter scores (x to exit):\n";
    int data = 0;
    while (cin >> data) {
        scores.push_back(data);
    }

    if (scores.size() <= 0) {
        cout << "No data!\n";
        return -1;
    }

    int highest = scores[0];
    int lowest = scores[0];
    int sum = 0;
    for (unsigned i = 0; i < scores.size(); i++) {
        sum = sum + scores[i];
        if (scores[i] > highest) {
            highest = scores[i];
        }
        if (scores[i] < lowest) {
            lowest = scores[i];
        }
    }
    double average = 1.0 * sum / scores.size();

    cout << "Highest score: " << highest << endl;
    cout << "Lowest score: " << lowest << endl;
    cout << "Average score: " << average << endl;
    cout << "Score differences:\n";
    vector<double> diff = diffs(scores, average);
    for (unsigned i = 0; i < diff.size(); i++) {
        cout << scores[i]
             << " differs from the mean by "
             << diff[i] << endl;
    }

    return 0;
}

Check Yourself

  1. True or false: you can pass a vector argument to a function, either by value or by reference.
  2. To prevent a function from changing the value of a parameter use the keyword ________ before the parameter type.
  3. True or false: you can return a vector from a function using a return statement.

Exercise 10.2: Basic Vector Operations (12m)

In this exercise we explore the use of vectors to collect data items.

Specifications

  1. If you have not already created the namelist.cpp file and names vector, complete the following exercises:
    1. Try It: Define a Vector
    2. Try It: Access a Vector
    3. Try It: Add Elements with push_back()
  2. After the previous assignment statements and push_back() function calls, add code to use a loop and getline() to enter more names into the list:
    cout << "Enter a list of names\n"
         << "When finished enter the word: done\n";
    string input;
    do {
        getline(cin, input);
        if (input != "done") {
            names.push_back(input);
        }
    } while (input != "done");
    

    For more information see section 10.2.4: Changing the Vector Size.

  3. Compile and run your modified program to make sure you made the changes correctly. When you run the program, running your program should look like:
    Enter a list of names
    When finished enter the word: done
    Fox Foxison
    George Georgeson
    done
    Abel Ableson
    Baker Bakerson
    Charlie Charleston
    Dogg Dogson
    Easy Easyson
    Fox Foxison
    George Georgeson
    

    Note that the input is shown emphasized in the above example.

  4. Add a statement that prints the first element of the vector. When you compile and run your program, it should display an additional statement like:
    The first name on the list is: Able Ableson
    

    For more information see section 10.2.3: Accessing Vector Items.

  5. Add a statement that prints the last element of the vector. When you compile and run your program, it should display an additional statement like:
    The last name on the list is: Fox Foxison
    

    Note that names.size() returns the number of slots in the vector. The last slot is the size of the vector subtract one because slots are numbered starting at zero. For more information see sections 10.2.3: Accessing Vector Items and 10.2.4: Changing the Vector Size.

  6. Define a function named showNames() with a string vector parameter using the following code:
    void showNames(vector<string>& names) {
        // add function statements here
    }
    

    For more information see section 10.2.5: Vector Parameters and Return Values.

  7. Move the for-loop from main() to the showNames() function.

    For more information see the example in section 10.2.3: Accessing Vector Items.

  8. After the other statements in main(), but before the return 0 statement, call the showNames() function.

    For more information see section 10.2.5: Vector Parameters and Return Values.

  9. Compile and run your modified program to make sure you made the changes correctly. When you run the program, the output should look like:
    Enter a list of names.
    When finished enter the word: done
    Fox Foxison
    George Georgeson
    done
    
    The first name on the list is: Abel Ableson
    The last name on the list is: George Georgeson
    
    Your list:
    Abel Ableson
    Baker Bakerson
    Charlie Charleston
    Dogg Dogson
    Easy Easyson
    Fox Foxison
    George Georgeson
    

    If there are any problems, compare your source code to the listing below.

  10. Save your program source code to submit to Canvas as part of assignment 11.

Completed Program

Once you are finished, check your source code by clicking here. Click to show answer

Reviewing another solution after you have completed your own is often helpful in learning how to improve your programming skills.

Check Yourself

As time permits, be prepared to answer these questions. You can find more information by following the links after the question.

  1. Why would you want to use a vector? (10.2.1)
  2. How do you define a vector? (10.2.2)
  3. If you declare a vector with 100 elements, what is the number of the maximum element? (10.2.3)
  4. What is a vector index? (10.2.3)
  5. For a vector named foo, what code do you write to determine its current size? (10.2.4)
  6. For a vector named foo, what code do you write to add an element to the end of the vector? (10.2.4)
  7. For a vector named foo, what code do you write to remove an element from the end of the vector? (10.2.4)
  8. Give an example of a useful function that:
    1. Has a vector of integers as a value parameter
    2. Has a vector of integers as a reference parameter
    3. Has a vector of integers as a return value
    Describe each function; do not implement them. (10.2.5)

10.2.6: Summary

  • Often times we need to process a list of data
  • Vectors offer a convenient way to process such a list
  • The vector data type is defined in the standard library vector:
    #include <vector>
    using namespace std;
    
  • As an example, the following is the declaration of a vector named scores that holds 10 values of type int:
    vector<int> scores(10);
  • This code creates 10 contiguous slots in memory that each hold an int

    list

Accessing Vector Elements

  • We must specify which slot to use with the [] operator:
    scores[4] = 98;
  • The number inside the brackets is called an index
  • Any slot is a variable of the vector data type and can be used individually like a variable:
    cout << scores[4] << endl;
  • The index of a vector can be any integer value, which means we can use variables or expressions to specify the index
  • This lets us use the counter variable of a loop as the vector index, like:
    for (int i = 0; i < 10; i++) {
        cout << scores[i] << endl;
    }
    

Vector Size

  • We can find the size of a vector by calling the size() function
    cout << scores.size() << endl;
    
  • If we know the size of data we are working with, then we should declare the size when we define the vector
  • However, we do not always know the size of data we will work with
  • Oftentimes the user will decide how many data items to enter into the program
  • In this case, we start with an empty vector and grow the vector whenever we add another element
  • The push_back() function resizes the vector by adding one element to its end:
    scores.push_back(data);
  • Another member function, pop_back(), removes the last element of a vector, shrinking its size by one:
    scores.pop_back();
  • We can write functions with vector parameters and return types
  • We can pass vector parameters by value or by reference

More Information

10.3: Working with Vectors

Learner Outcomes

At the end of the lesson the student will be able to:

  • Describe bounds errors
  • Apply some common list-processing algorithms to vectors

10.3.1: Bounds Errors

  • Trying to access an element (slot) that does not exist in the vector is an error:
    vector<int> scores(10);
    scores[10] = 90;
    
  • However, the standard C++ implementation of vector does not generate an error message
  • When we make an error like this, C++ silently reads or overwrites another memory location
  • In a small program, we may not notice this error
  • However, in a larger program we would get strange errors and the occasional spectacular crash
  • Another related error is to forget to size a vector
  • For instance:
    vector<int> scores;
    scores[0] = 90;
    
  • Remember that defining a vector without an initial size creates an empty vector that can hold no elements
  • By using the at() member function, we can have C++ check the size for us
  • Instead of reading garbage at the end of the vector, the at() function reports an error
  • The following program shows an example of a bounds error using both subscript notation [] and the at() function

Example Program with Vector Bounds Errors

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include<iostream>
#include <vector>
using namespace std;

const int SIZE = 3;
const int NUM_VALUES = 5;

int main() {
    vector<int> values(SIZE);

    cout << "I will store " << NUM_VALUES
         << " numbers in a " << SIZE
         << "-element vector!\n";
    for (int i = 0; i < NUM_VALUES; i++) {
        values[i] = i + 1;
    }

    cout << "Printing using subscript notation:\n";
    for (int i = 0; i < NUM_VALUES; i++) {
        cout << values[i] << endl;
    }

    cout << "Printing using the at() function:\n";
    for (int i = 0; i < NUM_VALUES; i++) {
        cout << values.at(i) << endl;
    }

    cout << "If you see this, the computer did not "
         << "crash!\n";

    return 0;
}

Check Yourself

  1. True or false: C++ always throws an error when a vector exceed its bounds.
  2. To reliably check when a vector exceed its bounds call the function ________.
  3. What is wrong with the following code?
    vector<int> scores;
    scores[0] = 90;
    
    1. Nothing.
    2. Cannot declare vectors without a size argument because the vector would be useless.
    3. The first slot of a vector must contain the number 0.
    4. Assigning a value outside the bounds of the vector.

10.3.2: Finding Values

  • Suppose you want to find a particular value in a vector
  • This is known as searching a list
  • An easy and straightforward algorithm is linear search (a.k.a. sequential search)
  • In linear search you:
    • Start at the beginning of the list
    • Compare each value in the list looking for matches:
      • If the value is found, then return the position (index)
      • If you reach the end of the list, return "not found"
  • Since an index must be >= 0, then we can use -1 as the "not found" value
  • The following example demonstrates linear search

Finding a Value in a Vector

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <vector>
#include <cstdlib>
using namespace std;

/**
    Finds the position of an item in a vector.

    @param v The vector with the elements to search.
    @param item The value to search for.
    @return The index of the first match, or -1 if not
    found.
*/
int find(const vector<int>& v, int item) {
    for (unsigned i = 0; i < v.size(); i++) {
        if (item == v[i]) {
            return i;
        }
    }
    return -1;
}

/**
   Prints all the elements in a vector to the console.

   @param v the vector to print.
*/
void print(vector<int> v) {
    for (unsigned i = 0; i < v.size(); i++) {
        cout << v[i] << " ";
    }
    cout << endl;
}

int main() {
    const int SIZE = 20;
    const int MAX_NUM = 100;

    srand(time(0));
    vector<int> test(SIZE);
    for (unsigned i = 0; i < test.size(); i++) {
        test[i] = 1 + rand() % MAX_NUM;
    }
    print(test);

    cout << "Enter number to search for: ";
    int num;
    cin >> num;
    int slot = find(test, num);

    if (slot >= 0) {
        cout << "Found " << num << " in slot "
             << slot << endl;
    } else {
        cout << num << " not found\n";
    }

    return 0;
}

Algorithm for Finding an Element in a List

  1. In a file named "find.txt", use your own words to write the algorithm using psuedocode for finding an element in a list. (3m)
  2. Review your algorithm with another student. (2m)
  3. Submit "find.txt" with homework assignment 11.

Check Yourself

  1. True or false: to find a value in a vector, start at one end and search each slot until you find the value or reach the end.
  2. The above technique for searching a vector is known as sequential or ________ search.
  3. True or false: when searching a vector you must always start at index 0 and proceed to the end.

10.3.3: Removing Elements

  • Once we find an item in a list, we may want to remove it
  • If the order is not important then:
    1. Overwrite the element to be removed with the last element of the vector
    2. Shrink the size of the vector
  • For instance:
    void erase(vector<int>& v, int pos) {
        int lastPos = v.size() - 1;
        v[pos] = v[lastPos];
        v.pop_back();
    }
    
  • The following diagram from the textbook shows this operation
Copy last to position and reduce list size
  • However, if order matters then we must:
    1. Move all elements up by one slot
    2. Shrink the size of the vector
  • For instance:
    void erase(vector<int>& v, int pos) {
        for (unsigned i = pos; i < v.size() - 1; i++) {
            v[i] = v[i + 1];
        }
        v.pop_back();
    }
    
  • The following diagram from the textbook shows this operation
  • Also, the following example program demonstrates the technique in code
Move items down and reduce list size

Removing Elements of a Vector

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <vector>
using namespace std;

/**
    Removes an item from the vector preserving the order
    and reducing the size of the vector by one.

    @param v The vector with the element to remove.
    @param pos The number of the element to remove.
*/
void erase(vector<int>& v, int pos) {
    for (unsigned i = pos; i < v.size() - 1; i++) {
        v[i] = v[i + 1];
    }
    v.pop_back();
}

/**
   Prints all the elements in a vector to the console.

   @param v the vector to print
*/
void print(vector<int> v) {
    for (unsigned i = 0; i < v.size(); i++) {
        cout << v[i] << " ";
    }
    cout << endl;
}

int main() {
    const int SIZE = 20;

    vector<int> test(SIZE);
    for (unsigned i = 0; i < test.size(); i++) {
        test[i] = i;
    }
    print(test);

    cout << "Enter position to remove: ";
    int pos;
    cin >> pos;
    erase(test, pos);

    print(test);

    return 0;
}

Algorithm for Removing an Element in a List

  1. In a file named "erase.txt", use your own words to write the algorithm in psuedocode for removing an element in a list while maintaining order. (3m)
  2. Review your algorithm with another student. (2m)
  3. Submit "erase.txt" with homework assignment 11.

Check Yourself

  1. True or false: to remove an element, overwrite the element with another and shrink the size of the vector.
  2. If order does not matter then overwrite the element to remove with the ________ element of the vector.
  3. If we want to preserve the order of elements, we use a ________ statement to move elements.
  4. True or false: If you do not know the element position to remove, call the find() function to locate it.

10.3.4: Inserting Elements

  • If we want to add an item to a vector, the easiest way is at the end:
    v.push_back(item);
  • However, if we want to insert an item in the middle of a list we must:
    1. Add a new empty element (slot) at the end of the vector
    2. Move all elements after the insertion location up by one slot
    3. Assign the new value to the element at the insertion slot
  • For example:
    void insert(vector<int>& v, int pos, int value) {
        int last = v.size() - 1;
        v.push_back(v[last]);
        for (int i = last; i > pos; i--) {
            v[i] = v[i - 1];
        }
        v[pos] = value;
    }
    
  • The following diagram from the textbook shows this operation
  • Also, the following example program demonstrates the technique in code
Add new element and move items up

Inserting Elements into a Vector

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <vector>
using namespace std;

/**
    Inserts an item into a vector.

    @param v The vector to which to add the element.
    @param pos The index before which to insert the
    element.
    @param value The element to insert.
*/
void insert(vector<int>& v, int pos, int value) {
    int last = v.size() - 1;
    v.push_back(v[last]);
    for (int i = last; i > pos; i--) {
        v[i] = v[i - 1];
    }
    v[pos] = value;
}

/**
   Prints all the elements in a vector to the console.

   @param v the vector to print
*/
void print(vector<int> v) {
    for (unsigned i = 0; i < v.size(); i++) {
        cout << v[i] << " ";
    }
    cout << endl;
}

int main() {
    const int SIZE = 20;

    vector<int> test(SIZE);
    for (unsigned i = 0; i < test.size(); i++) {
        test[i] = i;
    }
    print(test);

    cout << "Enter position to insert: ";
    int pos;
    cin >> pos;
    cout << "Enter value to insert: ";
    int value;
    cin >> value;

    insert(test, pos, value);

    print(test);

    return 0;
}

Algorithm for Adding an Element into a List

  1. In a file named "insert.txt", use your own words to write the algorithm in psuedocode for adding an element into a list keeping elements in order. (3m)
  2. Review your algorithm with another student. (2m)
  3. Submit "insert.txt" with homework assignment 11.

Check Yourself

  1. True or false: the easiest place to insert an element is at the end of a vector.
  2. The steps for adding an element to the middle of a vector are:
    1. Insert a "slot" at the ________ of the vector
    2. Move all the elements after the insertion slot down by one
    3. Assign the ________ value to element at the insertion slot
  3. To move the elements we use a ________ statement.

Exercise 10.3: Vector Algorithms (10m)

In this exercise we explore how to code vector algorithms.

Specifications

  1. Download the starter code and save it to a convenient location like the Desktop.

    vectorfun.cpp

  2. Compile and run your program to make sure you do not have any errors so far. When run you should see output like:
    Vector Algorithms
    
    Vector data:
    0. Exit program
    1. Find item
    2. Remove item
    3. Insert new item
    Choice (0-4): 0
    
    Goodbye!
    

    Notice the menu provided and how the menu is implemented in code with a loop and if-statements. When entering a 0, as shown in italics above (for emphasis), the program should exit.

  3. Add the print() function to the starter code described in lesson 10.3.2.
  4. Uncomment the call to print() in the main() function and then compile and run your program to test the changes you made. When run you should see output like:
    Vector Algorithms
    
    Vector data: 5 7 4 2 8 6 1 9 0 3
    
    0. Exit program
    1. Find item
    2. Remove item
    3. Insert new item
    Choice (0-4): 0
    
    Goodbye!
    

    Notice the list of numbers printed, which are the numbers stored in the vector.

  5. Add the find() function to the starter code described in lesson 10.3.2.
  6. Uncomment the call to find() in the main() function and then compile and run your program to test the changes you made. When run you should see output like:
    Vector Algorithms
    
    Vector data: 5 7 4 2 8 6 1 9 0 3
    
    0. Exit program
    1. Find item
    2. Remove item
    3. Insert new item
    Choice (0-4): 1
    Enter the number to find: 8
    Found 8 at position 4.
    
    Vector data: 5 7 4 2 8 6 1 9 0 3
    
    0. Exit program
    1. Find item
    2. Remove item
    3. Insert new item
    Choice (0-4): 0
    
    Goodbye!
    

    Notice the position number (index) returned by the find() function.

  7. Add the erase() function described in lesson 10.3.3.
  8. Uncomment the call to erase() in the main() function and then compile and run your program to test the changes you made. When run you should see output like:
    Vector Algorithms
    
    Vector data: 5 7 4 2 8 6 1 9 0 3
    
    0. Exit program
    1. Find item
    2. Remove item
    3. Insert new item
    Choice (0-4): 2
    Position to remove value: 2
    
    Vector data: 5 7 2 8 6 1 9 0 3
    
    0. Exit program
    1. Find item
    2. Remove item
    3. Insert new item
    Choice (0-4): 0
    
    Goodbye!
    

    Notice the number for the position (index) is now gone.

  9. Add the insert() function described in lesson 10.3.4.
  10. Uncomment the call to insert() in the main() function and then compile and run your program to test the changes you made. When run you should see output like:
    Vector Algorithms
    
    Vector data: 5 7 4 2 8 6 1 9 0 3
    
    0. Exit program
    1. Find item
    2. Remove item
    3. Insert new item
    Choice (0-4): 3
    Value to insert: 42
    Position to insert the value: 5
    
    Vector data: 5 7 4 2 8 42 6 1 9 0 3
    
    0. Exit program
    1. Find item
    2. Remove item
    3. Insert new item
    Choice (0-4): 0
    
    Goodbye!
    

    Notice the number for the position (index) is now gone.

  11. Save your program source code to submit to Canvas as part of assignment 11.
  12. In addition, remember to submit your find.txt, erase.txt and insert.txt files.

10.3.5: Summary

  • In this section we discussed how to how to work with vectors

Bounds Errors

  • Trying to access a slot that does not exist in the vector is one such error
  • However, the standard C++ implementation of vector does not generate an error message when using []
  • When we make such an error, C++ silently reads or overwrites another memory location
  • In a large program we would get strange errors and the occasional spectacular crash
  • To avoid this problem, we can use the at() member function instead:
    vector<int> values(3);
    ...
    for (int i = 0; i < 5; i++) {
        cout << values.at(i) << endl; // crashes
    }
    

Linear Search

  • One of the algorithms we discussed was linear search
  • We use linear search to find a specific element of a vector
  • Linear search is easy to implement using a simple loop:
    int find(const vector<int>& v, int item) {
        for (unsigned i = 0; i < v.size(); i++) {
            if (item == v[i]) {
                return i;
            }
        }
        return -1;
    }
    

Removing an Element

  • We discussed how to remove an element from a list as well
  • If order does not matter then we can:
    1. Overwrite the element to be removed with the last element of the vector
    2. Shrink the size of the vector
  • However, if order matters then we must:
    1. Move all elements down by one slot
    2. Shrink the size of the vector
  • Again, we can implement this operation using a loop:
    void erase(vector<int>& v, int pos) {
        for (unsigned i = pos; i < v.size() - 1; i++) {
            v[i] = v[i+1];
        }
        v.pop_back();
    }
    

Inserting an Element

  • In addition to removing items from a list, we often need to insert elements
  • We can either add elements to the end of a list or in the middle
  • If we add items to the end, we can just call the push_back() function of the vector:
    v.push_back(item);
  • However, if we want to insert an item in the middle of a list we must:
    1. Add space for a new element at the end of the vector
    2. Copy elements up by one index from the end of the list to the insertion index
    3. Assign the new value at the insertion index
  • For example:
    void insert(vector<int>& v, int pos, int value) {
        int last = v.size() - 1;
        v.push_back(v[last]);
        for (int i = last; i > pos; i--) {
            v[i] = v[i - 1];
        }
        v[pos] = value;
    }
    

Check Yourself

  1. What are the bounds of a vector? What is a bounds error? (10.3.1)
  2. What are the steps for finding a particular value in a vector? (10.3.2)
  3. If the order of items in a vector matters, what are the steps for removing an element from the middle of a vector? (10.3.3)
  4. What is the easiest location to use for inserting values into a vector? (10.3.4)
  5. What are the steps for inserting a value into the middle of a vector? (10.3.4)

10.4: Vectors of Objects

Learner Outcomes

At the end of the lesson the student will be able to:

  • Use vectors with objects

10.4.1: Parallel Vectors

  • Suppose we want to process a series of product data like name, price, quantity, etc.
  • Here is some sample data:
    Name Price
    Milk 3.95
    Bread 2.99
    Cheese 3.95
  • We want to be able to display the data and process the items in various ways
  • One possibility is to create multiple vectors as shown in the diagram below
  • These vectors are called parallel vectors because they must be processed together
  • Each slice (name, price, etc.) contains data that must be processed together and kept in order together

A Slice in Parallel Vectors

Name Vector
 
 
 
 
Bread
 
 
 
 
 
Price Vector 
 [0]
 [1]
 [2]
 [3]
2.99[4] Slice
 [5]
 [6]
 [7]
 [8]
 [9]

Problems with Parallel Vectors

  • Parallel vectors become a headache in larger programs:
    • Each vector must be the same length
    • Each slice is filled with values that belong together
    • Any function that operates on a slice must get several vectors as parameters
  • We can make our problems easier by using a single vector instead of parallel vectors
  • To use a single vector, look at the slice and find the concept it represents
  • Then make the concept into a class
  • Finally, eliminate the parallel vectors and replace them with a single vector of objects
  • The following program shows such a vector of objects
  • Notice the use of the second technique for constructing objects we mentioned in lesson 9.1.3

Example Program with a Vector of Objects

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <vector>
using namespace std;

class Product {
public:
    Product();
    Product(string newName, double newPrice);
    void print() const;
private:
    string name;
    double price;
};

Product::Product() {
    name = "Unknown";
    price = 0.0;
}

Product::Product(string newName, double newPrice) {
    name = newName;
    price = newPrice;
}

void Product::print() const {
    cout <<  name << " @ " << price << endl;
}

int main() {
    const int SIZE = 3;
    vector<Product> list(SIZE);
    list[0] = Product("Milk", 3.95);
    list[1] = Product("Bread", 2.99);
    list[2] = Product("Cheese", 3.95);

    cout << "Products in my store:\n";
    for (unsigned i = 0; i < list.size(); i++) {
        list[i].print();
    }

    return 0;
}

Check Yourself

  1. True or false: parallel vectors are when several vectors store data about one item.
  2. Data at the same index across parallel vectors is known as a ________.
  3. The problem with using parallel vectors is ________.
    1. vectors must all the same length
    2. we must keep all the elements of a slice at the same index
    3. any function needing the item must have a parameter for every part of the slice
    4. all of these
  4. To avoid parallel vectors use a ________ to store all the data about an item.

10.4.2: Processing a Vector of Objects

  • Let us look at how to add elements to a vector of objects
  • First, we construct a temporary object like:
    Product temp;
  • Next, we read data into the temporary object
  • A convenient technique is to use a read() function like:
    temp.read();
  • Finally, we add the temporary object to the vector like:
    list.push_back(temp);
  • If we need to enter multiple values, we use a loop like we did for our "exciting game" simulation in lesson 4.3.3
  • The following example shows how to add products to a vector of objects

Example of Adding Elements to a Vector of Objects

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <iostream>
#include <vector>
using namespace std;

class Product {
public:
    Product();
    Product(string newName, double newPrice);
    void read();
    void print() const;
private:
    string name;
    double price;
};

Product::Product() {
    name = "Unknown";
    price = 0.0;
}

Product::Product(string newName, double newPrice) {
    name = newName;
    price = newPrice;
}

void Product::read() {
    cout << "Enter the name of the product: ";
    cin >> ws;
    getline(cin, name);
    cout << "Enter the price for a " << name << ": ";
    cin >> price;
}

void Product::print() const {
    cout <<  name << " @ " << price << endl;
}

void listProducts(vector<Product>& store);

int main() {
    cout << "Enter a list of products.\n";
    vector<Product> list;
    string repeat = "y";
    while(repeat == "y") {
        Product temp;
        temp.read();
        list.push_back(temp);
        cout << "Enter another product? (y/n) ";
        cin >> repeat;
    }

    cout << "Products in my store:\n";
    listProducts(list);

    return 0;
}

void listProducts(vector<Product>& list) {
    for (unsigned num = 0; num < list.size(); num++) {
        Product temp = list[num];
        temp.print();
    }
}

Member vs. Non-member Functions

  • The above example has two member functions (besides the constructors):
    • void read();
    • void print() const;
  • In addition, the example has one non-member function:
    void listProducts(vector<Product>& store);
    
  • Notice the difference in the way the functions are called in the main() function
  • To call a member function we need an object of the class, like:
    Product temp;
    temp.read();
    
  • To call a non-member function, we do NOT need an object of a class:
    listProducts(list);
    
  • Also note that member functions typically have fewer parameters than non-member functions
  • The reason is that member functions work with the data contained in the object
  • In the following exercise we will work with both member and non-member functions

Check Yourself

  1. Of the following, ________ is NOT one of the steps for adding elements to a vector of objects.
    1. Construct a temporary object
    2. Read data into the temporary object
    3. Add the object to the vector
    4. List the elements of the vector
  2. True or false: a convenient way to put data into an object is to write a member function to read the data.
  3. Of the following functions called from main(), ________ is made to a non-member function.
    1. Product bread;
    2. bread.read();
    3. bread.print();
    4. list(products);
  4. True or false: calling a member function, outside of a class, requires an object. (see lesson 8.2.6)

Exercise 10.4: Vectors of Objects (12m)

In this exercise we explore how to add items to and list items of a vector of objects.

Specifications

  1. Copy the following program into a text editor, save it as prodvector.cpp, and then compile and run the starter program to make sure you copied it correctly.
    #include <iostream>
    #include <vector>
    using namespace std;
    
    class Product {
    public:
        Product();
        Product(string newName, double newPrice);
        void read();
        void print() const;
    private:
        string name;
        double price;
    };
    
    Product::Product() {
        name = "Unknown";
        price = 0.0;
    }
    
    Product::Product(string newName, double newPrice) {
        name = newName;
        price = newPrice;
    }
    
    void Product::read() {
        cout << "Enter the name of the product: ";
        cin >> ws;
        getline(cin, name);
        cout << "Enter the price for a " << name << ": ";
        cin >> price;
    }
    
    void Product::print() const {
        cout <<  name << " @ " << price << endl;
    }
    
    // Add a new product to the store
    void addProduct(vector<Product>& store);
    
    // List the products in the store
    void listProducts(vector<Product>& store);
    
    int main() {
        const int SIZE = 3;
        vector<Product> store(SIZE);
        store[0] = Product("Milk", 3.95);
        store[1] = Product("Bread", 2.99);
        store[2] = Product("Cheese", 3.95);
    
        // Enter new code here
    
        return 0;
    }
    

    Notice that we are using our Product class from lesson 8. Also notice that in main() we add three Product objects to a vector.

  2. After the closing curly brace of the main() function, add the following function definition:
    void listProducts(vector<Product>& store) {
        cout << "\nListing products:\n";
        for (unsigned num = 0; num < store.size(); num++) {
            cout << (num + 1) << " ";
            store[num].print(); // call print() in Product
        }
    }
    

    Note that this function is calling the print() member function of Product. For more information see section 10.3.5: Parallel Vectors.

  3. In the main() function after the comment that says:
    // Enter new code here
    

    add a function call to the listProducts() function you just defined.

  4. Compile and run your modified program to make sure you made the changes correctly. When you run the program, the output should look like:
    Listing products:
    1 Milk @ 3.95
    2 Bread @ 2.99
    3 Cheese @ 3.95
    
  5. After the closing curly brace of the main() function, add the following function definition:
    void addProduct(vector<Product>& store) {
        cout << "\nAdding a new product:\n";
        Product prod;
        prod.read();
        store.push_back(prod);
    }
    

    Note that this function is calling the read() member function of Product. For more information see section 10.3.6: Processing a Vector of Objects.

  6. In the main() function after the function call to listProducts(), add a function call to addProduct() followed by another call to listProducts() like:
    listProducts(store);
    addProduct(store);
    listProducts(store);
    
  7. Compile and run your modified program to make sure you made the changes correctly. When you run the program, the output should look like:
    1 Milk @ 3.95
    2 Bread @ 2.99
    3 Cheese @ 3.95
    
    Adding a new product:
    Enter the name of the product: Crackers
    Enter the price for a Crackers: 2.49
    1 Milk @ 3.95
    2 Bread @ 2.99
    3 Cheese @ 3.95
    4 Crackers @ 2.49
    

    As you can see, you should be able to add a new product to the list.

  8. Now we want to create a short menu to call our functions. Replace the sequence of three function calls in main() with the following code:
    int choice = 1;
    while (choice != 0) {
        cout << "\n0. Exit program\n"
             << "1. Report inventory\n"
             << "2. Add a new product\n"
             << "Choice (0-2): ";
        cin >> choice;
        if (choice == 1) {
            listProducts(store);
        } else if (choice == 2) {
            addProduct(store);
        } else if (choice != 0) {
            cout << "\nInvalid choice!\n";
        }
    }
    cout << "\nGoodbye!\n";
    
  9. Compile and run your modified program to make sure you made the changes correctly. When you run the program, the output should look like:
    0. Exit program
    1. Report inventory
    2. Add a new product
    Choice (0-2):
    

    Also, you should be able to add and list products as often as you like.

  10. Save your program source code to submit to Canvas as part of assignment 11.

Partial Listing of prodvector.cpp

Listing of prodvector.cpp

10.4.3: Summary

  • Sometimes we need to keep track of multiple attributes about a list of items
  • The naive way to code this is to use parallel vectors
  • Parallel vectors become a headache in larger programs:
    • Each vector must be the same length
    • Each slice is filled with values that belong together
    • Any function that operates on a slice must get several vectors as parameters
  • To remove parallel vectors, look at the slice and find the concept it represents
  • Then make the concept into a class
  • Finally, eliminate the parallel vectors and replace them with a single vector of objects
  • We looked at an example of a vector of Product objects

Check Yourself

  1. What are parallel vectors? (10.4.1)
  2. Why are parallel vectors indications of poor programming? (10.4.1)
  3. How can parallel vectors be avoided? (10.4.1)
  4. How can you read data into an object before inserting it into a vector? (10.4.2)

10.5: Midterm Preparation

Learner Outcomes

At the end of the lesson the student will be able to:

  • Discuss how to prepare for the midterm exam
  • Describe how to take the midterm exam

10.5.1: About the Exam

  • I am using Canvas to administer the test
  • Since there are more students than computers, we must take the exams in shifts
  • Shifts are determined by your last name and section as follows:
    Last Name Section Start Time
    A-Z Day 2:30 PM
    A-Z Evening 8:00 PM
  • If you want to change shifts then make arrangements to switch with another student who is on the other shift and email the instructor the information
  • Must not communicate test contents with other shifts until after they take the exam

Ground Rules

  • You must attend the exam or you will receive a score of zero (0)
    • Except by prior arrangement with the instructor
  • You must bring a valid ID to the exam
  • The exam is closed books and closed notes
    • However, you may have one 3" x 5" card of handwritten notes for the exam
  • Blank scratch paper is allowed
  • You may use a computer from the classroom, but only to:
    1. take the exam in Canvas
    2. type code into TextPad
    3. compile and run programs in Cygwin
  • You may NOT use the computer to:
    1. view documents on the Internet
    2. look at pre-existing code
    3. open documents
  • You may NOT use a calculator or electronic device
    • Thus, you may NOT use your own computer to take the exam
    • If you have a cell phone visible or in use during the exam, you will automatically fail
  • You may NOT communicate with anyone but the instructor during the exam

3"x5" Card Requirements

  • Put your name on your card
  • Maximum card (or paper) size is 3 inches by 5 inches
  • You may use both sides of the card
  • Notes must be handwritten and NOT photocopied
  • No more than three statements in a sequence on the card — only snippets
  • Any 3" x 5" cards violating these rules will be confiscated before the test
  • You must turn in your 3" x 5" card after the exam in any case

About Compiling

  • Code that does not compile contains an error
  • When given the tools to compile, your code must compile for a good score
  • Expect to lose points for every line that does not compile
  • If you are having problems compiling, comment out the lines that do not compile
  • Partial credit is available if you comment out your problem code
  • Make sure you know how to compile on the school computers

10.5.2: Exam Topics

  • To help you prepare for the exam, I am providing a list of exam topics
  • In return, I want each student to pick one topic (see below) and prepare 5 Jeopardy-style questions for their topic
  • Also, develop a short Jeopardy-style category name
  • At the next class meeting we will review the questions to help us prepare for the midterm
  • For reference, here are the topics for the prior midterm: Midterm 1 Topics

New Exam Topics

  1. Counting loops and for-statements (5.1)
  2. Nested loops (5.2)
  3. Indefinite loops (5.3.1-2)
  4. Summation, minimum and maximum (5.3-4)
  5. Input validation (5.3.5-8)
  6. Iterating strings (6.1.1-3)
  7. Array definition (7.2.1-2, 10.2.1)
  8. Array element access (7.2.2-3, 10.2.1)
  9. Random numbers (7.3.3-4, 7.3.5)
  10. Function definitions (7.4.1-5, 8.1.1, 8.1.3, 9.1.1)
  11. Parameters (7.4.3-4, 8.3.1-4, 9.1.2)
  12. Return statements (7.4.5, 8.1.1, 9.1)
  13. Variable scope (7.4.4, 8.1.2, 8.3.1, 9.1.2, 9.3.5)
  14. Function calls and flow (7.3.2, 7.4.6, 8.2.1, 8.2.4, 9.1)
  15. Function prototypes (8.2.2, 8.4.5, 9.1.3)
  16. Algorithms, psuedocode and function design (8.4, 9.1.3)
  17. Objects (9.2.1, 9.2.3, 9.3.3, 10.1.1)
  18. Coding classes (9.2.2-5, 10.1.1)
  19. Constructors (9.2.5, 9.3.1-3, 10.1.1)
  20. Accessor and mutator functions (9.2.4, 9.3.4)
  21. Object-oriented program flow (9.3.3-5, Exercise 10.1)

Exercise 10.5: Prepare Test Topics (6m)

Take a minute to review the above topics and select one of them to prepare 5 potential test questions for Assignment 10.

As a homework for the next class meeting, prepare a list of 5 Jeopardy-style questions/answers on your topic.

Jeopardy-style questions/answers have a twist. You provide the answer and the player states the question. For example, an answer is, "In the C++ Programming language, this variable type only has a value of either true or false." The player would pose the question as, "What is bool?"

Post your topic and the questions/answers in the Discussions area of Canvas. For each answer, supply a question and a point value of 100, 200, 300, 400 or 500. Remember to write each question in the Jeopardy style.

10.5.3: More Test Preparation

  • To help you study, you can use this review game: Greenfoot Jeopardy
  • Start the game with the "cpp.txt" file

Practice Exam

  • To help your understanding of how the midterm will operate, I am providing a practice exam in Canvas
  • The questions are intended to help you get a "feel" for taking an exam in Canvas
  • The questions are NOT intended to tell you everything that is on the exam
  • Suggestion: prepare first and then try the practice exam
  • This will give you a better understanding of how much more preparation you need

Exam Taking Tips

  • If you get stuck on a question, make your best guess and return later
  • If you are equally uncertain between two choices, go with your first impression
  • When writing code, do NOT add more than the problem asks for
  • You do not need to comment code for tests and exams
    • Unless specifically instructed to in the exam question
  • Use the full time available
    • Check your work if you finish early
  • Any questions?

Wrap Up

Due Next:
A10: Midterm 2 Review Problems (4/12/17)
  • When class is over, please shut down your computer
  • You may complete unfinished exercises at the end of the class or at any time before the next class.
Last Updated: May 07 2017 @19:53:52