56
1 CSC 221: Object-Oriented Programming with C++ Lecture Note by Dr. Oyelami M. O. Comparison of Some Programming Paradigms Paradig m Description Main characteristics (examples) Examples Imperativ e Computation as statements that di rectly change a program state (data fields) Direct assignments, common data structures, global variables C, C++, Java,PH P, Python Structure d A style of imperative programming with more logical program structure Structograms, indentat ion, no goto statements C, C++, Java Procedur al Derived from structured programming, based on the concept of modular programming or the procedure call Local variables, sequence, selection, iteration, and modularization C, C++, Lisp, PHP, Python Event- driven inc luding ti me driven Program flow is determined mainly by events, such as mouse clicks or interrupts including timer Main loop, event handlers, asynchronou s processes ActionScript Object- oriented Treats datafields as objects manipulated through pre- Objects, methods, message passing, information hiding, data C++, C#,Eiffel, Java,PHP, Pytho n, Ruby, Scala

Lecture Note 1 (2)

Embed Size (px)

DESCRIPTION

Lecture Note 1 (2)

Citation preview

Page 1: Lecture Note 1 (2)

1

CSC 221: Object-Oriented Programming with C++

Lecture Note by

Dr. Oyelami M. O.

Comparison of Some Programming Paradigms

Paradig

m

Description

Main

characteristics

(examples)

Examples

Imperativ

e

Computation

as statements that di

rectly change a program state (data

fields)

Direct assignments,

common data

structures, global

variables

C, C++, Java,PH

P, Python

Structure

d

A style of imperative

programming with

more logical program

structure

Structograms, indentat

ion,

no goto statements

C, C++, Java

Procedur

al

Derived from

structured

programming, based

on the concept

of modular programming or

the procedure call

Local variables,

sequence,

selection, iteration,

and modularization

C, C++, Lisp,

PHP, Python

Event-

driven inc

luding ti

me driven

Program flow is

determined mainly

by events, such

as mouse clicks or

interrupts including

timer

Main loop, event

handlers, asynchronou

s processes

ActionScript

Object-

oriented

Treats datafields as

objects manipulated

through pre-

Objects,

methods, message

passing, information

hiding, data

C++, C#,Eiffel,

Java,PHP, Pytho

n, Ruby, Scala

Page 2: Lecture Note 1 (2)

2

Paradigm

Description

Main

characteristics

(examples)

Examples

defined methods only abstraction, encapsulat

ion,polymorphism,inhe

ritance,serialization-

marshalling

Fundamentals of Object-Oriented Design

Object Oriented Design (OOD) attempts to help with the

complexity of designing, writing, and maintaining software.

OOD includes the following concepts:

o Modularity: Modularity is a technique of composing

software from separate parts.

o Encapsulation: Encapsulation is a technique of hiding

implementation details, grouping them together.

o Abstraction: The process of separating ideas from

specific instances of those ideas at work.

It attempts to allow building of software by modeling real-

world objects.

Features of Object Oriented Programming

1. Object

2. Class

3. Data Hiding and Encapsulation

4. Dynamic Binding

5. Message Passing

6. Inheritance

7. Polymorphism

Page 3: Lecture Note 1 (2)

3

Object

o Object is a collection of number of entities. Objects take up

space in the memory. Objects are instances of classes.

Class

o Class is a collection of objects of similar type. Objects are

variables of the type class.

Encapsulation

o Combining data and functions into a single unit

called class and the process is known as Encapsulation

Abstraction

o Hiding the complexity of program is called Abstraction and

only essential features are represented.

Dynamic Binding

o Refers to linking of function call with function definition is

called binding and when it takes place at run time called

dynamic binding.

Message Passing

o The process by which one object can interact with other

object is called message passing.

Inheritance

o it is the process by which object of one class acquires the

properties or features of objects of another class.

Page 4: Lecture Note 1 (2)

4

Polymorphism

o A greek term means ability to take more than one form. An

operation may exhibit different behaviours in different

instances. The behaviour depends upon the types of data

used in the operation.

Windows Programming

o Windows programming generally involves developing a GUI-

based program.

o Many high-level languages are well suited for GUI

development by hiding much of the programming complexity

using object oriented techniques.

C++

C++ is a general purpose programming language.

It is a superset of the C programming language and created by

Bjarne Stroustrup

The key concept in C++ is class. A class is a user-defined type

Structure of a C++ Program

//my first program in C++

#include <iostream> using namespace std;

int main ()

{

cout << "Hello World!";

return 0;

}

Comments

Page 5: Lecture Note 1 (2)

5

Comments are parts of the source code disregarded by the

compiler. They simply do nothing.

Their purpose is only to allow the programmer to insert notes

or descriptions embedded within the source code.

C++ supports two ways to insert comments:

/* my second program in C++

with more comments */

#include <iostream>

using namespace std;

int main () {

cout << "Hello World! "; // prints Hello World!

cout << "I'm a C++ program"; // prints I'm a C++

program

return 0;

}

