0% found this document useful (0 votes)
10 views266 pages

Programming Using C++ - With Cover

The document outlines a course titled 'Programming Using C++' designed to teach students the C++ programming language and its fundamental concepts. It includes a detailed course outline covering topics such as programming basics, arrays, strings, pointers, functions, structures, and file management, along with practical exercises and assessments. The course targets technical teacher education for TVET B-level trainers and requires a basic understanding of computer programming.

Uploaded by

Tirusew Chekol
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views266 pages

Programming Using C++ - With Cover

The document outlines a course titled 'Programming Using C++' designed to teach students the C++ programming language and its fundamental concepts. It includes a detailed course outline covering topics such as programming basics, arrays, strings, pointers, functions, structures, and file management, along with practical exercises and assessments. The course targets technical teacher education for TVET B-level trainers and requires a basic understanding of computer programming.

Uploaded by

Tirusew Chekol
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 266

Programming Using C++

Mahlet Teklay

January 2023
)

Technical and Vocational Training Institute (TVTI)


Programming Using C++

Mahlet Teklay

Department of Information and Communication


Technology

January 2023

Technical and Vocational Training Institute (TVTI)


Yeka Subcity, Woreda 9, Addis Ababa, Ethiopia
Phone: 011-646-4455, Fax: 011-646-5675/5678
E-mail: [email protected], Website: http://www.etu.edu.et
TABLE OF CONTENTS

Course Profile ......................................................................................................................................... 1


Detailed Course Outline .......................................................................................................................... 2
Chapter 1: Overview of Programming Basics .................................................................................... 5
Week 1: ................................................................................................................................................... 7
1.1 Structure of C++ Program ........................................................................................................... 7
1.2 Keywords, Identifiers, Inputs, Outputs, Comments .................................................................... 7
1.3 Data Types, Variables, and Constant variables ........................................................................... 9
1.4 Operators ................................................................................................................................... 14
Week 1:- Practice: ............................................................................................................................... 22
Assessments ......................................................................................................................................... 24
Week 2: ................................................................................................................................................ 26
1.5 Control Statements .................................................................................................................... 26
1.5.1 Sequential Statements ............................................................................................................... 26
1.5.2 Selection Statements ................................................................................................................. 26
1.5.3 Looping Statements .................................................................................................................. 29
Week 2:- Practice: ............................................................................................................................... 37
Assessment ........................................................................................................................................... 42
Reference .............................................................................................................................................. 45
Chapter 2: Arrays and String Manipulation .................................................................................... 47
Week 3: ................................................................................................................................................. 49
2.1 Introduction ............................................................................................................................... 49
2.2 What is an array? ...................................................................................................................... 50
2.3 One Dimensional Array ............................................................................................................ 50
2.3.1 Declaration of one Dimensional Array ..................................................................................... 51
2.3.2 Accessing Array Elements ........................................................................................................ 52
2.3.3 Initialization of arrays ............................................................................................................... 55
Week 3:- Practice: ................................................................................................................................. 61
Assessments ......................................................................................................................................... 65
Week 4: ................................................................................................................................................. 66
2.4 Multidimensional arrays ........................................................................................................... 66
2.4.1 Initializing Multidimensional Arrays ........................................................................................ 68
2.4.2 Omitting the Array Size ............................................................................................................ 69

i
Week 4:- Practice: ............................................................................................................................... 70
Assessments ......................................................................................................................................... 83
Week 5: ................................................................................................................................................. 84
2.5 Strings representation and manipulation ................................................................................... 84
2.5.1 Initialization of Strings.............................................................................................................. 85
2.5.2 Assigning Values to Strings ...................................................................................................... 86
2.5.3 String Output............................................................................................................................. 89
2.5.4 String Input ............................................................................................................................... 90
2.5.5 Reading multiple lines .............................................................................................................. 91
2.5.6 String constants ......................................................................................................................... 91
Week 5: Practice ................................................................................................................................... 93
Assessment ........................................................................................................................................... 99
Reference ............................................................................................................................................ 101
Chapter 3: Pointers ........................................................................................................................... 103
Week 6: ............................................................................................................................................... 104
3.1 Pointers Introduction ............................................................................................................... 104
3.2 Declaring Pointers ................................................................................................................... 109
3.3 Assigning values to pointers ................................................................................................... 109
3.4 Pointer to void ......................................................................................................................... 110
Week 6:- Practice ................................................................................................................................ 111
Assessment ......................................................................................................................................... 114
Week 7: ............................................................................................................................................... 115
3.5 Arrays of Pointers ................................................................................................................... 115
3.6 Pointer and arrays ................................................................................................................... 115
3.7 Pointer Advantage ................................................................................................................... 116
Week 7:- Practice ................................................................................................................................ 122
Assessments ....................................................................................................................................... 127
Reference ............................................................................................................................................ 128
Chapter 4: Function (Built in, User defined) .................................................................................. 129
Week 9: ............................................................................................................................................... 130
4.1 Modular programming and Modules ...................................................................................... 130
4.2 Declaring and Defining Functions .......................................................................................... 130
4.3 Defining the Function ............................................................................................................. 132
4.4 Scope of variables ................................................................................................................... 134
Week 9:- Practice ................................................................................................................................ 138
Assessments ....................................................................................................................................... 145

ii
Week 10: ............................................................................................................................................. 146
4.5 Function Arguments................................................................................................................ 146
4.6 Passing arguments ................................................................................................................... 147
4.7 Return Values.......................................................................................................................... 150
4.8 Default Parameters .................................................................................................................. 150
Week 10:- Practice .............................................................................................................................. 152
Assessment ......................................................................................................................................... 159
Week 11: ............................................................................................................................................. 162
4.9 Overloaded Functions ............................................................................................................. 162
4.10 Inline Functions ...................................................................................................................... 163
4.11 Recursive Functions ................................................................................................................ 165
Week 11 :- Practice ............................................................................................................................. 167
Assessment ......................................................................................................................................... 175
Reference ............................................................................................................................................ 179
Chapter 5: Structure......................................................................................................................... 181
Week 12 : ............................................................................................................................................ 182
5.1 Record: - Structure .................................................................................................................. 182
5.1.1 Structure .................................................................................................................................. 182
5.1.2 struct Specification: Defining Structures ................................................................................ 183
5.1.3 Declaring and using sturct data types ..................................................................................... 184
5.1.4 Initializing Structure Variables ............................................................................................... 185
5.1.5 Accessing members of a structure variable ............................................................................. 186
Week 12: Practice ............................................................................................................................... 187
Assessment ......................................................................................................................................... 194
Week 13: ............................................................................................................................................. 196
5.2 Array of structs ....................................................................................................................... 196
Week 13:- Practice .............................................................................................................................. 207
5.3 C++ Pointers to Structure........................................................................................................ 207
5.4 Pointers and Arrays ................................................................................................................. 208
Week 14: ............................................................................................................................................. 215
5.5 Passing Structure to Function ................................................................................................. 215
5.6 Returning Structures from Functions in C++ .......................................................................... 218
Week 14:- Practice: ............................................................................................................................. 221
Reference ............................................................................................................................................ 229
Chapter 6: File Management ........................................................................................................... 231
Week 15: ............................................................................................................................................. 232

iii
6.1 File Management Introduction ................................................................................................ 232
6.2 Streams and Files .................................................................................................................... 232
6.3 The standard streams............................................................................................................... 233
6.4 C++ File I/O Classes and Functions ....................................................................................... 233
6.5 Text and Binary Files .............................................................................................................. 234
6.6 Text File processing ................................................................................................................ 234
6.7 Reading from a File ................................................................................................................ 238
6.8 File Pointer and their Manipulators ........................................................................................ 240
6.9 Binary File processing ............................................................................................................ 243
6.10 Random Access Files .............................................................................................................. 248
Week 15 :- Practice: ............................................................................................................................ 251
Assesement ......................................................................................................................................... 254
Reference ............................................................................................................................................ 255

iv
Course Profile
Department Information Technology
Course title Programming Using C++

This course is designed to teach students C++ programming language and


introductory and intermediate programming concepts with examples and
Course applications using the C++ language. The class introduces the basic concepts,
principles, methods, implementation techniques, and applications of the C++. Details
description of the syntax of the C++ programming language including keywords, operators,
Loops, Arrays, Functions, String manipulation, pointers, structure and file handling
are covered in depth.
• Have an understanding of the concept and application of iteration and recursion
in program development;
• Describe and implement the concepts of modular programming (functions) in
solving problems.
Course • Describe and implement the concepts of Structures in solving problems.
• Describe how to manage files using C++.
Objective
• Be able to uncover and reason about repetitive aspects of a computing problem,
and to develop appropriate recursive or iterative solutions;
• Understand the specification of a program and its implementation as separate, but
related design problems.
• Know, understand and implement the basic concepts and tools in C++.
• Remind of basics programming.
• Describe and implement the concepts of modular programming in solving
• problems.
Learning
• Describe and implement the concepts of Structures in solving problems.
outcomes
• Describe how to manage files using C++.
• Explain the concept and application of iteration and recursion in program
development;
Pre-requisite Basic Computer Programming (ITec 1030)
Target group Technical teacher education for TVET B-level trainer.

1
Detailed Course Outline
Topics to be covered Topics to be covered Required materials
Week Outcomes
(2 lecture hours) (3 lab hours) /equipment/devices
Chapter 1: Overview of programming basics
Basics of C++ • Installing a C++ IDE 5.1.1 PC, C++ compiler
Structure of C++ Program; • Visualize the structure LaserJet Printers
Keywords, Identifiers, Inputs, of a C++ program LCD Projectors
Outputs, Comments, environment
Parts of a program; Data Types, • Lab experiment to see
Variables, and Constants all the operators in
Operators; Assignment action inside a C++
1 program
Operators; Compound
Assignment Operators; • Declaring a variable
Arithmetic Operators; with the correct choice
Relational Operators; of data types
Increment and Decrement
Operators; Infix and postfix
types; Precedence of Operators
• if statements 5.1.1 PC, C++ compiler
implementation syntax 5.22 LaserJet Printers
Control Statements Looping • switch Statements LCD Projectors
2 Statements: for, while, do, break, implementation syntax
continue; nested loops • for loop, while loop
and do while loop
implementation syntax
Chapter 2: Arrays and String Manipulation
• one dimensional array 5.2.3 PC, C++ compiler
declaration LaserJet Printers
Array Definition: • Accessing content of LCD Projectors
3 one dimensional and one-dimensional array
multidimensional arrays cycle • Displaying the content
of one-dimensional
array using loops.
• Displaying the content 5.2.3 PC, C++ compiler
of two-dimensional LaserJet Printers
Application of array (array array using loops.
4 LCD Projectors
sorting, matrix) • Array traversing
• Array sorting
• string declaration in C 5.2.3 PC, C++ compiler
style LaserJet Printers
• string declaration in LCD Projectors
Strings:
C++ style
5 Accessing strings
• Accessing and
manipulating strings
• Apply string built in
functions
Chapter 3: Pointers

2
6 Address-of operator • Pointer declaration 5.1.4 PC, C++ compiler
Dereference operator • Pointer initialization LaserJet Printers
Declaration of pointers LCD Projectors
Arrays and pointers
7 Pointers arithmetic, variable • Dynamic memory 5.2.3 PC, C++ compiler
access, strings, pointer to allocation and other LaserJet Printers
pointers, invalid pointer and null concepts related with LCD Projectors
Pointers and pointer to function pointers
8 Review of the above topics Midterm Exam
Chapter 4: Function (Built in, User defined)
9 Introduction to Modular • Use different built in 5.2.4 PC, C++ compiler
programming (Functions) functions in C++ 5.1.3 LaserJet Printers
Scope of Variables • Declaration of LCD Projectors
function
• Definition of functions
• Calling function
10 Function Arguments • How to pass 5.2.4 PC, C++ compiler
Return Values Parameters by value 5.1.2 LaserJet Printers
Default Parameters • How to pass 5.1.3 LCD Projectors
Parameters passing Parameters by
reference
11 Function Overloading • How to use recursive 5.2.4 PC, C++ compiler
Recursive function functions LaserJet Printers
Inline function • Declaring inline LCD Projectors
functions
Chapter 5: Structures
12 Introduction • Declaring structure 5.2.4 PC, C++ compiler
Overview of Structure • Defining structure in LaserJet Printers
Array of structure structure LCD Projectors
Nested structure
13 Structure, Reference and Pointer • Initializing structure 5.2.4 PC, C++ compiler
• Manipulating structure LaserJet Printers
LCD Projectors
14 Passing structure to function • Passing value of 5.2.4 PC, C++ compiler
structure to a function LaserJet Printers
• Passing address of a LCD Projectors
structure to a function
Chapter 6: File Management
15 Streams and Files Text and • Creating a file in PC, C++ compiler
Binary Files different modes 5.1.6 LaserJet Printers
Binary File processing • Reading from file 5.2.5 LCD Projectors
Random Access Files • Writing on existed
Buffers and Synchronization files
• Text File processing
16 Final Examination period

3
4
Chapter 1: Overview of Programming Basics

Lesson Plan
1. Learning objectives

• Be able to define variables, operators.

• Be able to differentiate different data types.

• Be able to install DEV C++ software.

• Be able to know the complete development cycle of C++.

• Be able to apply the concept and application of iteration and recursion in program
development.
2. Motivation

• Outputs through Question and Answer; repetitive discussion and instruction of the C++
programming basics; individual internet search.

• Solving a problem using programming language C++.

• Controlling the flow control of instruction execution.


3. Expectations or Outcomes
 Define the terminologies, differentiate different data types, explain variables; the
assessment standard attached at the end of the job task sheet.
 Can write C++ instructions to solve any problem using programming.
 Controlling the flow control of the instructions written using C++ programming
language.
4. Equipment

• Desktop or Laptop computer.

• DEV C++ software


5. Practice contents/Activities/Safety
 Brief introduction of C++ complete development life cycle (C++ IDE).
 Active practice; on declaring variables, writing C++ instructions (Editing), compilin
g, executing.
 Active practice on applying selective and looping statements in the program.

5
6. Assessments
• How to declare variables?
• How to apply flow control in programming?
• How can you install DEV C++ software?
7. Clean-up
 After finishing practice, computers should be properly shut down.
8. Independent practice/Follow-up activities

• Learning through assignment (practical exercises)


9. Review/Reflection

• Review the outcome of the practice, improvement measure and previous reflected
opinions.

6
Week 1:
1.1 Structure of C++ Program
A C++ program has the following structure
[Comments]
[Preprocessor directives]
[Global variable declarations]
[Prototypes of functions]
[Definitions of functions]

1.2 Keywords, Identifiers, Inputs, Outputs, Comments


Keywords (reserved words)
Reserved/Key words have a unique meaning within a C++ program. These symbols, the
reserved words, must not be used for any other purposes. All reserved words are in lower-case
letters.
Table 1.1: Some reserved words of C++

Asm Auto Bool break case catch

const_cast Class Const char continue default

dynamic_cast Do Double delete else enum

Explicit extern False float for friend

Goto If Inline int long mutable

Namespace New Operator private protected public

reinterpret_cast register Return short signed sizeof

static_cast Static struct switch template this

Throw True Try typedef typeid typename

Union unsigned Using virtual void volatile

Notice that main is not a reserved word. However, this is a fairly technical distinction, and for
practical purposes you are advised to treat main, cin, and cout as if they were reserved as well.

7
Identifiers
An identifier is name associated with a function or data object and used to refer to that function
or data object. An identifier must:
▪ Start with a letter or underscore
▪ Consist only of letters, the digits 0-9, or the underscore symbol _
▪ Not be a reserved word
Syntax of an identifier
Letter

Letter
- Digit
-

For the purposes of C++ identifiers, the underscore symbol, _, is considered to be a letter. Its
use as the first character in an identifier is not recommended though, because many library
functions in C++ use such identifiers. Similarly, the use of two consecutive underscore symbols,
_ _, is forbidden.

Table 1.2: Valid identifiers

Length days_in_year DataSet1 Profit95

Stud_name _Pressure first_one first_1

Table 1.3: Invalid i d e n t i f i e r s

days-in-year 1data Int first.val

Throw my__best No## bestWish!

Although it may be easier to type a program consisting of single character identifiers,


modifying or correcting the program becomes more and more difficult. The minor typing effort
of using meaningful identifiers will repay itself many fold in the avoidance of simple
programming errors when the program is modified.
At this stage it is worth noting that C++ is case-sensitive. That is lower-case letters are treated
as distinct from upper-case letters. Thus the word NUM different from the word num or the
word Num. Identifiers can be used to identify variable or constants or functions. Function
identifier is an identifier that is used to name a function.
Literals

8
Literals are constant values which can be a number, a character of a string. For example the
number 129.005, the character ‘A’ and the string “hello world” are all literals. There is no
identifier that identifies them.

Comments
A comment is a piece of descriptive text which explains some aspect of a program. Program
comments are totally ignored by the compiler and are only intended for human readers. C++
provides two types of comment delimiters:
• Anything after // (until the end of the line on which it appears) is considered a comment.
• Anything enclosed by the pair /* and */ is considered a comment.

1.3 Data Types, Variables, and Constant variables


A variable is a symbolic name for a memory location in which data can be stored and
subsequently recalled. Variables are used for holding data values so that they can be utilized in
various computations in a program. All variables have two important attributes:
• A type, which is, established when the variable is defined (e.g., integer, float, character).
Once defined, the type of a C++ variable cannot be changed.
• A value, which can be changed by assigning a new value to the variable. The kind of
values a variable can assume depends on its type. For example, an integer variable can
only take integer values (e.g., 2, 100, -12) not real numbers like 0.123.
Variable Declaration
Declaring a variable means defining (creating) a variable. You create or define a variable by
stating its type, followed by one or more spaces, followed by the variable name and a semicolon.
The variable name can be virtually any combination of letters, but cannot contain spaces and
the first character must be a letter or an underscore. Variable names cannot also be the same as
keywords used by C++. Legal variable names include x, J23qrsnf, and myAge. Good variable
names tell you what the variables are for; using good names makes it easier to understand the
flow of your program. The following statement defines an integer variable called myAge:
int myAge;

IMPORTANT- Variables must be declared before used!


As a general programming practice, avoid such horrific names as J23qrsnf, and restrict single-
letter variable names (such as x or i) to variables that are used only very briefly. Try to use
expressive names such as myAge or howMany.

A point worth mentioning again here is that C++ is case-sensitive. In other words, uppercase
and lowercase letters are considered to be different. A variable named age is different from
Age, which is different from AGE.
Creating More Than One Variable at a Time

9
You can create more than one variable of the same type in one statement by writing the type
and then the variable names, separated by commas. For example:
int myAge, myWeight; // two int variables

long area, width, length; // three longs

As you can see, myAge and myWeight are each declared as integer variables. The second line
declares three individual long variables named area, width, and length. However keep in mind
that you cannot mix types in one definition statement.
Assigning Values to Your Variables
You assign a value to a variable by using the assignment operator (=). Thus, you would assign
5 to Width by writing
int Width;

Width = 5;

You can combine these steps and initialize Width when you define it by writing
int Width = 5;
Initialization looks very much like assignment, and with integer variables, the difference is
minor. The essential difference is that initialization takes place at the moment you create the
variable.
Just as you can define more than one variable at a time, you can initialize more than one
variable at creation.

For example:

// create two int variables and initialize them

int width = 5, length = 7;

This example initializes the integer variable width to the value 5 and the length variable to the
value 7. It is possible to even mix definitions and initializations:

int myAge = 39, yourAge, hisAge = 40;

This example creates three type int variables, and it initializes the first and third.

Basic Data Types


When you define a variable in C++, you must tell the compiler what kind of variable it is: an
integer, a character, and so forth. This information tells the compiler how much room to set
aside and what kind of value you want to store in your variable.

10
Several data types are built into C++. The varieties of data types allow programmers to select
the type appropriate to the needs of the applications being developed. The data types supported
by C++ can be classified as basic (fundamental) data types, user defined data types, derived
data types and empty data types. However, the discussion here will focus only on the basic data
types.

Basic (fundamental) data types in C++ can be conveniently divided into numeric and character
types. Numeric variables can further be divided into integer variables and floating-point
variables. Integer variables will hold only integers whereas floating number variables can
accommodate real numbers.

Both the numeric data types offer modifiers that are used to vary the nature of the data to be
stored. The modifiers used can be short, long, signed and unsigned.

The data types used in C++ programs are described in Table 1.4. This table shows the variable
type, how much room it takes in memory, and what kinds of values can be stored in these
variables. The values that can be stored are determined by the size of the variable types.

Table 1.4: C++ data types and their ranges

Type Size Values


unsigned short int 2 bytes 0 to 65,535
short int(signed short int) 2 bytes -32,768 to 32,767
unsigned long int 4 bytes 0 to 4,294,967,295
long int(signed long int) 4 bytes -2,147,483,648 to 2,147,483,647
int 4 bytes -2,147,483,648 to 2,147,483,647
unsigned int 4 bytes 0 to 4,294,967,295
signed int 4 bytes -2,147,483,648 to 2,147,483,647
Char 1 byte 256 character values
Float 4 bytes 3.4e-38 to 3.4e38
Double 8 bytes 1.7e-308 to 1.7e308
long double 10 bytes 1.2e-4932 to 1.2e4932

Signed and Unsigned


As shown above, integer types come in two varieties: signed and unsigned. The idea here is
that sometimes you need negative numbers, and sometimes you don't. Integers (short and long)
without the word "unsigned" are assumed to be signed. Signed integers are either negative or
positive. Unsigned integers are always positive.
Because you have the same number of bytes for both signed and unsigned integers, the largest
number you can store in an unsigned integer is twice as big as the largest positive number you
11
can store in a signed integer. An unsigned short integer can handle numbers from 0 to 65,535.
Half the numbers represented by a signed short are negative, thus a signed short can only
represent numbers from -32,768 to 32,767.

Example: A demonstration of the use of variables.

1: // demonstration of the use of variables


2: #include <iostream>
3: using namespace std;
4: int main()
5: {
6: unsigned short int Width = 5, Length=10 , Area; // Variable initialization
11: Area = Width * Length; //multiplying Width by Length to get the Area
13: cout<< "Width:" << Width << "\n";
14: cout<< "Length: " << Length <<endl;
15: cout<< "Area: " << Area <<endl;
16: return 0;
17: }
Output:

Width:5

Length: 10

Area: 50

Line 2 includes the required include statement for the iostream's library so that cout will work.
Line 4 begins the program.
On line 6, Width is defined as an unsigned short integer, and its value is initialized to 5. Another
unsigned short integer, Length, is also defined, but it is not initialized. On line 7, the value 10
is assigned to Length.
On line 11, an unsigned short integer, Area, is defined, and it is initialized with the value
obtained by multiplying Width times Length. On lines 13-15, the values of the variables are
printed to the screen. Note that the special word endl creates a new line.
Wrapping around integer values
The fact that unsigned long integers have a limit to the values they can hold is only rarely a
problem, but what happens if you do run out of room? When an unsigned integer reaches its
maximum value, it wraps around and starts over, much as a car odometer might. The following
example shows what happens if you try to put too large a value into a short integer.

Example: A demonstration of putting too large a value in a variable


1: #include <iostream>
using namespace std;
2: int main()
3: {

12
4: unsigned short int smallNumber;
5: smallNumber = 65535;
6: cout<< "small number:" <<smallNumber<<endl;
7: smallNumber++;
8: cout<< "small number:" <<smallNumber<<endl;
9: smallNumber++;
10: cout<< "small number:" <<smallNumber<<endl;
11: return 0;
12: }

Output:
small number: 65535
small number:0
small number:1

A signed integer is different from an unsigned integer, in that half of the values you can
represent are negative. Instead of picturing a traditional car odometer, you might picture one
that rotates up for positive numbers and down for negative numbers. One mile from 0 is either
1 or -1. When you run out of positive numbers, you run right into the largest negative numbers
and then count back down to 0. The whole idea here is putting a number that is above the range
of the variable can create unpredictable problem.
Example: A demonstration of adding too large a number to a signed integer.

