Lecture 1

34
Pointers Pointers Function Templates Function Templates Class Templates Class Templates Lecture#2 Lecture#2

description

Data Structures, Tree, Queue

Transcript of Lecture 1

Page 1: Lecture 1

Pointers Pointers Function TemplatesFunction TemplatesClass TemplatesClass Templates

Lecture#2Lecture#2

Page 2: Lecture 1

POINTER OVERVIEWPOINTER OVERVIEW

A pointer provides a way of accessing a A pointer provides a way of accessing a variable (or a more complex kind of data, variable (or a more complex kind of data, such as an array) without referring to the such as an array) without referring to the variable directly.variable directly.

The mechanism used for this is the The mechanism used for this is the address of the variableaddress of the variable. In effect, the . In effect, the address acts as an intermediary between address acts as an intermediary between the variable and the program accessing the variable and the program accessing it.it.

Page 3: Lecture 1

POINTER OVERVIEWPOINTER OVERVIEW

In a similar way, a program statement can In a similar way, a program statement can refer to a variable indirectly, using the refer to a variable indirectly, using the address of the variable as a sort of post address of the variable as a sort of post office box or hollow tree for the passing of office box or hollow tree for the passing of information.information.

Why are pointers used?Why are pointers used? Pointers are used in situations when Pointers are used in situations when

passing actual values is difficult or passing actual values is difficult or undesirable.undesirable.

Page 4: Lecture 1

POINTER OVERVIEWPOINTER OVERVIEW Some reasons to use pointers are:Some reasons to use pointers are:

To return more than one value from a function.To return more than one value from a function. To pass arrays and strings more conveniently from To pass arrays and strings more conveniently from

one function to another.one function to another. To manipulate arrays more easily by moving pointers To manipulate arrays more easily by moving pointers

to them (or to parts of them), instead of moving the to them (or to parts of them), instead of moving the arrays themselves. arrays themselves. 

To create complex data structures, such as linked lists To create complex data structures, such as linked lists and binary trees, where one data structure must and binary trees, where one data structure must contain references to other data structure.contain references to other data structure.

To communicate information about memory, as in the To communicate information about memory, as in the function malloc( )/new, which returns the location of function malloc( )/new, which returns the location of the free memory by using a pointer. the free memory by using a pointer.

Page 5: Lecture 1

Pointer VariablesPointer Variables

int* ptr;int* ptr; Asterisk means pointer toAsterisk means pointer to Statement defines Statement defines ptrptr as a pointer to as a pointer to intint This variable can hold the This variable can hold the address ofaddress of integer integer

variablesvariables

char* cptr;//pointer to charchar* cptr;//pointer to char

int* iptr;//pointer to intint* iptr;//pointer to int

float* fptr;//pointer to floatfloat* fptr;//pointer to float

Distance* distptr; //pointer to user-defined Distance Distance* distptr; //pointer to user-defined Distance classclass

Page 6: Lecture 1

Accessing the ContentsAccessing the Contents

If we know the address of a variable If we know the address of a variable and don’t know its name. Can we and don’t know its name. Can we access the contents of this variable?access the contents of this variable?

There is a special syntax to access There is a special syntax to access the value/contents of a variable the value/contents of a variable using its address.using its address.

Page 7: Lecture 1

Accessing the ContentsAccessing the Contents

int main()int main()

{{

int var1=11;int var1=11;

int* ptr;int* ptr;

ptr=&var1;ptr=&var1;

cout << *ptr << endlcout << *ptr << endl;//prints contents of pointer(11);//prints contents of pointer(11)

//* acts as indirection operator//* acts as indirection operator

}}

Page 8: Lecture 1

Declaration Vs IndirectionDeclaration Vs Indirection

Asterisk used as the indirection operator has Asterisk used as the indirection operator has a different meaning then the asterisk used to a different meaning then the asterisk used to declare pointer variables.declare pointer variables.

Indirection operator precedes the variable and Indirection operator precedes the variable and means means value of the variable pointed to byvalue of the variable pointed to by..

The asterisk used in the declaration means The asterisk used in the declaration means pointer topointer toint* ptr;//declaration: pointer to intint* ptr;//declaration: pointer to int*ptr = 37;//indirection: value of variable pointed to *ptr = 37;//indirection: value of variable pointed to

by ptrby ptr

Page 9: Lecture 1

Pointers and ArraysPointers and Arrays

There is a close association between There is a close association between pointers and arrayspointers and arrays

These two expressions have exactly These two expressions have exactly the same effect:the same effect:intarray[j]intarray[j]

*(intarray+j)//using indirection operator*(intarray+j)//using indirection operator

