Cos1512 202 3 2022

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 26

COS1512/201/0/2022

Tutorial Letter 202/3/2022

Introduction to Programming II
COS1512

School of Computing

This tutorial letter contains the solutions to Assignment 2

BARCODE

Open Rubric
COS1512/202/0/2022

Introduction
By the time you receive this tutorial letter you should have already completed assignment 2 and we hope
that you are well on your way with your studies. This tutorial letter contains the solutions to Assignment
2. You are welcome to e-mail me with any queries at schoema@unisa.ac.za.

Please study this tutorial letter carefully, even if you achieved a good mark. We provide valuable
explanations with each question to help you understand the study material and prepare for the
examination.

Allocation of marks
When we mark assignments, we comment on your answers. Many students make the same mistakes
and consequently we discuss general problems in the tutorial letters. It is, therefore, important to work
through the tutorial letters and to make sure you understand our solutions and where you went wrong.
The maximum number of marks you could obtain for Assignment 2 is 65. This is converted to a
percentage. If you for instance obtained 40 marks for Assignment 2, you received 40/65 * 100 = 62% for
Assignment 2. This percentage in turn contributes a weight of 30% to the year mark, as can be seen in
the summary of the weights allocated to the assignments for COS1512 below.

Assignment number Weight

1 5

2 30

3 35

4 30

We give the mark allocation for the questions below. Please note that this is NOT the way exam answers
will be marked. Note that you were required to include the program code and the input and output for all
the questions. If you did not include the output for your program, you will not get full marks for the
question. We discuss a possible solution for each question below. Please study the solution and the
discussions thoroughly.

We did not mark all the question in detail.

The marks you received for questions 1, 2 and 5 was determined on the following basis:
Question not done 0/5
Question attempted, but the program does not work at all 2/5
A good attempt, but there are a few problems with your answer
(e.g. no output or incorrect output) 3.5/5
The program works correctly and produces the correct output 5/5

2
COS1512/202/0/2022

The marks you received for question 3 was determined on the following basis:
Question not done 0/10
Question attempted, but the program does not work at all 2/10
A good attempt, but there are a few problems with your answer 6/10
The program works correctly and produces the correct output, but
no planning is shown 7/10
The program works correctly, the planning of the program is shown
and the program produces the correct output 10/10

Questions 4 and 6 were not marked in detail.

The marks you received for question 4 was determined on the following basis:
This question was not marked in detail. You were expected to process the text file character by
character. If you did not process the question character by character, you did not get full marks. If you
attempted the question, processed the text file character by character and produced the correct output,
you will get 5 marks. If you did not show how you planned your program but processed the text file
character by character and produced the correct output, you will get 4 marks. If you attempted the
question but did not process the text file character by character or did not show the correct output, you
will get 3 marks. If you attempted the question but did not process the text file character by character,
and did not show the correct output, you will get 2 marks. If you did not attempt the question, you will get
0 marks. Please go through the solution that we give for question 4 to make sure that you understand
how to work with text files.

The marks you received for question 6 was determined on the following basis:
Question not done 0/5
Question attempted, but no output or incorrect output 2/5
The program works correctly and produces the correct output 5/5

The marks you received for question 7 was determined on the following basis:
We marked only questions 7(n), 7(o) and 7(p). We allocated 7 marks to question7(n); 5 marks to
question 7(o) and 7 marks to question 7(p). The exact mark allocation is shown in the solution below.
You also received 6 marks if you answered all of the questions from question 7(a) to question 7(m), and
less according to what you did if you did not answer all of the questions from 7(a) to 7(m). Total number
of marks for question 7 is max 25 marks.

The marks you received for question 8 was determined on the following basis:
Question 8 was not marked in detail. If you answered it, i.e. reflected on your learning experience while
doing this assignment, you received 5 marks. If you did not answer the question, you will get 0 marks.

3
COS1512/202/0/2022

Solution to assignment

Question 1 5 marks

In this question, you were required to write an overloaded function max that takes either two or three
parameters of type double and returns the largest of them. You also had to test the two versions of the
function max in a program to show that the overloading works.