1: #include <iostream>
2. using namespace std
3: int main()
4: {
5: short int smallNumber;
6: smallNumber = 32767;
7: cout<< "small number:" <<smallNumber<<endl;
8: smallNumber++;
9: cout<< "small number:" <<smallNumber<<endl;
10: smallNumber++;
11 cout<< "small number:" <<smallNumber<<endl;
12: return 0;
13`: }

Output:
small number:32767
small number:-32768
small number:-32767
IMPORTANT – To any variable, do not assign a value that is beyond its range!

13
Characters
Character variables (type char) are typically 1 byte, enough to hold 256 values. A char can be
interpreted as a small number (0-255) or as a member of the ASCII set. ASCII stands for the
American Standard Code for Information Interchange. The ASCII character set and its ISO
(International Standards Organization) equivalent are a way to encode all the letters, numerals,
and punctuation marks.
In the ASCII code, the lowercase letter "a" is assigned the value 97. All the lower- and
uppercase letters, all the numerals, and all the punctuation marks are assigned values between
0 and 127. Another 128 marks and symbols are reserved for use by the computer maker,
although the IBM extended character set has become something of a standard.
Characters and Numbers
When you put a character, for example, `a', into a char variable, what is really there is just a
number between 0 and 255. The compiler knows, however, how to translate back and forth
between characters (represented by a single quotation mark and then a letter, numeral, or
punctuation mark, followed by a closing single quotation mark) and one of the ASCII values.
The value/letter relationship is arbitrary; there is no particular reason that the lowercase ‘a’ is
assigned the value 97. As long as everyone (your keyboard, compiler, and screen) agrees, there
is no problem. It is important to realize, however, that there is a big difference between the
value 5 and the character `5'. The latter is actually valued at 53, much as the letter ‘a’ is valued
at 97.

1.4 Operators
C++ provides operators for composing arithmetic, relational, logical, bitwise, and conditional
expressions. It also provides operators which produce useful side-effects, such as assignment,
increment, and decrement. We will look at each category of operators in turn. We will also
discuss the precedence rules which govern the order of operator evaluation in a multi-operator
expression.

Assignment Operators

The assignment operator is used for storing a value at some memory location (typically denoted
by a variable). Its left operand should be an lvalue, and its right operand may be an arbitrary
expression. The latter is evaluated and the outcome is stored in the location denoted by the
lvalue.

An lvalue (standing for left value) is anything that denotes a memory location in which a value
may be stored. The only kind of lvalue we have seen so far is a variable. Other kinds of lvalue

14
(based on pointers and references) will be described later. The assignment operator has a
number of variants, obtained by combining it with the arithmetic and bitwise operators.

Table 1.5: Assignment Operator


Operator Example Equivalent To
= n = 25
+= n += 25 n = n + 25
-= n -= 25 n = n – 25
*= n *= 25 n = n * 25
/= n /= 25 n = n / 25
%= n %= 25 n = n % 25
&= n &= 0xF2F2 n = n & 0xF2F2
|= n |= 0xF2F2 n = n | 0xF2F2
^= n ^= 0xF2F2 n = n ^ 0xF2F2
<<= n <<= 4 n = n << 4
>>= n >>= 4 n = n >> 4

An assignment operation is itself an expression whose value is the value stored in its left
operand. An assignment operation can therefore be used as the right operand of another
assignment operation. Any number of assignments can be concatenated in this fashion to form
one expression. For example:
int m, n, p;
m = n = p = 100; // means: n = (m = (p = 100));
m = (n = p = 100) + 2; // means: m = (n = (p = 100)) + 2;
This is equally applicable to other forms of assignment. For example:
m = 100;
m += n = p = 10; // means: m = m + (n = p = 10);

Arithmetic Operators
C++ provides five basic arithmetic operators. These are summarized in table below
Table 1.5: Arithmetic Operator
Operator Name Example
+ Addition 12 + 4.9 // gives 16.9
- Subtraction 3.98 - 4 // gives -0.02
* Multiplication 2 * 3.4 // gives 6.8
/ Division 9 / 2.0 // gives 4.5
% Remainder 13 % 3 //gives 1 // gives 1

Except for remainder (%) all other arithmetic operators can accept a mix of integer and real
operands. Generally, if both operands are integers then the result will be an integer. However,
if one or both of the operands are real numbers then the result will be a real (or double to be
exact).
15
When both operands of the division operator (/) are integers then the division is performed as
an integer division and not the normal division we are used to. Integer division always results
in an integer outcome (i.e., the result is always rounded down). For example:

9/2 // gives 4, not 4.5!


-9 / 2 / / gives -5, not -4!

Unintended integer divisions are a common source of programming errors. To obtain a real
division when both operands are integers, you should cast one of the operands to be real:

int cost = 100;


int volume = 80;
double unitPrice = cost / (double) volume; // gives 1.25

The remainder operator (%) expects integers for both of its operands. It returns the remainder
of integer-dividing the operands. For example 13%3 is calculated by integer dividing 13 by 3
to give an outcome of 4 and a remainder of 1; the result is therefore 1.

It is possible for the outcome of an arithmetic operation to be too large for storing in a
designated variable. This situation is called an overflow. The outcome of an overflow is
machine-dependent and therefore undefined. For example:

unsigned char k = 10 * 92; // overflow: 920 > 255

It is illegal to divide a number by zero. This results in a run-time division-by-zero failure, which
typically causes the program to terminate.

There are also a number of predefined library functions, which perform arithmetic operations.
As with input & output statements, if you want to use these you must put a #include statement
at the start of your program.

Table 1.6: Some of the more common library functions

Parameter Result
Function Result
Header File Type(s) Type

<stdlib.h> abs(i) int int Absolute value of i

<math.h> cos(x) float float Cosine of x (x is in radians)

<math.h> fabs(x) float float Absolute value of x

<math.h> pow(x, y) float float x raised to the power of y

16
<math.h> sin(x) float float Sine of x (x is in radians)

<math.h> sqrt(x) float float Square root of x

<math.h> tan(x) float float Tangent of x

Relational Operators
C++ provides six relational operators for comparing numeric quantities. These are summarized
in table below. Relational operators evaluate to 1 (representing the true outcome) or 0
(representing the false outcome).
Table 1.7: Relational Operators
Operator Name Example

== Equality 5 == 5 // gives 1

!= Inequality 5 != 5 // gives 0

< Less Than 5 < 5.5 // gives 1

<= Less Than or Equal 5 <= 5 // gives 1

> Greater Than 5 > 5.5 // gives 0

>= Greater Than or Equal 6.3 >= 5 // gives 1

Relational operators

Note that the <= and >= operators are only supported in the form shown. In particular, =< and
=> are both invalid and do not mean anything.
The operands of a relational operator must evaluate to a number. Characters are valid operands
since they are represented by numeric values. For example (assuming ASCII coding):
'A' < 'F' // gives 1 (is like 65 < 70)
The relational operators should not be used for comparing strings, because this will result in
the string addresses being compared, not the string contents. For example, the expression
"HELLO" < "BYE" causes the address of "HELLO" to be compared to the address of "BYE".

17
As these addresses are determined by the compiler (in a machine-dependent manner), the
outcome may be 0 or 1, and is therefore undefined. C++ provides library functions (e.g., strcmp)
for the lexicographic comparison of string.

Logical Operators
C++ provides three logical operators for combining logical expression. These are summarized
in the table below. Like the relational operators, logical operators evaluate to 1 or 0.

Table 1.8: Logical Operators


Operator Name Example

! Logical Negation !(5 == 5) // gives 0

&& Logical And 5 < 6 && 6 < 6 // gives 0

|| Logical Or 5 < 6 || 6 < 5 // gives 1

Logical operators

Logical negation is a unary operator, which negates the logical value of its single operand. If
its operand is nonzero it produces 0, and if it is 0 it produces 1.
Logical and produces 0 if one or both of its operands evaluate to 0. Otherwise, it produces 1.
Logical or produces 0 if both of its operands evaluate to 0. Otherwise, it produces 1.
Note that here we talk of zero and nonzero operands (not zero and 1). In general, any nonzero
value can be used to represent the logical true, whereas only zero represents the logical false.
The following are, therefore, all valid logical expressions:
!20 // gives 0
10 && 5 // gives 1
10 || 5.5 // gives 1
10 && 0 // gives 0
C++ does not have a built-in boolean type. It is customary to use the type int for this purpose
instead. For example:
int sorted = 0; // false
int balanced = 1; // true
Increment/decrement Operators
The auto increment (++) and auto decrement (--) operators provide a convenient way of,
respectively, adding and subtracting 1 from a numeric variable. These are summarized in the
following table. The examples assume the following variable definition:

18
int k = 5;

Table 1.9: Increment/decrement Operators

Operator Name Example

++ Auto Increment (prefix) ++k + 10 // gives 16

++ Auto Increment (postfix) k++ + 10 // gives 15

-- Auto Decrement (prefix) --k + 10 // gives 14

-- Auto Decrement (postfix) k-- + 10 // gives 15

Increment and decrement operators

Both operators can be used in prefix and postfix form. The difference is significant. When used
in prefix form, the operator is first applied and the outcome is then used in the expression.
When used in the postfix form, the expression is evaluated first and then the operator applied.
Both operators may be applied to integer as well as real variables, although in practice real
variables are rarely useful in this form.

Precedence of Operators
The order in which operators are evaluated in an expression is significant and is determined by
precedence rules. These rules divide the C++ operators into a number of precedence levels.
Operators in higher levels take precedence over operators in lower levels.
Table 1.10: Order of Precedence
Level Operator Kind Order

Highest :: Unary Both

() [] -> . Binary Left to Right

+ ++ ! * new sizeof() Unary Right to Left

- -- ~ & delete

19
Level Operator Kind Order

Highest :: Unary Both

->* .* Binary Left to Right

* / % Binary Left to Right

+ - Binary Left to Right

<< >> Binary Left to Right

< <= > >= Binary Left to Right

== != Binary Left to Right

& Binary Left to Right

^ Binary Left to Right

| Binary Left to Right

& Binary Left to Right


&

|| Binary Left to Right

?: Ternary Left to Right

= += *= ^= &= <<= Binary Right to Left

-= /= %= |= >>=

Lowest , Binary Left to Right

For example, in
a==b+c*d
c * d is evaluated first because * has a higher precedence than + and ==. The result is then
added to b because + has a higher precedence than ==, and then == is evaluated. Precedence
rules can be overridden using brackets. For example, rewriting the above expression as
a == (b + c) * d
causes + to be evaluated before *.

20
Operators with the same precedence level are evaluated in the order specified by the last
column of Table 1.10. For example, in
a = b += c
the evaluation order is right to left, so first b += c is evaluated, followed by a = b.

21
Week 1:- Practice:
C++ IDE

The complete development cycle in C++ is: Write the program, compile the source code, link
the program, and run it.
Writing a Program
To write a source code, your compiler may have its own built-in text editor, or you may be
using a commercial text editor or word processor that can produce text files. The important
thing is that whatever you write your program in, it must save simple, plain-text files, with no
word processing commands embedded in the text. Examples of safe editors include Windows
Notepad, the DOS Edit command. Many commercial word processors, such as WordPerfect,
Word, and dozens of others, also offer a method for saving simple text files.

The files you create with your editor are called source files, and for C++ they typically are
named with the extension .CPP.

Compiling
Your source code file can't be executed, or run, as a program can. To turn your source code
into a program, you use a compiler. How you invoke your compiler, and how you tell it where
to find your source code, will vary from compiler to compiler; check your documentation. In
Borland's Turbo C++ you pick the RUN menu command or type

tc<filename>

from the command line, where <filename> is the name of your source code file (for example,
test.cpp). Other compilers may do things slightly differently. After your source code is
compiled, an object file is produced. This file is often named with the extension .OBJ. This is
still not an executable program, however. To turn this into an executable program, you must
run your linker.

Linking
C++ programs are typically created by linking together one or more OBJ files with one or more
libraries. A library is a collection of linkable files that were supplied with your compiler, that
you purchased separately, or that you created and compiled. All C++ compilers come with a
library of useful functions (or procedures) and classes that you can include in your program. A
function is a block of code that performs a service, such as adding two numbers or printing to
the screen. A class is a collection of data and related functions.

Summary
The steps to create an executable file are

22
1. Create a source code file, with a .CPP extension.
2. Compile the source code into a file with the .OBJ extension.
3. Link your OBJ file with any needed libraries to produce an executable program.

Showing Sample program


Any meaningful program written in C++ has to contain a number of components: the main
function; some variable declarations; and some executable statements. For example, the
following is a very basic C++ program:

1. #include <iostream>
2. using namespace std;

3. int main()
4. {
5. cout<< "Hello World!\n";
6. return 0;
7. }
On line 1, the file iostream is included in the file. The first character is the # symbol, which is
a signal to the preprocessor. Each time you start your compiler, the preprocessor is run. The
preprocessor reads through your source code, looking for lines that begin with the pound
symbol (#), and acts on those lines before the compiler runs.
include is a preprocessor instruction that says, "What follows is a filename. Find that file and
read it in right here." The angle brackets around the filename tell the preprocessor to look in
all the usual places for this file. If your compiler is set up correctly, the angle brackets will
cause the preprocessor to look for the file iostream.h in the directory that holds all the H files
for your compiler. The file iostream.h (Input-Output-Stream) is used by cout, which assists
with writing to the screen. The effect of line 1 is to include the file iostream.h into this program
as if you had typed it in yourself.

The preprocessor runs before your compiler each time the compiler is invoked. The
preprocessor translates any line that begins with a pound symbol (#) into a special command,
getting your code file ready for the compiler.

Line 3 begins the actual program with a function named main(). Every C++ program has a
main() function. In general, a function is a block of code that performs one or more actions.
Usually functions are invoked or called by other functions, but main() is special. When your
program starts, main() is called automatically.

main(), like all functions, must state what kind of value it will return. The return value type for
main() in HELLO.CPP is int, which means that this function will return an integer value.

All functions begin with an opening brace ({) and end with a closing brace (}). The braces for
the main() function are on lines 4 and 7. Everything between the opening and closing braces is
considered a part of the function.

23
Assessments
I. Practical
1. Write C++ program which accepts any three integers from user and calculates the sum
and average of the three numbers.

2. Write a C++ program that accepts your information and display in the following format.
Name: ________________________

Department: ____________________

Year: __________________________

Semester: ________________________

3. Write a C++ program for XYZ supermarket that computes transactions in the following
format.
Given: VAT=10%total
Service Charge=2%total
XYZ Supermarket
Pasta: __________________________________
Macaroni: ______________________________
Soap: _________________________________
Milk: _________________________________
Total: ________________________________
VAT: ___________________________________
Service Charge: __________________________
Total Payment: __________________________
THANK YOU!!!

II: Objective Type Question


Choose the correct answer to the following questions.
1. Which one of the following is NOT true about comments?
A. Every line that starts with two slash signs (//) are considered comments.
B. Words between /* and */ is also be considered as Multi line comments.
C. Comments are executed by processor.
D. C++ comments can be used to explain difficult sections.

2. Which one of the following function is the point where all C++ programs start its
execution
A. main() C. cout<<

24
B. return 0; D. cin>>
3. Every statement or instruction of a C++ statement must end with one of the following.
A. : (colon) C. , (comma)
B. ; (semicolon) D. { } (curly brackets)
4. Which one of the following is NOT true about C++ Identifiers?
A. Must begin with a letter or underscore or digits.
B. It should not be a reserved (key) word.
C. It can be a combination of letters, digits and the underscore characters.
D. It should not start with digits
5. Which one of the following is INVALID identifier?
A. _xyz C. int
B. xyz9 D. xy_9
6. Which one of the following is NOT a correct variable declaration?
A. Int x; C. x float;
B. int y,z; D. float x;
7. Which one of the following data type is used to represent textual information?
A. int C. string
B. float D. char
8. What will be the output of the following statement when it is executed inside the main
function?
{ cout<<(11%2); }
A. 0 C. 5.5
B. 1 D.5
9. Which one of the following statement has a correct syntax?
A. cin<<x; C. cin>>x;
B. cint<x; D. cin>x
10. What will be the output of the following statement when it is executed with in the main
function?
{ cout<<((5>4)&&(4>5)); }
A. 5 C.1
B. 4 D.0

25
Week 2:

1.5 Control Statements


Running program spends all of its time executing instructions or statements in that program.
The order in which statements in a program are executed is called flow of that program.
Programmers can control which instruction to be executed in a program, which is called flow
control.
This term reflects the fact that the currently executing statement has the control of the CPU,
which when completed will be handed over (flow) to another statement. Flow control in a
program is typically sequential, from one statement to the next. But we can also have
execution that might be divided to other paths by branching statements. Or perform a block
of statement repeatedly until a condition fails by Repetition or looping.
Flow control is an important concept in programming because it will give all the power to the
programmer to decide what to do to execute during a run and what is not, therefore, affecting
the overall outcome of the program.
1.5.1 Sequential Statements
Such kind of statements are instruction in a program which will executed one after the other in
the order scripted in the program. In sequential statements, the order will be determined during
program development and cannot be changed.
1.5.2 Selection Statements
Selection statements are statements in a program where there are points at which the program
will decide at runtime whether some part of the code should or should not be executed.
There are two types of selection statements in C++, which are the “if statement” and the
“switch statement”

The if Statement
It is sometimes desirable to make the execution of a statement dependent upon a condition
being satisfied.
The different forms of the ‘If” statement will be used to decide whether to execute part of the
program based on a condition which will be tested either for TRUE or FALSE result.
The different forms of the “if” statements are:
• The simple if statement
• The If else statement
• The if else if statement
The simple if statement
The simple if statement will decide only one part of the program to be executed if the condition
is satisfied or ignored if the condition fails.
• The General Syntax is:
if (expression)

26
statements;
In any “if” statement, first the “expression” will be evaluated and if the outcome is non zero
(which means TRUE), then the “statements” is executed. Otherwise, nothing happens (the
statement will not be executed) and execution resumes to the line immediately after the “if”
block.
To make multiple statements dependent on the same condition we can use a compound
statement, which will be implemented by embracing the group of instructions within the left
“{“ and right “}” French bracket.
Eg:
if(age>18)
cout<<”you are an adult”;

Eg.:
if(balance > 0)
{
interest = balance * creditRate;
balance += interest;
}
Most of the time “expression” will have relational expressions testing whether something is
equal, greater, less, or different from something else.
It should be noted that the output of a relational expression is either True (represented by
anything different from zero) or False (represented by Zero).
Thus any expression, whose final result is either zero or non-zero can be used in ”expression”

Eg:
int x;
cin >>x;
if(x)
cout <<”you are an adult”;

In the above example, the value of variable x will be an input from the user. The “if” statement
will be true if the user gives anything different from zero, which means the message “you are
an adult” will be displayed on the screen. If the user gives zero value for x, which will be
interpreted as False, nothing will be done as the if statement is not satisfied.
Thus, expression can be:
• Relational expression,
• A variable,
• A literal constant, or
• Assignment operation, as the final result is whatever we have at the right hand side and
the one at the left hand side is a variable.

The if else statement


Another form of the “if” is the “if …else” statement. The “if else if” statement allows us to
specify two alternative statements: One which will be executed if a condition is satisfied and
another which will be executed if the condition is not satisfied.

27
• The General Syntax is:
if (expression)
statement1;
else
statment2;

First “expression” is evaluated and if the outcome is none zero (true), then “statements1” will
be executed. Otherwise, which means the “expression” is false “statements2” will be executed.
E.g.:
if(balance > 0)
{
interest = balance * creditRate;
balance += interest;
}
else
{
interest = balance * debitRate;
balance += interest;
}

The Switch Statement


Another C++ statement that implements a selection control flow is the switch statement
(multiple-choice statement).The switch statement provides a way of choosing between a set of
alternatives based on the value of an expression.
The switch statement has four components:
• switch
• case
• default
• break
Where Default and Break are Optional.
The General Syntax might be:
switch(expression)
{
case constant1:
statements;
.
.
case constant n:
statements;
default:
statements;
}
Expression is called the switch tag and the constants preceding each case are called the case
labels. The output of “expression” should always be a constant value. First expression is
evaluated, and the outcome, which is a constant value, will compared to each of the numeric

28
constants in the case labels, in the order they appear, until a match is found. Note, however,
that the evaluation of the switch tag with the case labels is only for equality. The statements
following the matching case are then executed. Note the plural: each case may be followed by
zero or more statements (not just one statement). After one case is satisfied, execution
continues until either a break statement is encountered or all intervening statements are
executed, which means until the execution reaches the right French bracket of the switch
statement. The final default case is optional and is exercised if none of the earlier cases provide
a match. This means that, if the value of the “expression” is not equal to any of the case labels,
then the statements under default will be executed. Now let us see the effect of including a
break statement in the switch statement.

Scenario One
switch (N)
{
case 1: x=10;
case 2: x=20;
case 3: x=30;
}
Even if N is 1 or 2 x will have 30
Scenario Two
switch(N)
{
case 1: x=10; break;
case 2: x=20; break;
case 3: x=30; break;
}
X will have either 10, 20 or 30 based on the value of N

1.5.3 Looping Statements


Repetition statements control a block of code to be executed repeatedly for a fixed number of
times or until a certain condition fails.
There are three C++ repetition statements:
1) The for Statement or loop
2) The while statement or loop
3) The do…while statement or loop
The for statement / loop
The “for” statement (also called loop) is used to repeatedly execute a block of instructions until
a specific condition fails.
The General Syntax is:

29
for(expression1 ; expression2 ; expression3)
statements;
The for loop has three expressions:
Expression1: is one or more statements that will be executed only once and before the looping
starts.
Expression2: is the part that decides whether to proceed with executing the instructions in the
loop or to stop. Expression2 will be evaluated each time before the loop continues. The output
of expression2 should be either zero (to proceed with the loop) or none zero (to stop the loop)
to represent false and true output respectively.
Expression3: is one or more statements that will be executed after each iteration. Thus, first
expression1 is evaluated and then each time the loop is executed, expression2 is evaluated. If
the outcome of expression2 is nonzero, then statements are executed and expression3 is
evaluated. Otherwise, the loop is terminated.
In most programs, the “for loop” will be used for such expressionswhereexpression1 is
initialization, expression2 is condition andexpression3is either increment or decrement.
The general format can be expressed as follows for the sake of clarity:
for(initialization; condition; increase/decrease)
statement;
Steps of execution of the for loop:
1. Initialization is executed. (Will be executed only once)
2. Condition is checked, if it is true the loop continues, otherwise the loop finishes and
statement is skipped.
3. Statement is executed.
4. Finally, whatever is specified in the increase or decrease field is executed and the loop gets
back to step 2.

E.g. : What is the output of the following code:


int main()
{
for(int i=10;i>0;i--)
{
cout<<n<<“,”;
}
cout<< “FIRE!”;
getch();
return 0;
}
Even though it is not recommended, expression1, expression2 andexpression3 can be optional
or can be ignored. This means that they can take NULL statement. But making expression2
null means that the loop will not terminate. In such cases one can include an “if” statement
inside the “for” loop which will test a condition and break out from the loop using the break
statement.
While making one or more of the three expressions null, the semicolons CAN NOT be ignored.

30
Eg:
for (;n<10;) //if we want nether initialization nor increase/decrease
for (;n<10;n++) //if no initialization is needed.
for ( ; ; ) //is an infinite loop unless an otherwise there is if statement inside the loop.
It is declared above that expression1 and expression3 can be one or more statements. The
composite statements should be separated by comma. This means, optionally, using the comma
operator (,) we can specify more than one instruction in any of the two fields included in a “for”
loop.
Eg:
for(n=0,i=100;n!=i; n++,i--)
{
//what ever here
}
In the above example, n=0 and i=100 will be part of expression1and will be executed only once
before the loop starts. In addition, n++ and i-- will be part of expression3 and will be executed
after each looping/iteration.
Eg:1
//The following for statement adds the numbers between 0 and n
int Sum=0;
for(inti=0; i<=n;i++)
Sum=Sum+i;
Eg:2
//the following for statement adds the even numbers between 0 and n
int Sum=0;
for(int i=0; i<=n;)
{
Sum=Sum+i;
i+=2;
}

Eg:3
//the following for statement adds the even numbers between 0 and n
//where all the three expressions are null.
int Sum=0;
int i=0;
for( ; ; )
{
if(i<=n)
break;
else
{
Sum=Sum+i;

31
i++;
}
}
In the above example, the initialization is at the top before the looping starts, the condition is
put in if statement before the instructions are executed and the increment is found immediately
after the statements to be executed in the loop.
NB: even though there is the option of making all the three expressions null in a “for” loop, it
is not recommended to make the condition to take null statement.
The while statement
The while statement (also called while loop) provides a way of repeating a statement or a block
as long as a condition holds / is true.
The general form of the while loop is:
while(expression)
statements;
First expression (called the loop condition) is evaluated. If the outcome is non zero then
statement (called the loop body) is executed and the whole process is repeated. Otherwise, the
loop is terminated.
Suppose that we wish to calculate the sum of all numbers from 1 to some integer value n. this
can be expressed as:

Eg1:
// adds the numbers between 0 and any given number n
i=1;
sum = 0;
while(i<= n)
sum += i++;
Eg2:
//adds the numbers between 0 and 100
number=1;
sum=0;
while(number <= 100)
{
sum += number;
number++;
}
E.g.3:

32
/*the following while loop will request the user to enter his/her age which should be between
0 and 130. If the user enters a value which is not in the range, the while loop test the value and
request the age again until the user enters a valid age.*/
cout<<“\n enter your age [between 0 and 130]:”;
cin>>age;
while(age < 0 || age > 130)
{
cout<<“\n invalid age. Plz try again!”;
cin>>age;
}
do…while loop
The do statement (also called the do loop) is similar to the while statement, except that its body
is executed first and then the loop condition is examined.
In do…while loop, we are sure that the body of the loop will be executed at least once. Then
the condition will be tested.

The general form is:


Do
{
statement;
}
while(expression);

First statement is executed and then expression is evaluated. If the outcome of the expression
is nonzero, then the whole process is repeated. Otherwise the loop is terminated.
E.g.:
//our previous example (Eg3) in the while loop might be changed as:
age=-1;
do
{
cout<<“\n enter your valid age [between 0 and 130]:”;
cin>>age;
}
while(age < 0 || age > 130);

33
Pitfalls in witting repetition statements
There are some pitfalls worth mentioning in repletion statements. These pit falls are the most
common programming errors committed by programmers ’Infinite loop: no matter what you
do with the while loop (and other repetition statements), make sure that the loop will eventually
terminate.
Eg1:
//Do you know why the following is an infinite loop?
int product = 0;
while(product < 50)
product *= 5;
Eg2:
//Do you know why the following is an infinite loop?
int counter = 1;
while(counter != 10)
counter += 2;
In the first example, since product is initialized with zero, the expression “product*=5” will
always give us zero which will always be less than 50.
In the second example, the variable counter is initialized to 1 and increment is 2, counter will
never be equal to 10 as the counter only assumes odd values. In theory, this while loop is an
infinite loop, but in practice, this loop eventually terminates because of an overflow error as
counter is an integer it will have a maximum limit.
Off-By-One Bugs (OBOB): another thing for which you have to watch out in writing a loop
is the so called Off-By-One Bugs or errors. Suppose we want to execute the loop body 10 times.
Does the following code work?
Eg:1
count = 1;
while(count < 10)
{

count++;
}
No, the loop body is executed nine times. How about the following?
Eg:2
count = 0;
while(count <= 10)
{

count++;
}
No this time the loop body is executed eleven times. The correct is
E.g:3

34
count = 0;
while(count < 10)
{

count++;
}
or
count = 1;
while(count <= 10)
{

count++;
}
Types of Loops
Count controlled loops
Repeat a statement or block a specified number of times Count-controlled loops contain
• An initialization of the loop control variable
• An expression to test if the proper number of repetitions has been completed
• An update of the loop control variable to be executed with each iteration of the body
The continue and break statements
The continue statement
The continue statement terminates the current iteration of a loop and instead jumps to the next
iteration. It is an error to use the continue statement outside a loop. In while & do while loops,
the next iteration commences from the loop condition.
In a “for” loop, the next iteration commences from the loop’s third expression.
Eg:
for(int n=10;n>0;n--)
{
if(n==5)
continue; //causes a jump to n
cout<<n<< “,”;
}
When the continue statement appears inside nested loops, it applies to the loop immediately
enclosing it, and not to the outer loops. For example, in the following set of nested loops, the
continue statement applies to the “for” loop, and not to the “while” loop.
while(more)
{
for(i=0;i<n;i++)
{
cin>>num;
if(num<0)
continue; //causes a jump to :i++
}

35
}

The break statement


A break statement may appear inside a loop (while, do, or for) or a switch statement. It causes
a jump out of these constructs, and hence terminates them.
Like the continue statement, a break statement only applies to the “loop” or “switch”
immediately enclosing it. It is an error to use the break statement outside a loop or a switch
statement.
Eg:
for(n=10;n>0;n--)
{
cout<<n<< “,”;
if(n = = 3)
{
cout<< “count down aborted!!”;
break;
}
}
Week 11 Practice:

36
Week 2:- Practice:
If statement
The simple if statement will decide only one part of the program to be executed if the condition
is satisfied or ignored if the condition fails.
The General Syntax is:
if (expression)
statements;
#include <iostream>
using namespace std;
int main ()
{
int x = 10;
if( x< 20 )
{
cout<<"This is if statement";
}
return 0;
}

if….else statement
Another form of the “if” is the “if…else” statement.
The “if else if” statement allows us to specify two alternative statements: One which will be
executed if a condition is satisfied and another which will be executed if the condition is not
satisfied.
The General Syntax is:
if (expression)
statement1;
else
statment2;

#include <iostream>
using namespace std;
int main ()
{
37
int x = 30;
if( x< 20 )
{
cout<<"This is if statement";
}
else
{
cout<<"This is else statement";
}
}

if….else if…else Statement


The third form of the “if” statement is the “if …else if” statement. The “if else if” statement
allows us to specify more than two alternative statements each will be executed based on testing
one or more conditions.
The General Syntax is:
if (expression1)
statements1;
else if(expression2)
statements2;
.
.
else if(expressionN)
statementsN;
else
statements;

Eg.
#include <iostream>
using namespace std;
int main ()
{
int x = 30;
if( x == 10 )
{
cout<<"Value of X is 10";
}
else if( x == 20 )
{
cout<<"Value of X is 20";
}
else if( x == 30 )
{
cout<<"Value of X is 30";
}
else
{
cout<<"This is else statement";
}

38
}
switch statement:
Another C++ statement that implements a selection control flow is the switch statement
(multiple-choice statement). The switch statement provides a way of choosing between a set of
alternatives based on the value of an expression.
The switch statement has four components:
• switch
• case
• default
• break
Where Default and Break are Optional.

The General Syntax might be:


switch(expression)
{
case constant1:
statements;
.
case constant n:
statements;
default:
statements;
}

Eg 1.
#include <iostream>
using namespace std;
int main ()
{
char grade = 'C';
switch(grade)
{
case 'A' :
cout<<"Excellent!";

39
break;
case 'B' :
cout<<"Very Good!";
break;
case 'C' :
cout<<"Well done";
break;
case 'D' :
cout<<"You passed";
break
case 'F' :
cout<<"Better try again";
break;
default :
cout<<"Invalid grade";
}
cout<<"Your grade is " + grade;
}
for loop:
The “for” statement (also called loop) is used to repeatedly execute a block of instructions until
a specific condition fails.
The General Syntax is:
for(initialization ; condition ; increase/decrease)
statement;
Eg 1.
#include <iostream>
using namespace std;
int main ()
{
for(int i=1; i<11; i++)
{
cout<<"Count is:" <<i<<"\n";
}
}
while Loop
The while statement (also called while loop) provides a way of repeating a statement or a block
as long as a condition holds / is true.
The general form of the while loop is:
while(expression)
statements;
Eg1:
#include <iostream>
using namespace std;
int main ()
{

40
int count = 1;
while (count < 11)
{
cout<<"Count is: " <<count<<"\n";
count++;
}
}
Eg 2:
#include <iostream>
using namespace std;
int main ()
{
int count = 5;
while (count < 4)
{
cout<<"Count is: " <<count<<"\n";
count++;
}
}

Do -- while Loop
The do statement (also called the do loop) is similar to the while statement, except that its body
is executed first and then the loop condition is examined.In do…while loop, we are sure that
the body of the loop will be executed at least once. Then the condition will be tested.
The general form is:
do
{
statement;
}
while(expression);

Eg 1
#include <iostream>
using namespace std;
int main ()
{
int count = 1;
do
{
cout<<"Count is: " << count<<"\n";
count++;
}
while (count < 11);
}

41
Assessment
I. Practical Questions
1. Write a C++ program which receive a number and determine whether it is odd or even.
2. Write a C++ program which calculates sum, difference, product and quotient of two
integers by accepting from key board. Use switch for each arithmetic calculation (case 1:
for Addition, case 2: for subtraction, case 3: for multiplication and case 4 for division.
3. Write a C++ program which displays integers from 1to 50 in ascending and descending
order using for, while, and do while loops.
4. Write a C++ program which adds odd numbers between 1 to 100.
5. Write a C++ program that accepts marks of five students and then displays their average.
The program should not accept mark which is less than 0 and mark greater than 100.
6. Write for, do-while, and while statements to compute the following sums and products.
a. 1+2+3+…+100
b. 5+10+15+…+50
c. 1+1/2+1/3+1/4+…1/15
d. 1*2*3*…*20
7. write an application to print out the numbers 10 through 49 in the following manner 10 11
12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47 48 49
8. A prime number is an integer greater than one and divisible only by itself and one. The
first seven prime numbers are 2, 3, 5, 7, 11, 13, and 17. Write a program that displays all
the prime numbers between 1 and 100.
9. Write a C++ program that counts the number of digits in an integer number. For example;
23,498 has five digits.
10. Write a C++ application that can compute the letter grade of a student after accepting the
student’s mid and final mark. The program should only accept mid result [0-40] and final
[0- 60]. If the data entered violates this rule, the program should display that the user should
enter the mark in the specified range. The program is also expected to run until the user
refuses to continue.
11. Write a C++ program that accepts a positive number from the user and displays the
factorial of that number. Use for loops to find the factorial of the number.
12. Write a C++ code that computes the sum of the following series.
Sum = 1! + 2! + 3! + 4! + …n!
The program should accept the number from the user.

13. Using the ASCII table numbers, write a program to print the following output, using a
nested for loop. (Hint: the outer loop should loop from 1 to 5, and the inner loop’s start
variable should be 65, the value of ASCII “A”).
A
AB
ABC
42
ABCD
ABCDE
14. Write a C++ program that displays the following output using their ASCII values.
a
bc
def
gehi
jklmn
opqrst
15. Write a C++ program that will print the following shapes.
A.
*
**
***
****
*****
B.
*****
****
***
**
*
C.
*
***
*****
*******
*********
D.
*
***
*****
***
*
16. Write a weather-calculator program that asks for a list of the previous 10 days’
temperatures, computes the average, and prints the results. You have to compute the total
as the input occurs, then divide that total by 10 to find the average. Use a while loop for the
10 repetitions.
17. Write a C++ program that accepts marks of five students and then displays their average.
The program should not accept mark which is less than 0 and mark greater
Than 100.

II. Subjective Questions

43
1. What is flow control in programming?
2. List three types of selection statements and their syntax.
3. List some types of looping statements.

44
Reference
[1]. Stephen R. Davis, C++ Weekend Crash, John Wiley & Sons, 2003
[2]. Herbert Schildt, C++: A Beginner's Guide, Second Edition 2nd Edition, McGraw Hill,
2003
[3]. P B Mahapatra, Programming in C++, S Chand, 2008
[4]. Ashok Kamthane, Programming in C++, Pearson, 2013
[5]. https://www.w3schools.com/cpp/
[6]. https://www.tutorialspoint.com/cplusplus/index.htm
[7]. https://www.learncpp.com/

45
Chapter 2: Arrays and String Manipulation

Lesson Plan

1. Learning objectives

• Be able to define array.

• Be able to array variables.

• Be able to differentiate single and multi-dimensional array.


• Be able to apply the array variables in C++ programming.
2. Motivation

• Outputs through Question and Answer; repetitive discussion and using array variables;

• Solving a problem using array in C++.


3. Expectations or Outcomes
 Define the terminologies, differentiate different types of arrays, explain array variables;
the assessment standard attached at the end of the job task sheet.
 Can write C++ instructions to solve any problem using the concept of arrays in
programming.
4. Equipment

• Desktop or Laptop computer.

• DEV C++ software


5. Practice contents/Activities/Safety
 Active practice; on declaring array variables, initializing array variables, accessing el
ements of the array.
 Active practice on single and multi-dimensional array.
6. Assessments
• How to declare array variables?
• How to access elements of an array?
7. Clean-up
 After finishing practice, computers should be properly shut down.
8. Independent practice/Follow-up activities

47
• Learning through assignment (practical Exercises)
9. Review/Reflection
• Review the outcome of the practice, improvement measure and previous reflected
opinions.

48
Week 3:
2.1 Introduction

Variables in a program have values associated with them. During program execution these
values are accessed by using the identifier associated with the variable in expressions etc. In
none of the programs written so far have very many variables been used to represent the values
that were required. Thus even though programs have been written that could handle large lists
of numbers it has not been necessary to use a separate identifier for each number in the list.
This is because in all these programs it has never been necessary to keep a note of each number
individually for later processing. For example, in summing the numbers in a list only one
variable was used to hold the current entered number which was added to the accumulated sum
and was then overwritten by the next number entered. If that value were required again later in
the program, there would be no way of accessing it because the value has now been overwritten
by the later input.
If only a few values were involved a different identifier could be declared for each variable,
but now a loop could not be used to enter the values. Using a loop and assuming that after a
value has been entered and used no further use will be made of it allows the following code to
be written. This code enters six numbers and outputs their sum:
sum = 0.0;
for (i = 0; i < 6; i++)
{
cin >> x;
sum += x;
}
This of course is easily extended to n values where n can be as large as required. However, if
it was required to access the values later the above would not be suitable. It would be possible
to do it as follows by setting up six individual variables:
float a, b, c, d, e, f;
and then handling each value individually as follows:
sum = 0.0;
cin >> a; sum += a;
cin >>b; sum += b;
cin >>c; sum += c;
cin >> d; sum += d;
cin >> e; sum += e;
cin>>f; sum += f;
Which is obviously a very tedious way to program. To extend this solution so that it would
work with more than six values then more declarations would have to be added, extra
assignment statements added and the program re-compiled. If there were 10000 values imagine

49
the tedium of typing the program (and making up variable names and remembering which is
which)!
To get round this difficulty all high-level programming languages use the concept of a data
structure called an Array.

2.2 What is an array?


C++ provides a data structure, the array, which stores a fixed-size sequential collection of
elements of the same type. An array is used to store a collection of data, but it is often more
useful to think of an array as a collection of variables of the same type. Instead of declaring
individual variables, such as number0, number1, ..., and number99, you declare one array
variable such as numbers and use numbers[0], numbers[1], and ..., numbers[99] to represent
individual variables. A specific element in an array is accessed by an index. All arrays consist
of contiguous memory locations. The lowest address corresponds to the first element and the
highest address to the last element.
An array is a data structure which allows a collective name to be given to a group of elements
which all have the same type. An individual element of an array is identified by its own unique
index (or subscript).
An array can be thought of as a collection of numbered boxes each containing one data item.
The number associated with the box is the index of the item. To access a particular item the
index of the box associated with the item is used to access the appropriate box. The index must
be an integer and indicates the position of the element in the array. Thus the elements of an
array are ordered by the index.
A collection of identical data objects, which are stored in consecutive memory locations under
a common heading or a variable name. In other words, an array is a group or a table of values
referred to by the same name. The individual values in array are called elements. Array
elements are also variables.
Set of values of the same type, which have a single name followed by an index. In C++, square
brackets appear around the index right after the name
A block of memory representing a collection of many simple data variables stored in a separate
array element, and the computer stores all the elements of an array consecutively in memory.

Properties of arrays:
• Arrays in C++ are zero-bounded; that is the index of the first element in the array is 0
and the last element is N-1, where N is the size of the array.
• It is illegal to refer to an element outside of the array bounds, and your program will
crash or have unexpected results, depending on the compiler.
• Array can only hold values of one type

2.3 One Dimensional Array

50
2.3.1 Declaration of one Dimensional Array
An array declaration is very similar to a variable declaration. First a type is given for the
elements of the array, then an identifier for the array and, within square brackets, the number
of elements in the array. The number of elements must be an integer.
For example, data on the average temperature over the year in Ethiopia for each of the last 100
years could be stored in an array declared as follows:
float annual_temp[100];
This declaration will cause the compiler to allocate space for 100 consecutive float variables
in memory. The number of elements in an array must be fixed at compile time. It is best to
make the array size a constant and then, if required, the program can be changed to handle a
different size of array by changing the value of the constant,
Constint NE = 100;
float annual_temp[NE];
then if more records come to light it is easy to amend the program to cope with more values by
changing the value of NE. This works because the compiler knows the value of the constant
NE at compile time and can allocate an appropriate amount of space for the array. It would not
work if an ordinary variable was used for the size in the array declaration since at compile time
the compiler would not know a value for it.
Declaring the name and type of an array and setting the number of elements in an array is called
dimensioning the array. The array must be declared before one uses in like other variables. In
the array declaration one must define:
1. The type of the array (i.e. integer, floating point, char etc.)
2. Name of the array,
3. The total number of memory locations to be allocated or the maximum value of each
subscript i.e. the number of elements in the array.
The general syntax for the declaration is:

DataType name arrayname [array size];


The expression array size, which is the number of elements, must be a constant such as 10 or a
symbolic constant declared before the array declaration, or a constant expression such as
10*sizeof (int), for which the values are known at the time compilation takes place.

Note: array size cannot be a variable whose value is set while the program is running.

Thus to declare an integer with size of 10 having a name of num is: int num [10];
This means: ten consecutive two byte memory location will be reserved with the name num.
That means, we can store 10 values of type int without having to declare 10 different variables
each one with a different identifier. Instead of that, using an array we can store 10 different
values of the same type, int for example, with a unique identifier.

51
2.3.2 Accessing Array Elements
In any point of the program in which the array is visible we can access individually
anyone of its elements for reading or modifying it as if it was a normal variable. To
access individual elements, index or subscript is used. The format is the following:
name [index]
In C++ the first element has an index of 0 and the last element has an index, which is one less
the size of the array (i.e. arraysize-1). Thus, from the above declaration, day[0] is the first
element and day[4] is the last element.
Following the previous examples where day had 5 elements and each element is of type int,
the name, which we can use to refer to each element, is the following one:

Figure 2- 1:Array indexing

For example, to store the value 75 in the third element of the array variable day a suitable
sentence would be: day[2] = 75; //as the third element is found at index 2
And, for example, to pass the value of the third element of the array variable day to the variable
a , we could write:
a = day[2];
Therefore, for all the effects, the expression day[2] is like any variable of type int with the same
properties. Thus an array declaration enables us to create a lot of variables of the same type
with a single declaration and we can use an index to identify individual elements.
Notice that the third element of day is specified day[2] , since first is day[0] , second day[1] ,
and therefore, third is day[2] . By this same reason, its last element is day [4]. Since if we wrote
day [5], we would be acceding to the sixth element of day and therefore exceeding the size of
the array. This might give you either error or unexpected value depending on the compiler.
In C++ it is perfectly valid to exceed the valid range of indices for an Array, which can cause
certain detectable problems, since they do not cause compilation errors but they can cause
unexpected results or serious errors during execution. The reason why this is allowed will be
seen ahead when we begin to use pointers.
At this point it is important to be able to clearly distinguish between the two uses the square
brackets [ ] have for arrays.
• One is to set the size of arrays during declaration
• The other is to specify indices for a specific array element when accessing the elements
of the array
• We must take care of not confusing these two possible uses of brackets [ ] with arrays:

52
Eg:
int day[5]; // declaration of a new Array (begins with a type name)
day[2] = 75; // access to an element of the Array.

Other valid operations with arrays in accessing and assigning:


int a=1;
day [0] = a; day[a] = 5; b = day [a+2]; day [day[a]] = day [2] + 5;
day [day[a]] = day[2] + 5;
Eg: Arrays example ,display the sum of the numbers in the array

#include <iostream>

int day [ ] = {16, 2, 77, 40, 12071};

int n, result=0;

void main ( )

for ( n=0 ; n<5 ; n++ )

result += day[n];

cout << result;

getch();
}
Given the declaration above of a 100-element array the compiler reserves space for 100
consecutive floating point values and accesses these values using an index/subscript that takes
values from 0 to 99.
The first element in an array in C++ always has the index 0, and if the array has n elements the
last element will have the index n-1.
An array element is accessed by writing the identifier of the array followed by the subscript
in square brackets. Thus to set the 15th element of the array above to 1.5 the following
assignment is used:
annual_temp[14] = 1.5;
Note that since the first element is at index 0, then the ith element is at index i-1. Hence in
the above the 15th element has index 14.

53
An array element can be used anywhere an identifier may be used. Here are some examples
assuming the following declarations:
const int NE = 100, N = 50;
int i, j, count[N];
float annual_temp[NE];
float sum, av1, av2;
A value can be read into an array element directly, using cin.
cin>> count[i];
The element can be increased by 5,
count[i] = count[i] + 5;
or, using the shorthand form of the assignment
count[i] += 5;
Array elements can form part of the condition for an if statement, or indeed, for any other
logical expression:
if (annual_temp[j] < 10.0)
cout<< "It was cold this year "<<endl;
for statements are the usual means of accessing every element in an array. Here, the first NE
elements of the array annual_temp are given values from the input stream cin.
for (i = 0; i< NE; i++)
cin>>annual_temp[i];

The following code finds the average temperature recorded in the first ten elements of the array.
sum = 0.0;
for (i = 0; i <10; i++)
sum += annual_temp[i];
av1 = sum / 10;
Notice that it is good practice to use named constants, rather than literal numbers such as 10.
If the program is changed to take the average of the first 20 entries, then it is easy to forget to
change 10 to 20. If a const is used consistently, then changing its value will be all that is
necessary.
For example, the following example finds the average of the last k entries in the array. k could
either be a variable, or a declared constant. Observe that a change in the value of k will still
calculate the correct average (provided k<=NE).
sum = 0.0;
for (i = NE - k; i < NE; i++)
sum += annual_temp[i];
av2 = sum / k;

54
Important - C++ does not check that the subscript that is used to reference an array element
actually lies in the subscript range of the array. Thus C++ will allow the assignment of a value
to annual_temp[200], however the effect of this assignment is unpredictable. For example it
could lead to the program attempting to assign a value to a memory element that is outside the
program's allocated memory space.
This would lead to the program being terminated by the operating system. Alternatively it
might actually access a memory location that is within the allocated memory space of the
program and assign a value to that location, changing the value of the variable in your program
which is actually associated with that memory location, or overwriting the machine code of
your program.
Similarly reading a value from annual_temp[200] might access a value that has not been set
by the program or might be the value of another variable. It is the programmer's responsibility
to ensure that if an array is declared with n elements then no attempt is made to reference any
element with a subscript outside the range 0 to n-1. Using an index, or subscript, that is out of
range is called Subscript Overflow. Subscript overflow is one of the commonest causes of
erroneous results and can frequently cause very strange and hard to spot errors in programs.

2.3.3 Initialization of arrays


The initialization of simple variables in their declaration has already been covered. An array
can be initialized in a similar manner. In this case the initial values are given as a list enclosed
in curly brackets. For example initializing an array to hold the first few prime numbers could
be written as follows:
int primes[] = {1, 2, 3, 5, 7, 11, 13};
Note that the array has not been given a size, the compiler will make it large enough to hold
the number of elements in the list. In this case primes would be allocated space for seven
elements. If the array is given a size then this size must be greater than or equal to the number
of elements in the initialization list. For example:
int primes[10] = {1, 2, 3, 5, 7};
would reserve space for a ten element array but would only initialize the first five elements.
When declaring an array of local scope (within a function), if we do not specify the array
variable will not be initialized, so its content is undetermined until we store some values in it.
If we declare a global array (outside any function) its content will be initialized with all its
elements filled with zeros.
Thus, if in the global scope we declare: int day [5]; every element of day will be set initially
to 0:

55
Figure 2- 2:Array initialization to 0

But additionally, when we declare an Array, we have the possibility to assign initial values to each one
of its elements using curly brackets { } . For example: int day [5] = { 16, 2, 77, 40, 12071 };
The above declaration would have created an array like the following one:

Figure 2- 3: indexed Day Array elements


The number of elements in the array that we initialized within curly brackets { } must be equal
or less than the length in elements that we declared for the array enclosed within square brackets
[ ]. If we have less number of items for the initialization, the rest will be filled with zero.
For example, in the example of the day array we have declared that it had 5 elements and in
the list of initial values within curly brackets { } we have set 5 different values, one for each
element. If we ignore the last initial value (12071) in the above initialization, 0 will be taken
automatically for the last array element.
Because this can be considered as useless repetition, C++ allows the possibility of
leaving empty the brackets [ ], where the number of items in the initialization bracket
will be counted to set the size of the array.

int day [] = { 1, 2, 7, 4, 12,9 };


The compiler will count the number of initialization items which is 6 and set the size of the
array day to 6 (i.e.: day[6])
You can use the initialization form only when defining the array. You cannot use it later, and
cannot assign one array to another once. I.e.
int arr [ ] = {16, 2, 77, 40, 12071};
int ar [4];
ar[ ]={1,2,3,4};//not allowed
arr=ar;//not allowed
Note: when initializing an array, we can provide fewer values than the array elements. Eg:
int a [10] = {10, 2, 3};
in this case the compiler sets the remaining elements to zero.
Example Program: Printing Outliers in Data

56
The requirement specification for a program is:
A set of positive data values (200) are available. It is required to find the average value of these
values and to count the number of values that are more than 10% above the average value.
Since the data values are all positive a negative value can be used as a sentinel to signal the end
of data entry. Obviously this is a problem in which an array must be used since the values must
first be entered to find the average and then each value must be compared with this average.
Hence the use of an array to store the entered values for later re-use.
An initial algorithmic description is:
initialize.
enter elements into array and sum elements.
evaluate average.
scan array and count number greater than 10% above average.
output results.

This can be expanded to the complete algorithmic description:


set sum to zero.
set count to zero.
set nogt10 to zero.
enter first value.
while value is positive
{
put value in array element with index count.
add value to sum.
increment count.
enter a value.
}
average = sum/count.
for index taking values 0 to count-1
if array[index] greater than 1.1*average
then increment nogt10.
output average, count and nogt10.
In the above the variable nogt10 is the number greater than 10% above the average value. It is
easy to argue that after exiting the while loop, count is set to the number of positive numbers
entered. Before entering the loop count is set to zero and the first number is entered, that is
count is one less than the number of numbers entered. Each time round the loop another number
is entered and count is incremented hence count remains one less than the number of numbers
entered. But the number of numbers entered is one greater than the number of positive numbers
so count is therefore equal to the number of positive numbers.
A main() program written from the above algorithmic description is given below:
void main()
{

57
const int NE = 200; // maximum no of elements in array
float sum = 0.0; // accumulates sum
int count = 0; // number of elements entered
int nogt10 = 0; // counts no greater than 10%
// above average
float x; // holds each no as input
float indata[NE]; // array to hold input
float average; // average value of input values
int i; // control variable
// Data entry, accumulate sum and count
// number of +ve numbers entered
cout<< "Enter numbers, -ve no to terminate: " <<endl;
cin>> x;
while (x >= 0.0)
{
sum = sum + x;
indata[count] = x;
count = count + 1;
cin>> x;
}
// calculate average
average = sum/count;
// Now compare input elements with average
for (i = 0; i< count; i++)
{
if (indata[i] > 1.1 * average)
nogt10++;
}
// Output results
cout<< "Number of values input is " << n;
cout<<endl<< "Number more than 10% above average is "<< nogt10<<endl;
}
Since it was assumed in the specification that there would be less than 200 values the array size
is set at 200. In running the program less than 200 elements may be entered, if n elements
where n < 200 elements are entered then they will occupy the first n places in the array indata.
It is common to set an array size to a value that is the maximum we think will occur in practice,
though often not all this space will be used.
Example Program: Test of Random Numbers
The following program simulates the throwing of a dice by using a random number generator
to generate integers in the range 0 to 5. The user is asked to enter the number of trials and the
program outputs how many times each possible number occurred.

58
An array has been used to hold the six counts. This allows the program to increment the correct
count using one statement inside the loop rather than using a switch statement with six cases
to choose between variables if separate variables had been used for each count. Also it is easy
to change the number of sides on the dice by changing a constant. Because C++ arrays start at
subscript 0 the count for an i occurring on a throw is held in the i-1th element of this count
array. By changing the value of the constant die_sides the program could be used to simulate a
die_sides-sided die without any further change.
#include <iostream.h>
#include <stdlib.h> // time.h and stdlib.h required for
#include <time.h> // random number generation
void main()
{
const int die_sides = 6; // maxr-sided die
int count[die_sides]; // holds count of each
// possible value
int no_trials, // number of trials
int roll, // random integer
int i; // control variable
float sample; // random fraction 0 .. 1

// initialize random number generation and count


// array and input no of trials
srand(time(0));
for (i=0; i<die_sides; i++)
count[i] = 0;
cout<< "How many trials? ";
cin>>no_trials;
// carry out trials
for (i = 0; i<no_trials; i++)
{
sample = rand()/float(RAND_MAX);
roll = int ( die_sides * sample);
// returns a random integer in 0 to die_sides-1
count[roll]++; // increment count
}
// Now output results
for (i = 0; i < die_sides; i++)
{
cout<<endl<< "Number of occurrences of "<< (i+1) << " was "
<<count[i];
}
cout<<endl;
}

59
60
Week 3:- Practice:
Declaration of One dimensional Array
To declare an array in C++, the programmer specifies the type of the elements and the number
of elements required by an array as follows:

type arrayName [ arraySize ];

This is called a single-dimension array. The arraySize must be an integer constant greater than
zero and type can be any valid C++ data type. For example, to declare a 10-element array called
balance of type double, use this statement:

double balance[10];

Initializing Arrays You can initialize C++ array elements either one by one or using a single
statement as follows:

double balance[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};

The number of values between braces { } cannot be larger than the number of elements that we
declare for the array between square brackets [ ]. Following is an example to assign a single
element of the array: If you omit the size of the array, an array just big enough to hold the
initialization is created. Therefore, if you write:

double balance[] = {1000.0, 2.0, 3.4, 17.0, 50.0};

You will create exactly the same array as you did in the previous example.

balance[4] = 50.0;

The above statement assigns element number 5th in the array a value of 50.0. Array with 4th
index will be 5th, i.e., last element because all arrays have 0 as the index of their first element
which is also called base index. Following is the pictorial representation of the same array we
discussed above:

Accessing Array Elements

61
An element is accessed by indexing the array name. This is done by placing the index of the
element within square brackets after the name of the array. For example:

double salary = balance[9];

The above statement will take 10th element from the array and assign the value to salary
variable. Following is an example, which will use all the above mentioned three concepts with
declaration, assignment.

• Examine array c in the figure


– c is the array name
– c has 12 elements ( c[0], c[1], … c[11] )
• The value of c[0] is –45
• Brackets used to enclose an array subscript are actually an operator in C++

Example:

C++ Program to store 5 numbers entered by user in an array and display first and last number
only.

62
#include <iostream>

using namespace std;

int main( )

int n[5];

cout<<"Enter 5 numbers: ";

/* Storing 5 number entered by user in an array using for loop. */

for (int i = 0; i< 5; i++)

cin>>n[i];

cout<<"First number:"<<n[0]<<endl; //first element of an array is n[0]

cout<<"Last number: "<<n[4]; // last element of an array is n[SIZE_OF_ARRAY -


1]

return 0;

Copying Arrays
The assignment operator cannot be applied to array variables:

const int SIZE=10


int x [SIZE] ;

63
int y [SIZE] ;
x = y ; // Error - Illegal
Only individual elements can be assigned using the index operator, e.g., x[1] = y[2];.

To make all elements in 'x' the same as those in 'y' (equivalent to assignment), a loop has to
be used.

// Loop to do copying, one element at a time


for (int i = 0 ; i < SIZE; i++)
x[i] = y[i];

This code will copy the elements of array y into x, overwriting the original contents of x. A
loop like this has to be written whenever an array assignment is needed.

Notice the use of a constant to store the array size. This avoids the literal constant '10' appearing
number times in the code. If the code needs to be edited to use different size arrays, only the
constant needs to be changed. If the constant is not used, all the '10's would have to be changed
individually - it is easy to miss one out.

64
Assessments
I. Practical
1. Write an array declaration for the following
A) A list of 100 floating-point voltage
B) A list of 100 integer years
C) A list of 30 characters
D) A list of 32 floating-point velocities
2. Write a program to input the following values into an array named volts: 10.95, 16.32, 8.22,
15.98, 26.22, 13.54, 8.22, 6.45, and 173.86. After the data has been entered, have your
program output the values.
3. Write a program to input eight integer numbers into an array named temp. As each number
is input, add the number into a total. After all numbers are input, display the number and
their average.
4. Create an array that can hold ten integers, and get input from user. Display those values on
the screen, and then prompt the user for an integer. Search through the array, and count the
number of times the item is found.
5. Write a program that asks for an index and a number. Then it includes the number at the
indicated index of the array ={1,2,3,4,5,6} and moves a position forward (from u to u+1)
each element after the selected index.
6. Write a program that reverses a string and prints it on the screen.

65
Week 4:
2.4 Multidimensional arrays
Multidimensional arrays can be described as arrays of arrays. For example, a bi-dimensional
array can be imagined as a bi-dimensional table of a uniform concrete data type.

Figure 2- 4:2.4 Multidimensional array indexing

Matrix represents a bi-dimensional array of 3 per 5 values of type int . The way to
declare this array would be:
int matrix[3][5];
For example, the way to reference the second element vertically and fourth horizontally in an
expression would be:
matrix[1][3]

Figure 2- 5:Multidimensional array indexing

(Remember that array indices always begin by 0 )


Multidimensional arrays are not limited to two indices (two dimensions). They can
contain so many indices as needed, although it is rare to have to represent more than 3
dimensions. Just consider the amount of memory that an array with many indices may
need. For example:
char century [100][365][24][60][60];
Assigns a char for each second contained in a century, that is more than 3 billion chars ! What
would consume about 3000 megabytes of RAM memory if we could declare it?

66
Multidimensional arrays are nothing else than an abstraction, since we can simply obtain the
same results with a simple array by putting a factor between its indices:
int matrix [3][5]; is equivalent to
int matrix [15]; (3 * 5 = 15)

With the only difference that the compiler remembers for us the depth of each imaginary
dimension. Serve as example these two pieces of code, with exactly the same result, one using
bi-dimensional arrays and the other using only simple arrays:
// multidimensional array
#include <iostream>
#define WIDTH 5
#define HEIGHT 3
int matrix [HEIGHT][WIDTH];
int n,m;
int main ( )
{
for (n=0;n<HEIGHT;n++)
for (m=0;m<WIDTH;m++)
{
matrix [n][m]=(n+1)*(m+1);
}
return 0;
}
None of the programs above produce any output on the screen, but both assign values to the
memory block called matrix in the following way:

Figure 2- 6:matrix

We have used defined constants ( #define ) to simplify possible future modifications of


the program, for example, in case that we decided to enlarge the array to a height of 4
instead of 3 it would be enough by changing the line: #define HEIGHT 3 by the
following code
#define HEIGHT 4

67
C++ allows multidimensional arrays. Here is the general form of a multidimensional array
declaration:
type name[size1][size2]...[sizeN];
For example, the following declaration creates a three dimensional 5 . 10 . 4 integer array:
int threedim[5][10][4];
Two-Dimensional Arrays
The simplest form of the multidimensional array is the two-dimensional array. A two-
dimensional array is, in essence, a list of one-dimensional arrays. To declare a two-dimensional
integer array of size x,y, you would write something as follows:
type arrayName [ x ][ y ];
An array may have 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 most of the arrays that you create will
likely be of one or two dimensions.
A chess board is a good example of a two-dimensional array. One dimension represents the
eight rows, the other dimension represents the eight columns.
Such a representation does not correspond as closely to the real-world object as the two
dimensional array, however.
Suppose that when the game begins. The king id located in the fourth position in the first row.
Counting from zero that position corresponds to board[0][3] in the two dimensional array,
assuming that the first subscript corresponds to the row, and the second to the column.

2.4.1 Initializing Multidimensional Arrays


To initialize multidimensional arrays, you must assign the list of values to array elements in
order, with last array subscript changing while the first subscript holds steady. Therefore, if the
program has an array int theArray[5][3], the first three elements go int
theArray[0]; the next three into theArray[1]; and so forth.
The program initializes this array by writing
int theArray[5][3] ={ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
for the sake of clarity, the program could group the initializations with braces, as shown below.
int theArray[5][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}, {13, 14,15} };

The compiler ignores the inner braces, which clarify how the numbers are distributed.
Each value should be separated by comma, regardless of whither inner braces are include. The
entire initialization must set must appear within braces, and it must end with a semicolon.

68
2.4.2 Omitting the Array Size
If a one-dimensional array is initialized, the size can be omitted as it can be found from the
number of initializing elements:
int x[] = { 1, 2, 3, 4} ;
This initialization creates an array of four elements.
Note however:
int x[][] = { {1,2}, {3,4} } ; // error size cannot be omitted
int x[2][2] = { {1,2}, {3,4} } ;

69
Week 4 Practice:

Multi-dimensional array

To declare a multi-dimensional array, define the variable type, specify the name of the array
followed by square brackets which specify how many elements the main array has, followed
by another set of square brackets which indicates how many elements the sub-arrays have:

string letters[2][4];

As with ordinary arrays, you can insert values with an array literal - a comma-separated list
inside curly braces. In a multi-dimensional array, each element in an array literal is another
array literal.

string letters[2][4]={

{ "A", "B", "C", "D" },

{ "E", "F", "G", "H" }

};

Each set of square brackets in an array declaration adds another dimension to an array. An
array like the one above is said to have two dimensions.

Arrays can have any number of dimensions. The more dimensions an array has, the more
complex the code becomes. The following array has three dimensions:

Syntax of Multidimensional arrays

• Called two dimensional or 2-D arrays


• Represent tables of values with rows and columns
• Elements referenced with two subscripts ([x][y])
• In general, an array with m rows and n columns is called an m-by-n array
• Multidimensional arrays can have more than two dimensions

70
Eg:

int a[5][4]; // row then column twenty elements, numbered from [0][0] to [4][3]

Example of multidimensional array to access its elements


#include<iostream>
void main()
{
int SomeArray[5][2] = {{0,0},{1,2}, {2,4},{3,6}, {4,8}}
for ( int i=0; i<5; i++)
{
for (int j = 0; j<2;j++)
{
cout<<"SomeArray["<<i<<"]["<<j<<'']: '';
cout<<endl<<SomeArray[i][ j];
}
}
}
Example: Change Elements in a Multi-Dimensional Array

To change the value of an element, refer to the index number of the element in each of the
dimensions:

string letters[2][4] = {
{ "A", "B", "C", "D" },
{ "E", "F", "G", "H" }
};
letters[0][0] = "Z";
cout << letters[0][0]; // Now outputs "Z" instead of "A"

Example: Loop through a Multi-Dimensional Array

string letters[2][4] = {
{ "A", "B", "C", "D" },
{ "E", "F", "G", "H" }
};

for(int i = 0; i < 2; i++)


{
for(int j = 0; j < 4; j++)
{
cout << letters[i][j] << "\n";
}
}

This example shows how to loop through a three-dimensional array:

string letters[2][2][2] = {
{

71
{ "A", "B" },
{ "C", "D" }
},
{
{ "E", "F" },
{ "G", "H" }
}
};

for(int i = 0; i < 2; i++)


{
for(int j = 0; j < 2; j++)
{
for(int k = 0; k < 2; k++)
{
cout << letters[i][j][k] << "\n";
}
}
}

Why Multi-Dimensional Arrays?

Multi-dimensional arrays are great at representing grids. This example shows a practical use
for them. In the following example we use a multi-dimensional array to represent a small
game of Battleship:

// We put "1" to indicate there is a ship.


bool ships[4][4] = {
{ 0, 1, 1, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 1, 0 },
{ 0, 0, 1, 0 }
};

// Keep track of how many hits the player has and how many turns they have played
in these variables
int hits = 0;
int numberOfTurns = 0;

// Allow the player to keep going until they have hit all four ships
while (hits < 4) {
int row, column;
cout << "Selecting coordinates\n";

// Ask the player for a row


cout << "Choose a row number between 0 and 3: ";
cin >> row;

72
// Ask the player for a column
cout << "Choose a column number between 0 and 3: ";
cin >> column;

// Check if a ship exists in those coordinates


if (ships[row][column])
{
// If the player hit a ship, remove it by setting the value to zero.
ships[row][column] = 0;
// Increase the hit counter
hits++;
// Tell the player that they have hit a ship and how many ships are left
cout << "Hit! " << (4-hits) << " left.\n\n";
}
else
{
// Tell the player that they missed
cout << "Miss\n\n";
}
// Count how many turns the player has taken
numberOfTurns++;
}
cout << "Victory!\n";
cout << "You won in " << numberOfTurns << " turns";

Application of Array
An array is a linear data structure which is used to store collection of similar type of data each
of which can be accessed by using an index. The memory location of every element can be
calculated by using a simple mathematical formula. The main advantage of an array over any
other data structure is any location can be accessed in constant time in an array which makes it
so useful in the design of other data structures. So an array is used as a basic building block in
many data structures.

The following are some applications of arrays

• Arrays are used to implement vectors and lists which are an important part of C++ STL.
• Arrays are also used to implement stack and queues.
• Trees also use array implementation whenever possible as arrays are easy to handle
compared to pointers. Tress, in turn, are used to implement various other types of data
structures.
• Matrices which are an important part of the mathematical library in any programming
languages is implemented using arrays.
• Adjacency list implementation of graph uses vectors which are again implemented using
arrays.
• Data structures like a heap, map, and set use binary search tree and balanced binary trees
which uses can be implemented using arrays.

73
• Arrays are used to maintain multiple variables with the same name.
• CPU scheduling algorithms use implemented using arrays.
• All sorting algorithms use arrays at its core.
• Used in mathematical problems like matrices etc.
• They are used in the implementation of other data structures like linked lists etc.
• Database records are usually implemented as arrays.
• Used in lookup tables by computer.
• It effectively executes memory addressing logic wherein indices act as addresses to the
one-dimensional array of memory.

Here are some examples which shows the application of arrays using C++ programming
language.

1. Matrix Addition using Two Dimensional Arrays in C++


As an example let us see how we can use 2D arrays to perform matrix addition and print the
result

#include<iostream>

using namespace std;

int main()

int m1[5][5], m2[5][5], m3[5][5];

int i, j, r, c;

cout<<"Enter the no.of rows of the matrices to be added(max 5):";

cin>>r;

cout<<"Enter the no.of columns of the matrices to be added(max 5):";

cin>>c;

cout<<"\n1st Matrix Input:\n";

for(i=0;i<r;i++)

for(j=0;j<c;j++)

cout<<"\nmatrix1["<<i<<"]["<<j<<"]= ";

cin>>m1[i][j];

74
}

cout<<"\n2nd Matrix Input:\n";

for(i=0;i<r;i++)

for(j=0;j<c;j++)

cout<<"\nmatrix2["<<i<<"]["<<j<<"]= ";

cin>>m2[i][j];

cout<<"\nAdding Matrices...\n";

for(i=0;i<r;i++)

for(j=0;j<c;j++)

m3[i][j]=m1[i][j]+m2[i][j];

cout<<"\nThe resultant Matrix is:\n";

for(i=0;i<r;i++)

for(j=0;j<c;j++)

cout<<"\t"<<m3[i][j];

cout<<endl;

The ouput for the above example looks like the following.

75
• We take two matrices m1 and m2 with a maximum of 5 rows and 5 columns. And another
matrix m3 in which we are going to store the result,
• As user inputs, we took the number of rows and columns for both the matrices. Since we are
performing matrix addition, the number of rows and columns should be the same for both the
matrices,
• After that, we take both the matrices as user inputs, again using nested for loops,
• At this point, we have both the matrices m1 and m2,
• then we traverse through the m3 matrix, using two for loops and update the respective
elements m3[ i ][ j ] by the value of m1[i][j]+m2[i][j]. In this way, by the end of the outer for
loop, we get our desired matrix,
• At last, we print out the resultant matrix m3.

76
2. Pointer to a 2D Array in C++
#include<iostream>

using namespace std;

/* Usage of pointer to an array */

int main( )

int s[5][2] = {

{1, 2},

{1, 2},

{1, 2},

{1, 2}

};

int (*p)[2] ;

int i, j;

for (i = 0 ; i <= 3 ; i++)

p=&s[i];

cout<<"Row"<<i<<":";

for (j = 0; j <= 1; j++)

cout<<"\t"<<*(*p+j);

cout<<endl;

77
• In the above code, we try to print a 2D array using pointers,
• As we earlier did, at first we initialize the 2D array, s[5][2]. And also a pointer (*p)[2],
where p is a pointer which stores the address of an array with 2 elements,
• As we already said, we can break down a 2D array as an array of arrays. So in this case, s is
actually an array with 5 elements, which further are actually arrays with 2 elements for each
row.
• We use for loop to traverse over these 5 elements of the array, s. For each iteration, we
assign p with the address of s[i],
• Further, the inner for loop prints out the individual elements of the array s[i] using the pointer p.
Here, (*p + j) gives us the address of the individual element s[i][j], so using *(*p+j) we can
access the corresponding value.

3. Passing 2-D Array to a Function


In this section, we are going to learn how to pass a 2D array to any function and access the
corresponding elements. In the code below, we pass the array a, to two
functions show() and print() which prints out the passed 2D array.

#include<iostream>

using namespace std;

void show(int (*q)[4], int row, int col)

int i, j ;

for(i=0;i<row;i++)

78
for(j=0;j<col;j++)

cout<<"\t"<<*(*(q + i)+j);

cout<<"\n";

cout<<"\n";

void print(int q[][4], int row, int col)

int i, j;

for(i=0;i<row;i++)

for(j=0;j<col;j++)

cout<<"\t"<<q[i][j];

cout<<"\n";

cout<<"\n";

int main()

int a[3][4] = { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21} ;

show (a, 3, 4);

print (a, 3, 4);

return 0;

79
4. C++ Program to Sort the given matrix
Given n x n matrix. The problem is to sort the given matrix in strict order. Here strict order
means that matrix is sorted in a way such that all elements in a row are sorted in increasing
order and for row ‘i’, where 1 <= i <= n-1, first element of row 'i' is greater than or equal to
the last element of row 'i-1'.

Input : mat[][] = { {5, 4, 7},


{1, 3, 8},
{2, 9, 6} }
Output : 1 2 3
456
789
Approach: Create a temp[] array of size n^2. Starting with the first row one by one copy
the elements of the given matrix into temp[]. Sort temp[]. Now one by one copy the elements
of temp[] back to the given matrix.

// C++ implementation to sort the given matrix


#include <iostream>
using namespace std;

#define SIZE 10

// function to sort the given matrix


void sortMat(int mat[SIZE][SIZE], int n)
{
// temporary matrix of size n^2
int temp[n * n];
int k = 0;

80
// copy the elements of matrix one by one
// into temp[]
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
temp[k++] = mat[i][j];

// sort temp[]
sort(temp, temp + k);

// copy the elements of temp[] one by one


// in mat[][]
k = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
mat[i][j] = temp[k++];}
// function to print the given matrix
void printMat(int mat[SIZE][SIZE], int n)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++)
cout << mat[i][j] << " ";
cout << endl;
}}
// Driver program to test above
int main()
{
int mat[SIZE][SIZE] = { { 5, 4, 7 },{ 1, 3, 8 }, { 2, 9, 6 } };
int n = 3;
cout << "Original Matrix:";
printMat(mat, n);
sortMat(mat, n);
cout << "Matrix After Sorting:";
printMat(mat, n);
return 0;
}

Output:
Original Matrix:
547
138
296
Matrix After Sorting:
123
456
789

81
82
Assessments
I. Practical
1. Determine the output produced by the following program
#include <iostream>
int main()
{
int i, j,val[3][4]={8,16,9,52,3,15,27,6,14,25,2,10};
for (i=0;i<3;i++)
{
for(j=0;j<4;j++)
{
cout<<” “<<val[i][j];
}
}
return 0;
}
2. Write a C++ program to select the values in a four by five array of integers in increasing
order and store the selected values in a single dimensional array named sort. Use the
following values to initialize the array 16, 22, 99, 4, 18, -258, 4, 101, 5, 98, 105, 6, 15, 2,
45, 33, 88, 72, 16.
3. Write a program which reads two matrix and multiply them if possible.
4. Write a program which reads a 3 x 2 matrix and then calculates the sum of each row and
store that in a one dimension array.
5. what is the value of sum after this code executes?
int[][] matrix = {{1,1,2,2},{1,2,2,4},{1,2,3,4},{1,4,1,2}};
int sum = 0; int col = matrix[0].length - 2;
for (int row = 0; row < 4; row++)
{
sum = sum + matrix[row][col];
}

83
Week 5:

2.5 Strings representation and manipulation


What are Strings?
In all programs and concepts we have seen so far, we have used only numerical variables, used
to express numbers exclusively. But in addition to numerical variables there also exist strings
of characters that allow us to represent successive characters, like words, sentences, names,
texts, etc. Until now we have only used them as constants, but we have never considered
variables able to contain them.
In C++ there is no specific elementary variable type to store string of characters. In order to
fulfil this feature we can use arrays of type char, which are successions of char elements.
Remember that this data type (char) is the one used to store a single character, for that reason
arrays of them are generally used to make strings of single characters.
For example, the following array (or string of characters) can store a string up to 20 characters
long. You may imagine it thus:

char name [20];

This maximum size of 20 characters is not required to be always fully used. For example, name
could store at some moment in a program either the string of characters "Hello" or the string
"studying C++”. Therefore, since the array of characters can store shorter strings than its total
length, there has been reached a convention to end the valid content of a string with a null
character, whose constant can be written as '\0’.
We could represent name (an array of 20 elements of type char) storing the strings of
characters "Hello" and "Studying C++" in the following way:

The C++ Standard Library implements a powerful string class, which is very useful to handle
and manipulate strings of characters. However, because strings are in fact sequences of
characters, we can represent them also as plain arrays of char elements.
For example, the following array:
char jenny [20];
is an array that can store up to 20 elements of type char. It can be represented as:
jenny

Therefore, in this array, in theory, we can store sequences of characters up to 20 characters


long. But we can also store shorter sequences. For example, jenny could store at some point in

84
a program either the sequence "Hello" or the sequence "Merry Christmas", since both are
shorter than 20 characters.

Therefore, since the array of characters can store shorter sequences than its total length, a
special character is used to signal the end of the valid sequence: the null character, whose
literal constant can be written as '\0' (backslash, zero).

The array of 20 elements of type char, called jenny, can be represented storing the character’s
sequences "Hello" and "Merry Christmas" as:

H e l l o ‘\0’ M e r r y ‘\0’ C h r i s t m a s ‘\0’

Notice how after the valid content a null character ('\0') has been included in order to indicate
the end of the sequence. The panels in grey colour represent char elements with undetermined
values.
2.5.1 Initialization of Strings
Because strings of characters are ordinary arrays they fulfil same rules as any array. For
example, if we want to initialize a string of characters with predetermined values we
can do it in a similar way to any other array:
char mystring[] = { 'H', 'e', 'l', 'l', 'o', '\0' };
In this case we would have declared a string of characters (array) of 6 elements of type char
initialized with the characters that compose Hello plus a null character '\0' .
Nevertheless, string of characters have an additional way to initialize its values: using constant
strings.
In the expressions we have used in examples of previous chapters there have already appeared
several times constants that represented entire strings of characters. These are specified
enclosed between double quotes ( “ “ ), for example: "the result is: " is a constant string that
we have probably used in some occasion.

Unlike single quotes ( ' ) which allow to specify single character constants, double quotes ( " )
are constants that specify a succession of characters. These strings enclosed between double
quotes have always a null character ( '\0' ) automatically appended at the end.
Therefore we could initialize the string mystring with values by any of these two ways:
char mystring [] = { 'H', 'e', 'l', 'l', 'o', '\0' };
char mystring [] = "Hello";

In both cases the Array or string of characters mystring is declared with a size of 6 characters
(elements of type char ): the 5 characters that compose Hello plus a final null character ( '\0' )
which specifies the end of the string and that, in the second case, when using double quotes
( " ) it is automatically appended.

85
Before going further, you should note that the assignation of multiple constants like double-
quoted constants ( " ) to arrays are only valid when initializing the array, that is, at the moment
when declared.
The following expressions within a code are not valid for arrays

mystring="Hello";
mystring[] = "Hello";

neither would be:

mystring = { 'H', 'e', 'l', 'l', 'o', '\0' };

So remember: We can "assign" a multiple constant to an Array only at the moment of


initializing it. The reason will be more comprehensible when you know a bit more about
pointers, since then it will be clarified that an array is simply a constant pointer pointing to an
allocated block of memory. And because of this constant feature, the array itself cannot be
assigned any value, but we can assign values to each of the elements of the array.

At the moment of initializing an Array it is a special case, since it is not an assignation, although
the same equal sign ( =) is used. Anyway, have always present the rule previously underlined.
2.5.2 Assigning Values to Strings
Just like any other variables, array of character can store values using assignment operators.
But the following is not allowed.
mystring=”Hello”;
This is allowed only during initialization. Therefore, since the lvalue of an assignation can only
be an element of an array and not the entire array, what would be valid is to assign a string of
characters to an array of char using a method like this:
mystring[0] = 'H';
mystring[1] = 'e';
mystring[2] = 'l';
mystring[3] = 'l';
mystring[4] = 'o';
mystring[5] = '\0';
But as you may think, this does not seem to be a very practical method. Generally for assigning
values to an array, and more specifically to a string of characters, a series of functions like
strcpy are used. strcpy ( string copy ) is defined in the ( string.h ) library and can be called
the following way:
strcpy ( string1 , string2 );
This does copy the content of string2 into string1 .string2 can be either an array, a pointer, or
a constant string , so the following line would be a valid way to assign the constant string
"Hello" to mystring :

86
strcpy (mystring, "Hello");
For example:
#include <iostream>
#include <string>
int main ()
{
char szMyName [20];
strcpy (szMyName,"Abebe");
cout << szMyName;
return 0;
}

Initialization of null-terminated character sequences


Because arrays of characters are ordinary arrays they follow all their same rules. For example,
if we want to initialize an array of characters with some predetermined sequence of characters
we can do it just like any other array:
char myword[] = { 'H', 'e', 'l', 'l', 'o', '\0' };

In this case we would have declared an array of 6 elements of type char initialized with the
characters that form the word "Hello" plus a null character '\0' at the end.
But arrays of char elements have an additional method to initialize their values: using string
literals.

In the expressions we have used in some examples in previous chapters, constants that represent
entire strings of characters have already showed up several times. These are specified enclosing
the text to become a string literal between double quotes (").

Double quoted strings (") are literal constants whose type is in fact a null-terminated array of
characters. So string literals enclosed between double quotes always have a null character ('\0')
automatically appended at the end.

Therefore we can initialize the array of char elements called myword with a null-terminated
sequence of characters by either one of these two methods:
char myword [] = { 'H', 'e', 'l', 'l', 'o', '\0' };
char myword [] = "Hello";

In both cases the array of characters myword is declared with a size of 6 elements of type char:
the 5 characters that compose the word "Hello" plus a final null character ('\0') which specifies
the end of the sequence and that, in the second case, when using double quotes (") it is appended
automatically.

Notice that we are talking about initializing an array of characters in the moment it is being
declared, and not about assigning values to them once they have already been declared. In fact
because this type of null terminated arrays of characters are regular arrays we have the same

87
restrictions that we have with any other array, so we are not able to copy blocks of data with
an assignment operation.
Assuming mystext is a char[] variable, expressions within a source code like:
mystext = "Hello";
mystext[] = "Hello";
would not be valid, like neither would be:
The reason for this may become more comprehensible once you know a bit more about pointers,
since then it will be clarified that an array is in fact a constant pointer pointing to a block of
memory.
String in C++ is nothing but a sequence of character in which the last character is the null
character ‘\0’. The null character indicates the end of the string. Any array of character can be
converted into string type in C++ by appending this special character at the end of the array
sequence.
In C++ strings of characters are held as an array of characters, one character held in each
array element. In addition a special null character, represented by `\0', is appended to the end
of the string to indicate the end of the string. Hence if a string has n characters then it requires
an n+1 element array (at least) to store it. Thus the character `a' is stored in a single byte,
whereas the single-character string "a" is stored in two consecutive bytes holding the character
`a' and the null character.
A string variable s1 could be declared as follows:
char s1[10];
The string variable s1 could hold strings of length up to nine characters since space is needed
for the final null character. Strings can be initialized at the time of declaration just as other
variables are initialized. For example:
char s1[] = "example";
char s2[20] = "another example";
would store the two strings as follows:
s1 |e|x|a|m|p|l|e|\0|
s2 |a|n|o|t|h|e|r| |e|x|a|m|p|l|e|\0|?|?|?|?|
In the first case the array would be allocated space for eight characters that is space for the
seven characters of the string and the null character. In the second case the string is set by the
declaration to be twenty characters long but only sixteen of these characters are set, i.e. the
fifteen characters of the string and the null character. Note that the length of a string does not
include the terminating null character.
Using null-terminated sequences of characters
Null-terminated sequences of characters are the natural way of treating strings in C++, so they
can be used as such in many procedures. In fact, regular string literals have this type (char[])
and can also be used in most cases.

88
For example, cin and cout support null-terminated sequences as valid containers for sequences
of characters, so they can be used directly to extract strings of characters from cin or to insert
them into cout.
For example:
null-terminated sequences of characters
#include <iostream>
using namespace std;
int main ( )
{
char question[ ] = "Please, enter your first name: ";
char greeting[ ] = "Hello, ";
char yourname [80];
cout << question;
cin >> yourname;
cout << greeting << yourname <<"!";
return 0;
}

The output will be:


Please, enter your first name: Abebe
Hello, Abebe!
As you can see, we have declared three arrays of char elements. The first two were initialized
with string literal constants, while the third one was left uninitialized. In any case, we have to
specify the size of the array: in the first two (question and greeting) the size was implicitly
defined by the length of the literal constant they were initialized to. While for yourname we
have explicitly specified that it has a size of 80 chars.
Finally, sequences of characters stored in char arrays can easily be converted into string objects
just by using the assignment operator:

string mystring;
char myntcs[ ]="some text";
mystring = myntcs;

2.5.3 String Output


A string is output by sending it to an output stream, for example:

string s1;
cout<< "The string s1 is " << s1 <<endl;
would print
The string s1 is example
The setw(width) I/O manipulator can be used before outputting a string, the string will then be
output right-justified in the field width. If the field width is less than the length of the string

89
then the field width will be expanded to fit the string exactly. If the string is to be left-justified
in the field then the setiosflags manipulator with the argument ios::left can be used.

2.5.4 String Input


When the input stream cin is used space characters, newline etc. are used as separators and
terminators. Thus when inputting numeric data cin skips over any leading spaces and
terminates reading a value when it finds a white-space character (space, tab, newline etc.).
This same system is used for the input of strings, hence a string to be input cannot start with
leading spaces, also if it has a space character in the middle then input will be terminated on
that space character. The null character will be appended to the end of the string in the character
array by the stream functions. If the string s1 was initialized as in the previous section, then the
statement
cin>> s1;
would set the string s1 as follows when the string "first" is entered (without the double quotes)

|f|i|r|s|t|\0|e|\0|
Note that the last two elements are a relic of the initialization at declaration time. If the string
that is entered is longer than the space available for it in the character array then C++ will just
write over whatever space comes next in memory. This can cause some very strange errors
when some of your other variables reside in that space!
To read a string with several words in it using cin we have to call cin once for each word. For
example to read in a name in the form of a Christian name followed by a surname we might
use code as follows:
char christian[12], surname[12];
cout<< "Enter name ";
cin>>christian;
cin>> surname;
cout<< "The name entered was "<<christian<< " "<< surname;
The name would just be typed by the user as, for example, Abebe and the output would then
be
The name entered was Abebe
Where did the rest of the phrase go?
It turns the insertion operator >> consider a space to be a terminating character. Thus it will
read strings consisting of a single word, but anything typed after a space is thrown away.
To read text containing blanks we use another function, cin::get().

#include<iostream>
void main()
{
const int max=80;
char str[max];
cout<<"\n Enter a string;";

90
cin.get(str,max); // max avoid buffer overflow
cout<<"\n You entered : "<<str;
}

2.5.5 Reading multiple lines


We have solved the problem of reading strings with embedded blanks, but what about strings
with multiple lines? It turns out that the cin::get() function can take a third argument to help
out in this situation.
This argument specifies the character that tells the function to stop reading. The default value
of this argument is the newline('\n')character, but if you call the function with some other
character for this argument, the default will be overridden by the specified character.
In the next example, we call the function with a dollar sign ('$') as the third argument
//reads multiple lines, terminates on '$' character
#include<iostream>
void main ()
{
const int max=80;
char str[max];
cout<<"\n Enter a string:\n";
cin.get(str, max, '$'); //terminates with $
cout<<\n You entered:\n"<<str;
}
Now you can type as many lines of input as you want. The function will continue to accept
characters until you enter the terminated character $ (or until you exceed the size of the array.
Remember, you must still press Enter key after typing the '$' character.

2.5.6 String constants


You can initialize a string to a constant value when you define it. Here's an example'
#include<iostream>
void main( )
{
char str[] = "Welcome to C++ programming language";
cout<<str;
}
if you tried to the string program with strings that contain more than one word , you may have
unpleasant surprise. Copying string the hard way
The best way to understand the true nature of strings is to deal with them character by character
#include<iostream.h>
#include<string.h> //for strlen()
void main()

91
{
const int max=80;
char str1[]='' Oh, Captain, my Captain!" our fearful trip is done";
char str2[max];
for(int i=0; i<strlen(str1);i++)
str2[i]=str1[1];
str2[i]='\0';
cout<<endl;
cout<<str2;
}

92
Week 5: Practice

1. Functions to manipulate strings


The cstring library ( string.h ) defines many functions to perform some manipulation
operations with C-like strings (like already explained strcpy). Here you have a brief with the
most usual:
a) String length
Returns the length of a string, not including the null character (\0).
strlen (const char* string );
b) String Concatenation:
Appends src string at the end of dest string. Returns dest.