Page 10: Lecture 1

Pointers and FunctionsPointers and Functions

Passing arguments by pointerPassing arguments by pointer#include <iostream.h>#include <iostream.h>void increment(int void increment(int **); );   void main(void)void main(void){{int tvar = 10;int tvar = 10;increment(increment(&&tvar);tvar);cout << tvar;cout << tvar;}}void increment(int void increment(int **counter)counter){{**counter = 11;counter = 11;//acts as tvar = 11//acts as tvar = 11}}

Page 11: Lecture 1

Passing ArraysPassing Arrays

const int MAX=5;const int MAX=5;void main()void main(){{void centimize(double*);//prototypevoid centimize(double*);//prototypedouble varray[MAX]={10.0,43.1,95.9,59.7,87.3};double varray[MAX]={10.0,43.1,95.9,59.7,87.3};centimize(varray);centimize(varray);//since the name of an array is array’s address, there is no need for &//since the name of an array is array’s address, there is no need for &……}}Void centimize(double* ptrd)Void centimize(double* ptrd){{for(int j=0; j<MAX;j++)for(int j=0; j<MAX;j++)

*ptrd++ *= 2.54;//ptrd points to element of array *ptrd++ *= 2.54;//ptrd points to element of array }}

Page 12: Lecture 1

const Modifier and Pointersconst Modifier and Pointers

There are two possibilitiesThere are two possibilitiesconst int* ptrcint; // ptrcint is a pointer to constant intconst int* ptrcint; // ptrcint is a pointer to constant int

int* const cptrint; // cptrint is a constant pointer to intint* const cptrint; // cptrint is a constant pointer to int In first declaration, you can’t change the value of In first declaration, you can’t change the value of

whatever cptrint points to, although you can whatever cptrint points to, although you can change cptrint itself.change cptrint itself.

In second declaration, you can change what In second declaration, you can change what ptrcint points to, but you can’t change the value ptrcint points to, but you can’t change the value of ptrcint itself.of ptrcint itself.

Page 13: Lecture 1

Memory ManagementMemory Management

If we use arrays for data storage, we must know If we use arrays for data storage, we must know at the time we write the program at the time we write the program how big the how big the array will be.array will be.Cin<<size;//get size from userCin<<size;//get size from user

Int arr[size];//error: array size must be a constantInt arr[size];//error: array size must be a constant C++ provides a new approach to obtaining blocks C++ provides a new approach to obtaining blocks

of memory: the new operator.of memory: the new operator. This versatile operator obtains memory from the This versatile operator obtains memory from the

operating system and returns a pointer to its operating system and returns a pointer to its starting point.starting point.

Page 14: Lecture 1

The new OperatorThe new Operator#include<iostream.h>#include<iostream.h>

#include<cstring>#include<cstring>

int main()int main()

{{

char* str="self conquest is the greatest victory";char* str="self conquest is the greatest victory";

int len = strlen(str);int len = strlen(str);

char* ptr;char* ptr;

ptr = new char[len+1];//set aside memory: string + ‘\0’ptr = new char[len+1];//set aside memory: string + ‘\0’

strcpy(ptr, str);strcpy(ptr, str);

cout << ptr << endl;cout << ptr << endl;

delete[] ptr;//release ptr’s memory delete[] ptr;//release ptr’s memory

return 0;return 0;

}}

Page 15: Lecture 1

TemplatesTemplates

C++ supports code reuse in different C++ supports code reuse in different ways. ways.

The template feature in C++ The template feature in C++ provides way to reuse source code.provides way to reuse source code.

Page 16: Lecture 1

Function TemplatesFunction Templates

Suppose you want to write a function that Suppose you want to write a function that returns the absolute value of a number. returns the absolute value of a number.

Ordinarily, this function would be written for a Ordinarily, this function would be written for a particular data type:particular data type:int abs(int n) // absolute value of intsint abs(int n) // absolute value of ints{{return (n<0) ? -n : n; // if n is negative, return –n return (n<0) ? -n : n; // if n is negative, return –n }}

Here the function is defined to take an Here the function is defined to take an argument of type argument of type intint and to return a value of and to return a value of this same type.this same type.

Page 17: Lecture 1

Function TemplatesFunction Templates

But now suppose you want to find the absolute value of But now suppose you want to find the absolute value of a type a type longlong. You need to write a completely new . You need to write a completely new function:function:long abs(long n) // absolute value of longslong abs(long n) // absolute value of longs{ { return (n<0) ? -n : n; return (n<0) ? -n : n; }}

And again, for type And again, for type floatfloat::float abs(float n) // absolute value of floatsfloat abs(float n) // absolute value of floats{{return (n<0) ? -n : n;return (n<0) ? -n : n;}}

Page 18: Lecture 1

Function TemplatesFunction Templates

The body of the function is the same in each The body of the function is the same in each case, but they must be case, but they must be separate functionsseparate functions because they handle variables of different types.because they handle variables of different types.

It’s true that in C++ these functions can all be It’s true that in C++ these functions can all be overloadedoverloaded to have the same name, but you must to have the same name, but you must nevertheless write a separate definition for each nevertheless write a separate definition for each one.one.

Rewriting the same function bodyRewriting the same function body over and over over and over for different types Wastes time as well as space for different types Wastes time as well as space in the listing.in the listing.

Page 19: Lecture 1

Function TemplatesFunction Templates

Also, if you find you’ve made an Also, if you find you’ve made an errorerror in one such in one such function, you’ll need to remember to correct it in function, you’ll need to remember to correct it in each function body. Failing to do this correctly is each function body. Failing to do this correctly is a good way to introduce inconsistencies into your a good way to introduce inconsistencies into your program.program.

It would be nice if there were a way to It would be nice if there were a way to write such write such aa function just oncefunction just once and have it work for many and have it work for many different data types. This is exactly what Function different data types. This is exactly what Function templates do for you.templates do for you.

Page 20: Lecture 1

Function TemplatesFunction Templates// template used for absolute value function// template used for absolute value function#include <iostream.h>#include <iostream.h>template <class T> template <class T> // function template// function templateT T abs(abs(TT n)n){ return (n < 0) ? -n : n; }{ return (n < 0) ? -n : n; }void main()void main(){{ int int1 = 5;int int1 = 5;

int int2 = -6;int int2 = -6;long lon1 = 70000;long lon1 = 70000;long lon2 = -80000;long lon2 = -80000;double dub1 = 9.95;double dub1 = 9.95;double dub2 = -10.15; // calls instantiate functionsdouble dub2 = -10.15; // calls instantiate functionscout << "abs(" << int1 << ")=" << cout << "abs(" << int1 << ")=" << abs(int1) abs(int1) << endl; // abs(int)<< endl; // abs(int)cout << "abs(" << int2 << ")=" << cout << "abs(" << int2 << ")=" << abs(int2) abs(int2) << endl; // abs(int)<< endl; // abs(int)cout << "abs(" << lon1 << ")=" << cout << "abs(" << lon1 << ")=" << abs(lon1) abs(lon1) << endl; // abs(long)<< endl; // abs(long)cout << "abs(" << lon2 << ")=" << cout << "abs(" << lon2 << ")=" << abs(lon2) abs(lon2) << endl; // abs(long)<< endl; // abs(long)cout << "abs(" << dub1 << ")=" << cout << "abs(" << dub1 << ")=" << abs(dub1) abs(dub1) << endl; // abs(double)<< endl; // abs(double)cout << "abs(" << dub2 << ")=" << cout << "abs(" << dub2 << ")=" << abs(dub2) abs(dub2) << endl; // abs(double)<< endl; // abs(double)

}}

