0% found this document useful (0 votes)
3 views16 pages

Module 1(Lesson5)

This lesson covers arrays and vectors in C++ programming, highlighting their roles as containers for storing multiple values. It explains the definitions, usage, and differences between arrays and vectors, including the importance of understanding pointers and the potential pitfalls of array bounds. Additionally, it introduces the vector class from the C++ standard library, emphasizing its advantages over arrays, such as dynamic resizing and built-in methods for manipulation.

Uploaded by

Bangkal Ml
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
0% found this document useful (0 votes)
3 views16 pages

Module 1(Lesson5)

This lesson covers arrays and vectors in C++ programming, highlighting their roles as containers for storing multiple values. It explains the definitions, usage, and differences between arrays and vectors, including the importance of understanding pointers and the potential pitfalls of array bounds. Additionally, it introduces the vector class from the C++ standard library, emphasizing its advantages over arrays, such as dynamic resizing and built-in methods for manipulation.

Uploaded by

Bangkal Ml
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 16

Lesson 5: Arrays and Vectors

In this lesson, we will tackle two of the important concepts in C++


programming: arrays and vectors. Arrays and vectors are containers
or specialized variables. The reason why they are called as specialized
variables is that both of them can use used to store values. But
unlike the variables that we have learned in the previous lessons
where one variable can only hold one value, one array or one vector
can be able to hold multiple values. These two concepts are
particularly useful when you program is becoming more complicated
where there is a need for you to handle multiple values while at the
same time, considering the performance of your C++ programs.

Our main goal for this lesson is for you to fully understand these two
concepts and how to apply them into computer codes.

It is my hope that you will endeavor to understand the concepts as


these will be important preparations to the next lesson. Happy
coding!

Learning Outcomes

At the end of this lesson, you shall be able to:

 understand the concepts of arrays and pointers;


 identify the similarities and differences between arrays
and pointers;
 write a C++ program applying the two concepts; and
 appreciate the importance of the arrays and vectors as
applied in C++ programs.
ARRAYS AND VECTORS

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

An array is defined with this syntax.

datatype arrayName[size];

Examples:

int ID[30]; /* Could be used to store the ID


numbers of students in a class */

float temperatures[31]; /* Could be used to store the daily


temperatures in a month */

char name[20]; /* Could be used to store a character


string. C-style character strings are
terminated be the null character, '\0'.
This will be discussed in a later lesson. */
int *ptrs[10]; /* An array holding 10 pointers
to integer data */

unsigned short int[52]; /* Holds 52 unsigned short integer


values */

class POINT {
public:
POINT() { x = 0; y = 0;}
~POINT();
//Accessor methods declared here
private:
int x;
int y;
}

POINT dots[100];

This last example declared an array of objects of class POINT. A class to be


used in an array must have a default constructor, that is, a constructor
without arguments. The compiler uses this constructor when allocating space
for the array when it is defined.

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.

int myExample[5]; /* Defines myExample to be of length 5


and to contain integer data */

myExample[0] /* First element of myExample */


myExample[1] /* Second element of myExample */
myExample[2] /* Third element of myExample */
myExample[3] /* Fourth element of myExample */
myExample[4] /* Fifth and final element of myExample */
Here is a sample program that calculates and stores the squares of the first one
hundred positive integers.

#include <iostream>
using namespace std;

int main()
{
int square[100];
int i; /* loop index */;
int k; /* the integer */

/* Calculate the squares */


for (i = 0; i < 100; i++) {
k = i + 1; /* i runs from 0 to 99 */
/* k runs from 1 to 100 */
square[i] = k*k;
cout << "The square of " << k << " is " << square[i] << endl;
}

return 0;
}

An array can be initialized with an explicit initialization list in its definition.

int myArray[5] = {6, 7, 8888, 98765, 0}; //Defines and initializes

Relationship Between Pointers and Arrays

In some cases, a pointer can be used as a convenient way to access or


manipulate the data in an array.

Suppose the following declarations are made:

float temperatures[31]; /* An array of 31 float values, the


daily temperatures in a month */

float *temp; /* A pointer to type float */


Since temp is a float pointer, it can hold the address of a float variable. The
address of the first element of the array temperatures can be assigned to temp
in two ways.

temp = &temperatures[0];
temp = temperatures;
/* This is an alternate notation for the first
element of the array.
Same as temperatures = &temperatures[0]. */

The temperature of the first day can be assigned in two ways.

temperatures[0] = 29.3; /* brrrrrrr */


*temp = 15.2; /* BRRRRRRR */

Other elements can be updated via the pointer, as well.

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.

float temperatures[12][31]; /* Used to store temperature data


for a year */

float altitude[100][100]; /* Used to store the altitudes of 10000


grid points of a 100 by 100 mile
square */
A common way to access the elements of a multidimensional arrays is with
nested for loops.

#define MAXI 50;


#define MAXJ 75;

int i;
int j;
float values[MAXI][MAXJ];

for (i = 0; i < MAXI; i++) {


for (j = 0; j < MAXJ; j++) {
values[i][j] = whatever;
}
}

Important Note About Array Dimensions

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 value will be in val? Whatever happens to be in memory at the location


right after the end of the array. This value could be anything. Worse yet, the
program may continue to run with the incorrect value and no warnings are
issued.

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];

for (i < 0 ; i <= 10; i++) {


b[i] = 3.14 * i * i;
}

This loop should use "<" rather than "<="

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>

A vector of integers is defined as follows:

vector<int> scores(50); //Defines a vector of 50 ints