The string concatenation can have two forms, where the first one is to append the whole
content of the source to the destination the other will append only part of the source to the
destination.
• Appending the whole content of the source
strcat (char* dest , const char* src );
• Appending part of the source
strncat (char* dest , const char* src, int size ); Where size is the number
characters to be appended
c) String Copy:
Overwrites the content of the dest string by the src string. Returns dest.
The string copy can have two forms, where the first one is to copying the whole content of the
source to the destination and the other will copy only part of the source to the destination.
• Copy the whole content of the source
strcpy (char* dest , const char* src );
• Appending part of the source
strncpy (char* dest , const char* src, int size ); Where size is the number
characters to be copied
d) String Compare:
Compares the two string string1 and string2.
The string compare can have two forms, where the first one is to compare the whole content of
the two strings and the other will compare only part of the two strings.
• Copy the whole content of the source
strcmp (const char* string1 , const char* string2 );
• Appending part of the source
strncmp (const char* string1 , const char* string2, int size ); Where size is the
number characters to be compaired
Both string compare functions returns three different values:
• Returns 0 is the strings are equal
• Returns negative value if the first is less than the second string
• Returns positive value if the first is greater than the second string

93
2. Copying string the easy way
Of course you don't need to use for loop to copy a string. As you might have guesses, a library
function will do it for you. You can copy strings using strcpy or strncpy function. We assign
strings by using the string copy function strcpy. The prototype for this function is instring.h.
strcpy(destination, source);
strcpy copies characters from the location specified by source to the location specified by
destination. It stops copying characters after it copies the terminating null character.
• The return value is the value of the destination parameter.
You must make sure that the destination string is large enough to hold all of the characters in
the source string (including the terminating null character).
Example:
#include <iostream.h>
#include <string.h>
void main()
{
char me[20] = "David";
cout<< me <<endl;
strcpy(me, "YouAreNotMe");
cout<< me <<endl ;
return 0;
}
There is also another function strncpy, is like strcpy, except that it copies only a specified
number of characters.
strncpy(destination, source, int n);