OUTPUT:

abs(5)=5

abs(-6)=6

abs(70000)=70000

abs(-80000)=80000

abs(9.95)=9.95

abs(-10.15)=10.15

Page 21: Lecture 1

Function TemplatesFunction Templates

The key The key innovationinnovation in function templates is to in function templates is to represent the data type used by the function not as a represent the data type used by the function not as a specific typespecific type such as such as intint, but by a name that can stand , but by a name that can stand for any type. for any type.

In the function template above, this name is In the function template above, this name is TT.. The The templatetemplate keyword signals the compiler that I’m keyword signals the compiler that I’m

about to define a Function template. about to define a Function template. The keyword The keyword classclass, within the angle brackets, might , within the angle brackets, might

just as well be called type. As you’ve seen, you can just as well be called type. As you’ve seen, you can define your own data types using classes, so there’s define your own data types using classes, so there’s really no distinction between types and classes. really no distinction between types and classes.

The variable following the keyword class (The variable following the keyword class (TT in this in this example) is called the example) is called the template argumenttemplate argument..

Page 22: Lecture 1

Function TemplatesFunction Templates

What does the What does the compilercompiler do when it sees the do when it sees the templatetemplate keyword and the Function definition that follows it?keyword and the Function definition that follows it?

The function template itself doesn’t cause the compiler The function template itself doesn’t cause the compiler to generate any code. to generate any code.

It can’t generate code because it doesn’t know yet what It can’t generate code because it doesn’t know yet what data type the function will be working with. data type the function will be working with.

