1 Array and Record
1 Array and Record
Contents
Arrays ............................................................................................................................................................ 1
One dimensional array .............................................................................................................................. 1
Reversal problem .................................................................................................................................. 2
Passing Arrays as Arguments ................................................................................................................ 4
Array Copying ........................................................................................................................................ 6
Array Comparison ................................................................................................................................. 6
Returning Array as Function Value ....................................................................................................... 6
Two dimensional array.............................................................................................................................. 7
Sales report example ............................................................................................................................ 7
Simulating Two-dimensional Arrays by One-dimensional Arrays ....................................................... 12
Multi-dimensional array ......................................................................................................................... 13
Simulating Multi-dimensional Arrays by One-dimensional Arrays ..................................................... 14
Records (struct) ........................................................................................................................................... 16
Library catalog example .......................................................................................................................... 16
Arrays of records ..................................................................................................................................... 19
Arrays in Records .................................................................................................................................... 20
Arrays
One dimensional array
Composite date type (or aggregate data type): A data type is composite if we store more than one
values under a same variable name.
Homogenous datatype: A composite data type is homogenous if all the values are of same type.
Heterogeneous datatype: A composite data type is heterogeneous if all the values are not same type.
Structured datatype: A composite data type is structured if order of the values matters.
Structured datatype: A composite data type is unstructured if order of the values does not matter.
Page 1 of 21
Reversal problem
Example: Write a C++ program that takes 1000 integers as input and prints the same set of numbers in
reversed order.
int main()
{
int value0;
int value1;
int value2;
.
.
.
int value999;
return 0;
}
This program is difficult to maintain. What happens if we decide to process 1200 elements rather than
1000 later? We can handle such sceneries by using array.
An array is a composite data type, where all components have the same data type and the components
can be uniquely identified by integer expressions that we call index.
Page 2 of 21
The following is an array-based solution for the reversal problem above.
#include <iostream>
using namespace std;
int main()
{
int a[1000]; // Array declaration
return 0;
}
The above is not good programming style. We want to be able to change the size of input with ease.
#include <iostream>
using namespace std;
int main()
{
int a[N]; // Array size must be constant expression
return 0;
}
Page 3 of 21
Passing Arrays as Arguments
Example: Write a C++ function, called sumArray, that takes two parameters as input. First parameter is
an array of integer values. Second parameter is the size of the array. The function returns the sum of
the array elements.
#include <iostream>
using namespace std;
int main()
{
int a[] = { 3, 24, -88, 17, -1 }; // Array initialization
cout << sumArray(a, 5) << endl;
}
Note that array arguments are always automatically passed by reference. No special notation is required
to pass arrays by reference.
// int sumArray(int& a[], unsigned int n) - INCORRECT
int sumArray(int a[], unsigned int n) // CORRECT
{
...
}
-The interface is not safe, i.e., the function body may modify the content of the array a. A much better
function interface is the following.
int sumArray(const int a[], unsigned int n)
{
...
}
-This implementation works for arrays of all sizes. Array size is simply passed in as a separate argument.
Array dimension can be omitted in array initialization syntax. Doing so renders the function reusable for
arrays of all sizes. The array size (5) has to be specified explicitly in the current implementation. A more
maintainable way of writing it is the following.
int main()
{
int a[] = { 3, 24, -88, 17, -1 };
cout << sumArray(a, sizeof(a) / sizeof(int)) << endl;
}
Page 4 of 21
Example: Write a C++ function, called isArraySorted, that takes two input parameters. First parameter
is an array of integer. The second parameter is the size of the array. isArraySorted returns true if the
array is sorted in ascending order, otherwise it returns false. [Note that an array is sorted in ascending
order if every component (except the last) is smaller than (or equals to) the next one.]
bool isArraySorted(const int a[], unsigned int n)
{
for (int i = 0; i < n-1; i++)
{
if (a[i] > a[i+1])
return false;
}
return true;
}
Example: Write a C++ function, called reverseArray, that takes two input parameters. First parameter is
an array of integer values. The second parameter is the size of the array. reverseArray reverses the
elements in the array.
void swap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
Exercise: A palindrome is an array of integers such that reversing the array does not change its value.
For example, the following array is a palindrome.
1 2 7 7 2 1
5 1 0 3 0 1 5
5 1 1 0 0 5
Write a C++ function, called isPalindrome, that has two input parameters. First parameter is an array of
integer values. Second parameter is the size of the array. isPalindrome returns true if the array is a
palindrome, otherwise it returns false.
Page 5 of 21
Array Copying
Example: Write a C++ function, called CopyArray, that takes two integer arrays of same size as input
and copies the first array to the second array. Assume that NUMER_OF_ELEMENTS is a global constant
that indicates the array size.
Array Comparison
Example: Write a C++ function, called IsEqual, that takes two integer arrays of same size as input. The
function returns true if the arrays are same, otherwise it returns false. Assume that
NUMER_OF_ELEMENTS is a global constant that indicates the array size.
return true;
}
Page 6 of 21
Two dimensional array
One-dimensional arrays are good for occasions in which a single index is sufficient for addressing
elements of the array. A two-dimensional array supports efficient and convenient addressing of
elements with two indices.
(f) What is the total sales for all products and all regions?
(g) For the array, write a program that reads the sales figures from the standard input, and then prints
the total sales of product 0 over all four regions.
(h) For the array, write a program that prints the total sales in region 2.
(i) For the array, write a program that prints the total sales for each product.
(j) For the array, write a program that prints the total sales in each region.
(k) For the array, write a program that prints the total sales.
(l) For the array, write a function that prints the total sales of a given product over all four regions.
(m) For the array, write a function that returns the total sales in a given region.
(n) For the array, write a function that prints the total sales for each product.
(o) For the array, write a function that prints the total sales in each region.
(p) For the array, write a function that returns the total sales.
(q) For the array, write a function that returns the sales for every product in every region.
(r) For the array, write a function that returns the value of one element from the sales array, in
particular, the element representing the sales in region r of product p.
(s) For the array, write a function that sets the value of one element of the sales array; in particular, it
should set the element representing the sales in region r of product p to the value v.
Page 7 of 21
(a)
For example:
0 1 2
0 40 28 30
1 52 19 12
2 17 27 39
3 11 21 33
(d)
Product sales
0 40+52+17+11
1 28+19+27+21
2 30+12+39+33
(e)
Region sales
0 40+28+30
1 52+19+12
2 17+27+39
3 11+21+33
(g)
Page 8 of 21
for (unsigned int region = 0; region < NUM_OF_REGIONS; region++)
{
for (unsigned int product = 0; product < NUM_OF_PRODUCTS; product++)
{
cin >> Sales[region][product];
}
}
(h)
unsigned int total_sales = 0;
for (unsigned int product = 0; product < NUM_OF_PRODUCTS; product++)
{
total_sales += sales[2][product];
}
(i)
for (unsigned int product = 0; product < NUM_OF_PRODUCTS; product++)
{
unsigned int total_sales = 0;
for (unsigned int region = 0; region < NUM_OF_REGIONS; region++)
{
total_sales += sales[region][product];
}
cout << “total sales for product ”<< product <<”is ”<<
total_sales << endl;
}
Page 9 of 21
(j)
for (unsigned int region = 0; region < NUM_OF_REGIONSS; region++)
{
unsigned int total_sales = 0;
for(unsigned int product=0; product < NUM_OF_PRODUCTS; product++)
{
total_sales += sales[region][product];
}
cout << “total sales in region ”<< region <<”is ”<< total_sales
<< endl;
}
(k)
unsigned int total_sales = 0;
for (unsigned int region = 0; region < NUM_OF_REGIONSS; region++)
{
for(unsigned int product=0; product < NUM_OF_PRODUCTS; product++)
{
total_sales += sales[region][product];
}
}
cout << “total sales is ”<< total_sales << endl;
(l)
unsigned int sumProductSales(const unsigned int sales[][], unsigned
int product)
{
unsigned int total_sales = 0;
for(unsigned int region = 0; region < NUM_OF_REGIONS; region++)
{
total_sales += sales[region][product];
}
return total_sales;
}
(m)
unsigned int sumRegionsSales(const unsigned int sales[][], unsigned
int region)
{
unsigned int total_sales = 0;
Page 10 of 21
for(unsigned int product = 0; product < NUM_OF_PRODUCTS;
product++)
{
total_sales += sales[region][product];
}
return total_sales;
}
(n)
void ProductSales(const unsigned int sales[][] )
{
cout<<’Product number’<<’ ‘<<’total sales’<<endl;
(o)
void SalesInRegion( unsigned int sales[][] )
{
cout<<’Region number’<<’ ‘<<’total sales’<<endl;
Page 11 of 21
(p)
unsigned int sumSales(const unsigned int sales[][])
{
unsigned int total_sales = 0;
for (unsigned int region = 0; region < NUM_OF_REGIONS; region++)
{
for(unsigned int product = 0; product < NUM_OF_PRODUCTS;
product++)
{
total_sales += sales[region][product];
}
}
return total_sales;
}
(q) similar.
(r) similar.
(s) similar.
Recall that the two-dimensional array sales contains numOfRegions × numOfProducts elements.
Let us then declare a one-dimensional array _sales that holds all elements in sales.
unsigned int _sales[NUM_OF_REGIONS * NUM_OF_PRODUCTS];
We then need to decide how elements from the two-dimensional array sales should be represented in
its one-dimensional form _sales. As we shall see, the following layout scheme is appropriate.
_sales[0] sales[0][0]
_sales[1] sales[0][1]
_sales[2] sales[0][2]
_sales[3] sales[1][0]
_sales[4] sales[1][1]
_sales[5] sales[1][2]
_sales[6] sales[2][0]
_sales[7] sales[2][1]
_sales[8] sales[2][2]
_sales[9] sales[3][0]
_sales[10] sales[3][1]
_sales[11] sales[3][2]
Page 12 of 21
In essence, we line up the elements from row 0 first, then row 1, row 2, and so on. Such a layout, in
which a row is stored together is convenient for accessing. With this layout, retrieving the element at
row i and column j involves the evaluation of the following expression.
For example, total sales can be computed with the following program fragment.
unsigned int totalSales = 0;
No professional programmer will ever write a program in this way. Two-dimensional arrays give us a
cleaner syntax and more comprehensible abstraction to work with. Yet, the above simulation example
offers us a deeper understanding of how two-dimensional arrays are organized in computer memory. In
fact, the compiler implicitly translates two-dimensional array code into one-dimensional array code like
the simulation shown above.
Multi-dimensional array
Two-dimensional arrays are the simplest type of multi-dimensional arrays. In general, a multi-
dimensional array (or n-dimensional array for n > 1) supports efficient and convenient addressing of
elements with n indices.
Example: Recall the sales example. Let's say the sales data is accumulated across two years, i.e., year is
another dimension.
(a) Redefine the Sales array in order to cope with the added complexity.
const unsigned int NUM_OF_YEARS = 2;
const unsigned int NUM_OF_REGIONS = 4;
const unsigned int NUM_OF_PRODUCTS = 3;
unsigned int
Sales[NUM_OF_YEARS][NUM_OF_REGIONS][NUM_OF_PRODUCTS];
Page 13 of 21
(b) Write a function sumSales(const Sales sales) that returns the total sales.
unsigned int sumSales(const Sales sales)
{
unsigned int total_sales = 0;
for (unsigned int year = 0; year < NUM_OF_YEARS; year++)
{
for (unsigned int region = 0; region < NUM_OF_REGIONS;
region++)
{
for (unsigned int product = 0; product < NUM_OF_PRODUCTS;
product++)
{
total_sales += sales[year][region][product];
}
}
}
return total_sales;
}
int main()
{
const unsigned int NUM_OF_YEARS = 2; // d1
const unsigned int NUM_OF_REGIONS = 4; // d2
const unsigned int NUM_OF_PRODUCTS = 3; // d3
// declaration would be
int my_array[NUM_OF_YEARS][NUM_OF_REGIONS][NUM_OF_PRODUCTS];
// i * NUM_OF_PRODUCTS * NUM_OF_REGIONS +
// j * NUM_OF_PRODUCTS +
// k
Page 14 of 21
cout
<< "i = " << setw(2) << i << ", "
<< "j = " << setw(2) << j << ", "
<< "k = " << setw(2) << k << ", "
<< "(i * NUM_OF_PRODUCTS * NUM_OF_REGIONS) + (j *
NUM_OF_PRODUCTS) + k = "
<< setw(3)
<< (i * NUM_OF_PRODUCTS * NUM_OF_REGIONS) + (j *
NUM_OF_PRODUCTS) + k
<< endl;
}
}
}
}
The output of the above program is shown below:
Page 15 of 21
Records (struct)
Library catalog example
Example: Suppose we are developing a C++ program for storing and tracking the catalog information of
a library collection. Let's say every catalog entry is composed of the following components.
Title string
Author string
Publisher string
Publishing Year unsigned int
Call Number string
(a) Declare necessary variables in order to store one collection.
string titles;
string authors;
string publishers;
unsigned int publishingYears;
string callNumbers;
void printCatalogEntry(const string& title, const string& author, const string& publisher,
unsigned int publishingYear, const string& callNumber)
{
cout<< title << endl;
cout<< author << endl;
cout<< publisher << endl;
cout<< publishingYear << endl;
cout<< callNumber << endl;
}
This program looks ugly as, every time we need to invoke the function, a large number of arguments
must be supplied. Not only is this inefficient (the invocation record would be big), but it is also error
prone (programmers will have to make sure they are passing the arguments in the right order).
Note that the variables are related to each other, i.e., the five attributes are part of a single catalog
entry. Instead of declaring the variables separately, we can group together and form a composite data
type (which is heterogeneous and unstructured).
Page 16 of 21
Example: Suppose we are developing a C++ program for storing and tracking the catalog information of
a library collection. Let's say that every catalog entry is composed of the following components.
Title string
Author string
Publisher string
Publishing Year unsigned int
Call Number string
(a) By considering all catalog variables are related, declare a structure (called Catalog) in C++ to
represent a catalog.
struct Catalog
string titles;
string authors;
string publishers;
unsigned int publishingYears;
string callNumbers;
};
Catalog c;
(c) Assign title = “OOP”, author = “John”, publisher = “UR Press”, publishing = 2005, and call number =
“QA100” to c.
c.titles = “OOP”;
c.authors = “John”;
c.publishers = “UR Press”;
c.publishingYears = 2005;
c.callNumbers = “QA100”;
Page 17 of 21
Example: You are given the following structure.
struct Catalog
string titles;
string authors;
string publishers;
unsigned int publishingYears;
string callNumbers;
Two instances of Catalog are c1 and c2. Write a function (called IsEqual) that takes c1 and c2 as
parameters, and returns true if c1 and c2 are same. Otherwise, it returns false.
struct Catalog
string titles;
string authors;
string publishers;
unsigned int publishingYears;
string callNumbers;
Design and implement a C++ function that returns true if and only if two given Catalog instances are
not equal.
Page 18 of 21
Example: You are given the following structure.
struct Catalog
string titles;
string authors;
string publishers;
unsigned int publishingYears;
string callNumbers;
Design and implement a C++ function that returns true whenever two given Catalog instances are just
different copies of the same title.
Arrays of records
Example: You are given the following structure.
struct Catalog
string titles;
string authors;
string publishers;
unsigned int publishingYears;
string callNumbers;
Catalog A[30];
(b) Assigns author of first 10 catalogs to “AAA”, second 10 catalogs to “BBB”, and third 10 catalogs to
“CCC”.
A[i].author = “AAA”;
A[i].author = “BBB”;
A[i].author = “CCC”;
Page 19 of 21
(c) Assigns title of each catalog to “CS115-xx”, where xx is array index.
(e) Assigns publishing year of each catalog to “19xx”, xx is the index of array.
A[i].publishingYears = 1900 + i;
cout<<A[i].title<<endl;
Arrays in Records
Example: Suppose an existing record defined a FullName as a combination of a first name and a last
name:
struct FullName
{
string first_name;
string last_name;
};
Now, we want to generalize this record to allow full names consisting of any number of names up to
100.
Page 20 of 21
(a) Declare a structure that captures the idea above.
(b) Declare an instance (called SampleNames) of AllFullNames that represents the names of a person.
Assume that, initially, the person has no name.
AllFullNames SampleNames;
SampleNames.count = 0;
(c) Assume that the person has 26 names, which are A, B, …, Z. Assign these names to SampleNames in
chronological order, i.e., A is the oldest name and should be assigned first. [You should use a loop that
occurs 26 times, instead of manually assigning 26 times].
SampleNames.name[i] = ‘A’ + i;
SampleName.count++ ;
Page 21 of 21