Data Types

We can manipulate in C++ programs two different categories

of types:

• built-in types which are defined in the C++ compiler itself;

• class type which are defined in C++ source code from the

built-in types.

Page 6: Lecture Note 1 (2)

6

Fundamental Data Types

Page 7: Lecture Note 1 (2)

7

Variable Naming Conventions

A variable identifier can be composed of letters, digits and

underscore character ’_’.

It must begin with either a letter or an underscore.

Usually, one concatenates words to build long identifier either

using the under-score character ’-’ as a space, or by using

upper caps for first letter of each word (except the first letter):

A variable cannot contain a space and punctuation marks.

A variable cannot match any keyword of the C++ language nor

your compiler's specific ones, which are reserved keywords. The standard reserved keywords are:

Page 8: Lecture Note 1 (2)

8

asm, auto, bool, break, case, catch, char, class, const,

const_cast, continue, default, delete, do, double,

dynamic_cast, else, enum, explicit, export, extern, false,

float, for, friend, goto, if, inline, int, long, mutable,

namespace, new, operator, private, protected, public, register, reinterpret_cast, return, short, signed, sizeof,

static, static_cast, struct, switch, template, this, throw,

true, try, typedef, typeid, typename, union, unsigned,

using, virtual, void, volatile, wchar_t, while

Declaration of Variables

In order to use a variable in C++, we must first declare it

specifying which data type we want it to be.

Examples

Initialization of Variables

Syntax: type identifier = initial_value;

Example: int a = 0;

// initialization of variables

#include <iostream>

using namespace std;

int main ()

{ int a=5; // initial value = 5

int b(2); // initial value = 2

Page 9: Lecture Note 1 (2)

9

int result; // initial value

undetermined

a = a + 3;

result = a - b;

cout << result; return 0;

}

Scopes of Variables

A variable can be either of global or local scope.

A global variable is a variable declared in the main body of the

source code, outside all functions, while a local variable is one

declared within the body of a function or a block.

Global variables can be referred from anywhere in the code, even inside functions, whenever it is after its declaration.

Roughly, a identifier can be used everywhere from its

declaration point to the end of the block defined by a couple of

{ }.

#include <iostream>

using namespace std;

int main()

{

int i; i = 3;

if(i == 3) {

Page 10: Lecture Note 1 (2)

10

int j;

j = i + 4;

}

j = i + 3;

}

Variables can also be declared in the for statement.

In that case the scope of the identifier is the loop :

int main()

{

int j;

j = 0;

for(int i = 0; i < 10; i++) j = j + i; }

Basic Input/Output

The standard C++ library includes the header file iostream, where the standard input and output stream objects are

declared.

Standard Output (cout)

By default, the standard output of a program is the screen,

and the C++ stream object defined to access it is cout.

cout is used in conjunction with the insertion operator,

which is written as << (two "less than" signs).

Page 11: Lecture Note 1 (2)

11

The insertion operator (<<) may be used more than once in a

single statement:

cout << "Hello, " << "I am " << "a C++ statement";

In C++, a new-line character can be specified as \n or endl

Standard Input (cin).

Handling the standard input in C++ is done by applying the overloaded operator of extraction (>>) on the cin stream.

The operator must be followed by the variable that will store

the data that is going to be extracted from the stream. For

example:

Strings

Variables that can store non-numerical values that are longer than one single character are known as strings.

Page 12: Lecture Note 1 (2)

12

The C++ language library provides support for strings through

the standard string class.

This is not a fundamental type, but it behaves in a similar way

as fundamental types do in its most basic usage.

// my first string

#include <iostream>

#include <string>

using namespace std;

int main ()

{

string mystring = "This is a string";

cout << mystring;

return 0;

}

Constants

Constants are expressions with a fixed value.

Literals

Literals are used to express particular values within the source

code of a program.

Literal constants can be divided in Integer Numerals, Floating-

Point Numerals, Characters, Strings and Boolean Values.

Examples

5=5; //5 is a literal constant

75 // decimal

0113 // octal

0x4b // hexadecimal

75 // int 75u // unsigned int

75l // long

75ul // unsigned long

Page 13: Lecture Note 1 (2)

13

Floating Point Numbers

They express numbers with decimals and/or exponents.

3.14159 // 3.14159 6.02e23 // 6.02 x 10^23

1.6e-19 // 1.6 x 10^-19

3.0 // 3.0

3.14159L // long double

6.02e23f // float

Character and String Literals

'z'

'p'

"Hello world" "How do you do?"

Escape Codes

These are characters that are impossible to express otherwise

in the source code of a program.

Page 14: Lecture Note 1 (2)

14

Boolean Literals

There are only two valid Boolean values: true and false.

These can be expressed in C++ as values of type bool by

using the Boolean literals true and false.

Declared Constants (const)

With the const prefix you can declare constants with a specific

type in the same way as you would do with a variable:

const int pathwidth = 100;