It simply remembers the template for possible future use. It simply remembers the template for possible future use. Code generation doesn’t take place Code generation doesn’t take place until the function is until the function is

actually called (invoked)actually called (invoked) by a statement within the by a statement within the program. This happens in expressions such as abs(int1) program. This happens in expressions such as abs(int1) in the Statementin the Statementcout << "abs(" << int << ")=" << abs(int1);cout << "abs(" << int << ")=" << abs(int1);

Page 23: Lecture 1

Function TemplatesFunction Templates

When the compiler sees a function call, it When the compiler sees a function call, it knows that the type to use is int, because knows that the type to use is int, because that’s the type of the argument that’s the type of the argument int1int1..

So it generates a specific version of the So it generates a specific version of the abs()abs() function for type function for type intint, substituting , substituting intint wherever wherever it sees the name it sees the name TT in the function template. in the function template.

This is called This is called instantiating the function instantiating the function templatetemplate, and each instantiated version of , and each instantiated version of the function is called a the function is called a template functiontemplate function..

Page 24: Lecture 1

Function TemplatesFunction Templates

Notice that the amount of Notice that the amount of RAMRAM used by the used by the program is the same whether I use the template program is the same whether I use the template approach or write three separate functions.approach or write three separate functions.

What I’ve saved is having to What I’ve saved is having to type three separate type three separate functions into the source file. This makes the functions into the source file. This makes the listing shorter and easier to understand.listing shorter and easier to understand.

Also, if I want to Also, if I want to changechange the way the function the way the function works, I need to make the change in only one works, I need to make the change in only one place in the listing instead of three.place in the listing instead of three.

Page 25: Lecture 1

Function Templates with Function Templates with Multiple ArgumentsMultiple Arguments

Let’s look at another example of a function Let’s look at another example of a function template. This one takes Three arguments: template. This one takes Three arguments: two two template arguments and one basic typetemplate arguments and one basic type..

The purpose of this function is to search an The purpose of this function is to search an array for a specific value. array for a specific value.

The function returns the array index for that The function returns the array index for that value if it finds it, or -1 if it can’t find it.value if it finds it, or -1 if it can’t find it.

The The argumentsarguments are a pointer to the array, the are a pointer to the array, the value to search for, and the size of the array.value to search for, and the size of the array.

Page 26: Lecture 1

Function Templates with Function Templates with Multiple ArgumentsMultiple Arguments

// function returns index number of item, or -1 if not found // function returns index number of item, or -1 if not found templatetemplate

template <class template <class atypeatype>>int find(const int find(const atypeatype* array, * array, atypeatype value, int size)value, int size){{

for(int j=0; j<size; j++)for(int j=0; j<size; j++)if(array[ j ]==value) return j;if(array[ j ]==value) return j;

return -1;return -1;}}