The vector class is a template. The C++ language allows classes and functions
to be declared as templates. Templates allow data types to be parameterized in
the class or function definitions. This will be explained fully in later lessons.
For now, all that is needed is to think of templates as a way to allow a class or
function to work with different data types. For instance a vector of floats can be
defined as:

vector<float> amounts(50); //Defines a vector of 50 floats


The template allows the same class, vector in this case, to be used with many
different data types, including programmer defined classes.

Class Dog {...}

vector<Dog> dogs(99); // Defines a vector of 99 dogs.

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.

vector<float> weights(10); //Defines a vector of 10 weights


all initialized to 0.0

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};

vector<float> weights(w,w+10); /* Defines a vector of 10 weights


initialized by use of an iterator
pair. w is a pointer (iterator) to
the start of the array "w". "w+10"
is a pointer (iterator) to one past
the end of the array. */

vector<float> weights(readings); /* Where readings is another


vector. It could contain measured
values for instance. */

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

scores[0] //first element of the vector scores.


scores[1] //second element of the vector scores.
....
scores[k-1] //kth element of the vector scores.

for (int i = 0; i < scores.size(); i++)


{
scores[i] = 50 + i;
}

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.

at(size_type index) Returns a reference to the element at


the location specified.
back() Returns a reference to the element at
the end of the vector
begin() Returns an iterator to the start of the
vector.
clear() Erases the vector.
empty() Returns true if the vector is empty.
end() Returns an iterator one past the end of
the vector.
erase(iterator where) Removes a single element or range of
erase(iterator first, iterator elements.
last)
front() Returns a reference to the first
element of the vector.
insert(iterator where, const Inserts a value or values into a vector
type &val) at the specified position(s).
insert(iterator where,
size_type number, const
type &val)
insert(iterator where, iterator
input_begin, iterator
input_end)
pop_back() Deletes the element at the end of the
vector. (Compare with back)
push_back(const type &val) Adds an element to the end of the
vector.
size() Returns the number of elements in the
vector.
==, != Returns true or false.
<, <=, >, >= Returns true or false
= Assigns one vector to another

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.

An iterator to the start of a vector is defined as follows.

vector<int> myInts(30);

vector<int>::iterator iter = myInts.begin();


Iterators are classes. Each container class, vector, list, etc., needs its own
special iterators due to its unique properties. So, there are multiple iterator
classes. In order to hide the names of the actual iterator classes in the C++
library, each container class has a typedef for the correct iterator class,
renaming it "iterator". The "::" is called the resolution scope operator. It
identifies a variable as belonging to a particular class. So vector<int>::iterator
refers to the iterator that is part of the vector class. The expression sets this
iterator to the beginning of the vector.

The best way to understand how to use vectors is by examples.

#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

vector<int>::iterator iter = v1.begin();

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;

cout << "v1 is of length " << v1.size() << endl;


savedVal = v1.back();

cout << "Removing last element" << endl;


v1.pop_back(); // Removes the last element of v1
cout << "v1 is of length " << v1.size() << endl;
cout << "Last element of v1: " << v1.back() << endl;

cout << "Restoring last element" << endl;


v1.push_back(savedVal); // Adds back last element
cout << "v1 is of length " << v1.size() << endl;
cout << "Last element of v1: " << v1.back() << endl;

cout << "Adding an additional element" << endl;


// Note that vector will grow or shrink as necessary
iter = v1.end();
v1.insert(iter,53);
cout << "v1 is of length " << v1.size() << endl;
cout << "Last element of v1: " << v1.back() << endl;

for (size_t i = 0; i < v1.size(); i++)


{
cout << v1.at(i) << endl;
}

for (iter = v1.begin(); iter < v1.end(); iter++)


{
cout << *iter << endl; //Dereference iter to obtain values.
}
}

Here is the output.

First element of v1: 1


First element of v1: 1
Last element of v1: 6
V1 is of length 10
Removing last element
V1 is of length 9
Last element of v1: 9
Restoring last element
V1 is of length 10
Last element of v1: 6
Adding an additional element
V1 is of length 11
Last element of v1: 53
1
2
2
2
2
4
7
8
9
6
53
1
2
2
2
2
4
7
8
9
6
53
Press any key to continue

Here's another example showing the use of relational operators and


assignment. You can't directly compare arrays in this manner.
#include <iostream>
#include <vector>
using namespace std;

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 << "v1 less than v2" << endl;
}
else
{
cout << "v1 greater than v2" << endl;
}

if (v1 != v2)
{
cout << "They're different" << endl;
}

cout << "Assigning v1 to v2" << endl;


v2 = v1;

if (v1 == v2)
{
cout << "Now they're equal" << endl;
}

Here's the output.

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.

The generic algorithms are able to work in a container independent manner by


accepting as arguments iterators to the start point and one past the end point
of a range within the container. This range could, of course, span the entire
container. For arrays, pointers rather than iterators may be used as
arguments.

The simplest way to understand the use of these algorithms is by example.


Assume that there is a vector of ints that we want to manipulate. We will look
for a particular value within this vector and then count the number of
occurrences of some other values. We will then sort the vector and discard all
elements larger than the search value.

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 val[] = {1,4,67,11,55,23,94,18,2349,11,77,33,12,41,37};

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);

find returns an iterator to the first occurrence of the value if it is found, or an


iterator to one past the range searched if not found.

count returns the number of occurrences of the value found in the search
range.

Here's the code.

vector<int>::iterator start = num.begin();


vector<int>::iterator end = num.end();

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(Iterator start, Iterator end);

Here's the code.

sort(start,end);
iter = find(start,end,37);
num.erase(iter + 1,end); //Erase from the element past
37 to the end

You might also like