Pointers CSE 5100 Data Structures and Algorithms

Preview:

Citation preview

PointersPointers

CSE 5100CSE 5100

Data Structures and AlgorithmsData Structures and Algorithms

Getting the address of a variableGetting the address of a variable

You need to use the address operator You need to use the address operator &&#include <iostream.h>#include <iostream.h>  

void main()void main(){{ int num;int num;  

num = 22;num = 22; cout << "num= " << num << endl;cout << "num= " << num << endl; cout << "The address of num = " << &num << endl;cout << "The address of num = " << &num << endl;}}

Storing addressesStoring addresses

We can store addresses in suitably declared We can store addresses in suitably declared variablesvariables

num_addr = &num;num_addr = &num; The variable The variable num_addrnum_addr is called a is called a pointer pointer

variablevariable PointersPointers are simply variables that are used are simply variables that are used

to store the addresses of other variables.to store the addresses of other variables.

Storing addressesStoring addresses (cont.) (cont.)

Declaring PointersDeclaring Pointers

You need to specify two things:You need to specify two things:

(a) the data type of the variable pointed to (a) the data type of the variable pointed to by the pointer.by the pointer.

(b) the dereferencing operator (b) the dereferencing operator ** followed followed by by the name of the pointer. the name of the pointer.

int *num_addr;int *num_addr;

Dereferencing pointersDereferencing pointers

To obtain the contents of the variable pointed to by a To obtain the contents of the variable pointed to by a pointer, we need to use the dereferencing operator pointer, we need to use the dereferencing operator **, , followed by the name of the pointer.followed by the name of the pointer.#include <iostream.h>#include <iostream.h>  

void main()void main(){{ int *num_addr;int *num_addr; int miles, dist;int miles, dist;  

miles = 22;miles = 22; num_addr = &miles;num_addr = &miles;  

cout << "Address stored in num_addr is " << num_addr << endl;cout << "Address stored in num_addr is " << num_addr << endl; cout << "Value pointed to by num_addr is " << *num_addr << endl;cout << "Value pointed to by num_addr is " << *num_addr << endl;  

dist = 158;dist = 158; num_addr = &dist;num_addr = &dist;  

cout << "Address stored in num_addr is " << num_addr << endl;cout << "Address stored in num_addr is " << num_addr << endl; cout << "Value pointed to by num_addr is " << *num_addr << endl;cout << "Value pointed to by num_addr is " << *num_addr << endl;}}

Reference variablesReference variables

A reference variable stores the address of another A reference variable stores the address of another variable.variable.

Reference variables Reference variables mustmust be initialized when they are be initialized when they are declared.declared.

  

#include <iostream.h>#include <iostream.h>  

void main()void main(){{ int x = 3;int x = 3; int& y = x;int& y = x;   cout << "x= " << x << "y = " << y << endl;cout << "x= " << x << "y = " << y << endl; y = 7;y = 7; cout << "x= " << x << "y = " << y << endl;cout << "x= " << x << "y = " << y << endl;}}

Reference variables (cont.)Reference variables (cont.)

Very useful for calling a function by Very useful for calling a function by reference.reference.  

void newval(float& xnum, float& ynum)void newval(float& xnum, float& ynum)

{{

xnum = 89.5;xnum = 89.5;

ynum = 99.5;ynum = 99.5;

}}

Differences between references and pointersDifferences between references and pointers

a)a) A reference parameter is a A reference parameter is a constant constant pointerpointer (after initializing a reference (after initializing a reference parameter, we cannot change it again).parameter, we cannot change it again).

b)b) References are References are dereferenced dereferenced automaticallyautomatically (no need to use the (no need to use the dereferencing operator dereferencing operator **).).

int b; int b; // using reference variables// using reference variables

int& a = b;int& a = b;

a = 10;a = 10;

  

int b; int b; // using pointers// using pointers

int *a = &b;int *a = &b;

*a = 10;*a = 10;

Differences between references and pointers (cont.)Differences between references and pointers (cont.)

Passing a reference variable to a functionPassing a reference variable to a function

The disadvantage is that the function call The disadvantage is that the function call does not reveal whether the arguments of does not reveal whether the arguments of the function are reference parameters or the function are reference parameters or not!!not!!

#include <iostream.h>#include <iostream.h>  

void newval(float&, float&); // function prototypevoid newval(float&, float&); // function prototype  