It may not copy the terminating null character.


Example
#include <iostream>

#include <string>

void main()

char str1[] = "String test";

char str2[] = "Hello";

char one[10];

strncpy(one, str1, 9);

94
one[9] = '\0';

cout<< one <<endl;

strncpy(one, str2, 2);

cout<< one <<endl;

strcpy(one, str2);

cout<< one <<endl;

3. Concatenating strings
In C++ the + operator cannot normally be used to concatenate string, as it can in some
languages such as BASIC; that is you can't say
Str3 = str1 + str2;

You can use strcat() or strncat


The function strcat concatenates (appends) one string to the end of another string.
strcat(destination, source);

• The first character of the source string is copied to the location of the terminating null
character of the destination string.
• The destination string must have enough space to hold both strings and a terminating null
character.
Example:
#include <iostream>

#include <string>

void main()

char str1[30];

strcpy(str1, "abc");

cout<< str1 <<endl;

strcat(str1, "def");

cout<< str1 <<endl;

char str2[] = "xyz";

95
strcat(str1, str2);

cout<< str1 <<endl;

str1[4] = '\0';

cout<< str1 <<endl;

The function strncat is like strcat except that it copies only a specified number of characters.
strncat(destination, source, int n);

It may not copy the terminating null character.


Example:
#include <iostream>

#include <string>

void main() {

char str1[30];

strcpy(str1, "abc");

cout<< str1 <<endl;

strncat(str1, "def", 2);

str1[5] = '\0';

cout<< str1 <<endl;

char str2[] = "xyz";

strcat(str1, str2);

cout<< str1 <<endl;

str1[4] = '\0';

cout<< str1 <<endl;

4. Comparing strings
Strings can be compared using strcmp or strncmp functions. The function strcmp compares
two strings.

strcmp(str1, str2);

96
strcmp returns: <0 if str1 is less than str2

=0 if str1 is equal to str2

>0 if str1 is greater than str2

Example:
#include <iostream>

#include <string>

void main()

cout<<strcmp("abc", "def") <<endl;

cout<<strcmp("def", "abc") <<endl;

cout<<strcmp("abc", "abc") <<endl;

cout<<strcmp("abc", "abcdef") <<endl;

cout<<strcmp("abc", "ABC") <<endl;

The function strncmp is like strcmp except that it compares only a specified number of
characters.
strncmp(str1, str2, int n);

strncmp does not compare characters after a terminating null character has been found in one
of the strings.
Example:
#include <iostream.h>

#include <string.h>

void main()

cout<<strncmp("abc", "def", 2) <<endl;

cout<<strncmp("abc", "abcdef", 3) <<endl;

cout<<strncmp("abc", "abcdef", 2) <<endl;

cout<<strncmp("abc", "abcdef", 5) <<endl;

97
cout<<strncmp("abc", "abcdef", 20) <<endl;

98
Assessment
I. Practical
1. Define strlen function (i.e. write the function body of strlen)?
2. Define the strcmp function and the strncmp function ?
3. Define strcpy function and the strncpy function ?
4. Define strcat function and the strncat function ?
5. Write a program to store the ages of six of your friends in a single array. Store each of the six
ages using the assignment operator. print the ages on the screen ?
6. Write a C++ program that accepts 10 integers from the user and finally displays the smallest
value and the largest value.
7. Write a program that accepts ten different integers from the user and display these numbers
after sorting them in increasing order.
8. Write a program to store six of your friend’s ages in a single array. Assign the ages in a random
order. print the ages, from low to high, on-screen
9. Modify the program on Q8 to print the ages in descending order.
10. Write a C++ program that calculates the letter grades of 20 students. The program should
accept the mid result and the final result from the students. Use the appropriate validity control
mechanism to prevent wrong inputs.
11. Write a C++ program that has two functions toBinary and toDecimal. The program should
display a menu prompting the user to enter his choice. If the user selects toBinary, then the
function should accept a number in base ten and displays the equivalent binary representation.
The reverse should be done if the user selects toDecimal.
12. Develop a C++ program that accepts a word from the user and then checks whether the word
is palindrome or not. (NB a word is palindrome if it is readable from left to right as well as
right to left).
13. Write a C++ program that accepts a word from the user and then displays the word after
reversing it.
14. Develop a C++ program that accepts the name of a person and then counts how many vowels
the person’s name have.

99
15. Modify the question in Q14 in such a way that it should replace vowel characters with * in the
person name.
16. Write a program in C++ which read a three digit number and generate all the possible
permutation of numbers using the above digits. For example n = 123 then the permutations are
– 123, 213, 312, 132, 231, 321
17. Write a program which read a set of lines until you enter #.
18. Write a program which read two matrixes and then print a matrix which is addition of these
two matrixes.
19. Write a program which reads two matrices and multiply them if possible
20. Write a program which reads a 3 x 2 matrix and then calculates the sum of each row and store
that in a one dimension array.

100
Reference
[1]. Stephen R. Davis, C++ Weekend Crash, John Wiley & Sons, 2003
[2]. Herbert Schildt, C++: A Beginner's Guide, Second Edition 2nd Edition, McGraw Hill, 2003
[3]. P B Mahapatra, Programming in C++, S Chand, 2008
[4]. Ashok Kamthane, Programming in C++, Pearson, 2013
[5]. https://www.w3schools.com/cpp/
[6]. https://www.tutorialspoint.com/cplusplus/index.htm
[7]. https://www.learncpp.com

101
Chapter 3: Pointers

Lesson Plan

1. Learning objectives
• Be able to define pointer.
• Be able to define pointer variables.
• Be able to differentiate single and multi-dimensional array.
• Be able to apply the array variables in C++ programming.
2. Motivation
• Outputs through Question and Answer; repetitive discussion and using array variables;
• Solving a problem using pointers in C++.
3. Expectations or Outcomes
 Define the terminologies, differentiate pointer with references, explain pointer
variables; the assessment standard attached at the end of the job task sheet.
 Can write C++ instructions to solve any problem using the concept of arrays in
programming.
4. Equipment
• Desktop or Laptop computer.
• DEV C++ software
5. Practice contents/Activities/Safety
 Active practice; on declaring pointer variables, dynamic memory allocation of variab
les, using pointers with function.
 Active practice on single and multi-dimensional array.
6. Assessments
• How to declare pointer variables?
• How to apply pointer with functions?

7. Clean-up
 After finishing practice, computers should be properly shut down.
8. Independent practice/Follow-up activities
• Learning through assignment (practical Exercises)

9. Review/Reflection
Review the outcome of the practice, improvement measure and previous reflected opinions.

103
Week 6:

3.1 Pointers Introduction


We have already seen how variables are memory cells that we can access by an identifier. But
these variables are stored in concrete places of the computer memory. For our programs, the
computer memory is only a succession of 1 byte cells (the minimum size for a datum), each
one with a unique address.
A pointer is simply the address of a memory location and provides an indirect way of accessing
data in memory. A pointer variable is defined to ‘point to’ data of a specific type. For example:
int *ptr1; // pointer to an int
char *ptr2; // pointer to a char
The value of a pointer variable is the address to which it points. For example, given the
definitions
int num;
We can write:
ptr1 = &num;
The symbol & is the address operator; it takes a variable as argument and returns the memory
address of that variable. The effect of the above assignment is that the address of num is
assigned to ptr1. Therefore, we say that ptr1 points to num is illustrated diagrammatically below.

ptr1 num

Figure 4:1 A simple integer pointer.

Given that ptr1 points to num, the expression


*ptr1
dereferences ptr1 to get to what it points to, and is therefore equivalent to num. The symbol * is
the dereference operator; it takes a pointer as argument and returns the contents of the location
to which it points.
In general, the type of a pointer must match the type of the data it is set to point to. A pointer
of type void*, however, will match any type. This is useful for defining pointers which may
point to data of different types, or whose type is originally unknown. A pointer may be cast
(type converted) to another type.
For example,
ptr2 = (char*) ptr1;

104
converts ptr1 to char pointer before assigning it to ptr2.
Regardless of its type, a pointer may be assigned the value 0 (called the null pointer). The null
pointer is used for initializing pointers, and for marking the end of pointer-based data structures
(e.g., linked lists).

Dynamic Memory
In addition to the program stack (which is used for storing global variables and stack frames
for function calls), another memory area, called the heap, is provided. The heap is used for
dynamically allocating memory blocks during program execution. As a result, it is also called
dynamic memory. Similarly, the program stack is also called static memory.
Two operators are used for allocating and de-allocating memory blocks on the heap. The new
operator takes a type as argument and allocated a memory block for an object of that type. It
returns a pointer to the allocated block. For example,
int *ptr = new int;
char *str = new char[10];
allocate, respectively, a block for storing a single integer and a block large enough for storing
an array of 10 characters.
Memory allocated from the heap does not obey the same scope rules as normal variables. For
example, in
void Foo (void)
{
char *str = new char[10];
//...
}

When Foo returns, the local variable str is destroyed, but the memory block pointed to by str is
not. The latter remains allocated until explicitly released by the programmer.
The delete operator is used for releasing memory blocks allocated by new. It takes a pointer as
argument and releases the memory block to which it points. For example:

delete ptr; // delete an object


delete [] str; // delete an array of objects

Note that when the block to be deleted is an array, an additional [] should be included to indicate
this. Should delete be applied to a pointer which points to anything but a dynamically-allocated
object (e.g., a variable on the stack), a serious runtime error may occur. It is harmless to apply
delete to the 0 pointer. Dynamic objects are useful for creating data which last beyond the
function call which creates them.

105
Because of the limited memory resources, there is always the possibility that dynamic memory
may be exhausted during program execution, especially when many large blocks are allocated
and none released. Should new be unable to allocate a block of the requested size, it will return
0 instead. It is the responsibility of the programmer to deal with such possibilities.

Until now, in our programs, we have only had as much memory as we have requested in
declarations of variables, arrays and other objects that we included, having the size of all of
them to be fixed before the execution of the program. But, What if we need a variable amount
of memory that can only be determined during the program execution (runtime)?
For example, in case that we need a user input to determine the necessary amount of space.
The answer is dynamic memory, for which C++ integrates the operators new and delete.

Pointers are useful for creating dynamic objects during program execution. Unlike normal
(global and local) objects which are allocated storage on the runtime stack, a dynamic object
is allocated memory from a different storage area called the heap. Dynamic objects do not
obey the normal scope rules. Their scope is explicitly controlled by the programmer.

a) The New Operator


• In C++ new operator can create space dynamically i.e. at run time, and similarly delete
operator is also available which releases the memory taken by a variable and return memory to
the operating system.
• When the space is created for a variable at compile time this approach is called static. If space
is created at run time for a variable, this approach is called dynamic. See the following two
lines: int a[10];//creation of static array
int *a;
a = new int[10];//creation of dynamic array
• Lets have another example:
int * ptr3; ptr3 = new int [5];
• In this case, the operating system has assigned space for 5 elements of type int in the heap
and it has returned a pointer to its beginning that has been assigned to ptr3 . Therefore, now,
ptr3 points to a valid block of memory with space for 5 int elements.

Figure 4:2 A pointer memory.

You could ask what is the difference between declaring a normal array and assigning memory
to a pointer as we have just done. The most important one is that the size of an array must be a
constant value, which limits its size to what we decide at the moment of designing the program

106
before its execution, whereas the dynamic memory allocation allows assigning memory during
the execution of the program using any variable, constant or combination of both as size.
• The dynamic memory is generally managed by the operating system, and in the multi-
task interfaces can be shared between several applications, so there is a possibility that
the memory exhausts. If this happens and the operating system cannot assign the
memory that we request with the operator new , a null pointer will be returned. For that
reason it is recommendable to always verify if after a call to instruction new the
returned pointer is null:
int * ptr3; ptr3 = new int [5];
if (ptr3 == NULL) { // error assigning memory. Take measures.
};
• if ptr3 is NULL, it means that there is no enough memory location in the heap to be given for
ptr3.

b) Operator delete
• Since the necessity of dynamic memory is usually limited to concrete moments within a
program, once this one is no longer needed it shall be freed so that it become available for
future requests of dynamic memory. For this exists the operator delete , whose form is:
delete pointer ;
or
delete [] pointer ;
• The first expression should be used to delete memory allocated for a single element, and the
second one for memory allocated for multiple elements (arrays).
• In most compilers both expressions are equivalent and can be used without distinction,
although indeed they are two different operators and so must be considered for operator
overloading.
• In the following simple example, a program that memorizes numbers, does not have a limited
amount of numbers that can be introduced, thanks to the concept and power of pointer that we
request to the

A pointer is a variable which stores the address of another variable. The only difference
between pointer variable and regular variable is the data they hold.
There are two pointer operators in C++: & the address of operator

* The dereference operator


Whenever you see the & used with pointers, think of the words “address of.” The & operator
always produces the memory address of whatever it precedes. The * operator, when used with
pointers, either declares a pointer or dereferences the pointer’s value. The dereference operator
can be literally translated to "value pointed by" .

107
A pointer is simply the address of an object in memory. Generally, objects can be accessed in
two ways: directly by their symbolic name, or indirectly through a pointer. The act of getting
to an object via a pointer to it, is called dereferencing the pointer. Pointer variables are defined
to point to objects of a specific type so that when the pointer is dereference, a typed object is
obtained.

At the moment in which we declare a variable this one must be stored in a concrete location in
this succession of cells (the memory). We generally do not decide where the variable is to be
placed - fortunately that is something automatically done by the compiler and the operating
system on runtime, but once the operating system has assigned an address there are some cases
in which we may be interested in knowing where the variable is stored.

This can be done by preceding the variable identifier by an ampersand sign (&), which literally
means, "address of”. For example:
ptr= &var;
This would assign to variable ptr the address of variable var , since when preceding the name
of the variable var with the ampersand ( & ) character we are no longer talking about the
content of the variable, but about its address in memory.

We are going to suppose that var has been placed in the memory address 1776 and that we
write the following:

var=25; x=var; ptr = &var;


The result will be the one shown in the following diagram:

Figure 4:3 Example result.

We have assigned to x the content of variable var as we have done in many other occasions in
previous sections, but to ptr we have assigned the address in memory where the operating
system stores the value of var , that we have imagined that it was 1776 (it can be any address).
The reason is that in the allocation of ptr we have preceded var with an ampersand ( & )
character.

108
The variable that stores the address of another variable (like ptr in the previous example) is
what we call a pointer.

3.2 Declaring Pointers


• Is reserving a memory location for a pointer variable in the heap. Syntax:
type * pointer_name ;
• To declare a pointer variable called p_age, do the following:
int * p_age;
• Whenever the dereference operator, *, appears in a variable declaration, the variable being
declared is always a pointer variable.

3.3 Assigning values to pointers
• p_age is an integer pointer. The type of a pointer is very important. p_age can point only to
integer values, never to floating-point or other types.
• To assign p_age the address of a variable, do the following:
int age = 26;
int * p_age;
p_age = &age;
OR
int age = 26;
int * p_age = &age;
• Both ways are possible.
• If you wanted to print the value of age, do the following:

cout<<age;//prints the value of age


Or by using pointers you can do it as follows
cout<<*p_age;//dereferences p_age;

The dereference operator produces a value that tells the pointer where to point. Without the *,
(i.e cout<<p_age), a cout statement would print an address (the address of age). With the *, the
cout prints the value at that address.
You can assign a different value to age with the following statement:
age = 13; //assigns a new value to variable age
*p_age = 13 //assigns 13 as a value to the memory p_age points at.

N.B: the * appears before a pointer variable in only two places: when you declare a pointer
variable and when you dereference a pointer variable (to find the data it points to).
The following program is one you should study closely. It shows more about pointers and the
pointer operators, & and *, than several pages of text could do.

#...
#...

109
void main()
{
int num = 123; // a regular integer variable
int *p_num; //declares an integer pointer
cout<< “num is ”<<num<<endl;
cout<< “the address of num is ”<<&num<<endl;
p_num = &num;// puts address of num in p_num;
cout<< “*p_num is ”<<*p_num<<endl; //prints value of num
cout<< “p_num is ”<<p_num<<endl; //prints adress of P_num
getch();
}

3.4 Pointer to void


Note that we can’t assign the address of a float type variable to an integer pointer variable
and similarly the address of an integer variable cannot be stored in a float or character
pointer.
flaot y;
int x;
int *ip;
float *fp;
ip = &y; //illegal statement
fp = &x; //illegal statement
That means, if a variable type and pointer to type is same, then only we can assign the address
of variable to pointer variable. And if both are different type then we can’t assign the address
of variable to pointer variable but this is also possible in C++ by declaring pointer variable as
a void as follows: void *p;
Example:
void *p;
int x;
float y;
p = &x; //valid assignment
p = &y; //valid assignment
The difficulty on void pointers is that, void pointers cannot be dereferenced. They are aimed
only to store address and the dereference operator is not allowed for void pointers.

110
Week 6:- Practice

1. Assigning Addresses to Pointers


Here is how we can assign addresses to pointers:

int* pointVar, var;

var = 5;

// assign address of var to pointVar pointer

pointVar = &var;

Here, 5 is assigned to the variable var. And, the address of var is assigned to the pointVar
pointer with the code pointVar = &var.

2. Get the Value from the Address Using Pointers


To get the value pointed by a pointer, we use the * operator. For example:

int* pointVar, var;

var = 5;

// assign address of var to pointVar

pointVar = &var;

// access value pointed by pointVar

cout << *pointVar << endl; // Output: 5

In the above code, the address of var is assigned to pointVar. We have used the *pointVar to
get the value stored in that address.

When * is used with pointers, it's called the dereference operator. It operates on a pointer and
gives the value pointed by the address stored in the pointer. That is, *pointVar = var.

Example 1 : Working of C++ Pointers

#include <iostream>

using namespace std;

