Chapter 5
Chapter 5
Chapter 5
What is an Array?
So far, we have been using variables of different types for our data. A single variable was
capable of storing only one value at a time. We would probably have used the code shown
below if we were required to work with the ages of 4 students. Example:
age1
Each
in the figure.
2nd element
age
3rd element
4th element
In the figure shown, the name of the array is age, it can store 4 elements, and each one is
an integer.
where the type of the array is followed by the name which is followed by the size of the
array within square brackets. The size specifies the maximum number of elements that the
Note:
• The number in brackets specifying the size of the array must be a constant or an
expression that evaluates to a constant, and should also be an integer.
• The size of the array is fixed. There is no way to change the size after the array is
defined.
Example:
const int SIZE = 110; int
num_people = 100;
char letters [26]; //OK: 26 is a literal constant
double atomic weights[SIZE]; //OK: SIZE is a const variable float heights[num_people]; //ERROR:
num_people is a non const variable
Subscripts
Even though an entire array has only one name, the
elements may be accessed and used as individual 0
variables. Each element is assigned a number known as age1 a
subscript or an array index. 2
3
To access a specific element, we use the name of the array followed by the
subscript of the element in square brackets. An element, when accessed by its
subscript, behaves exactly like a variable of the array's type. Example:
5. int age[4]; //an array to hold 4 integers
6. age[0] = 23; //age[0] is a variable of type int
7. age[1] = 15;
8. age[2] = 12;
9. age[3] = age[1] + age[2];
10. cout<<"Age of first student = "<<age[0];
11. cout<<"\nTwo times age of third student = "<<age[2]*2;
Note:
• Subscript numbering in C++ always starts at zero. The subscript of the last element in
an array is one less than the total number of elements in the array. Therefore, in the
above example, there is no such element as age[4].
Individual elements of different arrays maybe used as normal variables. However, it is not
possible to assign one array to another or use an array in an expression hoping to affect all
its elements. Examples:
5. int age[4];
6. int student_age[4];
7. age[0] = 23;
8. age[1] = 15;
9. age[2] = 12;
10. age[3] = 27;
11. for (int i=0; i<4; i++)
12. student_age[i] = age[i]; //OK
13. student_age = age; //ILLEGAL
14. cout<<age*2; //ILLEGAL
Arrays provide a convenient method for working with groups of related values. The
same name can be used to refer to the group and loops can be used to access each
element in turn (see lines 11 and 12 above). The following example program
demonstrates this convenience. The program accepts the scores of students, calculates
the average, and displays the difference from the average for each student. Example:
1. #include <iostream.h>
2. using namespace std;
3.
4. int main() {
5. const int TOTAL = 5;
6. float scores[TOTAL], sum=0, avg;
7. cout<<"Score Averager\n";
8. //Read the scores
9. for (int i=0; i<TOTAL; i++) {
10. cout<<"Enter score for Student "<<i+1<<":> ";
11. cin>>scores[i];
12. }
13. //Caculate the average
14. for (int j=0; j<TOTAL; j++)
15. sum+=scores[j];
16. avg = sum/TOTAL;
17. cout<<"\nAverage = "<<avg<<endl;
18. //Display the difference
19. for (int k=0; k<TOTAL; k++) {
20. cout<<"\tThe difference from average for Student "
Initializing Arrays
From what we have seen so far, if we want to initialize the elements of an array, we have
to write separate assignment statements for each element.
int age[4]; age[0]=25;
age[1]=12; //and so on
Fortunately, C++ allows us to initialize array elements when they are defined.
int age[4] = {25, 12, 15, 27};
It is possible to define an array without specifying its size, as long as you provide an
initialization list that includes a value for every element. C++ automatically makes the
array large enough to hold all the initialization values. For example, the following
definition creates an array with five elements:
double factors [] = {1.0, 1.5, 2.0, 2.5, 3.0};
What happens if you use an explicit array size, but it doesn’t agree with the number of
initializers? If there are too few initializers, the missing elements will be set to 0. If there
are too many, an error is signaled.
int age [4] = {25, 12}; //age [2] and age [3] will be set to 0 double factors [4] = {1.0, 1.5, 2.0, 2.5,
3.0}; //ERROR!
Exercises:
1. What are the output of the following pieces of code? a)
5. double balance [5] = {100.0, 250.0, 325.0, 500.0, 1100.0};
6. const double INT_RATE = 0.1;
7. cout <<setprecision (2);
8. for (int count = 0; count < 5; count++)
9. cout << (balance[count] * INT_RATE) << endl;
b)
5. const int SIZE 5;
6. int count;
In prestandard C++, a string is an array of type char ending with a null character
('\0'). Character arrays can be defined, used, and initialized just like any other array.
char greeting[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\n', '\0'};
Note: The Standard C++ Library defines a string type. The strings defined here as "a null
terminated array of characters" are now commonly known as Cstyle strings or CStrings.
From now on, unless specified, the term strings refers to CStrings.
If you try running the above example and enter your full name as input, you will get an
output that looks like the following
Enter your name:> Mohammed Ahmed Hello,
Mohammed!
The first argument to cin.get() is the array address where the string being input will be
placed. The second argument specifies the maximum size of the array. This program now
works as expected.
Enter your name:> Mohammed Ahmed Hello,
Mohammed!Note:
• Functions of this type are known as member functions and will be discussed later.
• There is a potential problem when you mix cin.get() with cin and the extraction
operator (>>). This problem and the method to avoid it are to be observed in the lab.
If the function were written to accept the entire array as an argument, it would be set up as
follows
4. void showValue(int num[], int N)
5. {
6. for (int i=0; i<N; i++)
7. cout<<num[i];8. }
Note: Unlike the arguments we have seen before, array elements will not be copied to the
array specified in the parameter list. Instead, the original array itself is accessed by the
function with a different name. (In the above example, num simply refers to myArray).
This means that any modification made to the array inside the function will remain even
after the function completes. This will be discussed in detail in chapter 6.
The arrays we have seen so far are said to be one dimensional arrays. Sometimes though we
may want to work with data requiring multidimensional arrays for example, matrices and
data in the form of a table.
[ 1 2 3
A=4 5 6 ]
3 5 7
C++ allows us to have arrays of more than one dimension. Each dimension is represented as a
subscript in the array. Therefore, a two-dimensional array has two subscripts; a three-
dimensional array has three subscripts; and so on. Arrays can have any number of
dimensions, although it is highly unlikely that we will require arrays of more than two
dimensions.
Each element in a 2D array is accessed with two subscripts: the first one is for its row and
the second for its column. The following figure shows all the elements for the array
defined above.
this statement sets value for the third column of the second row to be 80.5.
The following program is fairly complex and demonstrates the usage of arrays. Compile it
and observe the results. Make sure you understand how it works. (You may want to
change the value of STUDENTS to something smaller) Example:
1. #include <iostream.h>
2. #include <iomanip.h>
3. using namespace std;
4.
5. int main () {
6. const int STUDENTS = 80;
7. const int COURSES = 4;
8. float scores[STUDENTS][COURSES];
9. cout<<"Course Average Calculator\n";
10. int i, j;
11. //read the scores
12. for (i=0; i<STUDENTS; i++)
13. {
14. cout<<"Enter scores for student "<<i+1<<endl;
15. for (j=0; j<COURSES; j++)
16. {
17. cout<<"\tFor Course "<<j+1<<":> ";
18. cin>>scores[i][j];
19. }
20. }
21. //calculate the averages
22. float sum=0, avg[STUDENTS];
23. for (i=0; i<STUDENTS; i++) {
24. sum=0;
25. for (j=0; j<COURSES; j++)
26. sum+=scores[i][j];
27. avg[i] = sum/COURSES;
28. }
28.
29. //First display the column headers
30. cout<<setw (4) <<"No.";
31. for (j=0; j<COURSES; j++)
The elements of the row are assigned the values {1, 2, 3} and those on the second row get
{4, 5, 6};
Exercises:
1. Write a program that accepts a 2D integer array from the user and
a. Sums all the elements
b. Stores the sum of each row in a 1D integer array
c. Stores the sum of each column in a 1D integer array
2. Write a program that accepts two square matrices of identical dimensions from the
user and
a. Transposes the two matrices and displays the results
b. Performs matrix addition and stores the result in a third matrix
c. Performs matrix multiplication and stores the result in a third matrix
strlen: takes a string as an argument and returns its length. The length of a string is the
number of characters up to, but not including, the null terminator. Example:
Note: Do not confuse the length of the string with the size of the array holding it.
strcat: takes two strings as arguments and concatenates them, giving a single string that
consists of all the characters of the first string followed by all the characters of the second.
The string passed as the first argument will hold the concatenated string.
Example: str1
char str1[13] = "Hello "; char str2[] = H e l l o \0
str2 "World!" cout<<"Before: "<<str1<<endl;
W o r l d \0
strcat(str1, str2); cout<<"After: strcat (str1, str2)
"<<str2<<endl;
H e l l o W o r l d \0
str1
Note:
• strcat will not add a space between the two strings. You have to do that yourself.
• Make sure that the array holding the first string is large enough to hold both strings
together plus a null character.
strcpy: is used to copy one string to another. This is because arrays can't be copied
using the assignment operator (=). Example:
char str1[20];
char str2[] = "Second String"; strcpy (str1, str2); cout<<"str1:
"<<str1<<endl; strcpy (str2, "Another String"); cout<<"str2:
"<<str2<<endl;
Note:
• If there is anything already stored in the first string, it will be overwritten.
• If the length of the second string is larger than the array size of the first string, a
buffer overflow may occur.
strcmp: takes two strings as arguments and returns an integer result which is
• 0 if the two strings are equal
• negative if the first string comes before the second in alphabetical order
• positive if the first string comes after the second in alphabetical order Example:
char password [30]; char quit [] = "exit";
cout<<"Enter your password: ";
cin>>password;
if (strcmp (password, "classpass”) ==0)
cout<<"Logon Successful!\n";
Note:
• strcmp is case sensitive.
strncpy and strncat: are alternate versions of strcpy and strcat. These functions take one
extra integer argument. In both cases, this integer specifies how many characters to take
from the second string. strncpy and strncat are safer than strcpy and strcat as they help
minimize buffer overflow errors.
Note: Standard C++ contains another header file, strings, for working with standard
strings. This header file is entirely different from string.h (or cstring)
String/Numeric Conversion
There is a difference between a number stored as a string and one stored as a numeric
value. For example
char strnum[] = “100”; int num = 100; '1' '0' '0' \0
100
C++ provides functions for converting strings to numbers and vice versa.
The following functions are defined in stdlib.h (or cstdlib in standard C++). atoi: accepts a
string as an argument and returns an integer which is the converted value.
int num = atoi("4123"); //num = 4123
Note: make sure that the size of the character array is enough to hold the converted value.
Exercise:
Write a program that checks whether a given password is strong. Requirements for a
strong password are:
• Minimum of 10 characters
• a mixture of uppercase letters, lowercase letters, digits, and punctuation marks.
• Does not contain whitespace
Case Conversion
There are two functions defined in ctype.h (or cctype) that are used for case conversion.
toupper: returns the uppercase of a character
tolower: returns the lowercase of a character
Arrays of Strings
You can consider a two dimensional array of characters as an array of strings. Example:
const int MONTHS = 13; const int
MAX = 10;
char ourMonths[MONTHS][MAX] = {"Meskerem", "Tikimt", "Hidar", "Tahsas",
"Tir", "Yekatit", "Megabit", "Miazya", "Ginbot", "Sene", "Hamle",
"Nehase", "Pagume"}; for (int i=0;
i<MONTHS; ++i)
cout<<ourMonths[i]<<endl;
Exercise:
Recall that every variable is allocated a section of memory large enough to hold a value of
the variable's data type 1Byte for char, 2Bytes for short and so on. Each byte of memory
has a unique address. A variable's address is the address of the first byte allocated to the
variable. Consider the following declarations
In this example, 1200 is the address of the char variable, letter, 1201 is the address of the
short variable, number, and 1203 is the address of the float variable, amount.
Pointer variables, which are often just called pointers, are designed to hold memory
addresses. With pointer variables you can indirectly manipulate data stored in other
In the above diagram, ptrl points to letter, ptrn points to number, and ptra points to
amount. A pointer is declared as follows.
int *ptrInt;
The above statement defines a pointer to a variable of type int called ptrInt. The asterisk
(*) in front of the variable name indicates that ptrInt is a pointer variable. The int data
type indicates that ptrInt can be used to hold the address of an integer variable. Getting the
address of a variable is accomplished with the address operator (&) in C++. When this
operator is placed in front of a variable name, it returns the address of that variable.
Example:
int x = 10; int
*ptrInt;
ptrInt = &x; //now ptrInt points to the variable x
Pointers allow us to indirectly access and modify the variable being pointed to. When an
asterisk is placed in front of a pointer variable name, it dereferences the pointer it gives
the value of the variable that the pointer is pointing to.
Example:
int x = 10; int *ptrInt =
&x;
cout<<*ptrInt; //displays 10
In this usage, the asterisk is known as the indirection operator.
In the above example, values points to the first element of the array. Therefore, *values
gives us the value of the first element of the array (values [0]).
So far we have been using data types that are built into the C++ language, such as int and
double. However, C++ also allows us to create our own data types. In the remaining
sections of this chapter, we will see the constructs that allow us to define our own data
types.
An enumerated data type is a programmer defined data type that contains a set of named
integer constants.
enum Mood {Depressed, Sad, Happy, Ecstatic};
The declaration shown above creates a data type named Mood. It is called an enumerated
type because the legal set of values that variables of this type can have are enumerated, or
listed, as part of the declaration. A variable of type Mood may only have values that are in
the list inside the braces. These permissible values are called enumerators.
Note that the enum statement above does not actually create any variables it just defines
the data type.
A variable of the Mood type would be defined just like a variable of any other type.
Mood today;
Note that there are no quotation marks around Happy or Ecstatic. These are named
constants, not string literals.
So what exactly is the value of Happy? By default, the first enumerator is assigned the
value 0. Each subsequent enumerator is assigned a value one greater than the value of the
enumerator. Therefore, the symbol Depressed is stored as the integer 0, Sad is stored as
the integer 1, Happy is stored as 2 and Ecstatic is stored as 3. If you don't like the way the
enumerator values are assigned by default, you can explicitly assign a value to an
enumerator. This value need not be unique. As before, in the absence of an explicit
assignment, the value assigned to an enumerator is one greater than its immediately
You can, however, test an enumerated variable by using an integer value instead of a
symbolic name.
Coins b = Asir;
if (b == Asir) //legal cout<<"You have 10
cents"; if (b != 10) //Still legal
cout<<"You don't have 10 cents";
You can in fact use relational operators with enumerators in any way you like. For
example, both usages shown below are legal.
enum Mood {Depressed, Sad, Happy, Ecstatic};
Mood today = Happy, yesterday = Sad; if (today < yesterday)
cout<<"Things are bad, huh? \n";
else
cout<<"Feeling better! \n";
if (today >= 2)
cout<<"You are in a good mood today!\n";
Note: Annoyingly enum types don't behave well with cin and cout statements. cout treats
variables of enum types as integers. A program that attempts to use cin to read a value for
an enumerated type will not compile. Example:
enum cppClasses {Tuesday=2, Saturday=6}; cppClasses
today = Tuesday; cout <<today; //outputs 2
One of the advantages of an enumerated data type is that the symbolic names help make a
program selfdocumenting. The symbolic names may also be used in a switch statement as
they are associated with integer values.
Example:
1. #include <iostream.h>
2. using namespace std;
3.
4. int main ()
5. {
6. enum Mood {Depressed, Sad, Happy, Ecstatic};
7. int ans;
8. cout<<"Mood Companion\n";
9. cout<<"What is your mood today? ";
10. cin>>ans;