Page 15: Lecture Note 1 (2)

15

Defined Constants (#define)

You can define your own names for constants that you use very often without having to resort to memory consuming

variables, simply by using the #define preprocessor directive.

Its format is:

#define identifier value

For example:

#define PI 3.14159

#define NEWLINE '\n'

Expressions

An expression is a sequence of one or more operands, and zero

or more operators, that when combined, produce a value.

For example:

x - 3

cos(y) + y

x + y + z x <= y * 7 - 2

Arithmetic Operators

List of operators

The standard mathematic symbols can be used to write

arithmetic expressions

Page 16: Lecture Note 1 (2)

16

The % computes the reminder of an integer division (for

instance 17 % 5 has the value 2) ; the result is well defined only if both operands are positive.

All those operators but % can be used with either integer or

floating point operands.

Operators Depend on the Types of the Operands

Internally, each symbol corresponds to different operations,

depending with the type of the operands:

#include <iostream>

using namespace std;

int main()

{

cout << 15 / 4 << ’ ’ << 15.0 / 4.0 << ’\n’;

}

displays 3 3.75.

Page 17: Lecture Note 1 (2)

17

Implicit Conversions

Basically operators are defined for two operands of the same

type. The compiler can automatically convert a numerical type

into another one so that the operator exists:

#include <iostream>

using namespace std;

int main()

{

cout << 3 + 4.3 << ’\n’;

}

result is 7.3

The implicit conversion cannot be done to a type that loses

information (i.e. double to int for instance).

For example the % operators is only defined for integer

operands :

#include <iostream>

using namespace std; int main()

{

cout << 3.0%4.0 << ’\n’;

}

Boolean Operators

We can define more precisely what we called a condition in the

description of the if, for, and while syntax. It is a boolean expression, which is an expression whose value

is of type bool.

Page 18: Lecture Note 1 (2)

18

A few operators have a boolean value and takes boolean

operands:

#include <iostream>

using namespace std;

int main() {

bool c1, c2;

c1 = true; c2 = !c1 && false;

cout << c1 << ’ ’ << c2 << ’\n’;

}

The compiler is smart and will compute the value of the second

operand of a boolean operation only if this is necessary.

Comparison Operators

The comparison operators take two numerical operands and have a Boolean value:

Page 19: Lecture Note 1 (2)

19

The equality and inequality are defined for any types and

return a Boolean value:

Assignment Operator

A strange thing in C++ is that assignments are also

expressions:

j = 3 + (i = 5);

is legal, and will assign to i the value 5, and to j the value 8.

But feel free not to use such weird tricks.

Page 20: Lecture Note 1 (2)

20

Compound Assignment (+=, -=, *=, /=, %=, >>=, <<=,

&=, ^=, |=)

When we want to modify the value of a variable by performing

an operation on the value currently stored in that variable, we

can use compound assignment operators:

// compound assignment operators

#include <iostream> using namespace std;

int main ()

{

int a, b=3;

a = b;

a+=2; // equivalent to a=a+2

cout << a;

return 0;

}

Page 21: Lecture Note 1 (2)

21

Increase and decrease (++, --)

c++;

c+=1;

c=c+1; are all equivalent

Precedence of Operators

The precedence of operators is the order used to evaluate

them during the evaluation of the complete expression.

To be compliant with the usual mathematical notations, the

evaluation is not left-to-right.

For example 3 + 4 * 5 + 6 * 7 is considered by the compiler as 3 + (4 * 5) + (6 * 7) and NOT AS (((3 + 4) * 5) + 6) * 7

When two operators have same precedence (i.e. when we have

the same operator twice), the evaluation is left-to-right

From greatest to lowest priority, the priority order is as

follows:

Page 22: Lecture Note 1 (2)

22

Page 23: Lecture Note 1 (2)

23

Control Structures

Control structures help a program to branch, repeat code or

take decisions instead of linear execution of instructions.

Conditional Statement

The if statement

The if statement executes a part of a program only if a given

condition is

if(condition)

<statement to execute if the condition is true>

or

Page 24: Lecture Note 1 (2)

24

if (condition)

<statement to execute if the condition is true>

else

<statement to execute if the condition is false>

A statement here is either a part of a program enclosed in { },

or a single line terminated with a ’;’.

For example :

#include <iostream>

using namespace std;

int main()

{

int n; cin >> n;

if(n < 0) n = 0;

else {

n = 2 * n;

n = n - 1;

}

cout << n << ’\n’;

system("pause");

}

Loops

Loops have as purpose to repeat a statement a certain number

of times or while a condition is fulfilled.

The for statement

The for statement repeats the execution of a part of a

program.

for(initialization; condition; increment)

<statement to repeat>

Page 25: Lecture Note 1 (2)

25

For example, to display all positive integers strictly smaller

than a value given by the user :

#include <iostream>

using namespace std;

int main()

{

int n, k;

cin >> n; for(k = 0; k < n; k++) cout << k << ’\n’;

system(“pause”);

}

The while statement

The while statement repeats the execution of a statement as

long as a condition is true.

For instance:

#include <iostream>

using namespace std;

int main()

{

double a, b, c;

a = 0.0; b = 2.0;

while(b-a > 1e-9) {

c = (a+b)/2.0;

if(c*c - 2.0 > 0.0) b = c; else a = c; }

cout << c << ’\n’;

system(“pause”);

}

Page 26: Lecture Note 1 (2)

26

The do { } while statement

Similar to while, but the statement is always executed at least

once.

#include <iostream>

using namespace std;

double a, b, c;

a = 0.0; b = 2.0;

do {

c = (a+b)/2.0;

if(c*c - 2.0 > 0.0) b = c; else a = c;

} while(fabs(c*c - 2.0) > 1e-4); cout << c << ’\n’;

system(”pause”);

}