int main() {

int var = 5;

int* pointVar; // declare pointer variable

111
pointVar = &var; // store address of var

cout << "var = " << var << endl; // print value of var

cout << "Address of var (&var) = " << &var << endl// print address of var << endl;

cout << "pointVar = " << pointVar << endl; // print pointer pointVar

// print the content of the address pointVar points to

cout << "Content of the address pointed to by pointVar (*pointVar) = " << *pointVar <<
endl;

return 0;

Output

var = 5

Address of var (&var) = 0x61ff08

pointVar = 0x61ff08

Content of the address pointed to by pointVar (*pointVar) = 5

Exercise 1

Write a program that asks the user to enter integers as inputs to be stored in the variables 'a'
and 'b' respectively. There are also two integer pointers named ptrA and ptrB. Assign the
values of 'a' and 'b' to ptrA and ptrB respectively, and display them.

Solution

// Exercises: Pointers

112
// Exercise 1

#include <iostream>

using namespace std;

int main(){

int a; int b;

cout << "Enter value of A: ";

cin >> a;

cout << "Enter value of B: ";

cin >> b;

int *ptrA=&a;

int *ptrB=&b;

cout << "Value of ptrA is " << *ptrA << " sored in address "<< ptrA<<"\n";

cout << "Value of ptrB is " << *ptrB <<" sored in address "<< ptrB<<"\n";

return 0;

113
Assessment
I. Subjective Type Question
1. What is a pointer?
2. Explain why we use pointers in programming.
3. What is the difference between pointers and references?
4. Write the syntax of declaring a pointer variable with an example.

114
Week 7:

3.5 Arrays of Pointers


If you have to reserve many pointers for many different values, you might want to declare an
array of pointers. The following reserves an array of 10 integer pointer variables:

int *iptr[10]; //reserves an array of 10 integer pointers


The above statement will create the following structure in RAM
iptr[4] = &age;// makes iptr[4] point to address of age.

3.6 Pointer and arrays


The concept of array goes very bound to the one of pointer. In fact, the identifier of an
array is equivalent to the address of its first element, like a pointer is equivalent to the
address of the first element that it points to, so in fact they are the same thing.
For example, supposing these two declarations:
int numbers [20]; int * p;
The following allocation would be valid:
p = numbers;
At this point p and numbers are equivalent and they have the same properties, with the only
difference that we could assign another value to the pointer p whereas numbers will always
point to the first of the 20 integer numbers of type int with which it was defined. So, unlike p,
that is an ordinary variable pointer, numbers is a constant pointer (indeed that is an Array: a
constant pointer). Therefore, although the previous expression was valid, the following
allocation is not:
numbers = p;
Because numbers is an array (constant pointer), and no values can be assigned to constant
identifiers.
N.B: An array name is just a pointer, nothing more. The array name always points to the first
element stored in the array. Therefore, we can have the following valid C++ code:

int ara[5] = {10,20,30,40,50};


cout<< *(ara + 2); //prints ara[2];

The expression *(ara+2) is not vague at all if you remember that an array name is just a pointer
that always points to the array’s first element. *(ara+2) takes the address stored in ara, adds 2
to the address, and dereferences that location.

Consider the following character array:


char name[] = “C++ Programming”;
115
What output do the following cout statements produce?
cout<<name[0]; // ____C__
cout<<*name; // _____C__
cout<<*(name+3); //_________
cout<<*(name+0); //____C____

3.7 Pointer Advantage


You can’t change the value of an array name, because you can’t change constants. This explains
why you can’t assign an array a new value during a program’s execution:
eg: if Cname is array of characters then: Cname = “Football”; //invalid array assignment;

Unlike arrays, you can change a pointer variable. By changing pointers, you can make them
point to different values in memory. Have a look at the following code:

#...
#...
void main()
{
clrscr();
float v1 = 679.54;
float v2 = 900.18;
float * p_v;
p_v = &v1;
cout<< “\nthe first value is ”<<*p_v;
p_v = &v2;
cout<< “\nthe second value is ”<<*p_v;
getch();
}
You can use pointer notation and reference pointers as arrays with array notation. Study the
following program carefully. It shows the inner workings of arrays and pointer notation.

void main()
{
clrscr();
int ctr;
int iara[5] = {10,20,30,40,50};
int *iptr;
iptr = iara; //makes iprt point to array’s first element. Or iprt = &iara[0]
cout<< “using array subscripts:\n”
cout<< “iara\tiptr\n”;
for(ctr=0;ctr<5;ctr++)
{

116
cout<<iara[ctr]<< “\t”<< iptr[ctr]<< “\n”;
}
cout<< “\nUsing pointer notation\n”;
for(ctr=0;ctr<5;ctr++)
{
cout<< *(iara+ctr) << “\t” << *(iptr+ctr)<< “\n”;
}
getch();
}

Suppose that you want to store a person’s name and print it. Rather than using arrays, you can
use a character pointer. The following program does just that.
void main()
{
clrscr();
char *c = “Meseret Belete”;
cout<< “your name is : ”<<c;
}
Suppose that you must change a string pointed to by a character pointer, if the person’s name
in the above code is changed to Meseter Alemu: look at the following code:
void main()
{
char *c = “Meseret Belete”;
cout<< “your name is : ”<<c;
c = “Meseret Alemu”;
cout<< “\nnew person name is : ”<<c;
getch();
}
If c were a character array, you could never assign it directly because an array name can’t be
changed.

Pointer Arithmetic
In C++ one can add an integer quantity to or subtract an integer quantity from a pointer. This
is frequently used by programmers and is called pointer arithmetic. Pointer arithmetic is not
the same as integer arithmetic, because the outcome depends on the size of the object pointed
to. For example, suppose that an int is represented by 4 bytes. Now, given

char *str = "HELLO";


int nums[] = {10, 20, 30, 40};
int *ptr = &nums[0]; // pointer to first element

117
str++ advances str by one char (i.e., one byte) so that it points to the second character of "HELLO",
whereas ptr++ advances ptr by one int (i.e., four bytes) so that it points to the second element of
nums. The figure below illustrates this diagrammatically.

H E L L O \0 10 20 30 40

str ptr

str++ ptr++

Figure 4-4 :Pointer arithmetic

It follows, therefore, that the elements of "HELLO" can be referred to as *str, *(str + 1), *(str + 2),
etc. Similarly, the elements of nums can be referred to as *ptr, *(ptr + 1), *(ptr + 2), and *(ptr + 3).
Another form of pointer arithmetic allowed in C++ involves subtracting two pointers of the
same type. For example:

int *ptr1 = &nums[1];


int *ptr2 = &nums[2];
int n = ptr2 - ptr1;

Pointer arithmetic is very handy when processing the elements of an array. The following
shows as an example a string copying function similar to strcpy.

Example:
1 void CopyString (char *dest, char *src)
2 {
3 while (*dest++ = *src++)
4 ;
5 }
The condition of this loop assigns the contents of src to the contents of dest and then
increments both pointers. This condition becomes 0 when the final null
character of src is copied to dest.
In turns out that an array variable (such as nums) is itself the address of the first element of the
array it represents. Hence the elements of nums can also be referred to using pointer arithmetic
on nums, that is, nums[i] is equivalent to *(nums + i). The difference between nums and ptr is that
nums is a constant, so it cannot be made to point to anything else, whereas ptr is a variable and
can be made to point to any other integer.

Function Pointers
118
It is possible to take the address of a function and store it in a function pointer. The pointer can
then be used to indirectly call the function. For example,

int (*Compare)(const char*, const char*);


defines a function pointer named Compare which can hold the address of any function that takes
two constant character pointers as arguments and returns an integer. The string comparison
library function strcmp, for example, is such. Therefore:

Compare = &strcmp; // Compare points to strcmp function


The & operator is not necessary and can be omitted:
Compare = strcmp; // Compare points to strcmp function
Alternatively, the pointer can be defined and initialized at once:
int (*Compare)(const char*, const char*) = strcmp;
When a function address is assigned to a function pointer, the two types must match. The above
definition is valid because strcmp has a matching function prototype:
int strcmp(const char*, const char*);
Given the above definition of Compare, strcmp can be either called directly, or indirectly via
Compare. The following three calls are equivalent:
strcmp("Tom", "Tim"); // direct call
(*Compare)("Tom", "Tim"); // indirect call
Compare("Tom", "Tim"); // indirect call (abbreviated)

A common use of a function pointer is to pass it as an argument to another function; typically


because the latter requires different versions of the former in different circumstances. A good
example is a binary search function for searching through a sorted array of strings. This
function may use a comparison function (such as strcmp) for comparing the search string against
the array strings. This might not be appropriate for all cases. For example, strcmp is case-
sensitive. If we wanted to do the search in a non-case-sensitive manner then a different
comparison function would be needed.
References
A reference introduces an alias for an object. The notation for defining references is similar to
that of pointers, except that & is used instead of *. For example,
double num1 = 3.14;
double &num2 = num1; // num is a reference to num1
defines num2 as a reference to num1. After this definition num1 and num2 both refer to the same
object, as if they were the same variable. It should be emphasized that a reference does not
create a copy of an object, but merely a symbolic alias for it. Hence, after
num1 = 0.16;
both num1 and num2 will denote the value 0.16.
A reference must always be initialized when it is defined: it should be an alias for something.
It would be illegal to define a reference and initialize it later.
double &num3; // illegal: reference without an initializer
num3 = num1;

119
You can also initialize a reference to a constant. In this case a copy of the constant is made
(after any necessary type conversion) and the reference is set to refer to the copy.
int &n = 1; // n refers to a copy of 1
The reason that n becomes a reference to a copy of 1 rather than 1 itself is safety. Consider
what could happen if this were not the case.
int &x = 1;
++x;
int y = x + 1;
The 1 in the first and the 1 in the third line are likely to be the same object (most compilers do
constant optimization and allocate both 1’s in the same memory location). So although we
expect y to be 3, it could turn out to be 4. However, by forcing x to be a copy of 1, the compiler
guarantees that the object denoted by x will be different from both 1’s.

Typedefs
Typedef is a syntactic facility for introducing symbolic names for data types. Just as a reference
defines an alias for an object, a typedef defines an alias for a type. Its main use is to simplify
otherwise complicated type declarations as an aid to improved readability. Here are a few
examples:
typedef char string;
Typedef char Name[12];
typedef unsigned int uint;
The effect of these definitions is that String becomes an alias for char*, Name becomes an alias
for an array of 12 chars, and uint becomes an alias for unsigned int. Therefore:

string str; // is the same as: char *str;


Name name; // is the same as: char name[12];
uint n; // is the same as: unsigned int n;

The complicated declaration of Compare in Listing 3.7 is a good candidate for typedef:

typedef int (*Compare)(const char*, const char*);

int BinSearch (char *item, char *table[], int n, Compare comp)


{
//...
if ((cmp = comp(item, table[mid])) == 0)
return mid;
//...
}
The typedef introduces Compare as a new type name for any function with the given prototype.
This makes BinSearch’s signature arguably simpler.

120
121
Week 7:- Practice

Illustration of Function Pointers


Listing 1 illustrates using a function which takes a string parameter and returns a copy of the
string.

Listing 1:
1 #include <string.h>

2 char* CopyOf (const char *str)


3 {
4 char *copy = new char[strlen(str) + 1];

5 strcpy(copy, str);
6 return copy;
7 }

Annotation (analysis)
1 This is the standard string header file which declares a variety of functions for
manipulating strings.
4 The strlen function (declared in string.h) counts the characters in its string
argument up to (but excluding) the final null character. Because the null
character is not included in the count, we add 1 to the total and allocate an
array of characters of that size.
5 The strcpy function (declared in string.h) copies its second argument to its

first, character by character, including the final null character.

Listing 2 shows how the HighestTemp function (shown earlier in the earlier Listing 1) can be
improved using pointer arithmetic.

Listing 2:

122
1 int HighestTemp (const int *temp, const int rows, const int columns)
2 {
3 int highest = 0;
for (register i = 0; i < rows; ++i)
4 for (register j = 0; j < columns; ++j)
5 if (*(temp + i * columns + j) > highest)
6 highest = *(temp + i * columns + j);
7 return highest;
8 }
9

Annotation
1 Instead of passing an array to the function, we pass an int pointer and two
additional parameters which specify the dimensions of the array. In this way,
the function is not restricted to a specific array size.
6 The expression *(temp + i * columns + j) is equivalent to temp[i][j] in the previous
version of this function.

HighestTemp can be simplified even further by treating temp as a one-dimensional array of row
* column integers. This is shown in Listing 3

Listing 3
1 int HighestTemp (const int *temp, const int rows, const int columns)
2 {
3 int highest = 0;

4 for (register i = 0; i< rows * columns; ++i)


5 if (*(temp + i) > highest)
6 highest = *(temp + i);
7 return highest;
8 }

As shown in Listing 4, by making the comparison function a parameter of the search function,
we can make the latter independent of the former.

Listing 4

123
1 int BinSearch (char *item, char *table[ ], int n,
2 int (*Compare)(const char*, const char*))
3 {
4 int bot = 0;
5 int top = n - 1;
6 int mid, cmp;

7 while (bot <= top) {


8 mid = (bot + top) / 2;
9 if ((cmp = Compare(item,table[mid])) == 0)
10 return mid; // return item index
11 else if (cmp< 0)
12 top = mid - 1; // restrict search to lower half
13 else
14 bot = mid + 1; // restrict search to upper half
15 }
16 return -1; // not found
17 }

Annotation
1 Binary search is a well-known algorithm for searching through a sorted list of
items. The search list is denoted by table which is an array of strings of
dimension n. The search item is denoted by item.
2 Compare is the function pointer to be used for comparing item against the array
elements.
7 Each time round this loop, the search span is reduced by half. This is repeated
until the two ends of the search span (denoted by bot and top) collide, or until
a match is found.
9 The item is compared against the middle item of the array.
10 If item matches the middle item, the latter’s index is returned.
11 If item is less than the middle item, then the search is restricted to the lower
half of the array.
14 If item is greater than the middle item, then the search is restricted to the upper
half of the array.
16 Returns -1 to indicate that there was no matching item.
The following example shows how BinSearch may be called with strcmp passed as the
comparison function:
char *cities[] = {"Boston", "London", "Sydney", "Tokyo"};
cout<<BinSearch("Sydney", cities, 4, strcmp) << '\n';
This will output 2 as expected.

124
The most common use of references is for function parameters. Reference parameters
facilitates the pass-by-reference style of arguments, as opposed to the pass-by-value style
which we have used so far. To observe the differences, consider the three swap functions in
Listing 5.

Listing 5
1 void Swap1 (int x, int y) // pass-by-value (objects)
2 {
3 int temp = x;
4 x = y;
5 y = temp;
6 }

7 void Swap2 (int *x, int *y) // pass-by-value (pointers)


8 {
9 int temp = *x;
10 *x = *y;
11 *y = temp;
12 }

13 void Swap3 (int &x, int &y) // pass-by-reference


14 {
15 int temp = x;
16 x = y;
17 y = temp;
18 }

Annotation
1 Although Swap1 swaps x and y, this has no effect on the arguments passed to
the function, because Swap1 receives a copy of the arguments. What happens
to the copy does not affect the original.
7 Swap2 overcomes the problem of Swap1 by using pointer parameters instead.
By dereferencing the pointers, Swap2 gets to the original values and swaps
them.
13 Swap3 overcomes the problem of Swap1 by using reference parameters instead.
The parameters become aliases for the arguments passed to the function and
therefore swap them as intended.
Swap3 has the added advantage that its call syntax is the same as Swap1 and involves no
addressing or dereferencing. The following main function illustrates the differences:
int main (void)
{
int i = 10, j = 20;
Swap1(i, j); cout << i << ", " << j << '\n';
Swap2(&i, &j); cout<<i<< ", " << j << '\n';

125
Swap3(i, j); cout<<i<< ", " << j << '\n';
}

When run, it will produce the following output:

10, 20
20, 10
10, 20

126
Assessments

II. Practical Question


1. Write C++ program to swap two numbers using pointers

2. Write C++ program to add two numbers using pointers

3. Write C++ program to Sum of Array Elements using Pointers

4. Write C++ program to find length of string using pointer

5. Write C++ program to copy one string to another string using pointer

6. Write C++ program to concatenate two strings using pointer

7. Write C++ program to print the elements of the array in reverse order using a pointer

127
Reference
[1]. Stephen R. Davis, C++ Weekend Crash, John Wiley & Sons, 2003
[2]. Herbert Schildt, C++: A Beginner's Guide, Second Edition 2nd Edition, McGraw Hill,
2003
[3]. P B Mahapatra, Programming in C++, S Chand, 2008
[4]. Ashok Kamthane, Programming in C++, Pearson, 2013
[5]. https://www.w3schools.com/cpp/
[6]. https://www.tutorialspoint.com/cplusplus/index.htm
[7]. https://www.learncpp.com

128
Chapter 4: Function (Built in, User defined)
Lesson Plan
1. Learning objectives
• Be able to define modular programming.
• Be able to define and declare function.
• Be able to pass function arguments.
• Be able to know return values of a function
• Be able to apply inline and recursive functions.
2. Motivation

• Outputs through Question and Answer; repetitive discussion and using function in C++.
• Solving a problem using function in C++.
3. Expectations or Outcomes
 Define the terminologies, differentiate different types of function, explain function
(declaration, definition and calling); the assessment standard attached at the end of the
job task sheet.
 Can write C++ instructions to solve any problem using the concept of modular
programming.
4. Equipment
• Desktop or Laptop computer.
• DEV C++ software
5. Practice contents/Activities/Safety
 Active practice; on declaring function, defining function, calling function.
 Active practice on inline and recursive functions.
6. Assessments
• How to apply modular programming?
• How to create function using C++?
7. Clean-up
 After finishing practice, computers should be properly shut down.
8. Independent practice/Follow-up activities
• Learning through assignment (practical Exercises)
9. Review/Reflection
• Review the outcome of the practice, improvement measure and previous reflected
opinions.

129
Week 9:

4.1 Modular programming and Modules

Modular programming is breaking down the design of a program into individual components
(modules) that can be programmed and tested independently. It is a requirement for effective
development and maintenance of large programs and projects. With modular programming,
procedures of a common functionality are grouped together into separate modules. A program
therefore no longer consists of only one single part. It is now divided into several smaller parts
which interact and which form the whole program.

Definition of Functions

Modules in C++ are called functions. A function is a subprogram that can act on data and return
a value. Every C++ program has at least one function, main(). When your program starts,
main() is called automatically. main() might call other functions, some of which might call
still others. Each function has its own name, and when that name is encountered, the execution
of the program branches to the body of that function. When the function returns, execution
resumes on the next line of the calling function. When a program calls a function, execution
switches to the function and then resumes at the line after the function call. Well-designed
functions perform a specific and easily understood task. Complicated tasks should be broken
down into multiple functions, and then each can be called in turn. Functions come in two
varieties: user-defined and built-in. Built-in functions are part of your compiler package--they
are supplied by the manufacturer for your use. In this chapter we will discuss about user-defined
functions.

4.2 Declaring and Defining Functions


Using functions in your program requires that you first declare the function and that you then
define the function. The declaration tells the compiler the name, return type, and parameters of
the function. The definition tells the compiler how the function works. No function can be
called from any other function that hasn't first been declared. The declaration of a function is
called its prototype.

There are three ways to declare a function:

• Write your prototype into a file, and then use the #include directive to include it in your
program.
• Write the prototype into the file in which your function is used.
• Define the function before it is called by any other function. When you do this, the
definition acts as its own declaration.

130
Although you can define the function before using it, and thus avoid the necessity of creating
a function prototype, this is not good programming practice for three reasons. First, it is a bad
idea to require that functions appear in a file in a particular order. Doing so makes it hard to
maintain the program as requirements change. Second, it is possible that function A() needs to
be able to call function B(), but function B() also needs to be able to call function A() under
some circumstances. It is not possible to define function A() before you define function B()
and also to define function B() before you define function A(), so at least one of them must be
declared in any case. Third, function prototypes are a good and powerful debugging technique.
If your prototype declares that your function takes a particular set of parameters, or that it
returns a particular type of value, and then your function does not match the prototype, the
compiler can flag your error instead of waiting for it to show itself when you run the program.

Function Prototypes

Many of the built-in functions you use have their function prototypes already written in the
files you include in your program by using #include. For functions you write yourself, you
must include the prototype. The function prototype is a statement, which means it ends with a
semicolon. It consists of the function's return type, name, and parameter list. The parameter list
is a list of all the parameters and their types, separated by commas.

Function Prototype Syntax:

return_type function_name ( [type [parameterName1] type [parameterName2]]...);

The function prototype and the function definition must agree exactly about the return type,
the name, and the parameter list. If they do not agree, you will get a compile-time error. Note,
however, that the function prototype does not need to contain the names of the parameters, just
their types. A prototype that looks like this is perfectly legal:

long Area(int, int);

This prototype declares a function named Area() that returns a long and that has two
parameters, both integers. Although this is legal, it is not a good idea. Adding parameter names
makes your prototype clearer. The same function with named parameters might be

long Area(int length, int width);

It is now obvious what this function does and what the parameters are. Note that all functions
have a return type. If none is explicitly stated, the return type defaults to int. Your programs
will be easier to understand, however, if you explicitly declare the return type of every function,
including main().

Function Prototype Examples

long FindArea(long length, long width);// returns long, has two parameters

131
void PrintMessage(int messageNumber);// returns void, has one parameter

int GetChoice(); // returns int, has no parameters

BadFunction(); // returns int, has no parameters

4.3 Defining the Function


The definition of a function consists of the function header and its body. The header is exactly
like the function prototype, except that the parameters must be named, and there is no
terminating semicolon. The body of the function is a set of statements enclosed in braces.
Function Definition Syntax

return_type function_name ( [type parameterName1], [type parameterName2]...)

statements;

A function prototype tells the compiler the return type, name, and parameter list. Functions are
not required to have parameters, and if they do, the prototype is not required to list their names,
only their types. A prototype always ends with a semicolon (;). A function definition must
agree in return type and parameter list with its prototype. It must provide names for all the
parameters, and the body of the function definition must be surrounded by braces. All
statements within the body of the function must be terminated with semicolons, but the function
itself is not ended with a semicolon; it ends with a closing brace. If the function returns a value,
it should end with a return statement, although return statements can legally appear
anywhere in the body of the function. Every function has a return type. If one is not explicitly
designated, the return type will be int. Be sure to give every function an explicit return type.
If a function does not return a value, its return type will be void.

Function Definition Examples

long Area(long l, long w)


{
return l * w;
}
void PrintMessage(int whichMsg)
{
if (whichMsg == 0)
cout<< "Hello.\n";
if (whichMsg == 1)

132
cout<< "Goodbye.\n";
if (whichMsg> 1)
cout<< "I'm confused.\n";
}
Function Statements

There is virtually no limit to the number or types of statements that can be in a function body.
Although you can't define another function from within a function, you can call a function, and
of course main() does just that in nearly every C++ program. Functions can even call
themselves, which is discussed soon, in the section on recursion. Although there is no limit to
the size of a function in C++, well-designed functions tend to be small. Many programmers
advise keeping your functions short enough to fit on a single screen so that you can see the
entire function at one time. This is a rule of thumb, often broken by very good programmers,
but a smaller function is easier to understand and maintain. Each function should carry out a
single, easily understood task. If your functions start getting large, look for places where you
can divide them into component tasks.

Execution of Functions

When you call a function, execution begins with the first statement after the opening brace ({).
Branching can be accomplished by using the if statement. Functions can also call other
functions and can even call themselves (see the section "Recursion," later in this chapter). Each
function has its own name, and when that name is encountered, the execution of the program
branches to the body of that function. When the function returns, execution resumes on the next
line of the calling function. This flow is illustrated in the following figure.

Figure 4-1: Execution of Functions

133
4.4 Scope of variables

A variable has scope, which determines how long it is available to your program and where it
can be accessed. There are two scopes Local and Global.

Local Variables

Not only can you pass in variables to the function, but you also can declare variables within
the body of the function. This is done using local variables, so named because they exist only
locally within the function itself. When the function returns, the local variables are no longer
available. Local variables are defined like any other variables. The parameters passed in to the
function are also considered local variables and can be used exactly as if they had been defined
within the body of the function. Variables declared within the function are said to have "local
scope." That means that they are visible and usable only within the function in which they are
defined. In fact, in C++ you can define variables anywhere within the function, not just at its
top. The scope of the variable is the block in which it is defined. Thus, if you define a variable
inside a set of braces within the function, that variable is available only within that block.
Listing 4.1 is an example of using parameters and locally defined variables within a function.

Example: The use of local variables and parameters.

1: #include <iostream>
3: float Convert(float);
4: int main()
5: {
6: float TempFer;
7: float TempCel;
9: cout<< "Please enter the temperature in Fahrenheit: ";
10: cin>>TempFer;
11: TempCel = Convert(TempFer);
12: cout<< "\nHere's the temperature in Celsius: ";
13: cout<<TempCel<<endl;
14: return 0;
15: }
17: float Convert(float TFer)
18: {
19: float TCel;

134
20: TCel = ((TFer - 32) * 5) / 9;
21: return TCel;
22: }

Output:
Please enter the temperature in Fahrenheit: 212
Here's the temperature in Celsius: 100
Please enter the temperature in Fahrenheit: 32
Here's the temperature in Celsius: 0
Please enter the temperature in Fahrenheit: 85
Here's the temperature in Celsius: 29.4444

Analysis: On lines 6 and 7, two float variables are declared, one to hold the temperature in
Fahrenheit and one to hold the temperature in degrees Celsius. The user is prompted to enter a
Fahrenheit temperature on line 9, and that value is passed to the function Convert().
Execution jumps to the first line of the function Convert() on line 19, where a local variable,
named TCel, is declared. Note that this is local variable that exists only within the function
Convert(). The value passed as a parameter, TFer, is also just a local copy of the variable
passed in by main().The local function variable TCel is assigned the value that results from
subtracting 32 from the parameter TFer, multiplying by 5, and then dividing by 9. This value
is then returned as the return value of the function, and on line 11 it is assigned to the variable
TempCelin the main() function. The value is printed on line 13. The program is run three times.
The first time, the value 212 is passed in to ensure that the boiling point of water in degrees
Fahrenheit (212) generates the correct answer in degrees Celsius (100). The second test is the
freezing point of water. The third test is a random number chosen to generate a fractional result.

Variables declared within a block are scoped to that block; they can be accessed only within
that block and "go out of existence" when that block ends. Global variables have global scope
and are available anywhere within your program. Normally scope is obvious, but there are
some tricky exceptions. Currently, variables declared within the header of a for loop (for int i
= 0; i<SomeValue; i++) are scoped to the block in which the for loop is created.

Global Variables

Variables defined outside of any function have global scope and thus are available from any
function in the program, including main(). Local variables with the same name as global
variables do not change the global variables. A local variable with the same name as a global
variable hides the global variable, however. If a function has a variable with the same name as
a global variable, the name refers to the local variable--not the global--when used within the
function. Listing 4.2 illustrates these points.

Example: Demonstrating global and local variables

135
1: #include <iostream.h>
2: void myFunction(); // prototype
4: int x = 5, y = 7; // global variables
5: int main()
6: {
8: cout<< "x from main: " << x << "\n";
9: cout<< "y from main: " << y << "\n\n";
10: myFunction();
11: cout<< "Back from myFunction!\n\n";
12: cout<< "x from main: " << x << "\n";
13: cout<< "y from main: " << y << "\n";
14: return 0;
15: }
17: void myFunction()
18: {
19: int y = 10;
21: cout<< "x from myFunction: " << x << "\n";
22: cout<< "y from myFunction: " << y << "\n\n";
23: }
Output:
x from main: 5
y from main: 7
x from myFunction: 5
y from myFunction: 10
Back from myFunction!
x from main: 5
y from main: 7

Analysis: This simple program illustrates a few key, and potentially confusing, points about
local and global variables. On line 1, two global variables, x and y, are declared. The global
variable x is initialized with the value 5, and the global variable y is initialized with the value
7. On lines 8 and 9 in the function main(), these values are printed to the screen. Note that the
function main() defines neither variable; because they are global, they are already available to
main().

When myFunction() is called on line 10, program execution passes to line 18, and a local
variable, y, is defined and initialized with the value 10. On line 21, myFunction() prints the
value of the variable x, and the global variable x is used, just as it was in main(). On line 22,
however, when the variable name y is used, the local variable y is used, hiding the global
variable with the same name. The function call ends, and control returns to main(), which
again prints the values in the global variables. Note that the global variable y was totally
unaffected by the value assigned to myFunction()'s local y variable.

Global Variables: A Word of Caution

136
In C++, global variables are legal, but they are almost never used. Global variables are
dangerous because they are shared data, and one function can change a global variable in a way
that is invisible to another function. This can and does create bugs that are very difficult to find.

Scope resolution operator

When a local variable has the same name as a global variable, all references to the variable name
made with in the scope of the local variable. This situation is illustrated in the following program.

# include<iostream>
float num = 42.8; //global variable
int main()
{
float num = 26.4; //local variable
cout<<”the value of num is:”<<num<<endl;
return 0;
}

The output of the above program is:


the value of num is: 26.4

As shown by the above output, the local variable name takes precedence over the global
variable. In such cases, we can still access the global variable by using C++’s scope resolution
operator (::). This operator must be placed immediately before the variable name, as in ::num.
When used in this manner, the :: tells the compiler to use global variable.E.g

float num = 42.8; //global variable


int main()
{
float num = 26.4; //local variable
cout<<”the value of num is:”<< ::num<<endl;
return 0;
}

The out is:


the value of the number is 42.8

As indicated the above output, the scope resolution operator causes the global, rather the local
variable to be accessed.

137
Week 9:- Practice

1. Declaration of Functions
• Functions must be declared before use
• The declaration tells the compiler
– The name,
– Return type,
– Parameters of the function
• Three ways
– Write your prototype into a file, and then use the #include directive to include it in
your program.
– Write the prototype into the file in which your function is used.
– Define the function before it is called by any other function.
• The declaration of a function is called its prototype
• Is a statement - it ends with a semicolon
• It consists of the function's
– return type,
– name,
– parameter list
• Syntax

return_type function_name (type [parameterName1], type [ParameterName2] ... );

E.g.

long int Area(int, int);

or

long int Area(int length, int width);

2. Defining a Function
• The definition tells the compiler how the function works.
• Consists of :
– the function header :
• like the function prototype except that the parameters must be named
• there is no terminating semicolon
– its body
• the task of the function

Syntax

138
return_type function_name(parameter declarations)

function owned variable declarations;

statements;

Eg:

long Area(long l, long w)

return l * w;

• The return statement without any value is typically used to exit the function early
• C++ does not allow nested functions
• The definition of one function cannot be included in the body of another function. A
function definition must agree in return type and parameter list with its prototype

3. Calling a Function
Function can be called in 2 ways. (a) Call by value (b) Call by reference

A. Call by Value:
This is one way of data transformation from calling portion to called portion. Means changes
inside the function cannot affect the main program.

B. Call by reference:
This is two way of data transformation from calling portion to called portion and called portion
to calling portion. Means when function is called by reference, changes inside the function
affect main program also. When function is called, argument corresponding to a reference
parameter is not copied. A reference is an alias for another variable & when we specify a
function argument as a reference type, function will use pass-by-reference technique for
passing the variables. Reason for this is because the parameter name simply becomes alias for
the argument value in the calling program. Whenever variable name is used in the body, it will
access argument value in the calling function directly.

//An example program illustrating Call_by_value and Call-by_reference

#include<iostream>

using namespace std;


139
int main()

int x,y,p,q; Local variable declaration

void swap1( int p, int q);


Function prototypes
void swap2( int &x, int &y);

cout<<"enter values for p,q,x and y: ";

cin>>p>>q>>x>>y;

swap1(p,q); Function calling

cout<<" p,q after calling swap1: "<<endl;

cout<<" p = "<<p<<" and q = "<<q<<endl;

swap2(x,y); x, y called as actual parameters

cout<<" x,y after calling swap2: "<<endl;

cout<<" x = "<<x<<" and y = "<<y<<endl;

p, q called as formal parameters

void swap1(int p, int q) called/definition function

int temp;

temp = p; Body of the function


p = q;

q = temp;

void swap2(int &x, int &y)

int temp;

temp = x;

x = y;

140
y = temp;

• To call a function, use the function name followed by () and ;

printHeading();

• When called, program executes the body of the called function

• After the function terminates, execution resumes in the calling function at point of call.

// Creating and using a programmer-defined function.


#include <iostream.h>
Function prototype: specifies data types
int square( int ); // function prototype of arguments and return values.
square expects an int, and returns
int main() an int.
{
// loop 10 times and calculate and output
// square of x each time
for ( int x = 1; x <= 10; x++ )
cout << square( x ) << " "; // function call

cout << endl;


Parentheses () cause function to be called.
When done, it returns the result.
return 0; // indicates successful termination

} // end main

// square function definition returns square of an integer


int square( int y ) // y is a copy of argument to function
{
return y * y; // returns square of y as an int
Definition of square. y is a
copy of the argument passed.
} // end function square Returns y * y, or y squared.

1 4 9 16 25 36 49 64 81 100
22

Listing 4.1 demonstrates a program that includes a function prototype for the Area() function.

Listing 4.1. A function declaration and the definition and use of that function.

141
1: // Listing 4.1 - demonstrates the use of function prototypes

3: typedef unsigned short USHORT;

4: #include <iostream.h>

5: int FindArea(int length, int width); //function prototype

7: int main()

8: {

9: int lengthOfYard;

10: int widthOfYard;

11: int areaOfYard;

13: cout<< "\nHow wide is your yard? ";

14: cin>>widthOfYard;

15: cout<< "\nHow long is your yard? ";

16: cin>>lengthOfYard;

18: areaOfYard= FindArea(lengthOfYard,widthOfYard);

20: cout<< "\nYour yard is ";

21: cout<<areaOfYard;

22: cout<< " square feet\n\n";

23: return 0;

24: }

26: int FindArea(int l, int w)

27: {

28: return l * w;

29: }

Output:

How wide is your yard? 100

How long is your yard? 200

Your yard is 20000 square feet

142
Analysis: The prototype for the FindArea() function is on line 5. Compare the prototype with
the definition of the function on line 26. Note that the name, the return type, and the parameter
types are the same. If they were different, a compiler error would have been generated. In fact,
the only required difference is that the function prototype ends with a semicolon and has no
body. Also note that the parameter names in the prototype are length and width, but the
parameter names in the definition are l and w. The names in the prototype are not used; they
are there as information to the programmer. When they are included, they should match the
implementation when possible. This is a matter of good programming style and reduces
confusion, but it is not required, as you see here.

The arguments are passed in to the function in the order in which they are declared and defined,
but there is no matching of the names. Had you passed in widthOfYard, followed by
lengthOfYard, the FindArea() function would have used the value in widthOfYard for
length and lengthOfYard for width. The body of the function is always enclosed in braces,
even when it consists of only one statement, as in this case.

Listing 4.2. Variables scoped within a block.

1: // Listing 4.2 - demonstrates variables


2: // scoped within a block
4: #include <iostream.h>
6: void myFunc();
8: int main()
9: {
10: int x = 5;
11: cout<< "\nIn main x is: " << x;
13: myFunc();
15: cout<< "\nBack in main, x is: " << x;
16: return 0;
17: }
19: void myFunc()
20: {
22: int x = 8;
23: cout<< "\nInmyFunc, local x: " << x <<endl;
25: {
26: cout<< "\nIn block in myFunc, x is: " << x;
28: int x = 9;
30: cout<< "\nVery local x: " << x;
31: }
33: cout<< "\nOut of block, in myFunc, x: " << x <<endl;
34: }
Output:
In main x is: 5
In myFunc, local x: 8
In block in myFunc, x is: 8
Very local x: 9

143
Out of block, in myFunc, x: 8
Back in main, x is: 5

Analysis: This program begins with the initialization of a local variable, x, on line 10, in
main(). The printout on line 11 verifies that x was initialized with the value 5. MyFunc() is
called, and a local variable, also named x, is initialized with the value 8 on line 22. Its value is
printed on line 23. A block is started on line 25, and the variable x from the function is printed
again on line 26. A new variable also named x, but local to the block, is created on line 28 and
initialized with the value 9. The value of the newest variable x is printed on line 30. The local
block ends on line 31, and the variable created on line 28 goes "out of scope" and is no longer
visible.

When x is printed on line 33, it is the x that was declared on line 22. This x was unaffected by
the x that was defined on line 28; its value is still 8. On line 34, MyFunc() goes out of scope,
and its local variable x becomes unavailable. Execution returns to line 15, and the value of the
local variable x, which was created on line 10, is printed. It was unaffected by either of the
variables defined in MyFunc(). Needless to say, this program would be far less confusing if
these three variables were given unique names!

144
Assessments

Practical
1. Write a C++ program using function which accept three integers as an argument and return
its product. Call this function from main() and print the results in the main().
2. Write a program that ask for two numbers, compare them and show the maximum.
Declare a function called max that compares the numbers and returns the maximum.
3. Write a C++ program which determines whether the given number is even or odd by
declaring function.
4. Write an int function cube () that returns the cube of its single int formal parameter.
5. Write a float function triangle() that computes the area of a triangle using its two formal
parameters h and w, where h is the height and w is the length of the bases of the triangle.
6. Write a program that accepts a positive integer from the user and displays the factorial of
the given number. You should use a recursive function called factorial() to calculate the
factorial of the number.

145
Week 10:

4.5 Function Arguments


Function arguments do not have to all be of the same type. It is perfectly reasonable to write a
function that takes an integer, two longs, and a character as its arguments. Any valid C++
expression can be a function argument, including constants, mathematical and logical
expressions, and other functions that return a value.

Using Functions as Parameters to Functions

Although it is legal for one function to take as a parameter a second function that returns a
value, it can make for code that is hard to read and hard to debug. As an example, say you have
the functions double(), triple(), square(), and cube(), each of which returns a value. You
could write

Answer = (double(triple(square(cube(myValue)))));

This statement takes a variable, myValue, and passes it as an argument to the function cube(),
whose return value is passed as an argument to the function square(), whose return value is
in turn passed to triple(), and that return value is passed to double(). The return value of
this doubled, tripled, squared, and cubed number is now passed to Answer.

It is difficult to be certain what this code does (was the value tripled before or after it was
squared?), and if the answer is wrong it will be hard to figure out which function failed. An
alternative is to assign each step to its own intermediate variable:

unsigned long myValue = 2;


unsigned long cubed = cube(myValue); // cubed = 8
unsigned long squared = square(cubed); // squared = 64
unsigned long tripled = triple(squared); // tripled = 196
unsigned long Answer = double(tripled); // Answer = 392

Now each intermediate result can be examined, and the order of execution is explicit.

The parameters of a function are list of variables used by the function to perform its task and
the arguments passed to the function during calling of a function are values sent to the function.
The arguments of function calling can be using either of the two supported styles in C++:
passing by value or passing by reference.

146
4.6 Passing arguments

Pass by Value

The arguments passed in to the function are local to the function. Changes made to the
arguments do not affect the values in the calling function. This is known as passing by value,
which means a local copy of each argument is made in the function. These local copies are
treated just like any other local variables.

A value parameter receives a copy of only the value of the argument passed to it. As a result,
if the function makes any changes to the parameters, this will not affect the argument.

For Example:

#..... void Foo(int num)

Num = 0;

cout<< “num = ” << num << “ \n”;

int main(void)

int x = 10;

Foo(x);

cout<< “x = ”<<x<< “\n”;

getch();

return 0;

• The single parameter of Foo is a value parameter. As far as this function is concerned,
num behaves just like a local variable inside the function.
• When the function is called and x passed to it, num receives a copy of the value of x.
As a result, although num is set to 0 by the function, this does not affect x. The program
produces the following output:

147
Num = 0

x = 10

• Passing arguments in this way, where the function creates copies of the arguments passed
to it is called passing by value.

Pass by reference

In C++, passing by reference is accomplished in two ways: using pointers and using references.
The syntax is different, but the net effect is the same. Rather than a copy being created within
the scope of the function, the actual original object is passed into the function. Passing an object
by reference allows the function to change the object being referred to. In previous section
showed that a call to the swap() function did not affect the values in the calling function.

A reference parameter, on the other hand, receives the argument passed to it and works on it
directly. Any change made by the function to a reference parameter is in effect directly applied
to the argument. Passing parameters in this way is called pass-by-reference. Taking the same
example above:

#.....
#.....
void Foo(int & num)
{
num = 0;
cout<< “num = ” << num << “ \n”;
}
int main(void)
{ int x = 10;
Foo(x);
cout<< “x = ”<<x<< “\n”;
getch();
return 0;
}

The parameter of Foo is a reference parameter. Num will correspond to x for this specific
program as it x is sent by its reference and not its value.

Any change made on num will be effected to x. Thus, the program produces the following
output:

num = 0
x=0

148
Suppose you have pairs of numbers in your program and you want to be sure that the smaller
one always precedes the larger one. To do this, you call a function, order(), which checks two
numbers passed to it by reference and swaps the originals if the first is larger than the second.

#.......
#.......
void order(int &, int &);
int main()
{
int n1 = 99, n2=11;
int n3 = 22, n4=88;
order(n1,n2);
order(n3,n4);
cout<< “n1=”<<n1<<endl;
cout<< “n2=”<<n2<<endl;
cout<< “n3=”<<n3<<endl;
cout<< “n4=”<<n4<<endl;
return 0;
}
void order(int & num1,int & num2)
{
if(num1 > num2)
{
int temp=num1;
num1 = num2;
num2 = temp; }
}
}

• In main() there are two pairs of numbers-the first pair is not ordered and the second pair is
ordered. The order() function is called once for each pair, and then all the numbers are
printed out. The output revels that the first pair has been swapped while the second pair has
not. Here it is:

N1 = 11

N2 = 99

N3 = 22

N4 = 88

• In the order() function the first variable is called num1 and the second is num2. If num1 is
greater than num2, the function stores num1 in temp, puts num2 in num1, and finally puts
temp back in num2.
• Using reference arguments in this way is a sort of remote control operation. The calling
program tells the function what variables in the calling program to operate on, and the
function modifies these variables without ever knowing their real names.

149
4.7 Return Values
Functions return a value or return void. Void is a signal to the compiler that no value will be
returned. To return a value from a function, write the keyword return followed by the value
you want to return. The value might itself be an expression that returns a value. For example:

return 5;
return (x > 5);
return (MyFunction());

These are all legal return statements, assuming that the function MyFunction() itself returns
a value. The value in the second statement, return (x > 5), will be zero if x is not greater
than 5, or it will be 1. What is returned is the value of the expression, 0 (false) or 1 (true),
not the value of x.

When the return keyword is encountered, the expression following return is returned as the
value of the function. Program execution returns immediately to the calling function, and any
statements following the return are not executed. It is legal to have more than one return
statement in a single function.

4.8 Default Parameters


Default argument is a programming convenience which removes the burden of having to
specify argument values for all function parameters.

Eg: You might pass a function an error message that is stored in a character array, and the
function displays the error for a certain period of time. The prototype for such a function can
be this:

Void pr_msg(char note[]);

Therefore, to request that pr_msg() display the line ‘Turn printer on’, you call it this way:
Pr_msg(“Turn printer on”);

As you write more of the program, you begin to realize that you are displaying one message-
for instance, the ‘Turn printer on’ msgmore often than any other message.

Instead of calling the function over and over, typing the same message each time, you can set
up the prototype for pr_msg() so that it defaults to the ‘turn printer on’ message in this way:
void pr_msg(char note[] = “Turn printr on”);

This makes your programming job easier. Because you would usually want pr_msg() to display
‘turn printer on’, the default argument list takes care of the message and you don’t have to pass
the message when you call the function.

150
For functions having more than one argument with default, the parameters with possible
default value should be declared in the right side of the function definition and prototype.

For every parameter you declare in a function prototype and definition, the calling function
must pass in a value. The value passed in must be of the declared type. Thus, if you have a
function declared as

long myFunction(int);

the function must in fact take an integer variable. If the function definition differs, or if you fail
to pass in an integer, you will get a compiler error. The one exception to this rule is if the
function prototype declares a default value for the parameter. A default value is a value to use
if none is supplied. The preceding declaration could be rewritten as

long myFunction (int x = 50);

This prototype says, "myFunction() returns a long and takes an integer parameter. If an
argument is not supplied, use the default value of 50." Because parameter names are not
required in function prototypes, this declaration could have been written as

long myFunction (int = 50);

The function definition is not changed by declaring a default parameter. The function
definition header for this function would be

long myFunction (int x)

If the calling function did not include a parameter, the compiler would fill x with the default
value of 50. The name of the default parameter in the prototype need not be the same as the
name in the function header; the default value is assigned by position, not name. Any or all of
the function's parameters can be assigned default values. The one restriction is this: If any of
the parameters does not have a default value, no previous parameter may have a default value.

If the function prototype looks like

long myFunction (int Param1, int Param2, int Param3);


you can assign a default value to Param2 only if you have assigned a default value to Param3.
You can assign a default value to Param1 only if you've assigned default values to both Param2
and Param3.

E.g.: Let us develop part of the program with default arguments.

#include…..
void Add_Display(int x=10, int y=20, int z=30)
{
cout<< (x+y+z);
}
void Mult_Dispaly (int x, int y=70)

151
{
cout<< (x*y);
}
void main()
{
int a=40, b=50, c=60;
Add_Display(a,b,c); //will print 150 (ie 40+50+60)
Add_Display(a,b); //will print 120 (ie 40+50+30)
Add_Display(a); //will print 90 (ie 40+20+30)
Add_Display(); //will print 60 (ie 10+20+30)
Mult_Display(a,b) //will print 2000 (40*50)
Mult_Display(a) //will print 2800 (40*70)
//Mult_Display() //is invalid as there is no default for x
getch();
}
//the following function definition is invalid as z is
//a parameter without a default and written after y
//parameters with default should always be at the
//right side of function declaration void
Mult_Dispaly (int x, int y=70, int z)
{
cout<< (x*y*z);
}
//thus the following function definition will be correct
void Mult_Dispaly (int x, int z, int y=70)
{
cout<< (x*y*z);
}

Week 10:- Practice

Argument passing
Function is dependent on whether arguments are present or not, and a value is returned or not
to the calling function. Based on these criteria a function can be classified as:

Category (types) of functions:

a. Functions with no arguments & no return values.


b. Functions with arguments & no return values.
c. Functions with arguments & return values.
a) Functions with no arguments & no return values:

This kind is peculiar in 2 aspects:

(i) A function with no argument does not receive data from calling function.
(ii) A function with no return value, does not give any data to calling function.

152
Thus the function can be used as an independent statement but not as an expression.

b) Functions with arguments & no return values:

Here the function will receive data from calling function, but will not return any data to it.

// Sample program to display the biggest of 3 numbers.

#include<iostream>

using namespace std;

int main()

int a, b, c;

void big(int, int, int);

cout<<"\n Enter 3 numbers \n";

cin>>a>>b>>c;

big(a, b, c);

void big(int x, int y, int z)

if (x>y && x>z)

cout<<"\n a is the biggest";

else if (y>z && y>x)

cout<<" \n b is the biggest";

else

cout<<" \n c is the biggest";

c) Functions with arguments & return values:

Here, two way data communication takes place i.e., both the called & calling functions
receive and transfer data from each other.

// Program to calculate area of a triangle.

153
#include<iostream>

using namespace std;

int main()

float x, y, c;

float area(float, float);

cout<<" \n Enter base & height ";

cin>>x>>y;

c=area(x, y);

cout<<"\n area is " <<c;

return 0;

float area(float b, float h)

return( 0.5 * b * h);

A demonstration of passing by value

1: // - demonstrates passing by value