Overloading is a feature in C++ that allows the programmer to define more than one function with the same
name, but with either a different number of function parameters, or with parameters of different types. The
compiler will use either the number of parameters, or the type of parameters to choose which function to
call. The first overloaded function will determine the highest of two numbers, and the second overloaded
function will determine the g=highest of three numbers. The output for the program listing below show
what happens when each of the two overloaded functions are called.

The functions on lines 3 and 9 have the


same function name max(). The
function is overloaded. The difference in
this case is the number of parameters in
these functions. In line 3 the function has
two double parameters and in line 9, three
double parameters. The compiler will use
the number of parameters to decide which
function to call. For instance, when the
function is called with two parameters, it
Program listing: will use the function that starts at line 3.
When max() is called with three double
1. #include <iostream> parameters it will use the function starting
at line 9.
2. using namespace std;

3. double max(double value1, double value2)


4. {
5. if (value1 > value2)
6. return value1;
7. else return value2;
8. }

9. double max(double value1, double value2, double value3)


10. {
11. if ((value1 > value2) && (value1 > value3))
12. return value1;
13. else if ((value2 > value1) && (value2 > value3))
14. return value2;
15. else if ((value3 >value1) && (value3 > value2))
16. return value3;
17. }

18. int main()


19. {
20. double val1, val2, val3;
21. char answer;

4
COS1512/202/0/2022

22. cout << "This program calculates the highest value. You can find the
highest of of either two or three values" << endl << endl;
23. cout << "Do you want to determine the highest of two values? Y/N: ";
24. cin >> answer;

25. if ((answer == 'Y') || (answer == 'y'))


26. {
27. cout << "Please enter two double values separated by a space: ";
28. cin >> val1 >> val2;
29. cout << endl << max (val1, val2) << " is the largest value entered "
<<endl;
30. }
31. else
32. {
33. cout << "Please enter three double values separated by a space: ";
34. cin >> val1 >> val2 >> val3;
35. cout << endl << max(val1, val2, val3) << "is the largest value entered
" <<endl;
36. }

37. return 0;
38. }

Input and corresponding output:

Question 2 5 marks

You were required to write a C++ program that includes a function to calculate the discount applicable on
the price of an item. The function should have three arguments: the price as a reference parameter to a
double, the discount as a double value, and a bool to indicate if the discount is calculated as a
percentage or a fixed amount. The parameter to indicate whether the discount is a fixed amount, or a
percentage, should be called fixed. When fixed is true, it will indicate that the discount is a fixed

5
COS1512/202/0/2022

amount and when it is false, the discount is a percentage. The function should calculate the discount
and modify the price of the item accordingly.

The function should check that the discount is not negative and that the price does not drop to zero or
below zero after applying the discount. You had to use the assert() function to ensure that the discount
is not negative and that the price does not drop to zero or below zero once the discount is applied.

The assert() function evaluates a boolean expression. If the result is 1 (true), the program continues.
If the result is 0 (false), the program aborts with an exception. You did not have to handle the exception
in your program. We just wanted to see that you did get the exception in your output, when the conditions
were not met. To use the assert() function in your program, you must include the cassert header file
in your program:

#include <cassert>

We highlight the use of the assert() function in the program listing below, and show the four sets of
output when the input for the four data sets given in the question, is used.

Program listing :

1 //This program demonstrates using the assert statement to ensure the input
2 //and discount calculation meet certain criteria.
3 //The discount value may not be negative and the price resulting from the
4 //discount may not be 0 or below 0.
5
6 #include <iostream>
7 #include <cassert>

8 using namespace std;

9 double calcDiscount(double price, double discount, bool fixed)


10 {
11 if (fixed)
a. price = price - discount;
12 else price -= discount/100 * price;
13 return price;
14 }