The continue statement

The continue statement forces the current execution of the

loop to stop.

It is equivalent to jump to the end of the statement, so that the next iteration can start:

#include <iostream>

using namespace std;

int main(int argc, char **argv)

{

for(int n = 0; n<6; n++)

{

cout << "n = " << n << ’\n’;

if(n%2 == 1) continue; cout << "This is even\n";

system(”pause”);

}

}

Page 27: Lecture Note 1 (2)

27

The break Statement

Using break we can leave a loop even if the condition for its

end is not fulfilled.

// break loop example

#include <iostream>

using namespace std;

int main ()

{

int n;

for (n=10; n>0; n--)

{

cout << n << ", ";

if (n==3) {

cout << "countdown aborted!";

break;

}

}

return 0;

}

The switch / case Statements

When the behaviour of the program can be organized as a

succession of separate cases, selected by an integer value, the

switch statement is more efficient and elegant than a

succession of if :

#include <iostream>

using namespace std;

int main()

{ int k;

cout << "Enter a value between 1 and 3 : ";

cin >> k;

Page 28: Lecture Note 1 (2)

28

switch(k)

{

case 1:

cout << "one!\n";

break; case 2:

cout << "two!\n";

break;

case 3:

cout << "three!\n";

break;

default:

cout << "Didn’t get it, did you ?\n";

break;

system(“pause”); }

}

Functions

Using functions we can structure our programs in a more

modular way, accessing all the potential that structured

programming can offer to us in C++. A function is a group of statements that is executed when it is

called from some point of the program. The following is its

format:

type name ( parameter1, parameter2, ...)

{

Statements

}

where:

type is the data type specifier of the data returned by the function.

name is the identifier by which it will be possible to call the

function.

Page 29: Lecture Note 1 (2)

29

parameters: Each parameter consists of a data type specifier

followed by an identifier, like any regular variable declaration

statements is the function's body. It is a block of statements

surrounded by braces { }.

// function example

#include <iostream>

using namespace std;

int addition (int a, int b)

{

int r;

r=a+b;

return (r);

} int main ()

{

int z;

z = addition (5,3);

cout << "The result is " << z;

system(“pause”);

return 0;

}

Functions with no Type

A function that returns no value is of type void

// void function example

#include <iostream>

using namespace std;

void printmessage ()

{

cout << "I'm a function!"; }

int main ()

{

printmessage ();

system(“pause”);

Page 30: Lecture Note 1 (2)

30

return 0;

}

Passing Arguments by Reference

// passing parameters by reference

#include <iostream>

using namespace std;

void duplicate (int& a, int& b, int& c)

{

a*=2;

b*=2;

c*=2;

}

int main () {

int x=1, y=3, z=7;

duplicate (x, y, z);

cout << "x=" << x << ", y=" << y << ", z=" << z;

return 0;

}

Default Values in Parameters

When declaring a function we can specify a default value for

each of the last parameters.

This value will be used if the corresponding argument is left

blank when calling to the function.

// default values in functions

#include <iostream>

using namespace std; int divide (int a, int b=2)

{

int r;

r=a/b;

return (r);

Page 31: Lecture Note 1 (2)

31

}

int main ()

{

cout << divide (12);

cout << endl; cout << divide (20,4);

system(“pause”);

return 0;

}

Overloaded Functions

In C++ two different functions can have the same name if their parameter types or number are different.

// overloaded function

#include <iostream>

using namespace std;

int operate (int a, int b)

{

return (a*b);

}

float operate (float a, float b) {

return (a/b);

}

int main ()

{

int x=5,y=2;

float n=5.0,m=2.0;

cout << operate (x,y);

cout << "\n"; cout << operate (n,m);

cout << "\n";

return 0;

}

Page 32: Lecture Note 1 (2)

32

Inline Functions

Inline specifier is used to suggest to the compiler that the

code generated by the function body is inserted at each

point the function is called, instead of being inserted only once and perform a regular call to it, which generally

involves some additional overhead.

The format for its declaration is:

inline typename ( arguments ... ) { instructions ... }

Recursivity Recursivity is the ability of a function to call itself.