3: #include <iostream>
5: void swap(int x, int y);
7: int main()
8: {
9: int x = 5, y = 10;
11: cout<< "Main. Before swap, x: " << x << " y: " <<y<< "\n";
12: swap(x,y);
13: cout<< "Main. After swap, x: " << x << " y: " <<y << "\n";
14: return 0;
15: }
16:
17: void swap (int x, int y)
18: {
19: int temp;

154
21: cout<< "Swap. Before swap, x: " << x << " y: " <<y<< "\n";
23: temp = x;
24: x = y;
25: y = temp;
27: cout<< "Swap. After swap, x: " << x << " y: " << y << "\n";
29: }

Output:
Main. Before swap, x: 5 y: 10
Swap. Before swap, x: 5 y: 10
Swap. After swap, x: 10 y: 5
Main. After swap, x: 5 y: 10

Analysis: This program initializes two variables in main() and then passes them to the swap()
function, which appears to swap them. When they are examined again in main(), however,
they are unchanged! The variables are initialized on line 9, and their values are displayed on
line 11. swap() is called, and the variables are passed in. Execution of the program switches to
the swap() function, where on line 21 the values are printed again. They are in the same order
as they were in main(), as expected. On lines 23 to 25 the values are swapped, and this action
is confirmed by the printout on line 27. Indeed, while in the swap() function, the values are
swapped. Execution then returns to line 13, back in main(), where the values are no longer
swapped.

As you've figured out, the values passed in to the swap() function are passed by value, meaning
that copies of the values are made that are local to swap(). These local variables are swapped
in lines 23 to 25, but the variables back in main() are unaffected.

A demonstration of passing by reference

swap() rewritten with references

1: // Demonstrates passing by reference


2: // using references!
4: #include <iostream>
6: void swap(int &x, int &y);
8: int main()
9: {
10: int x = 5, y = 10;
12: cout<< "Main. Before swap, x: " << x << " y: " <<y<<"\n";
13: swap(x,y);
14: cout<< "Main. After swap, x: " << x << " y: " <<y << "\n";
15: return 0;
16: }
18: void swap (int &rx, int &ry)
19: {
20: int temp;

155
22: cout<< "Swap. Before swap, rx: " <<rx<< " ry: "<<ry<<"\n";
24: temp = rx;
25: rx = ry;
26: ry = temp;
28: cout<< "Swap. After swap, rx: " <<rx<< " ry: " <<ry<< "\n";
30: }

Output:
Main. Before swap, x:5 y: 10
Swap. Before swap, rx:5 ry:10
Swap. After swap, rx:10 ry:5
Main. After swap, x:10, y:5

Analysis: Two variables are declared on line 10 and their values are printed on line 12. On
line 13, the function swap() is called, but note that x and y, not their addresses, are passed. The
calling function simply passes the variables.
When swap() is called, program execution jumps to line 18, where the variables are identified
as references. Their values are printed on line 22, but note that no special operators are required.
These are aliases for the original values, and can be used as such. On lines 24-26, the values
are swapped, and then they're printed on line 28. Program execution jumps back to the calling
function, and on line 14, the values are printed in main(). Because the parameters to swap()
are declared to be references, the values from main() are passed by reference, and thus are
changed in main() as well. References provide the convenience and ease of use of normal
variables.

A demonstration of multiple return statements


1: // demonstrates multiple return
2: // statements
3:
4: #include <iostream>
5:
6: int Doubler(int AmountToDouble);
7:
8: int main()
9: {
10:
11: int result = 0;
12: int input;
13:
14: cout<< "Enter a number between 0 and 10,000 to double: ";
15: cin>> input;
16:
17: cout<< "\nBeforedoubler is called... ";
18: cout<< "\ninput: " << input << " doubled:" <<result<<"\n";
19:
20: result = Doubler(input);
21:
22: cout<< "\nBack from Doubler...\n";

156
23: cout<< "\ninput: " << input << "doubled: " <<result<<"\n";
26: return 0;
27: }
28:
29: int Doubler(int original)
30: {
31: if (original <= 10000)
32: return original * 2;
33: else
34: return -1;
35: cout<< "You can't get here!\n";
36: }

Output:
Enter a number between 0 and 10,000 to double: 9000
Before doubler is called...
input: 9000 doubled: 0
Back from doubler...
input: 9000 doubled: 18000
Enter a number between 0 and 10,000 to double: 11000
Before doubler is called...
input: 11000 doubled: 0
Back from doubler...
input: 11000 doubled: -1

Analysis: A number is requested on lines 14 and 15, and printed on line 18, along with the
local variable result. The function Doubler() is called on line 20, and the input value is passed
as a parameter. The result will be assigned to the local variable result, and the values will be
reprinted on lines 22 and 23. On line 31, in the function Doubler(), the parameter is tested to
see whether it is greater than 10,000. If it is not, the function returns twice the original number.
If it is greater than 10,000, the function returns -1 as an error value. The statement on line 35
is never reached, because whether or not the value is greater than 10,000, the function returns
before it gets to line 35, on either line 32 or line 34. A good compiler will warn that this
statement cannot be executed, and a good programmer will take it out!

A demonstration of default parameter values

1: // demonstrates use
2: // of default parameter values
4: #include <iostream>
6: int AreaCube(int length, int width = 25, int height = 1);
8: int main()
9: {
10: int length = 100;
11: int width = 50;
12: int height = 2;
13: int area;
14:

157
15: area = AreaCube(length, width, height);
16: cout<< "First area equals: " << area << "\n";
18: area = AreaCube(length, width);
19: cout<< "Second time area equals: " << area << "\n";
21: area = AreaCube(length);
22: cout<< "Third time area equals: " << area << "\n";
23: return 0;
24: }
25:
26: AreaCube(int length, int width, int height)
27: {
28:
29: return (length * width * height);
30: }

Output:
First area equals: 10000
Second time area equals: 5000
Third time area equals: 2500

Analysis: On line 6, the AreaCube() prototype specifies that the AreaCube() function takes
three integer parameters. The last two have default values. This function computes the area of
the cube whose dimensions are passed in. If no width is passed in, a width of 25 is used and a
height of 1 is used. If the width but not the height is passed in, a height of 1 is used. It is
not possible to pass in the height without passing in a width. On lines 10-12, the dimensions
length, height, and width are initialized, and they are passed to the AreaCube() function on
line 15. The values are computed, and the result is printed on line 16. Execution returns to line
18, where AreaCube() is called again, but with no value for height. The default value is used,
and again the dimensions are computed and printed. Execution returns to line 21, and this time
neither the width nor the height is passed in. Execution branches for a third time to line 27.
The default values are used. The area is computed and then printed.

DO remember that function parameters act as local variables within the function.

DON'T try to create a default value for a first parameter if there is no default value for the second.
DON'T forget that arguments passed by value cannot affect the variables in the calling function.
DON'T forget that changes to a global variable in one function change that variable for all functions.

158
Assessment

Part I: Objective Questions: Choose the correct answer from the given alternatives

1. Which of the following function prototype is correctly declared?


A. int sum(int, int=4, int=5); C. int sum(int=3, int, int);
B. int sum(int=3, int, int=5); D. int sum( int=3, int=4, int);

2. Which of the following is true about function overloading?


A. Have the same name and the same parameter lists
B. Have the same name but different parameter lists
C. Can perform the same task but take different parameter
D. B& C

3. Which of the following is used to terminate the function declaration?


A. : B. ; C. } D. )
4. Values passed to a function are called?

A. Parameters C. Arguments
B. Constants D. Variables
5. What are the basic parts in function declaration?
A. Return type, function name C. Function name
B. Return type, function name, parameters D. All
6. Keywords in C++ are ignored by the compiler.
A. True B. False
7. Which of the following is Programmer given name?
A. Directives C. Keywords
B. Identifiers D. Comments
8. What is the only function all C++ programs must contain?
A. start() C. main()
B. system() D. program()

Part II. Subjective Questions

159
1. What is function?
2. Write the syntax of function declaration with example?
3. Write the definition of the function that you declare in question number 2?
4. Write the function calling that you define in question number 3?
5. What is the difference between parameter passing by value and by reference?
6. What is the difference between parameter and argument?
7. What is inline function? Explain its difference from normal function?
Part III: Practical Questions

1. Write a C++ program by creating a function with three default integer parameters display
the sum. Call the function four times from main().
• Call with no argument
• Call with one argument
• Call with two argument
• Call with three argument
2. Write a program that lets the user perform arithmetic operations on two numbers. Your
program must be menu driven, allowing the user to select the operation (+, -, *, or /) and
input the numbers. your program must consist of following functions:
• Function showChoice: This function shows the options to the user and explains
how to enter data.
• Function add: This function accepts two number as arguments and returns sum.
• Function subtract: This function accepts two number as arguments and returns
their difference.
• Function multiply: This function accepts two number as arguments and returns
product.
• Function divide: This function accepts two number as arguments and returns
quotient.

3. Write the output of the following C++ program

a)
#include<iostream>
using namespace std;
void function1();
int main()
{
function1();
cout<<" I am ICT first year student"<<endl;
cout<<" Programming is interesting"<<endl;

160
return 0;
}
void function1()
{
cout<<"Hello every one"<<endl;
}

b)
#include<iostream>
using namespace std;
int sum(int=10,int=5,int=2);
int main()
{
sum(10,10);
sum();
sum(7);
sum(2,3,4);
return 0;
}
int sum( int a, int b, int c)
{
int result;
result=a+b+c;
cout<<"sum="<<result<<endl;
}

161
Week 11:

4.9 Overloaded Functions


Unlike C, C++ lets you have more than one function with the same name. In other words, you
can have three functions called abs() in the same program. Functions with the same name are
called overloaded functions. C++ requires that each overloaded functions differ in its argument
list. Overloaded functions enable you to have similar functions that work on different types of
data. Suppose that you wrote a function that returned the absolute value of whatever number
you passed to it:

int iabs(int i)
{
if(i<0)
return (i*-1);
else
return (i);
}
float fabs(float x)
{
if(x<0.0)
return (x * -1.0);
else
return (x);
}

Without using overloading, you have to call the function as:


int ans = iabs(weight);//for int arguments
float ans = fabs(weight);//for float arguments
But with overloading, the above code can be used as:
int abs(int i);
float abs(float x);
int main()
{

ians = abs(i);//calling abs with int arguments
fans = abs(p);//calling abs with float arguments

}
int abs(int i)
{
if(i<0)
return i*-1;

162
else
return I;
}
float abs(flaot x)
{
if(x<0.0)
return x*-1.0;
else
return x;
}
N.B: if two or more functions differ only in their return types, C++ can’t overload them. Two
or more functions that differ only in their return types must have different names and can’t be
overloaded

4.10 Inline Functions


Suppose that a program frequently requires finding the absolute value of an integer quantity.
For a value denoted by n, this may be expressed as:

(n > 0 ? n : -n)
However, instead of replicating this expression in many places in the program, it is better to
define it as a function:
int Abs(int n)
{
return n > 0 ? n : -n;
}
The function version has a number of advantages.

• It leads to a more readable program.


• It is reusable.

The disadvantage of the function version, however is that

• Its frequent use can lead to considerable performance penalty due to overheads
associated with calling a function.

The overhead can be avoided by defining Abs as an inline function.

inline int Abs(int n)


{
return n > 0 ? n : -n;
}

The effect of this is that when Abs is called, the compiler, instead of generating code to call
Abs, expands the program body and substitutes the body of Abs in place of the call. While
essentially the same computation is performed, no function call is involved and hence no stack
frame is allocated.

163
The "inline" keyword is merely a hint to the compiler or development environment. Not every
function can be inlined. Some typical reasons why inlining is sometimes not done include:

• The function calls itself, that is, is recursive


• The function contains loops such as for(;;) or while()
• The function size is too large

Another good reason to inline is that you can sometimes speed up your program by inlining the
right function. Instead of calling the function every time it is invoked, the compiler will replace
the function call with a copy of the function body. If it's a small function which gets called a
lot, this can sometimes speed things up.

Most of the advantage of inline functions comes from avoiding the overhead of calling an actual
function. Such overhead includes saving registers, setting up stack frames, and so on. But with
large functions the overhead becomes less important.

Concerning inline functions, the compiler is free to decide whether a function qualifies to be
an inline function. If the inline function is found to have larger chunk (amount) of code, it will
not be treated as an inline function, but as like other normal functions.

Then, Why not inline everything? :Since the compiler will copy the entire function body every
time the function is called, if it is a large function (more than three or four lines), inlining can
increase the size of your executable program significantly.

When you define a function, normally the compiler creates just one set of instructions in
memory. When you call the function, execution of the program jumps to those instructions,
and when the function returns, execution jumps back to the next line in the calling function. If
you call the function 10 times, your program jumps to the same set of instructions each time.
This means there is only one copy of the function, not 10.

There is some performance overhead in jumping in and out of functions. It turns out that some
functions are very small, just a line or two of code, and some efficiency can be gained if the
program can avoid making these jumps just to execute one or two instructions. When
programmers speak of efficiency, they usually mean speed: the program runs faster if the
function call can be avoided.

If a function is declared with the keyword inline, the compiler does not create a real function:
it copies the code from the inline function directly into the calling function. No jump is made;
it is just as if you had written the statements of the function right into the calling function.

Syntax

inline return_type function_name ( [type parameterName1], [type parameterName2]...)

164
statements;

Note that inline functions can bring a heavy cost. If the function is called 10 times, the inline
code is copied into the calling functions each of those 10 times. The tiny improvement in speed
you might achieve is more than swamped by the increase in size of the executable program.
What's the rule of thumb? If you have a small function, one or two statements, it is a candidate
for inline. When in doubt, though, leave it out.

target = 2 * target;

Everywhere you entered

target = Double(target);

By the time your program executes, the instructions are already in place, compiled into the
OBJ file. This saves a jump in the execution of the code, at the cost of a larger program.

4.11 Recursive Functions

A function which calls itself is said to be recursive. Recursion is a general programming


technique applicable to problems which can be defined in terms of themselves. Take the
factorial problem, for instance which is defined as:

factorial of 0 is 1

factorial of a positive number n is n time the factorial of n

The second line clearly indicates that factorial is defined in terms of itself and hence can be
expressed as a recursive function.

int Factorial(unsigned int n )

return n == 0 ? 1 : n * factrial(n-1);

165
For n set to 4, the following figure shows the recursive call:

The stack frames for these calls appear sequentially on the runtime stack, one after the other.
A recursive function must have at least one termination condition which can be satisfied.
Otherwise, the function will call itself indefinitely until the runtime stack overflows.

The three necessary components in a recursive method are:

1. A test to stop or continue the recursion

2. An end case that terminates the recursion

3. A recursive call(s) that continues the recursion

Let us implement two more mathematical functions using recursion. E.g the following function
computes the sum of the first N positive integers 1,2,…,N. Notice how the function includes
the three necessary components of a recursive method.

int sum(int N)
{
if(N==1)
return 1;
else
return N+sum(N);
}

The last method computes the exponentiation An where A is a real number and N is a positive
integer. This time, we have to pass two arguments. A and N. the value of A will not change in
the calls, but the value of N is decremented after each recursive call.

float expo(float A, int N)


{
if(N==1)
return A;
else
return A * expo(A,N-1);
}
Try to use a recursive function call to solve the Fibonacci series. The Fibonacci series is :

166
0,1,1,2,3,5,8,13,21,…

the recursive definition of the Fibonacci series is as follows:

Fibonacci (0) =0

Fibonacci (1) =1

Fibonacci (n) =Fibonacci (n-1) +Fibonacci (n-2);

Recursion versus iteration


Both iteration and recursion are based on control structure. Iteration uses a repetition structure
(such as for, while, do…while) and recursive uses a selection structure (if, if else or switch).
Both iteration and recursive can execute infinitely-an infinite loop occurs with iteration if the
loop continuation test become false and infinite recursion occurs if the recursion step doesn’t
reduce the problem in a manner that coverage on a base case.

Recursion has disadvantage as well. It repeatedly invokes the mechanism, and consequently
the overhead of method calls. This can be costly in both processor time and memory space.
Each recursive call creates another copy of the method (actually, only the function’s variables);
this consumes considerable memory.

N.B: Use recursion if:

1. A recursive solution is natural and easy to understand

2. A recursive solution doesn’t result in excessive duplicate computation.

3. The equivalent iterative solution is too complex and

4. Of course, when you are asked to use one in the exam!!

Week 11 :- Practice

Most mathematical functions that we are familiar with are described by a simple formula. For
example, we can convert temperatures from Fahrenheit to Celsius by applying the formula

C = 5 (F-32) / 9

Given this formula, it is trivial to write a C++function; with declarations and braces removed,
the one line formula above translates into one line C++ statement. Mathematical functions are
sometimes defined in a less standard form. For example we can define a function f, valid on
non negative integers, that satisfies:

167
f(0) = 0

f(x) = 2*f(x-1) +x2 for x>0, x  Z


From this definition,
f(3) = 2f(2) + 32
= 2f(2) + 9 now we should compute f(2) first.
f(2) = 2f(1) + 22
= 2f(1) + 4 now we should compute f(1) first.
f(1) = 2f(0) + 12
= 2f(0) + 1 now we should compute f(0) first.
f(0) = 0
 f(1) = 2 (0) + 1
=0+1=1
 f(2) = 2 (1) + 4
=2+4=6
=> f(3) = 2 (6) + 9
= 12 + 9= 21
A function that is defined in terms of itself is called recursive. f(0) in the above function is the
value which is the function directly known without resorting to recursion. Such case is known
as the base case. A recursive function without a base case is meaningless. When writing
recursive routines, it is crucial to keep in mind the four basic rules of recursion. These are:

1. Base case: you must always have some Base case, which can be solved with out
recursion.
2. Making progress: for the cases that are to be solved recursively, the recursive call must
always be to a case that makes progress to ward a base case.
3. Design rule: Assume that all recursive calls work without fail. In order to find f(n)
recursively you can assume f(n-k) will work (k  1)
4. Compound interest rule: never duplicate work by solving the same instance of a
problem in separate recursive rule.
Some examples of recursive problems

a) The factorial function f(n) = n!


f(n) can be defined as:

f(N) = N x (N-1) x (N-2) x (N-3) x ……..x 1 this is iterative definition

168
 Nx f(N - 1) for N  0
f (N ) =  this is called recursion.
1 for N = 0

This function can be implemented both iteratively or recursively as


//iterative implementation
int factorial (int N)
{
int fact =1;
for(int i=1;i<=n; i++)
{
fact *=I;
}
return fact;
}
//recursive implementation
int factorial (int n)
{
if (n == 0) return 1;
return n*factorial(n-1)
}
b) Fibonacci progress is a sequence in which the ith term equals f(i) defined as
 f(i - 1) + f(i - 2) for i  2
f(i) = 
1 for i = 1 and 2

Some of the elements in the sequence are


1, 1, 2, 3, 5, 8, 13, 21, 34 …….
The function can be implemented both iteratively and recursively. The recursive
implementation is shown bellow.
int i_th_fibonacci_element (int n)
{
if (n == 1|| n==2)
return 1;

169
else if n > 2
{
int val1 = i_th_fibonacci_element ( n-1);
int val2 = i_th_fibonacci_element ( n-2);
return (val1 + val2);
}
}
Some function cannot be implemented easily without recursion. Other functions, which
do admit both iterative and recursive solution are easier to understand in their recursive
form. So recursion is an essential tool for computer scientist.

However recursion is very expensive in terms of time complexity of a program so that


it is not generally advisable to use recursion to problems that is simple to implement in
iterative way. This is because of the time requirement to manipulate stack at each
function call.

Some more recursive problems and their implementation

C) The Euclidean algorithm

A positive integer d is a divisor of a larger integer n if n is some multiple of d; i.e. n =


k. d for some positive integer k

A positive integer is a common divisor of two larger integer n and m if it is a divisor of


both m & n. d is said to be greatest common divisor of two large integers m& n, if it is
a common divisor of m & n, and no other common divisor of m & n is greater than d.

This can be denoted as d = gcd (m, n).

It might seem that finding gcd of large integers could be very tedious and time
consuming. But fortunately the ancient Greek scientist Euclid discovered a clever
recursive algorithm as follow.

 N if N = M

gcd (M, N) =  gcd (N, M) if M  N
 gcd (N - M, M) if M  N

int gcd (int m, int n)

if (m == n)

170
return n;

else if (m > n)

return gcd (n, m);

else

return gcd (n-m, m);

D) Binary Search
Binary search for an element x in sorted array A[] looks at the middle of the array. If that is not
x (the middle element of A ≠ x) then it continues the search in the half that potential could
hold x. Assuming the array is sorted in ascending order, the potential half array is the left array
if the middle is larger than x otherwise the right the potential list to hold x. The process
contributes this recursive step until either x is found or the sub array is empty. What should be
returned in the index of the array that hold x if it founds or -1.

Implementation

int find (float*a, int start, int stop, float x )

if (start > stop)

return -1;

int mid = (start + stop) / 2;

if (x == a[mid]

return mid;

if (x < a[mid]

return find (a, start, mid -1, x );

else

return find (a, mid +1, start , x );

171
The call from other program to this function may look like

index = find(list, 0, size-1);

e) The tower of Hanoi


A classic example to demonstrate the power of recursion in problem solving is the tower of
Hanoi puzzle. In this puzzle we are given three pegs labeled A, B and C. Initially a tower of N
disk of different sizes is stacked on peg A in order of decreasing size. That is, the largest disk
is on the bottom, and the smallest disk is on the top of the tower as shown bellow

A B C

The objective is to transfer the entire disks from peg A to one of the other pegs, say C moving
only one disk at one time, never moving the larger disk on the top of smaller disk.

The solution follows a simple procedure.

if N = 1 then just move it to destination peg. Otherwise

1- Reduce the problem that say move the top N-1 disk from peg A to B using C.
2- Move the Nth disk (which is the largest) from peg A to C.
3- Now move the N-1 disks from B to C using A. And this will tell us what to do for any N.
The implementation is as follows:

#include <iostream>
#include <conio.h>
void Form(int N, char pegA ,char pegB , char pegC )
{
if (N==1)
cout<<"move top disk on peg "<<pegA<<" to peg "<<pegC<<endl;
else
{
Form(N-1,pegA,pegC,pegB);
cout<<"move top disk on peg "<<pegA<<" to peg "<<pegC<<endl;
Form(N-1,pegB,pegA,pegC);
}

172
}
int main ()
{
char F;
int N;
cout<<"How many disks ?=====>";cin>>N;
Form(N,'A','B','C') ;
getch () ;
return 0;
}

Demonstratation of an inline function


1: // demonstrates inline functions
3: #include <iostream>
4: using namespace std;
5: inline int Double(int);
7: int main()
8: {
9: int target;
11: cout<< "Enter a number to work with: ";
12: cin>> target;
13: cout<< "\n";
15: target = Double(target);
16: cout<< "Target: " << target <<endl;
18: target = Double(target);
19: cout<< "Target: " << target <<endl;
22: target = Double(target);
23: cout<< "Target: " << target <<endl;
24: return 0;
25: }
27: int Double(int target)
28: {
29: return 2*target;
30: }

Output:
Enter a number to work with: 20
Target: 40

173
Target: 80
Target: 160

Analysis: On line 5, Double() is declared to be an inline function taking an int parameter and
returning an int. The declaration is just like any other prototype except that the keyword inline
is pretended just before the return value. This compiles into code that is the same as if you had
written the following:

174
Assessment
Practical Questions

1. Write a function named mult() that accepts two floating-point numbers as a parameters,
multiplies these two numbers and display the result.
2. Write a function that accepts a year as a user input and returns a one if the year is a leap
year or a zero if it is not.
3. Write a program that can be used to play a number guessing game. The player is first asked
for the number of games he wishes to play. Each game gives the player a maximum of three
chances to guess a number chosen randomly. If the player makes a correct guess, he is
given a score depending on the number of guesses he has made (10, 8, or 5). The final score
is given as a percentage with some complementary remarks.
4. Consider the following program:
int foo(int x)

static int k = x;

if (x == 0)

return 0;

if (x < 0)

return k + foo(-x);

else {

int y = foo(x-1);

return k + y + 1;

What will this program compute?

5. Consider the following code fragment

175
# include <iostream>

char key;

long int number;

int main()

int a,b,c;

double x,y;

return 0;

double secnum;

int func1(int num1, int num2)

int o,p;

float q;

return p;

double func2( float fisrt, float last)

int a,b,c,o,p;

floar r;

double s,t,x;

return s*t; }

176
Draw a box around the appropriate section of the above code to enclose the scope of
the variables key, secnum, y, and r.

6. Describe the difference between a local auto variable and a local static variable.
7. Given the following code:
int sum(int 0)

if(n==0)

return 0;

else

return(n+sum(n-1));

a) show the terminating condition


b) show the recursive part
c) hand trace this peace of code for n=4 and find the output.
8. Write a recursive program that
a. Checks whether a given word is palindrome. A word is plaindrom if it has same
spelling when we read it from left to right and vice versa (e.g noon)
b. Checks whether two one dimensional arrays of the same size are identical (have the
same elements)
9. Determine the values displayed by each cout statement in the following program:
#include <iostream>

using namespace std;

int firstnum=20;

void display(void);

int main()

int firstnum =20;

cout<<”\nthe value of firstnum is<<firstnum<<endl;

display();

return 0;

177
void display(void)

cout<<”the value of firstnum is now<<endl;

return;

10. Write a modular program that reads a list of marks and display their range, mean, median.
Suggested functions and their prototypes:

Void readList(float myList[], unsigned & maxNo);

Float findMax(const float myList [] , unsigned maxNo);

Float findMin(const float myList [] , unsigned maxNo);

Float findRange(const float myList [] , unsigned maxNo);

Float findmean(const float myList [] , unsigned num);

Void display(const float myList [] , unsigned maxNo);

178
Reference

[1]. Stephen R. Davis, C++ Weekend Crash, John Wiley & Sons, 2003
[2]. Herbert Schildt, C++: A Beginner's Guide, Second Edition 2nd Edition, McGraw Hill,
2003
[3]. P B Mahapatra, Programming in C++, S Chand, 2008
[4]. Ashok Kamthane, Programming in C++, Pearson, 2013
[5]. https://www.w3schools.com/cpp/
[6]. https://www.tutorialspoint.com/cplusplus/index.htm
[7]. https://www.learncpp.com/

179
Chapter 5: Structure

Lesson Plan

1. Learning objectives
• Be able to define structure.
• Be able to declare structure and structure variables.
• Be able to initialize structure variables.
• Be able to access members of structure variable
• Be able to define structure within a stucture.
2. Motivation
• Outputs through Question and Answer; repetitive discussion and using structure in
C++.
• Solving a problem using structure in C++.
3. Expectations or Outcomes
 Define the terminologies, differentiate different types of function, explain (structure
declaration, members of structure, and accessing member variables); the assessment
standard attached at the end of the job task sheet.
 Can write C++ instructions to solve problem using structure in C++ programming.
4. Equipment
• Desktop or Laptop computer.
• DEV C++ software
5. Practice contents/Activities/Safety
 Active practice; on declaring of structure, member variables, accessing member varia
bles.
 Active practice on array of struts and structure of structure.
6. Assessments
• How to apply structure in C++ programming?
• How to create structure using C++?
7. Clean-up
 After finishing practice, computers should be properly shut down.
8. Independent practice/Follow-up activities
• Learning through assignment (practical Exercises)
9. Review/Reflection
• Review the outcome of the practice, improvement measure and previous reflected
opinions.

181
Week 12 :

5.1 Record: - Structure


Thus far you have worked with variable’s whose data types are very simple: they are a numbers
of either integer or floating-point format with a specific range. These types of variables, who
only have a single value to their name, are known as basic variables or primitives. Everything
in computers is built on numbers, but not necessarily singular types. Sometimes it’s
advantageous to group common variables into a single collection. For example a date would
require a day, month, and year. From what we have discussed currently explained, you could
create three separate variables for each, like so:
int day, month, year;

This isn’t so bad, but what happens if you want to store two dates and not one? You’d have to
create three more variables and give them unique names:
int day1, month1, year1;
int day2, month1, year2;
This begins to become a hassle. Not only do you have to create many variables, but you have
to keep giving them unique names. C++ provides a way to collect similar variables into a
single structure.
An array is a data structure which holds multiple numbers of objects having the same basic
property (data type) in a contiguous memory slots. Programmer can also reserve contiguous
memory space for aggregates of elements of arbitrary data types each. A data type which is
created to reserve such type of memory space is called user defined data type.
User defined data types can be equally used like predefined data types to declare variable
identifiers. For example we can define simple, array, or pointer variable identifier from this
user defined data type.
5.1.1 Structure

The term structure in C++ means both a user-defined type which is a grouping of variables as
well as meaning a variable based on a user-defined structure type. For the purpose of distinction
we will refer to the user-defined type side as structure definition and the variable side as
structure variable.
A structure definition is a user-defined variable type which is a grouping of one or more
variables. The type itself has a name, just like ‘int’, ‘double’, or ‘char’ but it is defined by the
user and follows the normal rules of identifiers. Once the type has been defined through the
C++ ‘struct’ keyword, you can create variables from it just like you would any other type.
Since a structure definition is a grouping of several types: it is a group of one or more variables.
These are known as elements or member variables as they are members of the structure
definition they are part of. Following through with our hinted example, a structure definition
could be a ‘date’ which might be made up of three ‘int’ member variables: ‘day’, ‘month’, and
‘year’.

182
Before creating a structure variable you must create a structure definition. This is a blue print
for the compiler that is used each time you create a structure variable of this type. The structure
definition is a listing of all member variables with their types and names.
When you create a structure variable based on a structure definition, all of the member variables
names are retained. The only name you have to give is that of the new structure variable. The
element names within that variable will be the same as in the structure type. If you create two
structure variables from ‘date’, both will have all three member variables with the same name
in both: ‘day’, ‘month’, and ‘year’.
Member variables are distinguished by the structure variable they are part of. You wouldn’t
simply be able to use ‘day’ by itself; instead you’d have to refer to both the structure variable’s
name (that you gave when you created it) as well as ‘day’.

5.1.2 struct Specification: Defining Structures


Defining a structure is giving the compiler a blue print for creating your type. When you create
a variable based on the structure definition, all of the member variables are created
automatically and grouped under the name you gave. Note that when you create a variable of
any kind, you must give it a unique name that is different than its type. Below is the syntax for
a structure definition:
struct structname
{
datatype1 variable1;
datatype2 variable2;

};
Discussion: Writing a structure definition begins with the word ‘struct’ followed by the type-
to-be, and ended with a structure block that is ultimately terminated with a semicolon. Do not
forget this trailing semi-colon when defining a structure!
The name of a structure definition is known as the structure tag. This will be the name of the
type that you create, like ‘int’ or ‘float’. It is the type that you will specify when creating a
structure variable. This structure block is remarkably similar to a statement block since it starts
and ends with curly braces. But don’t forget that it ultimately ends with a semi-colon. Within
the structure block you declare all the member variables you want associated with that type.
Declare them as you would normal variables, but do not try to initialize them. This is simply
a data blue print, it is not logic or instructions and the compiler does not execute it.
The data members (synonym for member variables) of a structure won’t actually be created
until a variable based on the structure is created. Technically an ‘int’ is just this as well. It’s a
description of a storage unit. That storage unit isn’t reserved until you create a variable with
it.

183
Example defining a student struct,
struct student
{
int id;
char name[15];
};
Example: The follow defines a structure called ‘date’ which contains three ‘int’ member
variables: ‘day’, ‘month’, and ‘year’:
struct date {
int day;
int month;
int year;
};
struct date
{
int day, month, year;
};
Note: You cannot initialize member variables in a structure definition. The following is wrong
and will not compile:
struct date{
int day = 24, month = 10, year = 2001;
};
A structure definition has the same type of scoping as a variable. If you define a structure in a
function, you will only be able to use it there. If you define it in a nested statement block, you
will only be able to use it inside there and any statement blocks nested within it. But the most
common place is defining it globally, as in outside of any functions or blocks. Typically, you’ll
want to be able to create variables of the defined structure anywhere in your program, so the
definition will go at the top. The following is an empty program that defines a ‘date’ structure
globally:
#include <iostream>

struct date
{
int day, month, year;
};
int main(){
return 0;
}

5.1.3 Declaring and using sturct data types


Once you have defined a structure you can create a variable from it just as you would any other
variable.
184
student std1;
date birthday;
The above declaration statements would create a variable called ‘birthday’ whose type is the
structure ‘date’. The variable contains three parts: ‘day’, ‘month’, and ‘year’. What this
actually does is set aside a whole block of memory that can contain all of the member variables.
Each member variable then occupies a chunk of it for their individual storage units. The
member variables are not actually created one at a time.
Storage for member variables exist at some offset from the beginning of the glob of memory
reserved by the entire structure. For example, in our ‘date’ structure variable the first member
variable is ‘day’ so it exists at offset 0. The next member variable, ‘month’ in this case, will
exist at the next available offset. If ‘day’ uses 4 bytes (32 bits), then ‘month’ will be at offset
4:
int i;
student std1;
The above statements are similar in nature because both declare a variable of a given type. The
former is a built in type, which is integer while the later declares a variable type of user-defined
type. std1 will have the characteristics of representing id and name of a student.

5.1.4 Initializing Structure Variables


You cannot initialize member variables in the structure definition. This is because that
definition is only a map, or plan, of what a variable based on this type will be made of. You
can, however, initialize the member variables of a structure variable. That is, when you create
a variable based on your structure definition you can pass each member variable an initializer.
To initialize a structure variable’s members, you follow the original declaration with the
assignment operator (=). Next you define an initialization block which is a list of initializers
separated by commas and enclosed in curly braces. Lastly, you end it with a semi-colon. These
values are assigned to member variables in the order that they occur. Let’s look at an example:
date nco_birthday = { 19, 8, 1979 };

student std1={143,"Ababe"};

This creates a variable called ‘nco_birthday’ and initializes it to a list of values. The values are
assigned to the member variables in the order they are declared in the structure definition.
Remember what is mentioned about each member variable having an offset. The same order
in which each member is given an offset is the order in which each is assigned a value in an
initialization. So the first initializer is used to initialize the first member variable in the
structure, next is the second, and so on and so forth. This order of initialization continues until
the values run out.
If you try to assign more values than are member variables, you will get a compiler error.
However, you can assign fewer values than there are member variables. If there are no more
values to be assigned, the assignment will simply end. For example, if we had omitted the last
value, ‘1979’, then no value would be assigned to ‘year’.

185
It is possible to use any expression that you normally would. But remember that the expression
must result in a value. Here is an example of initialization with things other than literals:
int myday = 19;
int mymonth = 5;
date nco_birthday = { myday, mymonth + 3, 2001 - 22 };
Although you can assign a value to a variable in the same way you initialize it, the same is not
true with structures. So while this works:
int x;
x = 0;
This doesn’t:
date nco_birthday;
nco_birthday = { 19, 8, 1979 };
Assigning values to multiple members of a structure variable is only possible when that
variable is first created. Once a structure variable has been declared, you must access each
member individually.

5.1.5 Accessing members of a structure variable


There’s not much you can do with the structure itself; much of your time with structure
variables will be spent using its members. You can use a member variable in any place you’d
use a normal variable, but you must specify it by the structure variable’s name as well as the
member variable’s name using the member operator.
To specify that you want a member of a specific structure variable, you use the structure
member operator which is the period (also known as a “dot”). Simply use the structure’s name,
follow with the period, and end with the member:
structure.member
Example: to reading and displaying values to and from structure s1.
cin>>s1.id; //storing to id item of s1
cin>>s1.name; //storing a name to s1
cout<<s1.id; //displaying the content of id of s1.
cout<<s1.name; //displaying name

