Module 1(Lesson5)
Module 1(Lesson5)
Our main goal for this lesson is for you to fully understand these two
concepts and how to apply them into computer codes.
Learning Outcomes
This lesson introduces arrays and vectors. Arrays are a data structure that is
used to store a group of objects of the same type sequentially in memory. They
are a built-in part of the C++ language. All the elements of an array must be
the same data type, for example float, char, int, pointer to float, pointer to int, a
class, structure or function. Functions provide a way to define a new operation.
They are used to calculate a result or update parameters. The elements of an
array are stored sequentially in memory. This allows convenient and powerful
manipulation of array elements using pointers. The use of arrays is common in
C and C++ coding and is important to understand well.
Vector is a container class from the C++ standard library. As is true for an array,
it can hold objects of various types. Vector will also resize, shrink or grow, as
elements are added. The standard library provides access to vectors via
iterators, or subscripting. Iterators are classes that are abstractions of pointers.
They provide access to vectors using pointer-like syntax but have other useful
methods as well. The use of vectors and iterators is preferred to arrays and
pointers. Common bugs involving accessing past the bounds of an array are
avoided. Additionally, the C++ standard library includes generic algorithms
that can be applied to vectors and to other container classes.
Defining Arrays
datatype arrayName[size];
Examples:
class POINT {
public:
POINT() { x = 0; y = 0;}
~POINT();
//Accessor methods declared here
private:
int x;
int y;
}
POINT dots[100];
Using Arrays
Arrays in C++ are zero based. Suppose an array named myExample contains N
elements. This array is indexed from 0 to (N-1). The first element of myExample
is at index 0 and is accessed as myExample[0]. The second element is at index
1 and is accessed as myExample[1]. The last element is at index (N-1) and is
accessed as myExample[N-1]. As a concrete example, suppose N equals 5 and
that myExample will store integer data.
#include <iostream>
using namespace std;
int main()
{
int square[100];
int i; /* loop index */;
int k; /* the integer */
return 0;
}
temp = &temperatures[0];
temp = temperatures;
/* This is an alternate notation for the first
element of the array.
Same as temperatures = &temperatures[0]. */
temp = &temperatures[0];
*(temp + 1) = 19.0; /* Assigns 19.0 to the second element
of temperatures */
temp = temp + 9; /* temp now has the address of the 10th
element of the array */
*temp = 25.0; /* temperatures[9] = 25, remember that arrays are
zero based, so the tenth element is at index 9. */
temp++; /* temp now points at the 11th element */
*temp = 40.9; /* temperatures[10] = 40.9 */
Multidimensional Arrays
The C++ language also allows multidimensional arrays. They are defined as
follows.
int i;
int j;
float values[MAXI][MAXJ];
The C++ language performs no error checking on array bounds, which is one
reason to use vectors rather than arrays. If you define an array with 50
elements and you attempt to access index 50 (the 51st element), or any out of
bounds index, the compiler issues no warnings. It is the programmer's task
alone to check that all attempts to access or write to arrays are done only at
valid array indexes. Writing or reading past the end of arrays is a common
programming bug and can be hard to isolate.
What will happen if a program accesses past the end of an array? Suppose a
program has the following code.
int val;
int buffer[10];
val = buffer[10]; /* Bug, remember that the indexes of buffer run
from 0 to 9. */
What will happen if a program writes past the end of an array? Suppose a
program has the following code.
int buffer[10];
buffer[593] = 99;
The value of 99 will be written at the memory location, buffer + 593. "buffer" is
a pointer to the beginning of the array. buffer + 593 is pointer arithmetic for
the address equal to the starting address of the array plus the size of 593
integers. The overwriting of the value at this memory location will change the
value of whatever variable is stored there. Some other variable may have its
value changed unintentionally. If the program writes unintentionally to
memory locations that not valid, the program may crash.
The most common cause of writing/reading to invalid array indexes are errors
in loop limits.
int i;
float b[10];
Defining Vectors
The vector container class is part of the C++ standard library. To define a
vector, it is necessary to include the vector class header file.
#include <vector>
Note that if templates were not part of the language, a separate "vector" class
would be needed for each data type. There would be a "vectori" for ints,
"vectorf" for floats and "bark" for dogs. For a user defined type to be used in a
vector there are three additional requirements that must be satisfied.
The type must supply a default value. For classes, this is the default
constructor.
The type must support the equality operator. For classes, this is an overloaded
operator. This will be discussed in later lessons.
The type must support the less-than operator. Again, this is an overloaded
operator for classes.
Built-in data numeric and pointer data types such as int and float get
initialized to zero when a vector is defined. A vector of classes is initialized by
its default constructor. In contrast, arrays are not initialized be default in C++.
Arrays should be explicitly initialized by the programmer with either code or an
initialization list in the array definition.
Vectors do not support explicit initialization list as do arrays. Does this mean
that each element must be assigned a value individually?
weights[0] = 5.6;
weights[1] = 4.999999;
....
Fortunately, not. Several different vector constructors exist. Here are examples
of their use.
vector<float> weights(10,5.9); //Defines a vector of 10
weights all initialized to 5.9
float w[10] = {0.0, 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9};
Using Vectors
Vectors can be accessed by subscripts and are zero based, just as arrays.
vector<int> scores(50);
//Defines a vector of 50 ints
The "for" loop sets each element of scores to a value. Notice the loop limit,
vector.size(). The method, size(), is a one of several defined for vector, as well as
for the other container classes, such as map, set and list. Here are some of the
more useful methods and operations in vector. We'll see how to use them soon.
The standard library also provides access to vectors and other containers via
iterators. Iterators are classes that are abstractions of pointers. They provide
pointer like syntax with increment, decrement and dereferencing. Their real
utility is more apparent in some of the other container classes. The list class is
essentially a linked-list. Iterators can be use to step easily through a list, while
a simple pointer cannot. The C++ standard library also provides a large
number of generic algorithms such as sort and find, which accept iterator
arguments. This allows the algorithms to be used consistently for any
container class.
vector<int> myInts(30);
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int val[10] = {1,2,2,2,2,4,7,8,9,6};
int savedVal;
vector<int> v1(val,val+10); //Defines and initializes v1 with
the array val
cout << "First element of v1: " << v1.at(0) << endl;
cout << "First element of v1: " << v1.front() << endl;
cout << "Last element of v1: " << v1.back() << endl;
int main()
{
int val[10] = {1,2,2,2,2,4,7,8,9,6};
vector<int> v1(val,val+10); //Defines and initializes v1 with
the array val
vector<int> v2(10); //Defines and initializes v2 with
zeros.
if (v1 != v2)
{
cout << "They're different" << endl;
}
if (v1 == v2)
{
cout << "Now they're equal" << endl;
}
v1 greater than v2
They're different
Assigning v1 to v2
Now they're equal
Generic Algorithms
The C++ standard library includes many generic algorithms that can be used
with any of the container classes, and also with the built-in array data type.
These algorithms can perform common programming tasks such as searching,
sorting, copying, substitution, relational operations and numerical operations.
This lesson will introduce some of the available routines. Please check your
IDE's help utility, man pages, or books for complete listings and descriptions of
all available algorithms. These algorithms can greatly simplify your code and
should be examined before you start coding any function or project, as a way to
reduce the code you'll need to write.
To use the generic algorithms the header file <algorithm> must be included. To
use a vector, <vector> is needed; Here is the code to define the vector.
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
vector<int> num(val,val+15);
//Defines an vector; initializes with values from the val array
The value to search for will be 37. We will also count the occurrence of the
numbers 11 and 77. To do this, the algorithms find and count will be used.
Here are the prototypes.
InputIterator find(InputIterator start, InputIterator end,const T& value);
size_t count(InputIterator start, InputIterator end,const T& value);
count returns the number of occurrences of the value found in the search
range.
vector<int>::iterator iter;
iter = find(start,end,37);
if (iter == end)
{
cout << "37 Not Found" << endl;
}
else
{
cout << "Found " << *iter << endl;
}
sval = 11;
cnt = count(start,end,sval);
cout << "Found " << cnt << " elevens" << endl;
sval = 77;
cnt = count(start,end,sval);
cout << "Found " << cnt << " seventy sevens" << endl;
The next task is to sort the vector and then discard values larger than the
search value, 37. We need the sort function. The container class, vector, has a
member function, erase, that we will use to discard values.
sort(start,end);
iter = find(start,end,37);
num.erase(iter + 1,end); //Erase from the element past
37 to the end