char chrArr[ ] = {'a', 'c', char chrArr[ ] = {'a', 'c', 'f''f', 's', 'u', 'z'}; // array, 's', 'u', 'z'}; // arraychar ch = char ch = 'f''f'; // value to find; // value to findint intArr[ ] = {1, 3, 5, 9, 11, 13};int intArr[ ] = {1, 3, 5, 9, 11, 13};int in = int in = 66;;double dubArr[ ] = {1.0, 3.0, 5.0, 9.0, 11.0, 13.0};double dubArr[ ] = {1.0, 3.0, 5.0, 9.0, 11.0, 13.0};double db = double db = 4.04.0;;

Page 27: Lecture 1

Function Templates with Multiple Function Templates with Multiple ArgumentsArguments

int main()int main()

{{

cout << "\n 'f' in chrArray: index=" << find(chrArr, ch, 6);cout << "\n 'f' in chrArray: index=" << find(chrArr, ch, 6);

cout << "\n 6 in intArray: index=" << find(intArr, in, 6);cout << "\n 6 in intArray: index=" << find(intArr, in, 6);

cout << "\n 4 in dubArray: index=" << find(dubArr, db, 6);cout << "\n 4 in dubArray: index=" << find(dubArr, db, 6);

return 0;return 0;

}} Here, the name of the template argument is Here, the name of the template argument is atypeatype. The . The

compiler generates compiler generates three versions of the functionthree versions of the function, one for , one for each type used to call it.each type used to call it. OUTPUT:

'f' in chrArray: index=2 6 in intArray: index=-1 4 in dubArray: index=-1

Page 28: Lecture 1

Template Arguments Must Template Arguments Must MatchMatch

When a template function is invoked, all instances of the When a template function is invoked, all instances of the same template argument must be of the same type. For same template argument must be of the same type. For example, in example, in find()find(), if the array name is of type , if the array name is of type intint, the , the value to search for must also be of type value to search for must also be of type intint. You can’t say. You can’t say

int intarray[ ] = {1, 3, 5, 7}; // int arrayint intarray[ ] = {1, 3, 5, 7}; // int arrayfloat f1 = 5.0; // float valuefloat f1 = 5.0; // float valueint value = find(intarray, f1, 4); // errorint value = find(intarray, f1, 4); // error

Because the compiler expects all instances of Because the compiler expects all instances of atypeatype to be to be the same type. the same type.

find(int*, int, int); // It can generate a functionfind(int*, int, int); // It can generate a functionfind(int*, float, int); // It can’t generate a functionfind(int*, float, int); // It can’t generate a function

Because the first and second arguments must be the same type.Because the first and second arguments must be the same type.

Page 29: Lecture 1

Class TemplatesClass Templates

The template concept can be applied to The template concept can be applied to classes as well as to functions. classes as well as to functions.

Class templates are generally used for Class templates are generally used for data storage (container) classesdata storage (container) classes. .

Stacks and linked lists, are examples of Stacks and linked lists, are examples of data storage classes. data storage classes.

The Stack class in the program that is The Stack class in the program that is presented below, could store data only of presented below, could store data only of type int:type int:

Page 30: Lecture 1

Class TemplatesClass Templatesclass Stack {class Stack {

int st[MAX]; // array of intsint st[MAX]; // array of intsint top; // index number of top of stackint top; // index number of top of stack

public:public:Stack(); // constructorStack(); // constructorvoid push(int var); // takes int as argumentvoid push(int var); // takes int as argumentint pop(); // returns int valueint pop(); // returns int value

};}; If I wanted to store data of type long in a stack, I would need to define a If I wanted to store data of type long in a stack, I would need to define a

completely new class:completely new class:class LongStack {class LongStack {

long st[MAX]; // array of longslong st[MAX]; // array of longsint top; // index number of top of stackint top; // index number of top of stack

public:public:LongStack(); // constructorLongStack(); // constructorvoid push(long var); // takes long as argumentvoid push(long var); // takes long as argumentlong pop(); // returns long valuelong pop(); // returns long value

};};

Page 31: Lecture 1

Class TemplatesClass TemplatesSolution with a class template:Solution with a class template:template <class template <class TypeType>>class Stack{class Stack{

enum {MAX=100};enum {MAX=100};TypeType st[MAX]; // stack: array of any typest[MAX]; // stack: array of any typeint top; // number of top of stackint top; // number of top of stack

public:public:Stack(){top = 0;} // constructorStack(){top = 0;} // constructorvoid push(void push(TypeType ); // put number on stack); // put number on stackTypeType pop(); // take number off stackpop(); // take number off stack

};};template<class Type>template<class Type>

void void Stack<Stack<TypeType>>::push(::push(TypeType var) // put number on stack var) // put number on stack{{

if(top > MAX-1) // if stack full,if(top > MAX-1) // if stack full,cout<< "Stack is full!"; cout<< "Stack is full!";

st[top++] = var;st[top++] = var;}}

Page 32: Lecture 1

Class TemplatesClass Templates

template<class Type>template<class Type>

TypeType Stack< Stack<TypeType>>::pop() // take number off stack::pop() // take number off stack

{{

if(top <= 0) // if stack empty,if(top <= 0) // if stack empty,

cout<< "Stack is empty!"; cout<< "Stack is empty!";

return st[--top];return st[--top];

}}

Page 33: Lecture 1

Class TemplatesClass Templates

int main()int main()

{{

// s1 is object of class Stack<float>// s1 is object of class Stack<float>

Stack<Stack<floatfloat> > s1;s1;

// push 2 floats, pop 2 floats// push 2 floats, pop 2 floats

s1.push(1111.1);s1.push(1111.1);

s1.push(2222.2);s1.push(2222.2);

cout << "1: " << s1.pop() << endl;cout << "1: " << s1.pop() << endl;

cout << "2: " << s1.pop() << endl;cout << "2: " << s1.pop() << endl;

Page 34: Lecture 1

Class TemplatesClass Templates

// s2 is object of class Stack<long>// s2 is object of class Stack<long>

Stack<Stack<longlong> > s2;s2;

// push 2 longs, pop 2 longs// push 2 longs, pop 2 longs

s2.push(123123123L);s2.push(123123123L);

s2.push(234234234L);s2.push(234234234L);

cout << "1: " << s2.pop() << endl;cout << "1: " << s2.pop() << endl;

cout << "2: " << s2.pop() << endl;cout << "2: " << s2.pop() << endl;

return 0;return 0;

} // End of program} // End of program