186
Week 12: Practice
C/C++ arrays allow you to define variables that combine several data items of the same kind,
but structure is another user defined data type which allows you to combine data items of
different kinds. A structure is a collection of one or more variable types grouped together that
can be referred using a single name (group name) and a member name.
You can refer to a structure as a single variable, and you also can initialize, read and change
the parts of a structure (the individual variables that make it up). Before creating a structure
variable you must create a structure definition. Each element (called a member) in a structure
can be of different data type.
The General Syntax of structures is: tag
struct structname
{
datatype1 variable1;
Members
datatype2 variable2;
};
Example of struct Inventory

struct Inventory
{
char description[15];
char part_no[6];
int quantity; // members of the structure
float cost;
}; // all structures end with semicolon

Another example might be: struct Student


{
char ID[8];
char FName[15];
char LName[15];
char Sex;
int age;
float CGPA;
};

187
• The above “Student” structure is aimed to store student record with all the relevant
details.
• After the definition of the structure, one can declare a structure variable using the
structure tag. If we need two variables to have the above structure property then
the declaration would be:
struct Inventory inv1,inv2; //or
struct Student Stud1,stud2,Stud3;

• Structure tag is not a variable name. Unlike array names, which reference the array
as variables, a structure tag is simply a label for the structure’s format.
• The structure tag Inventory informs C++ that the tag called Inventory looks like
two character arrays followed by one integer and one float variables.
• A structure tag is actually a newly defined data type that you, the programmer,
defined
Referencing members of a structure

• To refer to the members of a structure we need to use the dot operator (.)
• The General syntax to access members of a structure variable would be:
VarName.Member
• Where VarName is the varaibale name of the structure variable And Member is
varaibale name of the members of the structure

Eg:
For the above student structure:

struct Student Stud; //declaring Stud to have the property of the Student structure

strcpy(Stud.FName,”Abebe”); //assigned Abebe as First Name


Stud.CGPA=3.21; //assignes 3.21 as CGPA value of Abebe
sout<<Stud.FName; //display the name
sout<<Stud.CGPA; // display the CGPA of Abebe
Initializing Structure Data

You can initialize members when you declare a structure, or you can initialize a structure in
the body of the program. Here is a complete program.

.
..
struct cd_collection
{
char title[25];
188
char artist[20];
int num_songs;
float price;
char date_purchased[9];
}
cd1 = {"Red Moon Men","Sams and the Sneeds", 12, 11.95,"08/13/93"};
cout<<"\nhere is the info about cd1"<<endl;
cout<<cd1.title<<endl;
cout<<cd1.artist<<endl;
cout<<cd1.num_songs<<endl;
cout<<cd1.price<<endl;
ut<<cd1.date_purchased<<endl;
.
.
.
A better approach to initialize structures is to use the dot operator(.). the dot operator is one
way to initialize individual members of a structure variable in the body of your program. The
syntax of the dot operator is : structureVariableName.memberName

Example which shows how to create list of books using structure

Structures are used to represent a record, suppose you want to keep track of your books in a
library. You might want to track the following attributes about each book −
• Title
• Author
• Subject
• Book ID
• Defining a Structure
To define a structure, you must use the struct statement. The struct statement defines a new
data type, with more than one member, for your program. The format of the struct statement
is this –

struct [structure tag] {


member definition;
member definition;
...
member definition;
} [one or more structure variables];

189
The structure tag is optional and each member definition is a normal variable definition, such
as int i; or float f; or any other valid variable definition. At the end of the structure's
definition, before the final semicolon, you can specify one or more structure variables but it is
optional. Here is the way you would declare the Book structure –

struct Books {
char title[50];
char author[50];
char subject[100];
int book_id;
} book;
Accessing Structure Members

To access any member of a structure, we use the member access operator (.). The member
access operator is coded as a period between the structure variable name and the structure
member that we wish to access. You would use struct keyword to define variables of structure
type. Following is the example to explain usage of structure –

#include <iostream>
#include <cstring>
using namespace std;
struct Books {
char title[50];
char author[50];
char subject[100];
int book_id;
};

int main() {
struct Books Book1; // Declare Book1 of type Book
struct Books Book2; // Declare Book2 of type Book
// book 1 specification
strcpy( Book1.title, "Learn C++ Programming");
strcpy( Book1.author, "Chand Miyan");
strcpy( Book1.subject, "C++ Programming");
Book1.book_id = 6495407;

// book 2 specification
strcpy( Book2.title, "Telecom Billing");
190
strcpy( Book2.author, "Yakit Singha");
strcpy( Book2.subject, "Telecom");
Book2.book_id = 6495700;

// Print Book1 info


cout << "Book 1 title : " << Book1.title <<endl;
cout << "Book 1 author : " << Book1.author <<endl;
cout << "Book 1 subject : " << Book1.subject <<endl;
cout << "Book 1 id : " << Book1.book_id <<endl;

// Print Book2 info


cout << "Book 2 title : " << Book2.title <<endl;
cout << "Book 2 author : " << Book2.author <<endl;
cout << "Book 2 subject : " << Book2.subject <<endl;
cout << "Book 2 id : " << Book2.book_id <<endl;

return 0;
}
When the above code is compiled and executed, it produces the following result –

Book 1 title : Learn C++ Programming


Book 1 author : Chand Miyan
Book 1 subject : C++ Programming
Book 1 id : 6495407
Book 2 title : Telecom Billing
Book 2 author : Yakit Singha
Book 2 subject : Telecom
Book 2 id : 6495700

here is an example:
#include<iostream>
#include<conio>
#include<string.h>
void main()
{
clrscr();
struct cd_collection{
191
char title[25];
char artist[20];
int num_songs;
float price;
char date_purchased[9];
}cd1;
//initialize members here
strcpy(cd1.title,"Red Moon Men");
strcpy(cd1.artist,"Sams");
cd1.num_songs= 12;
cd1.price = 11.95f;
strcpy(cd1.date_purchased,"22/12/02");
//print the data
cout<<"\nHere is the info"<<endl;
cout<<"Title : "<<cd1.title<<endl;
cout<<"Artist : "<<cd1.artist<<endl;
cout<<"Songs : "<<cd1.num_songs<<endl;
cout<<"Price : "<<cd1.price<<endl;
cout<<"Date purchased : "<<cd1.date_purchased;
getch();
}
Example:-a program that creates student struct and uses it to store student information.
#include<iostream>
#include<conio.h>
using namespace std;
struct student
{
int id;
char name[15];
};
int main()
{
//creating three student variables
student s1,s2;
cout<<"\n Enter Student Id";
cin>>s1.id;
cout<<"\nEnter Name";
cin>>s1.name;
cout<<"\n Enter Student Id";
cin>>s2.id;

192
cout<<"\nEnter Name";
cin>>s2.name;
cout<<"\nStudents Information";
cout<<"\n Student id\t Student Name";
cout<<endl<<s1.id<<"\t""\t""\t"<<s1.name;
cout<<endl<<s2.id<<"\t""\t""\t"<<s2.name;
getch();
}

The above program shows you how to capture data in student variables.
Example 2: This program demonstrates using member variables for user input, output, and
mathematical operations.
#include <iostream>
using namespace std;
struct date
{
int day, month, year;
};
int main()
{
date birth;
cout << "Enter your birth date!" << endl;
cout << "Year: ";
cin >> birth.year;
cout << "Month: ";
cin >> birth.month;
cout << "Day: ";
cin >> birth.day;
cout << "You entered " << birth.day << "/"<< birth.month
<< "/" << birth.year << endl;
cout << "You were born in the "<< ((birth.year / 100) + 1)
<< "th Century!"<< endl;
return 0;
}

193
Assessment

Part I: Answer the following questions based on the program given below?
// Program which demonstrates structure
#include<iostream>
using namespace std;
struct student {
int id;
char name[15];
};
int main()
{
//creating 5 student using an array
student s[5];

int i;
for(i=0; i < 5; i ++)
{
cout<<"\n Enter Student Id";
cin>>s[i].id;
cout<<"\nEnter Name";
cin>>s[i].name;
}
cout<<"\n Displaying student Info";
cout<<"\nStudent Id \t Student Name";
cout<<"\n============================";
for( i = 0; i < 5; i++)
cout<<endl<<s[i].id<<"\t\t\t"<<s[i].name;
getch();
}

194
Part II: Answer the following questions?

1. Identify and write the name of the structure?

2. Identify and write the name of the structure variable?


3. Identify and write the member variables of the structure?
4. What is the use of for loop in the program?
5. Identify and write the comment statements in the program?
Practical

1. Write a C++ program which shows list of books which have title, Author and price
using structure data type and the total number of books to be displayed should be
entered from user.
2. Write a C++ program by creating structure data type which accepts two distances
(in inch & feet), adds the two inches together and the two feets’ together and
display the result on the screen.
3. Write a C++ program which stores the information (name, Id and marks of three
subjects entered by the user) of a student in a structure and displays name, Id and
average of marks entered for one student. The marks entered should be between 1
and 100

195
Week 13:

5.2 Array of structs


An array of structures is simply an array in which each element is a structure of the same type.
The referencing and subscripting of these arrays (also called structure arrays) follow the same
rules as simple arrays

An array is a collection of data items of the same type. Each element of the array can be int,
char, float, double, or even a structure. We have seen that a structure allows elements of
different data types to be grouped together under a single name. This structure can then be
thought of as a new data type in itself. So, an array can comprise elements of this new data
type. An array of structures finds its applications in grouping the records together and provides
for fast accessing. Below is the demonstration of an array of structures. The array holds the
details of the students in a class. The details include the roll number, grade, and marks, which
have been grouped under a structure (record). There exists one record for each student.

#include<iostream>
#include<conio.h>
struct student
{
int id;
char name[15];
};

void main()
{
clrscr();
//creating 5 student using an array
student s[5];
int i;
for(i=0; i < 5; i ++)
{
cout<<"\n Enter Student Id";
cin>>s[i].id;
cout<<"\nEnter Name";
cin>>s[i].name;
}
cout<<"\n Displaying student Info";
cout<<"\nStudent Id \t Student Name";
cout<<"\n============================";
for( i = 0; i < 5; i++)
cout<<endl<<s[i].id<<"\t\t\t"<<s[i].name;

getch();
}

196
. Table 5-1: Memory map of the above struct declaration

0 id 1

name Tameru

1 id 2

name Hassen

2 id 3

name Selamawit

3 id 4

name Asia

4 id 5

name Micheal

If you use s[0].id you will be referring to 1, and s[0].name will refer to Tameru.

The following program declares and uses a book struct. Also swaps the content of two book
struct variables.

#include<iostream>
#include<conio.h>
struct Book
{
int id;
char title[15];
};
void main()
{
//creating three Book variables
Book b1,b2,temp;
cout<<"\n Enter Book Id";
cin>>b1.id;
cout<<"\nEnter Title";
cin>>b1.title;
cout<<"\n Enter Book Id";
cin>>b2.id;
cout<<"\nEnter Title";
197
cin>>b2.title;
cout<<"\n Book Information";
cout<<"\n Before Changing Contents";
cout<<"\n Book id\t Title";
cout<<"\n=========================";
cout<<endl<<b1.id<<"\t\t\t"<<b1.title;
cout<<endl<<b2.id<<"\t\t\t"<<b2.title;
//swapping content
temp=b1;
b1=b2;
b2=temp;
cout<<"\nAfter swapping contents";
cout<<"\n Book Information";
cout<<"\n Book id\t Title";
cout<<"\n=========================";

cout<<endl<<b1.id<<"\t"<<b1.title;
cout<<endl<<b2.id<<"\t"<<b2.title;
getch();
}
Declaring struct types as part of a struct

A structure definition contains multiple variables, but not necessarily just primitives. You can
define a structure to have structure member variables.

Now if you have data's like birth of day of an employee, published year of a book, address of
a person. What are you going to do? You must be able to incorporate this type of data's in
other structs. The following program declares two structs one for address and other for student.

#include<iostream>
#include<conio.h>
struct Address
{
int kebele;
char Kefle_ketema[20];
char roadname[20];
};
struct Student {
int id;
char name[15];
char section[6];
//declaring address type within student
Address studaddress;
};

198
void main(){
clrscr();
//creating Student type that encapsulates Address
Student s1;
cout<<"\n Enter Student Id";
cin>>s1.id;
cout<<"\nEnter Student Name";
cin>>s1.name;
cout<<"\n Enter Section";
cin>>s1.section;
//reading address attributes
cout<<"\nEnter Kebele";
cin>>s1.studaddress.kebele;
cout<<"\nEnter Street Name";
cin>>s1.studaddress.roadname;
cout<<"\nEnter Kefle Ketema";
cin>>s1.studaddress.Kefle_ketema;
cout<<"\n Student Information";
cout<<"\n id\t Name\t Section \t Kebele";
cout<<" \t Street Name \t Kefele Ketema ";
cout<<"\n==================================";
cout<<endl<<s1.id<<"\t"<<s1.name;
cout<<"\t"<<s1.section<<"\t"<<s1.studaddress.kebele;
cout<<"\t"<<s1.studaddress.roadname<<"\t";
cout<<s1.studaddress.Kefle_ketema;
getch();
}
Table 5-2: The memory map of student s;

Id 1

Name Asefa

Section RDDOB02

studaddress kebele 21

Kefle_ketema Arada

roadname Gahandi

Using the above figure. You should be able to understand how data is accessed. Example s.id
refers id of student, but s.studadress.kebele refers kebele of student where the kebele is
referenced by studaddress, intern part of student.
199
Example: This assumes that ‘date’ and ‘time’ are structures that have already been declared.

struct moment

date theDate;

time theTime;

};

These structure members can then be accessed as normal member variables, but then their
variables must be accessed as well. If there is a variable based on ‘moment’ called ‘birth’, then
we would need to write the following to assign ‘19’ to “birth’s date’s day”:

birth.theDate.day = 19;

A structure only has to be declared before it can be used in another structure’s definition. The
following is perfectly acceptable:

struct date;
struct time;
struct moment
{
date theDate;
time theTime;
};
struct date
{
int day, month, year;
};
struct time
{
int sec, min, hour;
};

To be able to define a structure you only must know the types and the names of the member
variables declared inside. With the above we declare the structures ‘date’ and ‘time’ but do not
define them until later. This simply acknowledges that they exist and they can therefore be
used within ‘moment’.

What if ‘date’ and ‘time’ hadn’t defined? It would still be legal, but then I would not be able to
use ‘moment’ at all. Why? Since ‘date’ or ‘time’ have not been defined, the compiler does not
know how big they are supposed to be or what kind of data they contain. You couldn’t then

200
create a variable based on ‘moment’ because the compiler doesn’t know how big of a memory
block to allocate. Likewise if you try to use a structure that has been declared before it has
been defined, you will encounter the same problem.

Defining Structure in Structure

It is possible to define a structure inside a structure definition and create variables from it at
the same time. For example:

struct moment
{
struct date
{
int day, month, year;
} theDate;

struct time
{
int second, minute, hour;
} theTime;
};

The drawback of the above is that the ‘date’ and ‘time’ definitions cannot be used elsewhere
without also referring to the parent structure. If the ‘date’ definition isn’t going to be used
elsewhere anyway, the structure tag can simply be omitted. Thus we could remove the ‘date’
and ‘time’ structure type identifiers and it would work fine. You can write any number of
variables in a structure definition and a valid variable declaration statement (minus
initialization of course) is valid inside a structure definition.

Let’s say we want to be able to use ‘date’ elsewhere, but not ‘time’. The following program
demonstrates how the structure definitions would be written as well as uses the defined
structure types in an extended “birth date” sample:

#include <iostream.h>
struct date { int day, month, year; } ;
struct moment
{
date theDate;

201
struct
{
int sec, min, hour;
} theTime;
};
int main()
{
moment birth;
cout << “Enter your birth moment!” << endl;
cout << “Year: “;
cin >> birth.theDate.year;
cout << “Month: “;
cin >> birth.theDate.month;
cout << “Day: “;
cin >> birth.theDate.day;
cout << “Hour (military): “;
cin >> birth.theTime.hour;
cout << “Minute: “;
cin >> birth.theTime.min;
cout << “Second: “;
cin >> birth.theTime.sec;
cout << “You entered “ << birth.theDate.month << “/”
<< birth.theDate.day << “/” << birth.theDate.year
<< “ @ “ << birth.theDate.hour << “:”
<< birth.theDate.min << “:” << birth.theDate.sec
<< endl;
if (birth.theTime.hour > 20 || birth.theTime.hour < 8)
cout << “You were born early in the morning!”
<< endl;

return 0;
}

Any number of structure definitions can be nested; you can get extremely complex with
structures, which is why they are sometimes known as complex types.

Structure, Reference and Pointer

References to structure variables, work the same way as normal references. To create one you
would write out the name of the structure type, followed by the reference name which is
preceded by the reference operator (&):

struct_name &reference;
202
The following creates a structure variable based on ‘date’ and a reference to it:

date birth;

date &mybirth = birth;

Both of these, ‘birth’ and ‘mybirth’, would have access to the same member variables and their
values. Thus they can be used interchangeably:

birth.year = 1981;

mybirth.year -= 2;

Can you guess what the value of ‘birth.year’ would be from the above? It would be ‘1979’.
The reference ‘mybirth’ is just an alias to ‘birth’ and its group of member variables. Remember
that a reference is not a real variable (it has no value), but simply a nickname for another.

Utilizing pointers with structures, unfortunately, adds a previously unseen complexity. A


pointer to a variable cannot be used to modify the variable’s value until it has been dereferenced.
This case is no different from structures. But it affects the way you access the structure
variable’s members. Recall that a pointer simply contains a memory address. The pointer
knows nothing of what this memory address is used for, which is why you have to dereference
a pointer to a specific type. Thus, you cannot access a structure variable’s members until you
dereference a pointer to the structure type:

date birth;

date *p = &birth;

(*p).year = 1979;

The pointer ‘p’ above, had to be dereferenced before the member variable ‘year’ could be
accessed through it. It was surrounded in parenthesis because the indirection operator (asterisk
‘*’) has a lower precedence than the member operator. Thus the following would not work:

*p.year = 1979;

This would be seen as “get the value pointed to by ‘p.year’” and ‘p.year’ is an invalid identifier;
hence the parenthesis around the indirection operation. This method of accessing a structure
variable’s members is cumbersome and requires two operations simply to get at the member
variable: indirection and then member. For this purpose, there is an operator specifically for
accessing a structure variable’s members through a pointer. This is a member operator known
specifically as a pointer-to-member operator or a dash followed by a greater than sign ‘->’ (also
known as an “arrow”):

p->year = 1979;

203
This operator only works on pointers to structure variables. You cannot use it on normal
structure variables for members. The following would not work:

birth->year = 1979;

The left operand must be a pointer to a variable with members, and the right operand must be
the name of a member variable within that.

Pointers to Structures

Like any other type, structures can be pointed to by its own type of pointers:

struct movies_t {

string title;

int year;

};

movies_t amovie;

movies_t * pmovie;

Here amovie is an object of structure type movies_t, and pmovie is a pointer to point to objects
of structure type movies_t. Therefore, the following code would also be valid:

pmovie = &amovie;

The value of the pointer pmovie would be assigned the address of object amovie.

Now, let's see another example that mixes pointers and structures, and will serve to introduce
a new operator: the arrow operator (->):

// pointers to structures
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
struct movies_t {
string title;
int year;
};
int main ()
{
string mystr;
204
movies_t amovie;
movies_t * pmovie;
pmovie = &amovie;

cout << "Enter title: ";


getline (cin, pmovie->title);
cout << "Enter year: ";
getline (cin, mystr);
(stringstream) mystr >> pmovie->year;

cout << "\nYou have entered:\n";


cout << pmovie->title;
cout << " (" << pmovie->year << ")\n";

return 0;
}
The output is:

Enter title: Invasion of the body snatchers

Enter year: 1978

You have entered:

Invasion of the body snatchers (1978)

The arrow operator (->) is a dereference operator that is used exclusively with pointers to
objects that have members. This operator serves to access the member of an object directly
from its address. For example, in the example above:

pmovie->title

is, for all purposes, equivalent to:

(*pmovie).title

Both expressions, pmovie->title and (*pmovie).title are valid, and both access the
member title of the data structure pointed by a pointer called pmovie. It is definitely something
different than:

*pmovie.title

which is rather equivalent to:

*(pmovie.title)

205
This would access the value pointed by a hypothetical pointer member called title of the
structure object pmovie (which is not the case, since title is not a pointer type). The following
panel summarizes possible combinations of the operators for pointers and for structure
members:

A pointer variable can be created not only for native types like (int, float, double etc.) but they
can also be created for user defined types like structure. If you do not know what pointers are,
visit C++ pointers

Table 5-3 Combination of operators for Pointers

Expression What is evaluated Equivalent

a.b Member b of object a

a->b Member b of object pointed to by a (*a).b

*a.b Value pointed to by member b of object a *(a.b)

206
Week 13:- Practice

5.3 C++ Pointers to Structure


A pointer variable can be created not only for native types like (int, float, double etc.) but they
can also be created for user defined types like structure.

Here is an example which shows how you can create pointer for structures:

#include <iostream>

using namespace std;

struct temp {

int i;

float f;

};