Therefore, a recursive function is a function that contains a statement or

statements that make a call to itself.

A recursive function calls itself and looks like what is shown below:

function( )

{

function( ); }

Recursion is of two types:

i. Direct Recursion

ii. Indirect Recursion

In direct recursion, a function a calls itself. That is, its code contains a call to

itself while in indirect recursion, the function a calls function b, b calls

another function c and so on until a is called again.

Of necessity, a good recursive function must have the following components:

i. A test to stop or continue the recursion

ii. A recursive call that continues the recursion

iii. An end case that stops the recursion

Page 33: Lecture Note 1 (2)

33

Consider the recursive function below:

Int add( int m)

{

if (m==1) // test to stop or continue

return 1; // end case: stopping recursion

else

return m + add(m – 1); // recursive call that continues the

recursion

}

Consider another function recursion below:

void recursion(argumentlist)

{

statement1;

if(test)

recursion(arguments);

statement2;

}

As long as the if statement remains true, each call to recursion( )

executes statement1, then invokes a new incarnation of recursion( ) without

reaching statement2

When the if statement becomes false, the current call then proceeds to

statement2.Then, when the current call terminates, the program control

returns to the previous version of recursion( ) that called it. Then that

version of recursion( ) completes executing its statement2 section and

terminates, returning control to the prior call, and so on.

Example:

To obtain the factorial of a number (n!) the mathematical formula would

be: n! = n * (n-1) * (n-2) * (n-3) ... * 1

More concretely, 5! (factorial of 5) would be: 5! = 5 * 4 * 3 * 2 * 1 = 120

A recursive function to calculate this in C++ could be:

Page 34: Lecture Note 1 (2)

34

// factorial calculator

#include <iostream>

using namespace std; long factorial (long a)

{

if (a > 1)

return (a * factorial (a-1)); else

return (1);

}

int main ()

{

long number;

cout << "Please type a number: "; cin >> number;

cout << number << "! = " << factorial (number);

return 0;

}

Function Prototype

To be able to call a function, it must have been declared in

some earlier point of the code.

Function prototyping allows you to do this.

// declaring functions prototypes

#include <iostream>

using namespace std; void odd (int a);

void even (int a);

int main ()

{

int i;

do {

cout << "Type a number (0 to exit): ";

cin >> i;

odd (i); } while (i!=0);

Page 35: Lecture Note 1 (2)

35

return 0;

}

void odd (int a)

{

if ((a%2)!=0) cout << "Number is odd.\n"; else even (a);

}

void even (int a)

{

if ((a%2)==0) cout << "Number is even.\n";

else odd (a);

}

Arrays

An array is a series of elements of the same type placed in

contiguous memory locations that can be individually

referenced by adding an index to a unique identifier.

For example, an array to contain 5 integer values of type int

called billy could be represented like this:

A typical declaration for an array in C++ is:

type name[elements];

Example: int main[23];

Initializing Arrays

When declaring a regular array of local scope (within a

function, for example), if we do not specify otherwise, its

elements will not be initialized to any value by default.

Page 36: Lecture Note 1 (2)

36

Example:

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

Accessing the Values of an Array

The syntax is: name[index]

billy[2] = 75;

a = billy[2];

Some other valid operations with arrays:

billy[0] = a;

billy[a] = 75;

b = billy [a+2];

billy[billy[a]] = billy[2] + 5;

// arrays example

#include <iostream>

using namespace std;

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

int n, result=0;

int main ()

{

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

{ result += billy[n];

}

cout << result;

return 0;

system(“pause”);

}

Page 37: Lecture Note 1 (2)

37

Multidimensional Array

Multidimensional arrays can be described as "arrays of

arrays".

For example, a bidimensional array can be imagined as a bidimensional table made of elements, all of them of a same

uniform data type.

#include<iostream>

using namespace std; #define WIDTH 2

#define HEIGHT 3

int jimmy [HEIGHT][WIDTH];

int n,m;

int main ()

{

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

{

for (m=0;m<WIDTH;m++) {

jimmy[n][m]=(n+1)*(m+1);

}

}

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

for (m=0;m<WIDTH;m++)

{

cout<<jimmy[n][m]<<"\v";

}

system("pause"); return 0;

}

Page 38: Lecture Note 1 (2)

38

Arrays as Parameters

The name of an array is the address of the first element of the

array.

// arrays as parameters

#include <iostream>

using namespace std;

void printarray (int arg[], int length)

{

for (int n=0; n<length; n++)

cout << arg[n] << " ";

cout << "n"; }

int main ()

{

int firstarray[] = {5, 10, 15};

int secondarray[] = {2, 4, 6, 8, 10};

printarray (firstarray,3);

printarray (secondarray,5);

system(“pause”); return 0;

}

Structures Structure is a group of data elements grouped together under one name.

These data elements, known as members, can have different types and different lengths.

Structures are declared in C++ using the following syntax:

struct structure_name {

member_type1 member_name1;

member_type2 member_name2;

member_type3 member_name3;

Page 39: Lecture Note 1 (2)

39

.

.

} object_names;

Where structure_name is a name for the structure type, object_name

can be a set of valid identifiers for objects that have the type of this structure.

Within braces { } there is a list with the data members, each one is

specified with a type and a valid identifier as its name.

Structure variables can also be created as below:

struct product { int weight;

float price;

} ;

product apple;

product banana, melon;

// structur.cpp -- a simple structure

#include <iostream>

#include <string> using namespace std;

struct student // structure declaration

{ string name, sex;

short age;

};

int main() {

student John;

cout << “Enter Your Name \n”;

cin>>John.name; cout << “Enter Your Sex \n”;

cin>>John.sex;

cout << “Enter Your Age \n”;

cin>>John.age; //output student’s particulars

cout << “Your name is ”<<John.name<<”\n”;

cout << “Your sex is ”<<John.sex<<”\n”;

Page 40: Lecture Note 1 (2)

40

cout << “Your age is ”<<John.age<<”\n”;

system(“pause”);

return 0; }

An Overview of Pointers

Pointers are variables that store addresses of values.

Reference operator (&)

The address that locates a variable within memory is what we call a

reference to that variable.

This reference to a variable can be obtained by preceding the identifier of a variable with an ampersand sign (&), known as reference operator, and

which can be literally translated as "address of".

For example: ted = &andy; would assign to ted the address of variable

andy,

The listing below shows how to find the addresses of variables:

#include <iostream>

using namespace std;

int main(void) {

int donuts=6;

double cups=4.5;

cout<<”donuts value = “<<donuts<<”\n”;

cout<<”donuts address = “<<&donuts<<”\n”;

system(“pause”);

return 0;

}

Dereferencing Pointers

Page 41: Lecture Note 1 (2)

41

Dereferencing a pointer means referring to the pointed-to

value. To dereference a pointer, apply the dereferencing

operator (*) to it.

Listing 2

#include <iostream>

using namespace std;

int main(void)

{

int updates=6;

int *p_updates;

p_updates=&updates;

cout<<* p_updates<<”\n”;

return 0; }

*p_updates and updates are equivalent. We can assign values

to *p_updates as below:

*p_updates=* p_updates + 1;

Pointers and Numbers

Pointers are not integer types, even though computers

typically handle addresses as integers.

Integers are numbers you can add, subtract, divide, etc. but

a pointer describes a location, and it doesn’t make sense to

multiply two locations.

In terms of operations you can perform with them, pointers

and integers are different from each other.

You can’t assign an integer to a pointer as below:

int *pi;

Page 42: Lecture Note 1 (2)

42

pi=ox8566fff4; // type mismatch

Although you may know that ox8566fff4 is a combined

segment offset address, nothing in the statement tells the

program that this number is an address.

To correct that you should have the following:

int *pi;

pi=(int *)ox8566fff4;

Allocating Memory With New

To allocate memory at run-time instead of at compile time,

you use the new operator.

You tell the new operator what data type you want memory

for: new finds a block of memory of the correct size and

returns the address of the block. It assigns this address to a

pointer. It uses the type to figure out how many bytes are

needed. The syntax is:

type * poniter_name = new type

Listing 3

The listing below shows how to create memory with new:

#include<iostream>

using namespace std;

int main(void) {

int *pi=new int; // allocate a space for an int

*pi=1001;

cout<<"int value="<<*pi<<"location=" << pi<<"\n";

double *pd=new double;

*pd=100001.2;

cout<<"double value ="<<*pd<<"location: "<<pd<<"\n";

Page 43: Lecture Note 1 (2)

43

cout<<"sizeof pi="<<sizeof pi<<"\n";

cout<<"sizeof pd="<<sizeof pd<<"\n";

system(“pause”);

return 0;

}

Note: When a computer does not have enough memory to satisfy

a request for a new memory, ‘new’ returns the value 0. A pointer

with a value 0 is called a null pointer. It doesn’t point to any

valid data.

Using new to Create Dynamic Arrays

Static Binding: The space for any array declared is allocated at

compile time. Whether or not the program finally uses the array,

the array is there, using up memory. This is called static binding,

meaning that the array is built into the program at compilation

time.

Dynamic Binding: When memory is requested during run-time,

this is called dynamic binding.

The syntax for allocating and assigning memory for an array with

new is:

type_name *pointer_name = new

type_name[num_elements];

This returns a block of memory large enough to hold

num_elements elements of the type type_name, with

pointer_name pointing to the first element.

Example

int* psome= new int[10];

psome points to the first element of the array. Alternatively, the

elements can be accessed as psome[0], psome[1],… psome[9].

Page 44: Lecture Note 1 (2)

44

A fundamental difference between a pointer and an array name is

that you can’t change the value of an array name, but a pointer is

a variable and hence, you can change its value.

Listing 4

#include<iostream>

using namespace std;

int main(void)