int main()int main(){{ float firstnum, secnum;float firstnum, secnum;  

cout << "Enter two numbers: ";cout << "Enter two numbers: "; cin >> firstnum >> secnum;cin >> firstnum >> secnum;  

newval(firstnum, secnum);newval(firstnum, secnum);  

cout << firstnum << secnum << endl;cout << firstnum << secnum << endl;  

return 0;return 0;}}  

void newval(float& xnum, float& ynum)void newval(float& xnum, float& ynum){{ xnum = 89.5;xnum = 89.5; ynum = 99.5;ynum = 99.5;}}

Passing a reference variable to a function (cont’d)Passing a reference variable to a function (cont’d)

#include <iostream.h>#include <iostream.h>  

void newval(float *, float *); void newval(float *, float *); // function prototype// function prototype  

int main()int main(){{ float firstnum, secnum;float firstnum, secnum;  

cout << "Enter two numbers: ";cout << "Enter two numbers: "; cin >> firstnum >> secnum;cin >> firstnum >> secnum;  

newval(&firstnum, &secnum); newval(&firstnum, &secnum); // // pass the address explicitly !!pass the address explicitly !!  

cout << firstnum << secnum << endl;cout << firstnum << secnum << endl;  

return 0;return 0;}}  

void newval(float *xnum, float *ynum)void newval(float *xnum, float *ynum){{ *xnum = 89.5; *xnum = 89.5; // // dereferencing is required !!dereferencing is required !! *ynum = 99.5;*ynum = 99.5;}}

Passing a pointer variable to a functionPassing a pointer variable to a function (cont.) (cont.)

Array names as pointersArray names as pointers

When an array is created, the compiler When an array is created, the compiler automatically creates an internal automatically creates an internal pointer pointer constantconstant (i.e., we cannot change its (i.e., we cannot change its contents) for it and stores the starting contents) for it and stores the starting address of the array in this pointer.address of the array in this pointer.

The name of the array becomes the name of The name of the array becomes the name of the pointer constant.the pointer constant.

Array names as pointers (cont.)Array names as pointers (cont.)

*arr is equivalent to arr[0]

Referring to the fourth element of the array Referring to the fourth element of the array cause the compiler, cause the compiler, internallyinternally, to make the , to make the following address computation: following address computation: 

&arr[3] = &arr[0] + (3 * sizeof(int))&arr[3] = &arr[0] + (3 * sizeof(int))

(offset to arr[3] = 3 x 2 = 6 bytes)(offset to arr[3] = 3 x 2 = 6 bytes)

Alternatively, we can refer to Alternatively, we can refer to arr[3]arr[3] as as follows: follows: 

*(arr + 3)*(arr + 3)

Array names as pointers (cont.)Array names as pointers (cont.)

#include <iostream.h>#include <iostream.h>

  

void main()void main()

{{

const SIZE = 5const SIZE = 5

int i, arr[SIZE] = {98, 87, 92, 79, 85};int i, arr[SIZE] = {98, 87, 92, 79, 85};

  

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

cout << arr[i] << *(arr + i) << endl;cout << arr[i] << *(arr + i) << endl;

}}

Array names as pointers (cont.)Array names as pointers (cont.)

Static Array AllocationStatic Array Allocation

Static 2D arrays Static 2D arrays are stored in the memory as are stored in the memory as 1D arrays.1D arrays...

Dynamic Array AllocationDynamic Array Allocation

To avoid wasting memory, array allocation or To avoid wasting memory, array allocation or deallocation can take place at run time.deallocation can take place at run time.

To allocate memory, we need to use the To allocate memory, we need to use the newnew operatoroperator

ReservesReserves the number of bytes requested by the the number of bytes requested by the declaration. declaration. ReturnsReturns the address of the first reserved the address of the first reserved location or NULL if sufficient memory is not available.location or NULL if sufficient memory is not available.

To deallocate memory (which has previously been To deallocate memory (which has previously been allocated using the allocated using the newnew operator) we need to use the operator) we need to use the deletedelete operator. operator.

ReleasesReleases a block of bytes previously reserved. The a block of bytes previously reserved. The address of the first reserved location is passed as an address of the first reserved location is passed as an argument to the function.argument to the function.

case of 1D arrayscase of 1D arrays

cout << "Enter array size: ";cout << "Enter array size: ";

cin >> SIZE;cin >> SIZE;

  

int *arr;int *arr;

arr = new int[SIZE]; arr = new int[SIZE]; // // allocationallocation

  

delete [] arr; delete [] arr; // // deallocationdeallocation

case of 2D arrayscase of 2D arrays

cout << "Enter numRows and numCols: ";cout << "Enter numRows and numCols: ";cin >> numRows >> numCols;cin >> numRows >> numCols;  int **arr2D;int **arr2D;arr2D = new int* [numRows]; arr2D = new int* [numRows]; // // allocationallocation  for(i=0; i<numRows; i++)for(i=0; i<numRows; i++) arr2D[i] = new int[numCols];arr2D[i] = new int[numCols];  for(i=0; i<numRows; i++) for(i=0; i<numRows; i++) // // deallocationdeallocation   delete [] arr2D[i];delete [] arr2D[i];delete [] arr2D;delete [] arr2D;  

(individual elements can be accessed using indices!! (individual elements can be accessed using indices!! (e.g., (e.g., arr2D[0][2]=10;arr2D[0][2]=10;))))

case of 2D arrayscase of 2D arrays (cont.) (cont.)

Very Important diagram; don’t memorize it,

Understand it !!Understand it !!

Passing an array to a functionPassing an array to a function

When an array is passed to a function, its address is the only When an array is passed to a function, its address is the only item actually passed to the function. item actually passed to the function. 

Passing a 1D array to a functionPassing a 1D array to a function#include <iostream.h>#include <iostream.h>  float find_average(int *, int);float find_average(int *, int);  void main()void main(){{  int *arr;int *arr; arr = new int[numElems];arr = new int[numElems]; arr[0] = 2; arr[1] = 18; arr[2] = 1;arr[0] = 2; arr[1] = 18; arr[2] = 1; arr[3] = 27; arr[4]= 16;arr[3] = 27; arr[4]= 16;

// // or using static memory allocationor using static memory allocation::const numElems = 5;const numElems = 5;int arr[numElems] = {2, 18, 1, 27, 16};int arr[numElems] = {2, 18, 1, 27, 16};   cout << "The average is " << find_average(arr, numElems) << endl;cout << "The average is " << find_average(arr, numElems) << endl;}}

(continues)

float find_average(int *vals, int n)float find_average(int *vals, int n){{ int i;int i; float avg;float avg;   avg=0.0;avg=0.0; for(i=0; i<n; i++)for(i=0; i<n; i++) avg += vals[i];avg += vals[i];   avg = avg/n;avg = avg/n;   return avg;return avg;}}

Passing a 1D array to a functionPassing a 1D array to a function (cont.) (cont.)

#include <iostream.h>#include <iostream.h>  

float find_average(int **, int, int);float find_average(int **, int, int);  

void main()void main(){{  int **arr2D;int **arr2D; float average;float average;  

arr2D = new int*[numRows];arr2D = new int*[numRows]; for(i=0; i<numRows; i++)for(i=0; i<numRows; i++) arr2D[i] = new int[numCols];arr2D[i] = new int[numCols];

// using static array allocation will not work in this case !!// using static array allocation will not work in this case !!//const numRows = 2;//const numRows = 2;// const numCols = 6;// const numCols = 6;// int arr2D[numRows][numCols] = { {25, 29, 15, 95, 22, 21},// int arr2D[numRows][numCols] = { {25, 29, 15, 95, 22, 21}, // {105, 254, 125, 25, 925, 253} };// {105, 254, 125, 25, 925, 253} }; (continues)

Passing a 2D array to a functionPassing a 2D array to a function

 

average = find_average(arr2D, numRows, numCols);average = find_average(arr2D, numRows, numCols);  

cout << "The average is " << average << endl;cout << "The average is " << average << endl;}}  

float find_average(int **vals, int n, int m)float find_average(int **vals, int n, int m){{ int i, j;int i, j; float avg;float avg;  

avg=0.0;avg=0.0; for(i=0; i<n; i++)for(i=0; i<n; i++) for(j=0; j<m; j++)for(j=0; j<m; j++) avg += vals[i][j];avg += vals[i][j];  

avg = avg/(n*m);avg = avg/(n*m);  

return avg;return avg;}}

Passing a 2D array to a functionPassing a 2D array to a function (cont.) (cont.)

Recommended