15 int main()
16 {
17 double itemPrice, itemDiscount, discountPrice;
18 char answer;
19 bool fixedDiscount;

20 cout << endl << "Please enter the price and discount separated by spaces
" << endl;
21 cin >> itemPrice >> itemDiscount;
22 cout << "Is the discount a fixed amount or a percentage? Type F for a
fixed amount, P for a percentage:";
23 cin >> answer;

6
COS1512/202/0/2022

The assert function is used to check


that the discount is not negative. If this
criterium is not met, the assert
function will throw an exception error.

24 assert (itemDiscount >= 0);


25 fixedDiscount = (answer== 'f' || answer == 'F');

26 discountPrice = calcDiscount(itemPrice, itemDiscount, fixedDiscount);


27 assert(discountPrice > 0);
The assert function is used to check that
the result of the discount does not produce
28 cout.setf(ios::fixed);
a price equal to or below zero. If this
29 cout.setf(ios::showpoint); criterium is not met, the assert function
30 cout.precision(2); will throw an exception error.

31 cout << "The discounted price for R" << itemPrice << " is R " <<
discountPrice << endl;

32 return 0;
33 }

Output for first set of test data

The first set of input tests a percentage discount.

Output for second set of test data

The second set of input tests a fixed amount as discount.

7
COS1512/202/0/2022

Output for third set of test data

Note the ‘assertion failed’ message for the third set of input where a negative percentage is input for the
discount.

Output for fourth set of test data

Note the ‘assertion failed’ message for the fourth set of input where a fixed amount of R130 discount for
a price of R120 is suggested, resulting in a price below 0.

Question 3 10 marks

For this question, you had to write a program to process a data from a file. We use files when we have
to store large quantities of data, and also when we want to preserve the output from a program.
Typically, we will not know how many data values are stored in a file and have to be processed.
Therefore we use while loops when we process files.

This program had to search for either boy baby names or girl baby names starting with a specific letter
of the alphabet. Names in the input file (Babynames.dat) are ranked according to popularity. Each
line in the input file contains the rank followed by first a boy’s name and then a girl’s name.

Your program had to read the input file line by line, check if the boy name or girl name starts with the
specified letter and if so, output it to an output file PossibleNames.dat.
The first step is to create the input file. We created the input file Babynames.dat by using the CodeBlocks

8
COS1512/202/0/2022

editor and creating a new source file, entering the data, and saving it as a file with an extension of .dat.
(You could also have used Notepad.) Save your input file in the same directory where you save your
program.

The header file for the fstream library has to be added to the code with the
#include <fstream>
directive for file processing.

Though the question does not specify that the output should appear on the console window, we display
the output on the screen and also include code to display the contents of the output file (see the function
checkFile()). The output file can also be viewed in CodeBlocks. This file is opened with File | Open
and by selecting the correct file in the correct directory.

We open the input file BabyNames.dat and the output file, PossibleNames.dat, by associating
the file names with the ifstream and outstream variables, as shown in the statements below:

inFile.open("BabyNames.dat");
if (inFile.fail())
{
cout << "I/O failure opening file BabyNames.dat." << endl;
exit(1);
}

outFile.open("PossibleNames.dat");
if (!outFile)
{
cout << "I/O failure opening file PossibleNames.dat." << endl;
exit(1);
}

We could have used strings to allow the user to specify the file names. Then we would have used string
variables, e.g.

string inName;
cout << "Specify input file name:" << endl;
cin >> inName;

The string names have to be converted to C-strings before we can associate them with the internal
filenames.
infile.open(inName.c_str());

Note that if you create the input file in a directory different from the one where you save your program, you
need to specify the path as well, when specifying the filename, e.g.
C:\unisa\cos1512\BabyNames.dat