{

double *p3=new double[3];

p3[0]=0.2;p3[1]=0.5;p3[2]=0.8;

cout<< "p3[1] is"<<p3[1]<<"\n";

p3=p3+1;

cout<<"Now p3[0] is"<<p3[0]<<"\n"; double *pd=new double;

*pd=100001.2;

cout<<"double value ="<<*pd<<"location: "<<pd<<"\n";

system(“pause”);

return 0;

}

The output :

P3[1] is 0.5

Now p3[0] is 0.5

Creating Dynamic Structures With new

Using new with structures has two parts:

1. Creating the structure

2. Accessing its members

To create a dynamic structure, use the syntax:

type *pointer = new type;

Page 45: Lecture Note 1 (2)

45

For example, to create an unnamed structure of the inflatable

type and to assign its address to a suitable pointer, do the

following:

inflatable *ps = new inflatable;

To access the structure members, you can’t use the dot

membership operator with the structure name because the

structure has no name. All you have is its address. To access the

members, you have to use the arrow membership operator (->).

Example

Consider the following:

struct things

{ int good;

int bad;

};

things grubnose={3, 453};

things* pt=&grubnose;

Use the . operator with the structure name: grubnose.good and

grubnose.bad

Use -> operator with pointer-to-structure:

pt->good and pt->bad

Another approach to reference the structure members is to say

that if ps is a pointer to a structure, then *ps represents the

pointed-to value, the structure itself. Then, because *pt is a

structure, (*pt).good is the good member of the structure.

The listing below uses new to create an unnamed structure

and demonstrates both pointer notations for accessing

structure members.

Page 46: Lecture Note 1 (2)

46

Listing 5

// structur.cpp -- a simple structure allocated using new

#include <iostream>

#include <string>

using namespace std;

struct student // structure declaration

{

string name, sex;

short age; };

int main()

{

student* variable=new student;

cout << “Enter Your Name \n”;

cin>>variable->.name;

cout << “Enter Your Sex \n”;

cin>>variable->.sex; cout << “Enter Your Age \n”;

cin>>(*variable).age;

//output student’s particulars

cout << “Your name is ”<<variable->name<<”\n”;

cout << “Your sex is ”<<variable->sex<<”\n”;

cout << “Your age is ”<<variable->age<<”\n”;

system(“pause”);

return 0;

}

Freeing Memory with delete

Using new to request for memory when you need it is just the

more glamorous half of the C++ memory management package.

Page 47: Lecture Note 1 (2)

47

The other half is the delete operator, which lets you return

memory to the memory pool when you are finished with it. The

memory that you return or free can be reused by other parts of

your program.

You use delete by following it with a pointer to a block of

memory originally allocated with new:

int *ps=new int; delete ps;

Note: You cannot use delete to free memory created by declaring

variables.

int jugs =5; // ok

int* pi =&jugs //ok

delete pi; //not allowed, pi not allocated by new

You can use another pointer to free memory allocated with

another pointer:

int * ps= new int; // allocate memory

int * pq= ps; // set second pointer to the same block

delete pq; //delete with second pointer

Listing 6

#include<iostream.h>

#include<string.h>

char* getname (void); // function prototype

int main(void)

{

char* name; // create a pointer to no storage name=getname(); // assign address of string to name

cout<<name <<”at “<<(int*) name<<”\n”;

delete name; // memory freed

name=getname(); // reuse freed memory

Page 48: Lecture Note 1 (2)

48

cout<<name<<” at ”<< (int*)name<<”\n”;

return 0;

}

char* getname(void) {

char name[100];

cout<<”Enter your name\n”;

cin>>name;

return name;

}

Review Questions

1. Suppose ted is a double variable. Declare a pointer that

points to ted, and use the pointer to display ted’s value.

2. Write a code fragment that asks the user to enter a positive

integer and then creates a dynamic array of that many ints.

3. Is the following valid code? If so, what does it print?

cout <<(int*) “Home of the jolly bytes”;

Pointer Arithmetic

Only addition and subtraction operations are allowed to be conducted with pointers.

Suppose that we define three pointers as:

char *mychar;

short *myshort;

long *mylong;

Suppose we know that they point to memory locations 1000,

2000 and 3000 respectively.

Assuming that in a given compiler for a specific machine, char

takes 1 byte, short takes 2 bytes and long takes 4.

If we write: mychar++;

myshort++;

Page 49: Lecture Note 1 (2)

49

mylong++;

mychar, would contain the value 1001.

myshort would contain the value 2002

mylong would contain 3004

Void Pointers

Void pointers are pointers that point to a value that has no

type.

One of its uses may be to pass generic parameters to a

function:

// increaser

#include <iostream>

using namespace std;

void increase (void* data, int psize)

{

if ( psize == sizeof(char) )

{ char* pchar; pchar=(char*)data; ++(*pchar); }

else if (psize == sizeof(int) )

{ int* pint; pint=(int*)data; ++(*pint); }

}

Page 50: Lecture Note 1 (2)