int main() {

temp *ptr;

return 0;

Example: Pointers to Structure

#include <iostream>

using namespace std;

struct Distance {

int feet;

float inch;

};

int main() {

Distance *ptr, d;

ptr = &d;

cout << "Enter feet: ";

207
cin >> (*ptr).feet;

cout << "Enter inch: ";

cin >> (*ptr).inch;

cout << "Displaying information." << endl;

cout << "Distance = " << (*ptr).feet << " feet " << (*ptr).inch << " inches";

return 0;

Output

Enter feet: 4

Enter inch: 3.5

Displaying information.

Distance = 4 feet 3.5 inches

In this program, a pointer variable ptr and normal variable d of type structure Distance is
defined.

The address of variable d is stored to pointer variable, that is, ptr is pointing to variable d. Then,
the member function of variable d is accessed using pointer.

Notes:

• Since pointer ptr is pointing to variable d in this program, (*ptr).inch and d.inch are equivalent.
Similarly, (*ptr).feet and d.feet are equivalent.

• However, if we are using pointers, it is far more preferable to access struct members using
the -> operator, since the . operator has a higher precedence than the * operator.

Hence, we enclose *ptr in brackets when using (*ptr).inch. Because of this, it is easier to make
mistakes if both operators are used together in a single code.

ptr->feet is same as (*ptr).feet

ptr->inch is same as (*ptr).inc

5.4 Pointers and Arrays


In C++, Pointers are variables that hold addresses of other variables. Not only can a pointer
store the address of a single variable, it can also store the address of cells of an array.

Consider this example:

208
int *ptr;

int arr[5];

// store the address of the first

// element of arr in ptr

ptr = arr;

Here, ptr is a pointer variable while arr is an int array. The code ptr = arr; stores the address of
the first element of the array in variable ptr.

Notice that we have used arr instead of &arr[0]. This is because both are the same. So, the code
below is the same as the code above.

int *ptr;

int arr[5];

ptr = &arr[0];

The addresses for the rest of the array elements are given by &arr[1], &arr[2], &arr[3], and
&arr[4].

Point to Every Array Elements

Suppose we need to point to the fourth element of the array using the same pointer ptr.

Here, if ptr points to the first element in the above example then ptr + 3 will point to the fourth
element. For example,

int *ptr;

int arr[5];

ptr = arr;

ptr + 1 is equivalent to &arr[1];

ptr + 2 is equivalent to &arr[2];

ptr + 3 is equivalent to &arr[3];

ptr + 4 is equivalent to &arr[4];

209
Similarly, we can access the elements using the single pointer. For example,

// use dereference operator

*ptr == arr[0];

*(ptr + 1) is equivalent to arr[1];

*(ptr + 2) is equivalent to arr[2];

*(ptr + 3) is equivalent to arr[3];

*(ptr + 4) is equivalent to arr[4];

Suppose if we have initialized ptr = &arr[2]; then

ptr - 1 is equivalent to &arr[1];

ptr + 1 is equivalent to &arr[3];

ptr + 2 is equivalent to &arr[4];

Note: The address between ptr and ptr + 1 differs by 4 bytes. It is because ptr is a pointer to an
int data. And, the size of int is 4 bytes in a 64-bit operating system.

Similarly, if pointer ptr is pointing to char type data, then the address between ptr and ptr + 1
is 1 byte. It is because the size of a character is 1 byte.

210
Example 1: C++ Pointers and Arrays

// C++ Program to display address of each element of an array


#include <iostream>
using namespace std;
int main()
{
float arr[3];
// declare pointer variable
float *ptr;
cout << "Displaying address using arrays: " << endl;
// use for loop to print addresses of all array elements
for (int i = 0; i < 3; ++i)
{
cout << "&arr[" << i << "] = " << &arr[i] << endl;
}
// ptr = &arr[0]
ptr = arr;
cout<<"\nDisplaying address using pointers: "<< endl;
// use for loop to print addresses of all array elements
// using pointer notation
for (int i = 0; i < 3; ++i)
{
cout << "ptr + " << i << " = "<< ptr + i << endl;
}
return 0;
}

Output

Displaying address using arrays:

&arr[0] = 0x61fef0

&arr[1] = 0x61fef4

&arr[2] = 0x61fef8

Displaying address using pointers:

ptr + 0 = 0x61fef0

ptr + 1 = 0x61fef4

ptr + 2 = 0x61fef8

211
In the above program, we first simply printed the addresses of the array elements without using
the pointer variable ptr. Then, we used the pointer ptr to point to the address of a[0], ptr + 1 to
point to the address of a[1], and so on.

In most contexts, array names decay to pointers. In simple words, array names are converted
to pointers. That's the reason why we can use pointers to access elements of arrays. However,
we should remember that pointers and arrays are not the same.

Example 2: Array name used as pointer


// C++ Program to insert and display data entered by using pointer notation.
#include <iostream>
using namespace std;
int main() {
float arr[5];
// Insert data using pointer notation
cout << "Enter 5 numbers: ";
for (int i = 0; i < 5; ++i) {
// store input number in arr[i]
cin >> *(arr + i) ;
}
// Display data using pointer notation
cout << "Displaying data: " << endl;
for (int i = 0; i < 5; ++i) {
// display value of arr[i]
cout << *(arr + i) << endl ;
}
return 0;
}

Output

Enter 5 numbers: 2.5


3.5
4.5
5
2
Displaying data:
2.5
3.5
4.5
5
2
Here,
212
We first used the pointer notation to store the numbers entered by the user into the array arr.

cin >> *(arr + i) ;

This code is equivalent to the code below:

cin >> arr[i];

Notice that we haven't declared a separate pointer variable, but rather we are using the array
name arr for the pointer notation.

As we already know, the array name arr points to the first element of the array. So, we can
think of arr as acting like a pointer.

Similarly, we then used for loop to display the values of arr using pointer notation.

cout << *(arr + i) << endl ;

This code is equivalent to

cout << arr[i] << endl ;

213
Assesement
Practical
1. Write a C++ program which shows list of books which have title, Author and price
using structure data type and the total number of books to be displayed should be
entered from user.
2. Write a C++ program which stores the information (name, Id and marks of three
subjects entered by the user) of a student in a structure and displays name, Id and
average of marks entered for one student. The marks entered should be between 1 and
100.

3. Declare a single structure data type suitable for an employee record of the type
illustrated below:

Number Name Rate Hours


3462 Abeba 4.62 40
6793 Tesfaye 5.83 38
7834 Chaltu 6.89 40
9002 Hana 4.75 42

214
Week 14:

5.5 Passing Structure to Function


So far, all structures used in the preceding examples have been global and hence were available
to all the functions within program. But, if you have a structure local to a function and you
need to pass its values to another function, then it can be achieved in two ways:

• by passing individual structure elements


• by passing the entire structure
Both these ways can be achieved by call by value as well as call by reference method of passing
variables. Let's discuss these in details.

Passing Structure Elements to Functions

When an element of a structure is passed to a function, you are actually passing the values of
that element to the function. Therefore, it is just like passing a simple variable (unless, of course,
that element is complex such as an array of character). For example, consider the following
structure:

struct date

short day ;

short month ;

short year ;

}Bdate ;

Individual elements of this structure can be passed as follows:

func1(Bdate.day, Bdate.month, Bdate.year)

The above function-call invokes a function, func1() by passing values of individual structure
elements of structure Bdate.

The function can either receive the values by creating its own copy for them (call by value) or
by creating references for the original variables (call by reference). If You want that the values
of the structure elements should not be altered by the function, then you should pass the
structure elements by value and if you want the function to alter the original values, then you
should pass the structure elements by reference.

But remember if one of the structure elements happens to be an array, it will automatically be
passed by reference as the arrays cannot be passed by value.

215
Passing Entire Structure to Function

Passing entire structures makes the most sense when the structure is relatively compact. The
entire structure can be passed to the functions both ways by value and by reference. Passing by
value is useful when the original values are not to be changed and passing by reference is useful
when original values are to be changed.

C++ Pass Structure to Function Call by Value

When a structure is used as an argument to a function, the entire structure is passed using the
standard call-by-value method. Of course, this means that any changes made to the contents of
the structure inside the function to which it is passed do not affect the structure used as an
argument.

The receiving parameter for the passed structure must match the type of the passed structure.

Example

Consider the following example program, demonstrating how to pass structure to function with
call by value method:

// C++ Passing Structure to Function - Call by Value


#include<iostream>
#include<conio.h>
struct distance
{
int feet;
int inches;
};

void prnsum(distance l1, distance l2); // function prototype


void main()
{
clrscr();

distance length1, length2; // two structures of type distance declared


//Read values for length1
cout<<"Enter length 1:\n";
cout<<"Feet: ";
cin>>length1.feet;
cout<<"\nInches: ";
cin>>length1.inches;

// Read values for length2


cout<<"\n\nEnter length 2:\n";
cout<<"Feet: ";
216
cin>>length2.feet;
cout<<"\nInches: ";
cin>>length2.inches;
prnsum(length1, length2); // print sum of length1 and length2

getch();

} // end of main()

void prnsum(distance l1, distance l2)


{
distance l3; // new structure
l3.feet=l1.feet+l2.feet+(l1.inches+l2.inches)/12; // 1 feet=12 inches
l3.inches=(l1.inches+l2.inches)%12;
cout<<"\n\nTotal Feet: "<<l3.feet<<"\n";
cout<<"Total Inches: "<<l3.inches;
}
The above program inputs two structures length1 and length2 of distance type and prints the
sum of the two.

A function prnsum() is invoked by passing two structures length1 and length2 by value and
which calculates the sum of the two and prints it. The function prnsum() creates its own copies
for length1 and length2 namely l1 and l2 and works with it. Thus the original copies length1
and length2 remains untouched.

Passing Structure to Function Call by Reference

Structures can be passed by reference just as other simple types. When a structure is passed by
reference the called function declares a reference for the passed structure and refers to the
original structure elements through its reference. Thus, the called function works with the
original values.

Example

Following example program illustrates passing of structures to function with call by reference
method:

/* C++ Passing Structure to Function


* Passing Structure to Function with
* Call by Reference Method in C++ */

#include<iostream>
#include<conio.h>
struct distance
{
int feet;
217
int inches;
};
void prnsum(distance &l1, distance &l2); // watch the declaration
void main()
{
clrscr();
distance length1, length2; // two structures of type distance declared
// Read values for length1
cout<<"Enter Value for length 1:\n";
cout<<"Feet: ";
cin>>length1.feet;
cout<<"\nInches: ";
cin>>length1.inches;

// Read values for length2


cout<<"\n\nEnter Value for length 2:\n";
cout<<"Feet: ";
cin>>length2.feet;
cout<<"\nInches: ";
cin>>length2.inches;
prnsum(length1, length2); // print sum of length1 and length2

getch();
}

void prnsum(distance &l1, distance &l2)


{
distance l3; // new structure created
l3.feet=l1.feet+l2.feet+(l1.inches+l2.inches)/12; // 1 feet=12 inches
l3.inches=(l1.inches+l2.inches)%12;
cout<<"\n\nTotal Feet: "<<l3.feet<<"\n";
cout<<"Total Inches: "<<l3.inches;
}
When the above C++ program is compile and executed, it will produce the following output:

The above program invokes prnsum() by passing structures length1 and length2 by reference.
The function prnsum() creates references l1 and l2 for structures length1 and length2 and thus,
uses the original structures length1 and length2 by names l1 and l2 respectively.

5.6 Returning Structures from Functions in C++


Just like other types, functions can return structures also. Then the return type of the function
is the same as that of the type of the structure returned. For example, if the function prnsum()
218
(of the above 2 programs i.e. Program No. 1 and Program No. 2) has to return a structure of
type distance, its declaration will change as shown below :

distance prnsum(distance L1, L2) ;

See, the return type of prnsum() is distance. For Program No. 1 i.e., when structures are passed
by value and as

distance prnsum(distance &L1, distance &L2) ;

For Program No. 2 i.e, when structures are being passed by reference. The definition of the
function prnsum() of program no. 1 will be as follows :

distance prnsum(distance L1, distance L2)

distance L3 ;

L3.feet = L1.feet + L2.feet + (L1.inches + L2.inches) / 12 ; // 1 feet = 12 inches

L3.inches = (L1.inches + L2.inches) % 12 ;

return L3 ; // structure returned

If the return value of the function prnsum() is being assigned to a variable, then that variable
must be a structure variable of type distance. For example, notice the following code fragment

distance total ;

total = prnsum(length1, length2) ;

cout << total.feet << " " << total.inches ;

The above code fragment stores the return value of function prnsum() into the structure total
which is also of type distance and then prints the values of structure elements. The function
prnsum() that returns a structure and gets invoked in call-by-reference.

A function may even return a reference to a structure also. For example, consider the following
function :

distance & sum (distance L1, distance L2) ; //notice the declaration

distance L3 ; // global structure declared

// Function Definition follows

distance & sum (distance L1, distance L2)

219
{

L3.feet = L1.feet + L2.feet + (L1.inches + L2.inches) / 12 ;

L3.inches = (L1.inches + L2.inches) % 12 ;

return L3 ;

The above function is returning reference to a structure L3. When a function returns a reference,
it returns the lvalue (location value) in place of rvalue (data value) of a variable.

220
Week 14:- Practice:

1. C++ Structure and Function


In this article, you'll find relevant examples to pass structures as an argument to a function, and
use them in your program. Structure variables can be passed to a function and returned in a
similar way as normal arguments.

Passing structure to function in C++

• A structure can be passed to any function from main() function or from any sub function.
• Structure definition will be available within the function only.
• It won't be available to other functions unless it is passed to those functions by value or
by address (reference).
Ways to pass structure

If the structure itself is an argument, then it is called "call by value". If the reference of the
structure is passed as an argument, then it is called "call by reference".

• Call by value
• Call by reference
• Call by value
When a structure is passed as argument to a function using call by value method, any change
made to the contents of the structure variable inside the function to which it is passed do not
affect the structure variable used as an argument.

Example 1: C++ Structure and Function

#include <iostream>
using namespace std;
struct Employee
{
char name[50];
int age;
float salary;
};
void printData(Employee); // Function declaration
int main()
{
Employee p;
cout << "Enter Full name: ";
cin.get(p.name, 50);
cout << "Enter age: ";
cin >> p.age;
221
cout << "Enter salary: ";
cin >> p.salary;
// Function call with structure variable as an argument
printData(p);
return 0;
}
void printData(Employee p){
cout << "\nDisplaying Information." << endl;
cout << "Name: " << p.name << endl;
cout <<"Age: " << p.age << endl;
cout << "Salary: " << p.salary;
}

Output

Enter Full name: Micheal Clark

Enter age: 20

Enter salary: 20000

Displaying Information.

Name: Micheal Clark

Age: 20

Salary: 20000

In this program, user is asked to enter the name, age and salary of a Employee inside main()
function.

Then, the structure variable p is to passed to a function using.

printData(p);

The return type of printData() is void and a single argument of type structure Employee is
passed.

Then the members of structure p is displayed from this function.

222
Example 2: C++ Returning structure from function

#include <iostream>
using namespace std;
struct Employee {
char name[50];
int age;
float salary;
};
Employee getData(Employee);
void printData(Employee);
int main(){
Employee p;
p = getData(p);
printData(p);
return 0;
}
Employee getData(Employee p) {
cout << "Enter Full name: ";
cin.get(p.name, 50);
cout << "Enter age: ";
cin >> p.age;
cout << "Enter salary: ";
cin >> p.salary;

return p;
}
void printData(Employee p){
cout << "\nDisplaying Information." << endl;
cout << "Name: " << p.name << endl;
cout <<"Age: " << p.age << endl;
cout << "Salary: " << p.salary;
}
Output

Enter Full name: Micheal Clark


Enter age: 20
Enter salary: 20000
Displaying Information.
Name: Micheal Clark
Age: 20
Salary: 20000

223
The output of this program is same as program above.

In this program, the structure variable p of type structure Employee is defined under main()
function.

The structure variable p is passed to getData() function which takes input from user which is
then returned to main function.

p = getData(p);

Note: The value of all members of a structure variable can be assigned to another structure
using assignment operator = if both structure variables are of same type. You don't need to
manually assign each members.

Then the structure variable p is passed to printData() function, which displays the information.

2. Call by reference

In this method of passing the structures to function, the address of a structure variable/object
is passed to the function using address of (&) operator. So any change made to the contents of
structure variable inside the function are reflected back to the calling function.

Consider this example:

Example 3: C++ Structure and Function

#include <iostream>
using namespace std;
struct Employee{
char name[50];
int age;
float salary;
};
void readData(Employee &); // Function declaration
void printData(Employee); // Function declaration
int main(){
Employee p;
readData(p);
printData(p);
return 0;
}

void readData(Employee &p){


cout << "Enter Full name: ";
cin.get(p.name, 50);
cout << "Enter age: ";
cin >> p.age;
224
cout << "Enter salary: ";
cin >> p.salary;
}
void printData(Employee p){
cout << "\nDisplaying Information." << endl;
cout << "Name: " << p.name << endl;
cout <<"Age: " << p.age << endl;
cout << "Salary: " << p.salary;
}
Output

Enter Full name: Micheal Clark


Enter age: 20
Enter salary: 20000

Displaying Information.
Name: Micheal Clark
Age: 20
Salary: 20000
The output of this program is same as program above.

Structures are usually passed by reference method bacause it saves the memory space and
executes faster.

A structure variable can be passed to a function in similar way as normal argument. Consider
this example:

Example 4: C++ Structure and Function

#include <iostream>
using namespace std;
struct Person {
char name[50];
int age;
float salary;
};
void displayData(Person); // Function declaration
int main() {
Person p;
cout << "Enter Full name: ";
cin.get(p.name, 50);
cout << "Enter age: ";
cin >> p.age;
cout << "Enter salary: ";
cin >> p.salary;
225
// Function call with structure variable as an argument
displayData(p);
return 0;
}
void displayData(Person p) {
cout << "\nDisplaying Information." << endl;
cout << "Name: " << p.name << endl;
cout <<"Age: " << p.age << endl;
cout << "Salary: " << p.salary;
}
Output:

Enter Full name: Bill Jobs


Enter age: 55
Enter salary: 34233.4

Displaying Information.
Name: Bill Jobs
Age: 55
Salary: 34233.4

In this program, user is asked to enter the name, age and salary of a Person inside main()
function.

Then, the structure variable p is to passed to a function using.

displayData(p);

The return type of displayData() is void and a single argument of type structure Person is passed.

Then the members of structure p is displayed from this function.

Example 5: Returning structure from function in C++

#include <iostream>
using namespace std;
struct Person {
char name[50];
int age;
float salary;
};
Person getData(Person);
void displayData(Person);

226
int main()
{
Person p, temp;
temp = getData(p);
p = temp;
displayData(p);
return 0;
}

Person getData(Person p) {

cout << "Enter Full name: ";


cin.get(p.name, 50);
cout << "Enter age: ";
cin >> p.age;
cout << "Enter salary: ";
cin >> p.salary;
return p;
}
void displayData(Person p) {
cout << "\nDisplaying Information." << endl;
cout << "Name: " << p.name << endl;
cout <<"Age: " << p.age << endl;
cout << "Salary: " << p.salary;
}
The output of this program is the same as the program above.

In this program, we have created two structure variables p and temp of type Person under the
main() function.

The structure variable p is passed to getData() function which takes input from the user which
is then stored in the temp variable.

temp = getData(p);

We then assign the value of temp to p.

p = temp;

Then the structure variable p is passed to displayData() function, which displays the
information.

Note: We don't really need to use the temp variable for most compilers and C++ versions.
Instead, we can simply use the following code:

p = getData(p);

227
Assesement
Practical
1. Write a functions InputData and DisplayData that reads and display the elements of a
record(structure). Use the student record defined below.
struct Student{
char name[20];
char sex;
int age;
};
2. Use the functions in problem number 1 to read and display a list of students record. Modify
the display function so that it displays the list in a tabular form. Add another function to
your program in problem number 2 which can display only the list of female or male
students depending on the user choice.
3. A student record consist of his id number, a list of marks, average mark, and his rank.
struct Student{
unsigned id;
float marks[5];
float average;
unsigned rank;
};
use the above structure to write a program that can read the inputs (id number and list
of marks) for the students in a class and calculate the average mark for each student.
Your program should finally give the rank for each student. Write a function that
displays the list of students in the order of their rank
4. Write a program which defines a new structure type to contain the following information
about towns: the name (a sequence of characters); the population (aninteger); and a Boolean
value (i.e. true or false) which indicates whether the town has an airport or not. Use the
typedef statement to define your own Boolean data type -remember that true in C++ is
equivalent to the integer value 1, and false is equivalent to 0.

5. Declare a single structure data type suitable for an employee record of the type illustrated
below:
Number Name Rate Hours
3462 JONES 4.62 40
6793 Robbins 5.83 38
7834 Swain 6.89 40
9002 Williams 4.75 42

Using the data type declared above, write a C++ program that interactively accepts the above
data into an array of six structures. Once the data have been entered, the program should
create a payroll report listing each employee’s name, number, and gross pay. Include the total
gross pay of all employeesat the end of the report.
228
Reference

[1]. Stephen R. Davis, C++ Weekend Crash, John Wiley & Sons, 2003

[2]. Herbert Schildt, C++: A Beginner's Guide, Second Edition 2nd Edition, McGraw Hill,
2003

[3]. P B Mahapatra, Programming in C++, S Chand, 2008

[4]. Ashok Kamthane, Programming in C++, Pearson, 2013

[5]. https://www.w3schools.com/cpp/

[6]. https://www.tutorialspoint.com/cplusplus/index.htm

[7]. https://www.learncpp.com/

229
230
Chapter 6: File Management

Lesson Plan

1. Learning objectives
• Be able to define file and stream.
• Be able to declare file variable identifier.
• Be able to open file.
• Be able to process a file.
• Be able to define close a file.
2. Motivation
• Outputs through Question and Answer; repetitive discussion and using file
management in C++.
• Solving a problem using file processing in C++.
3. Expectations or Outcomes
 Define the terminologies, explain (file variable identifier declaration, opening a file,
reading a file and writing on a file); the assessment standard attached at the end of the
job task sheet.
4. Equipment
• Desktop or Laptop computer.
• DEV C++ software
5. Practice contents/Activities/Safety
 Active practice; on declaring of file variable identifier, creating and opening a file, w
riting on a file, reading from a file and closing a file.
 Active practice on array of struts and structure of structure.
6. Assessments
• How to apply file management in C++ programming?
• How to create file, how to open a file, how to process (read and write) file using C++?
7. Clean-up
 After finishing practice, computers should be properly shut down.
8. Independent practice/Follow-up activities
• Learning through assignment (practical Exercises)
9. Review/Reflection
• Review the outcome of the practice, improvement measure and previous reflected
opinions.

231
Week 15:

6.1 File Management Introduction


File handling is an important part of all programs. Most of the applications will have their own
features to save some data to the local disk and read data from the disk again. Files which are
on the secondary storage device are called physical files. In order to process file through
program, logical file must be created on the RAM. This logical file is nothing but an object
having file data type. As an object there should be a variable identifier that points to it. This
variable is called file variable and some times also called file handler. C++ File I/O classes
simplify such file read/write operations for the programmer by providing easier to use classes.

6.2 Streams and Files


The I/O system supplies a consistent interface to the C++ programmer independent of the actual
device being accessed. This provides a level of abstraction between the programmer and the
device. This abstraction is called stream. The actual device is called a file.

1. Streams
The C++ file system is designed to work with a wide variety of devices, including terminals,
disk drives, and tape drives. Even though each device is very different, the C++ file system
transforms each into a logical device called stream. There are two types of streams: text and
binary.

a. Text Streams
A text stream is a sequence of characters. In a text stream, certain character translations may
occur as required by the host environment. For example a new line may be converted to a
carriage return/linefeed pair. There may not be a one-to-one relationship between the characters
that are written (or read) and those on the external device. Because of possible transformations,
the number of characters written (or read) may not be the same as those on the external device.

b. Binary streams
A binary stream is a sequence of bytes with a one-to-one correspondence to those in the external
device i.e., no character translations occur. The number of bytes written (or read) is the same
as the number on the external device. However, an implementation-defined number of null
bytes may be appended to a binary stream. These null bytes might be used to pad the
information so that it fills a sector on a disk, for example.
232
2. Files
In C++, a file can be anything from a disk file to a terminal or printer. You associate a stream
with a specific file by performing an open operation. Once a file is open, information can be
exchanged between it and a program. All streams are the same but all files are not. If the file
can support position requests, opening that file also initializes the file position indicator to the
start of the file. As each character is read from or written to the file, the position indicator is
incremented. You disassociate a file from a specific stream with a close operation. If you close
a file opened for output, then contents, if any, of its associated stream are written to the external
device. -- this process is referred to as flushing the stream. All files are closed automatically
when the program terminates normally. Files are not closed when a program terminates
abnormally. Each stream that is associated with a file has a file control structure of type FILE.
This structure FILE is defined in the header stdio.h.

The File Pointer

A file pointer is a pointer to information that defines various things about the file, including its
name, status, and the current t position of the file. In essence, the file pointer identifies a specific
disk file and is used by the associated stream to direct the operation of the I/O functions. A file
pointer is a pointer variable of type FILE.

FILE * fp;

6.3 The standard streams


When ever a program starts execution, three streams are opened automatically.
stdin --- standard input.
stdout -- standard output
stderr -- standard error
Normally, these streams refer to the console. Because the standard streams are file pointers,
they can be used by the ANSI C file system to perform I/O operations on the console.

6.4 C++ File I/O Classes and Functions


To perform file I/O, the header file fstream.h is requied. fstream.h defines several classes,
including ifstream, ofstream, and fstream. These classes are derived form istream and ostream,
repectively. istream and ostream are derived form ios.

Three file I/O classes are used for File Read/Write operations:

233
a. ifstream - Can be used for File read/input operations
b. ofstream - Can be used for File write/output operations
c. fstream - Can be used for both read/write c++ file I/O operations
These classes are derived directly or indirectly from the classes istream, and ostream. We have
already used objects whose types were these classes: cin is an object of class istream and cout
is an object of class ostream. Therefore, we have already been using classes that are related to
our file streams. And in fact, we can use our file streams the same way we are already used to
use cin and cout, with the only difference that we have to associate these streams with physical
files. Let's see an example:

6.5 Text and Binary Files


In file processing, files are generally classified into two as

➢ Text file and


➢ Binary file
Text file is a file in which its content is treated as a sequence of characters and can be accessed
sequentially. Where as binary file is a file in which its content is treated as record sequence in
a binary format. Binary format refers to the actual format the data is going to be placed and
processed in the memory which is directly related to its data type.

For example, the value int count 321 will be stored in three byte if it is written in text file
considering the digit sequence ‘3’, ‘2’, ‘1’. It will be stored in two byte if it is written in binary
file since int requires two byte to store any of its value. When you open the binary file you will
see the character equivalence of the two bytes.

321 in binary equals 0000 0001 0100 0001

The first byte holds the character with ASCII value equals to one and the second byte a
character with ASCII value equals 65 which is ‘A’. Then if you open the binary file you will
see these characters in place of 321.

6.6 Text File processing


File processing involves the following major steps

1. Declaring file variable identifier


2. Opening the file
3. Processing the file
234
4. Closing the file when process is completed.
Opening and Closing a file
An open file is represented within a program by a stream object and any input or output
operation performed on this stream object will be applied to the physical file associated to it.
In C++, you open a file by linking it to a stream. Before you can open a file, you must first
obtain a stream. There are three types of streams: input, output, and input/output. To create an
input stream, you must declare the stream to be of class ifstream. To create an output stream,
you must declare it as class ofstream. Streams that will be performing both input and output
operations must be declared as class fstream.

ifstream in ; //input stream


ofstream out ; // output stream
fstream io ; // input and output
Once you have declared a stream, you associate it with a file by using the method open().

The method open ( ) is a member of each of the three stream classes. Its prototype is:
void open (const char *filename, int mode, int access = filebuf::penprot );

Where:
Filename is the name of the file.

The value of the mode determines how the file is opened. It must be one (or more) of these
values:

Table 6-1: file opening Values description

Mode Description

ios::app Write all output to the end of the file

ios::ate Open a file for output and move to the end of the file (normally used to
append data to a file). Data can be written anywhere in the file.

ios::binary Cause the file to be opened in binary mode.


ios::in Open a file for input
ios::nocreate If the file does not exist, the open operation fails.

235
Mode Description

ios::noreplace If the file exists, the open operation fails.


ios::out Open a file for output
ios:trunc Discard the file's content if it exists (this is also the default action
ios::out)

You can combine two or more of these values by using them together.

ofstream out ;
out.open ( "test", ios::out); // correct statement
ofstream out1 ;
out.open ( " test"); // the default value of mode is ios::out –
// correct statment
To open a stream for input and output, you must specify both the ios::in and the ios::out mode
values. (Noe default value for mode is supplied in this case.)

fstream myStream;
myStream.open ( "test", ios::in | ios::out );

If open ( ) fails, myStrream will be zero

if (myStream){

cout << "Cannot open a file.\n";


// handle error
}

Each one of the open() member functions of the classes ofstream, ifstream and fstream has a
default mode that is used if the file is opened without a second argument:

Table 6-2: open() member functions

class default mode parameter

ofstream ios::out

ifstream ios::in

fstream ios::in | ios::out

236
For ifstream and ofstream classes, ios::in and ios::out are automatically and respectively
assumed, even if a mode that does not include them is passed as second argument to the open()
member function. The default value is only applied if the function is called without specifying
any value for the mode parameter. If the function is called with any value in that parameter the
default mode is overridden, not combined.

File streams opened in binary mode perform input and output operations independently of any
format considerations. Non-binary files are known as text files, and some translations may
occur due to formatting of some special characters (like newline and carriage return characters).

Since the first task that is performed on a file stream object is generally to open a file, these
three classes include a constructor that automatically calls the open() member function and has
the exact same parameters as this member. Therefore, we could also have declared the previous
myfile object and conducted the same opening operation in our previous example by writing:

ofstream myfile ("example.bin", ios::out | ios::app | ios::binary);

Combining object construction and stream opening in a single statement. Both forms to open
a file are valid and equivalent.

To check if a file stream was successful opening a file, you can do it by calling to member
is_open() with no arguments. This member function returns a bool value of true in the case that
indeed the stream object is associated with an open file, or false otherwise:

if (myfile.is_open()) { /* ok, proceed with output */ }

ifstream myStream ( "myfile" ); // open file for input

When we are finished with our input and output operations on a file we shall close it so that its
resources become available again. In order to do that we have to call the stream's member
function close(). This member function takes no parameters, and what it does is to flush the
associated buffers and close the file:

myfile.close();

Once this member function is called, the stream object can be used to open another file, and
the file is available again to be opened by other processes.

237
In case that an object is destructed while still associated with an open file, the destructor
automatically calls the member function close(). The close method takes no parameters and
returns no value.

6.7 Reading from a File


Files you open for read access (using ios::in) must exist already, or C++ gives you an error
message. You can’t read a file that does not exist. Open() returns zero if the file does not exist
when you open it for read access.

- Another event happens when you read files. Eventually, you read all the data. Subsequently
reading produces error because there is no more data to read. C++ provides a solution to the
end-of-file occurrence.

- If you attempt to read a file that you have completely read the data from, C++ returns the
value zero. To find the end-of-file condition, be sure to check for zero when reading
information from files.

The following code asks the user for a file name and displays the content of the file to the screen.

Reading and writing text files


Simply use the << and >> operators in the same way you do when performing console I/O
except that instead of using cin and cout, you substitute a stream that is linked to a file.

ofstream out ("inventory");

out <<"Radios" << 39.95 << endl;


out << "Toastors" << 19.95 << endl;

out.close ( );

Example: Basic file operations

#include <iostream>

#include <fstream>

using namespace std;

int main () {

ofstream myfile;
238
myfile.open ("example.txt");

myfile << "Writing this to a file.\n";

myfile.close();

return 0;

This code creates a file called example.txt and inserts a sentence into it in the same way we are
used to do with cout, but using the file stream myfile instead.

Example 2: writing on a text file

#include <iostream>
#include <fstream>
using namespace std;
int main () {
ofstream myfile ("example.txt");
if (myfile.is_open())
{
myfile << "This is a line.\n";
myfile << "This is another line.\n";
myfile.close();
}
else cout << "Unable to open file";
return 0;
}

Example 3: reading a text file

#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main () {
string line;
ifstream myfile ("example.txt");
if (myfile.is_open())
{
while (! myfile.eof() )
{
getline (myfile,line);
cout << line << endl;
}
myfile.close();
239
}
else cout << "Unable to open file";
return 0;
}

This last example reads a text file and prints out its content on the screen. Notice how we have
used a new member function, called eof() that returns true in the case that the end of the file
has been reached. We have created a while loop that finishes when indeed myfile.eof() becomes
true (i.e., the end of the file has been reached).

6.8 File Pointer and their Manipulators


Each file has two pointers one is called input pointer and second is output pointer. The input
pointer is called get pointer and the output pointer is called put pointer. When input and output
operation take places, the appropriate pointer is automatically set according to the access mode.
For example when we open a file in reading mode, file pointer is automatically set to the start
of the file. When we open a file in append mode, the file pointer is automatically set to the end
of file. In C++ there are some manipulators by which we can control the movement of the
pointer. The available manipulators are:

1. seekg()

2. seekp()

3. tellg()

4. tellp()

seekg(): this moves get pointer i.e input pointer to a specified location.

For eg. infile.seekg(5); move the file pointer to the byte number 5 from starting point.

seekp(): this move put pointer (output pointer) to a specified location for example:
outfile.seekp(5);

tellg(): this gives the current position of get pointer (input pointer)

tellp(): this gives the current position of put pointer (output pointer) eg. ofstream fileout;

Checking state flags


240
In addition to eof(), which checks if the end of file has been reached, other member functions
exist to check the state of a stream (all of them return a bool value):

Table 6-3: functions to check the state of a stream

Function Description

bad() Returns true if a reading or writing operation fails. For example in the
case that we try to write to a file that is not open for writing or if the
device where we try to write has no space left.

fail() Returns true in the same cases as bad(), but also in the case that a
format error happens, like when an alphabetical character is extracted
when we are trying to read an integer number.

eof() Returns true if a file open for reading has reached the end.

good() It is the most generic state flag: it returns false in the same cases in
which calling any of the previous functions would return true.

In order to reset the state flags checked by any of these member functions we have just seen
we can use the member function clear(), which takes no parameters.

get and put stream pointers

All I/O streams objects have, at least, one internal stream pointer:

• ifstream, like istream, has a pointer known as the get pointer that points to the element
to be read in the next input operation.
• ofstream, like ostream, has a pointer known as the put pointer that points to the location
where the next element has to be written.
• Finally, fstream, inherits both, the get and the put pointers, from iostream (which is
itself derived from both istream and ostream).

These internal stream pointers that point to the reading or writing locations within a stream can
be manipulated using the following member functions:

241
tellg() and tellp()

These two member functions have no parameters and return a value of the member type
pos_type, which is an integer data type representing the current position of the get stream
pointer (in the case of tellg) or the put stream pointer (in the case of tellp).

seekg() and seekp()

These functions allow us to change the position of the get and put stream pointers. Both
functions are overloaded with two different prototypes. The first prototype is:

seekg ( position );
seekp ( position );

Using this prototype the stream pointer is changed to the absolute position position (counting
from the beginning of the file). The type for this parameter is the same as the one returned by
functions tellg and tellp: the member type pos_type, which is an integer value.

The other prototype for these functions is:

seekg ( offset, direction );


seekp ( offset, direction );

Using this prototype, the position of the get or put pointer is set to an offset value relative to
some specific point determined by the parameter direction. offset is of the member type
off_type, which is also an integer type. And direction is of type seekdir, which is an enumerated
type (enum) that determines the point from where offset is counted from, and that can take any
of the following values:

Table 6-4: offset values

ios::beg offset counted from the beginning of the stream

ios::cur offset counted from the current position of the stream pointer

ios::end offset counted from the end of the stream

242
The following example uses the member functions we have just seen to obtain the size of a file:

Example: obtaining file size

#include <iostream>
#include <fstream>
using namespace std;
int main () {
long begin,end;
ifstream myfile ("example.txt");
begin = myfile.tellg();
myfile.seekg (0, ios::end);
end = myfile.tellg();
myfile.close();
cout << "size is: " << (end-begin) << " bytes.\n";
return 0;
}

6.9 Binary File processing


In binary files, to input and output data with the extraction and insertion operators (<< and >>)
and functions like getline is not efficient, since we do not need to format any data, and data
may not use the separation codes used by text files to separate elements (like space, newline,
etc...).

File streams include two member functions specifically designed to input and output binary
data sequentially: write and read. The first one (write) is a member function of ostream
inherited by ofstream. And read is a member function of istream that is inherited by ifstream.
Objects of class fstream have both members. Their prototypes are:

write ( memory_block, size );


read ( memory_block, size );

Where memory_block is of type "pointer to char" (char*), and represents the address of an
array of bytes where the read data elements are stored or from where the data elements to be

243
written are taken. The size parameter is an integer value that specifies the number of characters
to be read or written from/to the memory block.

There are two ways to write and read binary data to and from a file.

− get ( ) and put ( )


− read ( ) and write ( )
If you will be performing binary operations on a file, be sure to open it using the ios::binary
mode specifier.

get ( ) and put ( )


These functions are byte-oriented.
o get ( ) will read a byte of data.
o put ( ) will write a bye of data.
The get ( ) method has many forms.
istream & get( char & ch );
ostream & put ( char ch);
The get ( ) method read a single character from the associated stream and puts the value in ch,
and returns a reference to the stream. The put ( ) method writes ch to the stream and returns a
reference to the stream.

char in;
ifstream in ( "test", ios::in | ios::binary);
if (!in){
cout <<"Cannot open file";
return 1;
}
while (in) //inn will be 0 when eof is reached
{ in.get ( ch );
cout << ch;
}
When the end-of-file is reached, the stream associated with the file becomes zero.
ofstream out ( "chars", io::out | ios::binary);
for (int i= 0; i < 256; i++)
out.put ( (char ) i ) ; //write all characters to disk
out.close ( );

244
read ( ) and write ( )
The read ( ) method reads num bytes from the associated stream, and puts them in a memory
buffer (pointed to by buf).

istream & read ( unsigned char * buf, int num );


The write ( ) method writes num bytes to the associated stream from the memory buffer
(pointed to by buf).

ostream & write ( const unsigned char * buf, int num );


If the end-of-file is reached before num characters have been read, then read ( ) simply stops,
and the buffer contains as many characters as were available. You can find out how many
characters have been read by using another member function, called gcount ( ), which has the
prototype:

int gcount ( );

More get ( ) functions


The method get ( ) is overloaded in several ways.

istream &get (char *buf, int num, char delim = '\n');

This get ( ) method reads characters into the array pointed to by the buf until either num
characters have been read, or the character specified by delim has been encountered. The array
pointed to by buf will be null terminated by get ( ). If the delimiter character is encountered in
the input stream, it is not extracted. Instead, it remains in the stream until the next input
operation.

a. int get ( )
It returns the next character from the stream. It returns EOF if the end of file is encountered.
b. getline ( )
istream & getline ( char *buf, int num, char delim ='\n');
This method is virtually identical to the get ( buf, num, delim) version of get ( ). The difference
is getline ( ) reads and removes the delimiter from the input stream.

Example: reading a complete binary file

#include <iostream>
245
#include <fstream>
using namespace std;

ifstream::pos_type size;
char * memblock;
int main () {
ifstream file ("example.txt", ios::in|ios::binary|ios::ate);
if (file.is_open())
{
size = file.tellg();
memblock = new char [size];
file.seekg (0, ios::beg);
file.read (memblock, size);
file.close();

cout << "the complete file content is in memory";

delete[] memblock;
}
else cout << "Unable to open file";
return 0;
}
In this example the entire file is read and stored in a memory block. Let's examine how this is
done:

First, the file is open with the ios::ate flag, which means that the get pointer will be positioned
at the end of the file. This way, when we call to member tellg(), we will directly obtain the size
of the file. Notice the type we have used to declare variable size:

ifstream::pos_type size;

ifstream::pos_type is a specific type used for buffer and file positioning and is the type returned
by file.tellg(). This type is defined as an integer type, therefore we can conduct on it the same
operations we conduct on any other integer value, and can safely be converted to another
integer type large enough to contain the size of the file. For a file with a size under 2GB we
could use int:

int size;
size = (int) file.tellg();

Once we have obtained the size of the file, we request the allocation of a memory block large
enough to hold the entire file:

memblock = new char[size];

246
Right after that, we proceed to set the get pointer at the beginning of the file (remember that
we opened the file with this pointer at the end), then read the entire file, and finally close it:

file.seekg (0, ios::beg);


file.read (memblock, size);
file.close();

At this point we could operate with the data obtained from the file. Our program simply
announces that the content of the file is in memory and then terminates.

Table 6-5: functions and their descriptions

Function Description

Detecting EOF It returns nonzero when the end of the file has been
reached; otherwise it returns zero.
int eof ( );

Reading and discarding characters Reads and discards characters until either num characters
from the input stream. have been nignored (1 by default ) or until the charcter
specified by delim is encounterdd (EOF by default). If
istream & ignore (int num = 1, int
the delimiting character is encountered, it is not removed
delim = EOF);
from the input stream.

Obtain the next character in the One can obtain the next character in the input stream
input stream without removing it without removing it from that stream by using peek ( ). It
from that stream returns the next character in the stream or EOF if the end
of file is encountered.
int peek ( );

247
istream & putback ( char c); One can return the last character read from a stream to
that stream using putback ( ).

Forcing data to be physically When the output is performed, data is not necessarily
written to the disk immediately written to the physical device linked to the
stream. Instead, information is stored in an internal
buffer until the buffer is full. Only then are the contents
ostream & flush ( ); of that buffer written to disk. However, you can force the
information to be physically written to the disk before the
buffer is full by calling flush ( ).

6.10 Random Access Files


In C++'s I/O system, you perform random access by using seekg ( ) and seekp ( ) methods.

istream *seekg (streamoff offset, sek_dir origin);


ostream & seekp ( streamoff offet, seek_dir origin);
Here, streamoff is a type defined in iostream.h that is capable of containing the largest valid
value that offset can have. Also seed-dir is an enumeration that has these values:

ios::beg
ios::cur
ios::end
The C++ I/O system manages two pointers associated with a file. One is the get pointer, which
specifies where in then file the next input operation will occur. The other is the put pointer,
which specifies where in the file the next output operation will occur. Each time an input or
output operation takes place the appropriate pointer is automatically sequentially advanced.
The seekg ( ) method moves the associated file's current get pointer offset number of bytes
from the specified origin, which must be one of three values. The seekp ( ) method moves the
associated file's current put pointer offset number of bytes from the specified origin, which
must be one of three values.

Obtaining the Current File Position


You can determine the current position of each file pointer by using these methods.

streampos tellg ( );
248
streampows tellp ( );
Here, streampos is a type defined in iostream.h that is capable of holding the largest value that
either function can return.

I/O Status
The C++ I/O system maintains status information about the outcome of each I/O operation.
The current state of the I/O system is held in an integer, in which the following flags are
encoded.

− eofbit -- 1 when end-of-file is encountered; 0 otherwise


− failbit -- 1 when a (possibly) nonfatal I/O error has occurred; 0 otherwise
− badbit -- 1 when a fatal I/O error has ocurred; 0 otherwise

These flags are enumerated inside ios. Also defined in ios is goodbit, which has the value 0.
There are two ways in which you can obtain I/O status information.

a. Use the rdstate function/method.

int rdstate ( );
rdstate function returns the current status of the error flags encoded into an integer. It returns
zero, when no error has occurred. Otherwise, an error bit is turned on.

b. Use one or more of these methods.

Table 6-6: error Methods

Method Description
int bad ( ) Returns true if badbit is set.
int fail ( ) Returns true if failbit is set.
int eof ( ) Returns true if there are no errors.
int good ( ) Otherwise they return false.

Once an error has occurred, it may need to be cleared before your program continues. to do
this, use the clear ( ) method.

void clear ( int flags = 0);


If flag = zero (as it is by default), all error flags are cleared (reset to zero). Otherwise, set flags
to the flags or values you want to clear.

249
Buffers and Synchronization
When we operate with file streams, these are associated to an internal buffer of type streambuf.
This buffer is a memory block that acts as an intermediary between the stream and the physical
file. For example, with an ofstream, each time the member function put (which writes a single
character) is called, the character is not written directly to the physical file with which the
stream is associated. Instead of that, the character is inserted in that stream's intermediate buffer.

When the buffer is flushed, all the data contained in it is written to the physical medium (if it
is an output stream) or simply freed (if it is an input stream). This process is called
synchronization and takes place under any of the following circumstances:

• When the file is closed: before closing a file all buffers that have not yet been
flushed are synchronized and all pending data is written or read to the physical
medium.

• When the buffer is full: Buffers have a certain size. When the buffer is full it is
automatically synchronized.

• Explicitly, with manipulators: When certain manipulators are used on streams, an


explicit synchronization takes place. These manipulators are: flush and endl.

• Explicitly, with member function sync(): Calling stream's member function


sync(), which takes no parameters, causes an immediate synchronization. This
function returns an int value equal to -1 if the stream has no associated buffer or in
case of failure. Otherwise (if the stream buffer was successfully synchronized) it
returns 0.

250
Week 15 :- Practice:

Consider the file Header .h which contains the basic preprocessing include files, structure
definition and functions other than the main function.

Header. h // this file is saved at D: and it has the following structure.

#include<iostream.h>
#include<fstream.h>
#include<conio.h>
struct studList
{
char firstName[12];
char lastName[12];
int age;
char gender;
char Id[12];
};
studList getStudent()
{
studList std;
cout<<"Enter student first name ===>";cin>>std.firstName;
cout<<"Enter student last name ===>";cin>>std.lastName;
cout<<"Enter student age ===>";cin>>std.age;
cout<<"Enter student gender ===>";cin>>std.gender;
cout<<"Enter student Id ===>";cin>>std.Id;
return std;
}
void DisplayStudent(studList std)
{
cout<<"Student first name:\t"<<std.firstName<<endl;
cout<<"Student last name :\t"<<std.lastName<<endl;
cout<<"Student age:\t\t"<<std.age<<endl;
cout<<"Student gender:\t\t"<<std.gender<<endl;
cout<<"Student Id:\t\t"<<std.Id<<endl;
}

Solution 1

#include "D:\ header.h"


int main() {
studList std;
fstream outf;
outf.open("d:\\test.txt",ios::app);
if(outf.fail()) {
cout<<"unable to open the file d:\test.txt\n";
251
return 1;
}
clrscr();
int N;
cout<<"Enter the number of students ===> ";cin>>N;
for(int i = 0; i < N; i++) {
std = getStudent();
clrscr();
outf<<std.firstName<<" "<<std.lastName<<" "<<std.Id<<" " <<std.gender<<"
"<<std.age<<endl;
}
getch();
return 0;
}

Solution 2

#include "D:\ header.h"


int main(){
studList std;
fstream inpf;
inpf.open("d:\\test.txt",ios::in);
if(inpf.fail())
{
cout<<"unable to open the file d:\test.txt\n"; return 1;
}
clrscr();
while (!inpf.eof())
{
inpf>>std.firstName>>std.lastName>>std.Id>>std.gender>>std.age;
if(inpf.eof()) break;
DisplayStudent(std);
cout<<"=====================================\n";
getch();
}
inpf.close();
return 0;
}

Solution 3

#include "D:\ header.h"


int main()
{
studList std;
fstream outf;
outf.open("d:\\test2.txt",ios::app|ios::binary);
if(outf.fail())
252
{
cout<<"unable to open the file d:\test.txt\n"; return 1;
}
clrscr();
int N;
cout<<"Enter the number of students ===> ";cin>>N;
for(int i = 0; i < N; i++)
{
std = getStudent();
clrscr();
outf.write((char *) &std, sizeof(std));
}
getch();
return 0;
}

Solution 4

#include "D:\ header.h"


int main() {
studList std;
fstream inpf;
inpf.open("d:\\test2.txt",ios::in|ios::binary);
if(inpf.fail())
{
cout<<"unable to open the file d:\test.txt\n";
return 1;
}
clrscr();
while (!inpf.eof()){
{
inpf.read((char*)&std, sizeof(std));
//inpf>>std.firstName>>std.lastName>>std.Id>>std.gender>>std.age;
if(inpf.eof()) break;
DisplayStudent(std);
cout<<"======================================\n";
getch();
}
inpf.close();
return 0;
}

253
Assesement

I. Practical

1. Input Character and write in a file. Hint: use put() function.

2. Input String and write in a file. Hint: use put() function inside a loop.

3. Read a character from a file. Hint: use get() function.

4. Read a line from a file. Hint: use getline() function.

5. Input filename and read all its content.

6. Write a program to count number of vowels from a input file.

7. Write a program to count number of characters and words.

8. Write a program to copy contents of one file into another file.

9. Write a record in a file. Hint: use write() function.

10. Read a record from a file. Hint: use read() function.

11. Write and Read a record from a file.

12. Read and Write records from a file using switch case. Assessment

13. Write a program to create a file in “D:\\ Computer.txt” and write three lines of computer
definition.

14. Write a program that reads computer definition from the text file “D:\\ Computer.txt”
and display on the screen.

15. Write a program that accept N student record from the keyboard & store the list on a
file “D:\\ Test.txt” in a text file format

16. Write a program that reads students record from the text file “D:\\ Test.txt” and display
on the screen.

17. Note Student record consists of first name, last name, gender, age and Id.

254
Reference

[1]. Stephen R. Davis, C++ Weekend Crash, John Wiley & Sons, 2003
[2]. Herbert Schildt, C++: A Beginner's Guide, Second Edition 2nd Edition, McGraw Hill,
2003
[3]. P B Mahapatra, Programming in C++, S Chand, 2008
[4]. Ashok Kamthane, Programming in C++, Pearson, 2013
[5]. https://www.w3schools.com/cpp/
[6]. https://www.tutorialspoint.com/cplusplus/index.htm
[7]. https://www.learncpp.com/

255
This textbook was developed by TVTI faculties through
KOICA project “Capacity Development for TVET Leaders
and Trainers in Ethiopia”

Technical and Vocational Training Institute (TVTI)


Yeka Subcity, Woreda 9, Addis Ababa, Ethiopia
Phone: 011-646-4455, Fax: 011-646-5675/5678
E-mail: [email protected], Website: http://www.ftveti.edu.et

You might also like