When using a file it is essential to test whether the file is available. The following code segment
tests whether the first input file is available before attempting to extract from it:
if (!inFile)
{
cout << "I/O failure opening file BabyNames.dat." << endl;
exit(1);

9
COS1512/202/0/2022

In the above code segment the program is terminated immediately when exit(1) is invoked. We need
to add
#include <cstdlib>
to our program i.e. the header file for the library that contains the exit() function.

To test whether a file is available, we can also use the fail()function:


outFile.open("PossibleNames.dat");
if (outFile,fail())
{
cout << "I/O failure opening file PossibleNames.dat." << endl;
exit(1);
}

The processing is done in the main function. The data from the input file is read line by line,
while (inFile >> rank >> boyname >> girlname) //read input

and then either the boy name or girl name is checked to see whether it starts with the required initial. If a
name starts with the required initial, the name is then written to the output file PossibleName.dat.

The next step is to close the output file. It has originally been opened as an output file. However,
we now want to read it to see if the data was written correctly, which means it now has to serve as
an input file, and we have to open it as an ifstream:

outFile.close();
ifstream inout;
inout.open("PossibleNames.dat");
if (!inout)
{
cout << "Cannot open file " << "PossibleNames.dat" << " Aborting!" << endl;
exit(1);

The function checkFile() is used to read the output file and display its contents on the screen.

void checkFile(ifstream& infile)


void checkFile(ifstream& infile)
{
cout << endl <<"Displaying contents of PossibleNames.dat: " << endl <<endl;
while(infile)
{
string temp; //temporary string to hold records of output file
getline(infile, temp, '\n');
cout << temp <<endl;
}
}

Note that when file streams are passed as arguments to a function, all the input- and output-file streams
need to be reference parameters for the function, since they will all be modified, as can be seen from

10
COS1512/202/0/2022

the prototype given above. The file streams should be passed by reference rather than by value
since the internal state of a file stream object may change with an open operation even if the contents of
the file have not changed. When you declare a reference parameter, the function call will pass the
memory address of the actual parameter, instead of copying the parameter value into the formal
parameter.

Remember to close the files:


inFile.close();
outFile.close();
inout.close();
before exiting the program finally.

Program Listing:
#include <iostream> // for screen/keyboard i/o
#include <fstream> // for files
#include <cstdlib> // for exit, assert

using namespace std;

void checkFile(ifstream& infile)


{
cout << endl <<"Displaying contents of PossibleNames.dat: " << endl <<endl;
while(infile)
{
string temp; //temporary string to hold records of output file
getline(infile, temp, '\n');
cout << temp <<endl;
}
}

int main()
{
ifstream inFile;
ofstream outFile;
char answer, letter;
int rank;
string boyname;
string girlname;

cout << "Do you want to look for a boy or a girl name? B/G ";
cin >> answer;
cout << endl << "What letter should the name start with? ";
cin >> letter;
letter = toupper(letter); //converting letter to uppercase

if (answer == 'b' || answer == 'B') //display heading for output


{
cout << "List of boys names starting with " << letter << endl;
cout << "The popularity ranking of the name is shown before the name"
<< endl;

11
COS1512/202/0/2022

}
else
{
cout << "List of girls names starting with " << letter << endl;
cout << "The popularity ranking of the name is shown before the name"
<< endl;
}

inFile.open("BabyNames.dat");
if (!inFile)
{
cout << "I/O failure opening file BabyNames.dat." << endl;
exit(1);
}

outFile.open("PossibleNames.dat");
if (outFile.fail())
{
cout << "I/O failure opening file PossibleNames.dat." << endl;
exit(1);
}

while (inFile >> rank >> boyname >> girlname) //read input
{
if (answer == 'b' || answer == 'B') //search for boy names
{
if (boyname[0] == letter)
{
cout << rank << ' ' << boyname << endl;
outFile << rank << ' ' << boyname << endl;
}
}
else //search for girl names
{
if (girlname[0] == letter)
{
cout << rank << ' ' << girlname << endl;
outFile << rank << ' ' << girlname << endl;
}
}
}
inFile.close();

outFile.close();
ifstream inout;
inout.open("PossibleNames.dat");
if (!inout)
{
cout << "Cannot open file " << "PossibleNames.dat" << " Aborting!"

12
COS1512/202/0/2022

<< endl;
exit(1);
}
checkFile(inout);
inout.close();

return 0;
}

Input and corresponding output:

Input file:

Output file:

13
COS1512/202/0/2022

Question 4 This question was not marked in detail 5 marks

Discussion:

For this question you had to write a program to remove unnecessary blanks from a text file.
Your program should read the text file and copy it to another text file, but whenever more than
one blank occurs consecutively, only one blank should be copied to the second file.

We did not write a function to perform this task – it is performed by the main function. We did,
however write a function to read and display the input file, as well as the output file that was
created from the input file. It is good programming practice to put the code that does all the reading
and writing together.

When implementing our solution, once again the first step is to create the input file. Since the
purpose of the program is to process files, the #include <fstream> and #include <cstdlib>
directives have to be included in the program in order to use the files and to test that they exist
before they are used. The names of the input and output files are requested from the user. We
did not specify that this had to be done, so you could also have initialized the file names in your
program.

In this program we process the input file as a text file. A text file is typically processed in the following way:
char ch;
infile.get(ch);
while (!infile.eof())
{
//process ch
infile.get(ch);
}

Compare this to the typical way to read a file containing values that should be processed as int, string
or float (as in Question 3), e.g. a file containing one int followed by a string on each line:
int value;
string name;
while (infile >> value >> name)
{
//process value and name
}

After having created the output file, we added some code to read the output file and display the
contents Note that after the output file is created and closed, it now acts as an input file if we
want to read and display its contents. We therefore need an ifstream definition. For this
purpose we defined:
ifstream inout;

This declaration will represent the created output file as an input file. We also pass the name of the output
file to checkFile function:

Note that when file streams are passed as arguments to a function, they need to be reference parameters
for the function, since they will be modified, as can be seen from the header for the function checkFile:
void checkFile(ifstream& infile, string name)

14
COS1512/202/0/2022

The file streams should be passed by reference rather than by value since the internal state of a file stream
object may change with an open operation even if the contents of the file have not changed. When you
declare a reference parameter, the function call will pass the memory address of the actual parameter,
instead of copying the parameter value into the formal parameter.

Also note that we have to close the output file before we can open it again to display the contents on the
screen. The content of the output file can also be viewed with Code::Blocks. This file is opened with File
| Open Project or File and by selecting the correct file in the correct directory.

Program Listing
//Ass 1 question 4
#include <iostream> // for screen/keyboard i/o
#include <fstream> // for file
#include <cstdlib> // for exit
using namespace std;
// Precondition:
// The input file is a text file.
// The input file has been opened.
//
// Postcondition:
// The output file is a text file.
// The output file has been opened.
// Output file will be similar to input file except for all numbers 0 to 7
// that will be replaced with the character as specified in the question
void checkFile(ifstream& infile, string name)
{
cout << endl <<"Displaying contents of " << name << endl <<endl;
while(infile)
{
string temp; //temporary string to hold records of output file
getline(infile, temp, '\n');
cout << temp <<endl; One reads input from a file into your
} program, or send output to a file from your
} program by using streams, or special
objects as they are called in C++. The type
for input-variable streams is named
int main() ifstream, and for output-variable
{ streams, ofstream.
ifstream inFile; One connects the object to the file by
ofstream outFile; opening the file, as is done in the code. We
include the fstream header file as well.
Please see section 6.1 in Savitch for more
string inName, outName;
information.

cout << "Specify input file name:" << endl;


cin >> inName;

inFile.open(inName.c_str());
if (!inFile)
{

15
COS1512/202/0/2022

cout << "I/O failure opening file " << inName << endl;
exit(1);
}

cout << endl << "Enter the output file name. " << endl
<< "WARNING: ANY EXISTING FILE WITH THIS NAME WILL"
<<" BE ERASED." << endl;
cin >> outName;
outFile.open(outName.c_str());
if (outFile.fail())
{
cout << "Cannot open file " << outName << " Aborting!" << endl;
exit(1);
}

char ch;
inFile.get(ch);
while (!inFile.eof())
{
if (ch != ' ')
{
outFile.put(ch);
}
else
{
outFile.put(ch); //write space to output file
while ((ch == ' ') && !inFile.eof()) // read all spaces until a
//character is read
inFile.get(ch);

if (!inFile.eof()) //write last character read to output file


outFile.put(ch);
}
inFile.get(ch);
}

inFile.close();
outFile.close();

ifstream inout;
inout.open(outName.c_str());
if (!inout)
{
cout << "Cannot open file " << outName << " Aborting!"
<< endl;
exit(1);
}

16
COS1512/202/0/2022

checkFile(inout, outName);
inout.close();
return 0;
}

Input and corresponding output 1:

Input and corresponding output 2:

Input.txt

Output.txt

Question 5 5 marks

For this question you had to write a program that reads a word into a C-string (a character array). The
program should then determine whether the word would be a palindrome if we remove the first character
and add it at the back of the word. You had to use only C-string functions and C-strings with a maximum
of 20 characters for each C-string.

17
COS1512/202/0/2022

Note that if a C-string can hold a maximum of 0 characters, we should declare it as


char word[21];
to allow space for the null character (‘\0’) indicating the end of the C-string.

We used the predefined character functions listed in Display 6.9 in Savitch. Note that we had to include
the header file for the library cctype to be able to use these functions:
#include <cctype>

We used the C-string function strlen() to ensure that we do not reference characters past the end of
the string. See e.g.
for (int i =1; i <= strlen(word); i++)
wordAdapted[i-1] = word[i]; //copy all characters in word except
//the first character

We could also have used the null character to ensure that we do not access characters past the ned of
the C-string:
int i = 1;
while (word[i] != '\0')
{
wordAdapted[i-1] = word[i]; //copy all characters in word except
//the first character
i++;
}

We copied the first character in word to a C-string so that we can concatenate it to the end of
wordAdapted:
//add first character in word to end of wordAdapted
char firstChar[2]; //C-string to copy first character in word
strncpy(firstChar, word, 1); //copy 1 character from word to firstChar
strcat(wordAdapted, firstChar); //we can only concatenate C-strings

We could achieve the same effect with this statement:


wordAdapted[strlen(word)] = word[0];

To reverse the adapted word (with the first character in word removed and put at the end of the word), we
made a copy and then used the strrev function:

strcpy(wordReversed, wordAdapted); // copy wordAdapted to wordReverse


strrev(wordReversed); //reverse wordReversed

You also have used the following code segment to reverse wordReversed:
int i,len=0,n;
char temp;
len=strlen(wordReversed);
n=len-1;
for(i = 0; i <=(len/2); i++)
{
temp= wordReversed [i];
wordReversed [i]=wordReversed[n];
wordReversed [n]=temp;
n--;
}
i
}

18
COS1512/202/0/2022

Program listing
#include <iostream>
#include <cstdlib>
#include <cstring> // to use C-strings
#include <cctype> //to use functions that transform characters, e.g.
//isupper()

using namespace std;

int main()
{
char word[21];
char wordReversed[21]; //the reverse of the original word
char wordAdapted[21]; //first letter removed and placed at the end
//of the word

cout << "Please enter the word you want to test: ";
cin >> word;

for (int i =1; i <= strlen(word); i++)


wordAdapted[i-1] = word[i]; //copy all characters in word except
//the first character

//add first character in word to end of wordAdapted


char firstChar[2]; //C-string to copy first character in word
strncpy(firstChar, word, 1); //copy 1 character from word to firstChar
strcat(wordAdapted, firstChar); //we can only concatenate C-strings

strcpy(wordReversed, wordAdapted); // copy wordAdapted to wordReverse


strrev(wordReversed); //reverse wordReversed

if (strcmp(word, wordReversed)) //compare word and wordReversed


cout << word << " is not a palindrome even when " << word
<< " is adapted to " << wordAdapted << endl;
else cout << word << " is a palindrome when " << word
<< " is adapted to " << wordAdapted << endl;

return 0;
}

Output 1:

Output 2:

19
COS1512/202/0/2022

Question 6 This question was not marked in detail 5 marks

For this question, you had to write a program that initialises a vector with the following string values: “what”
“book” “is” “that” “you” “are” “reading”.

The contents of the vector on the screen should be displayed on the screen as a question and the title of
a book the user is reading read as input. The program should then add the title of the book to the vector,
word by word and display the new vector.

Note that we use push_back() to insert an element in a vector.


vector<string> v;
v.push_back("what");
v.push_back("book");
v.push_back("is");
v.push_back("that");
v.push_back("you");
v.push_back("are");
v.push_back("reading");

We could also have initialized the vector in the same way as an array:
vector<string> v{"what", "book", "is", "that", "you", "are", "reading"};

The function size() indicates the number of elements in a vector. We use a for loop to iterate through
the vector to display the elements of the vector:
for (int i = 0; i < v.size(); i++)
cout << v[i] << " ";

We can refer to the elements in a vector in exactly the same way as we refer to the elements in an array,
e.g. cout << v[i];

We read in the title of the book as a string and then added the words in the title one by one to the vector.
We used string functions to extract a word from the title.

Program listing:
#include <iostream>
#include <vector>
using namespace std;

int main()
{
vector<string> v;
string inputString;
string word;
v.push_back("what");
v.push_back("book");
v.push_back("is");
v.push_back("that");
v.push_back("you");
v.push_back("are");
v.push_back("reading");

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


cout << v[i] << " ";

20
COS1512/202/0/2022

//Obtain name of book


getline(cin,inputString);

//split the string into words


int pos = inputString.find(' ');
while (pos > 0)
{
v.push_back(inputString.substr(0, pos)); //insert word into v
inputString.erase(0,pos+1);
pos = inputString.find(' ');
}
v.push_back(inputString); //insert last word in to v

cout << endl << "The new vector:" << endl;


for (int i = 0; i < v.size(); i++)
cout << v[i] << endl;

return 0;
}

Output:

Savitch limits his discussion to popular member functions of the STL vector class, such as push_back,
size, capacity, reserve and resize. However there are other member functions such as:

empty which returns true if the vector is empty and false otherwise

pop_back which removes the last element of a vector

back which returns the last element of the vector.

We could also have used iterators to display the elements in the vector. Note that this uses a pointer *n
to access the elements in the vector:
for (vector<string>::iterator n = v.begin(); n!=v.end();++n)
{
cout << *n << " ";
}
Iterators are beyond the scope of COS1512, but you can find out more about iterators, at this website
Introduction to Iterators in C++ - GeeksforGeeks

21
COS1512/202/0/2022

Question 7 25 marks

NB : Note that we did not mark 5(a) to 5(m) in detail. We allocated 6 marks if you attempted 5(a) to 5(m).
This may mean that you received 6 marks, but your answers are not all correct. Please check your
answers carefully against the solution below.

(a) A pointer is the memory address of a variable. A variable’s address can be thought of as ‘pointing’ to
the variable. See section 9.1 in Savitch.

(b) The deferencing operator is the *operator (the asterisk) used in front of a pointer variable. It
dereferences the pointer variable to produce the variable to which the pointer is pointing to.

(c) Assuming both p1 and p2 have been declared as pointers, i.e. as follows:
int *p1, *p2;
In the assignment statement p1 = p2, the value of one pointer (p2) is assigned to another pointer
(p1) so that the two pointers point to the same memory location. Basically you are working with the
actual pointers (addresses of memory locations). With the assignment statement *p1 = *p2, you
are using the variables to which the pointers are pointing to so that both variables will have the same
value.
(d) A dangling pointer is a pointer variable whose value is undefined, i.e. this means you do not know to
what memory location it points or what the value is to which it is pointing. This is the case when a
pointer has been instantiated (declared as a variable) but not yet assigned a value with the new
operator. It will point to some garbage address by default. It also typically happens when the
delete statement is applied to a pointer variable. If another pointer variable had been pointing to
the same location, that pointer variable also becomes undefined (dangling). A dangling pointer
should never be derefenced.

We can use a null value to indicate that a pointer is not pointing at anything. A pointer holding a null
value is called a null pointer.

In C++, we can assign a pointer a null value by initializing or assigning it the literal 0:

int *ptr1; // ptr1 is uninitialized


ptr1 = 0; // ptr1 is now a null pointer

or we can initialise it to a null pointer when we declare it as follows:


int*ptr1{};

(e) A dynamic variable is a variable that is created and destroyed during the execution of the program. It
is created using the new operator.

(f) The new operator produces a new, nameless variable, with a specified data type and returns a
pointer that point to this new variable. This means that the only way the program can access the
variable is through the pointer pointing to it.

(g) The delete operator eliminates (releases or erases) a dynamic variable and returns the memory
that the dynamic variable occupied to the freestore. It releases the memory so that it can be used for
the creation of new dynamic variables.

22
COS1512/202/0/2022

(h) The freestore (also called the heap) is a special area in memory that is reserved to be used for
dynamic variables.

(i) Dynamic variables are created in a reserved space in memory (the freestore or heap). They are
created and destroyed while the program is running. Automatic variables are automatically created
when the function in which they are declared is called and automatically destroyed when the
function ends. The ordinary variables we use in the programs we write for COS1512 are automatic
variables.

(j) A dynamic array is an array whose size is not specified when it is declared in the program. Instead,
its size is determined while the program is running.

(k) They are flexible in terms of size since the size of the array can be specified during the run time of
the program. This avoids the problem of specifying an array that is too small (not having enough
elements) or too big (wasting computer memory space).

(l) An array variable is a pointer variable that points to the first indexed variable in an array.

(m) Explain what is the difference between int* p1, p2;


and
typedef int* IntPtr;
IntPtr p1, p2;
The first declaration declares p1 as pointer variable pointing to an integer, and p2 as an ordinary
integer.
The second declaration declares both p1 and p2 as pointer variables that can point to integers.

(n) (7)
(i) double *fPtr1, *fPtr2; //declare pointers

(ii) fPtr1 = new double; //create a new dynamic variable and let fPtr1
// point to it

(iii) if (!fPtr2) //if fPtr2 does not point to anything


fPtr2 = fPtr1; //let it point to the same memory address as fPtr1
//alternative:
if (fPtr2 == NULL)
fPtr2 = fPtr1;

(iv) cout << "The address of the object pointed to by fPtr1 is "
<< fPtr1 << endl; //display memory address to which
//fPtr1 points

(v) cout << "The value of the object pointed to by fPtr2 is "
<< *fPtr2;// display value stored at memory address to
//which fPtr2 points

23
COS1512/202/0/2022

(vi) delete fPtr1; // release dynamic variable to which fPtr1 points

(vii) fPtr1 = nullptr; // fPtr1 is now undefined


fPtr2 = 0;// fPtr2 is now undefined
//alternative
fPtr2 = NULL;

(o) (5)
We reflect the state of memory diagrammatically after the statements above each diagram have been
executed:

int value1 = 20;


int value2 = 30;
int *ptr2 = &value1;
int *ptr1 = &value2;

value1 20 value2 30

ptr2 ptr1

✓✓

*ptr1 -= *ptr2;

value1 20 value2 10

ptr2 ptr1

ptr1 = ptr2;

value1 20 value2 10

ptr2 ptr1

cout << *ptr1 << endl;


cout << *ptr2 << endl;

Output:
20
20 ✓

24
COS1512/202/0/2022

It should have been fairly straightforward to follow the diagrams above. If you did not manage to follow
these diagrams, study chapter 9 in Savitch again, and ensure that you know what each of the statements
used in this program segment means.

(p) (7)
Program:
For this question, each sub-question is indicated by a comment, followed by the answer to the
sub-question in the program listing below.

Program listing:
#include <iostream>
using namespace std;
int main()
{
//(i)
typedef int* int_ptr; (1)

//(ii)
int_ptr p2; (1)

//(iii)
int nrElements;
cout << "Please enter the number of elements to allocate to the "
<< "array: ";
cin >> nrElements; (1)

//(iv)
p2 = new int [nrElements]; (1)

//(v)
int a[500]; (1)

//(vi)
for (int i =0; i < nrElements; i++)
a[i] = p2[i]; (1)

//(vii)
delete [] p2; (1)

return 0;
}

Output:

25
COS1512/202/0/2022

Question 8 5 marks

Question 8 was not marked in detail. If you answered it, i.e. reflected on your learning experience while
doing this assignment, you received 5 marks. If you did not answer the question, you will get 0 marks. We
used your proof that you did the form (e.g. e-mail receipt) to determine your mark for this question.

Unisa 2022

26

You might also like