50

int main ()

{

char a = 'x';

int b = 1602;

increase (&a,sizeof(a));

increase (&b,sizeof(b));

cout << a << ", " << b << endl;

return 0;

}

Null Pointer A null pointer is a regular pointer of any pointer type which has a special

value that indicates that it is not pointing to any valid reference or

memory address:

int * p;

p = 0; // p has a null pointer value

Other Data Types

1. Defined data types (typedef)

C++ allows the definition of our own types based on other

existing data types. We can do this using the keyword typedef,

whose format is:

typedef existing_type new_type_name ;

where existing_type is a C++ fundamental or compound type and

new_type_name is the name for the new type we are defining.

For example: typedef char C;

typedef unsigned int WORD;

typedef char * pChar;

typedef char field [50]

Page 51: Lecture Note 1 (2)

51

We can use the defined types in other declarations as below:

C mychar, anotherchar, *ptc1;

WORD myword;

pChar ptc2;

field name;

2. Unions

A union is a data format that can hold different data types but only one type at a time.

That is, whereas a structure can hold, say, an int and a long

and a double, a union can hold an int or a long or a double. Syntax:

union union_name {

member_type1 member_name1;

member_type2 member_name2;

member_type3 member_name3;

.

.

} object_names;

Example union one4all

{

int int_val;

long long_val;

double double_val;

};

You can use a one4all variable to hold an int, a long, or a double, just as long

as you do so at different times:

one4all pail;

pail.int_val = 15; // store an int

cout << pail.int_val;

pail.double_val = 1.38; // store a double, int value is lost

cout << pail.double_val;

Page 52: Lecture Note 1 (2)

52

3. Enumerations Enumerations create new data types to contain something different that

is not limited to the values fundamental data types may take.

Its syntax is:

enum enumeration_name

{

value1,

value2,

value3,

.

.

} object_names;

Example:

enum colors_t {black, blue, green, cyan, red, purple, yellow, white};

colors_t mycolor;

mycolor = blue;

Enumerations constants are always assigned an integer numerical value

internally.

If it is not specified, the integer value equivalent to the first possible

value is equivalent to 0 and the following ones follow a +1 progression. We can explicitly specify an integer value for any of the constant values

that our enumerated type can take:

enum months_t { january=1, february, march, april,may, june, july, august,

september, october, november, december} y2k;

Classes

A class is an expanded concept of a structure: instead of

holding only data, it can hold both data and functions.

An object is an instantiation of a class. In terms of variables, a

class would be the type, and an object would be the variable.

Classes are generally declared using the keyword class, with

the following format:

Page 53: Lecture Note 1 (2)

53

int * p;

p = 0; // p has a null pointer value

class class_name

{

access_specifier_1:

member1;

access_specifier_2:

member2;

...

} object_names;

class_name is a valid identifier for the class

object_names is an optional list of names for objects of this

class.

The body of the declaration can contain members, that can be

either data or function declarations, and optionally access

specifiers.

An access specifier is one of the following three keywords:

private, public or protected.

private members of a class are accessible only from within

other members of the same class or from their friends.

protected members are accessible from members of their same

class and from their friends, but also from members of their

derived classes.

public members are accessible from anywhere where the

object is visible.

By default, all members of a class declared with the class

keyword have private access for all its members.

Example

class CRectangle

{

int x, y;

Page 54: Lecture Note 1 (2)

54

public:

void set_values (int,int);

int area (void);

} rect;

You invoke a class member function, or method, by using a class object. You

do so by using the dot membership operator:

rect.set_values (3,4);

myarea = rect.area();

Here is the complete example of class CRectangle:

// classes example

#include <iostream>

using namespace std;

class CRectangle

{

int x, y;

public:

void set_values (int,int);

int area ()

{

return (x*y);

}

};

void CRectangle::set_values (int a, int b)

{

x = a;

y = b;

}

int main ()

{

CRectangle rect;

rect.set_values (3,4);

Page 55: Lecture Note 1 (2)

55

cout << "area: " << rect.area();

return 0;

}

The scope operator (::) specifies the class to which the

member being declared belongs.

Constructors and Destructors

Constructors are used to initialize member variables or assign dynamic memory during their process of creation of objects.

Constructors are automatically called whenever a new object of

this class is created.

A constructor function must have the same name as the class,

and cannot have any return type; not even void.

Constructors cannot be called explicitly as if they were regular

member functions. They are only executed when a new object

of that class is created

Constructor Example

// example: class constructor

#include <iostream>

using namespace std;

class CRectangle

{

int width, height;

public:

CRectangle (int,int);

int area () {return (width*height);}

};

CRectangle::CRectangle (int a, int b)

{

width = a;

height = b;

}

Page 56: Lecture Note 1 (2)

56

int main (){

CRectangle rect (3,4);

CRectangle rectb (5,6);

cout << "rect area: " << rect.area() << endl;

cout << "rectb area: " << rectb.area() << endl;

return 0;

}