260 likes | 354 Views
Pointers. CSE 5100 Data Structures and Algorithms. Getting the address of a variable. You need to use the address operator & #include <iostream.h> void main() { int num; num = 22; cout << "num= " << num << endl; cout << "The address of num = " << &num << endl; }.
E N D
Pointers CSE 5100 Data Structures and Algorithms
Getting the address of a variable • You need to use the address operator & #include <iostream.h> void main() { int num; num = 22; cout << "num= " << num << endl; cout << "The address of num = " << &num << endl; }
Storing addresses • We can store addresses in suitably declared variables num_addr = # • The variable num_addr is called a pointer variable • Pointers are simply variables that are used to store the addresses of other variables.
Declaring Pointers • You need to specify two things: (a) the data type of the variable pointed to by the pointer. (b) the dereferencing operator * followed by the name of the pointer. int *num_addr;
Dereferencing pointers • To obtain the contents of the variable pointed to by a pointer, we need to use the dereferencing operator *, followed by the name of the pointer. #include <iostream.h> void main() { int *num_addr; int miles, dist; miles = 22; num_addr = &miles; cout << "Address stored in num_addr is " << num_addr << endl; cout << "Value pointed to by num_addr is " << *num_addr << endl; dist = 158; num_addr = &dist; cout << "Address stored in num_addr is " << num_addr << endl; cout << "Value pointed to by num_addr is " << *num_addr << endl; }
Reference variables • A reference variable stores the address of another variable. • Reference variables must be initialized when they are declared. #include <iostream.h> void main() { int x = 3; int& y = x; cout << "x= " << x << "y = " << y << endl; y = 7; cout << "x= " << x << "y = " << y << endl; }
Reference variables (cont.) • Very useful for calling a function by reference. void newval(float& xnum, float& ynum) { xnum = 89.5; ynum = 99.5; }
Differences between references and pointers • A reference parameter is a constant pointer (after initializing a reference parameter, we cannot change it again). • References are dereferenced automatically (no need to use the dereferencing operator *).
Differences between references and pointers (cont.) int b; // using reference variables int& a = b; a = 10; int b; // using pointers int *a = &b; *a = 10;
Passing a reference variable to a function • The disadvantage is that the function call does not reveal whether the arguments of the function are reference parameters or not!!
Passing a reference variable to a function (cont’d) #include <iostream.h> void newval(float&, float&); // function prototype int main() { float firstnum, secnum; cout << "Enter two numbers: "; cin >> firstnum >> secnum; newval(firstnum, secnum); cout << firstnum << secnum << endl; return 0; } void newval(float& xnum, float& ynum) { xnum = 89.5; ynum = 99.5; }
Passing a pointer variable to a function (cont.) #include <iostream.h> void newval(float *, float *); // function prototype int main() { float firstnum, secnum; cout << "Enter two numbers: "; cin >> firstnum >> secnum; newval(&firstnum, &secnum); // pass the address explicitly !! cout << firstnum << secnum << endl; return 0; } void newval(float *xnum, float *ynum) { *xnum = 89.5; // dereferencing is required !! *ynum = 99.5; }
Array names as pointers • When an array is created, the compiler automatically creates an internal pointer constant (i.e., we cannot change its contents) for it and stores the starting address of the array in this pointer. • The name of the array becomes the name of the pointer constant.
Array names as pointers (cont.) *arr is equivalent to arr[0]
Array names as pointers (cont.) • Referring to the fourth element of the array cause the compiler, internally, to make the following address computation: &arr[3] = &arr[0] + (3 * sizeof(int)) (offset to arr[3] = 3 x 2 = 6 bytes) • Alternatively, we can refer to arr[3] as follows: *(arr + 3)
Array names as pointers (cont.) #include <iostream.h> void main() { const SIZE = 5 int i, arr[SIZE] = {98, 87, 92, 79, 85}; for(i=0; i<SIZE; i++) cout << arr[i] << *(arr + i) << endl; }
Static Array Allocation • Static 2D arrays are stored in the memory as 1D arrays..
Dynamic Array Allocation • To avoid wasting memory, array allocation or deallocation can take place at run time. • To allocate memory, we need to use the new operator Reserves the number of bytes requested by the declaration. Returns the address of the first reserved location or NULL if sufficient memory is not available. • To deallocate memory (which has previously been allocated using the new operator) we need to use the delete operator. Releases a block of bytes previously reserved. The address of the first reserved location is passed as an argument to the function.
case of 1D arrays cout << "Enter array size: "; cin >> SIZE; int *arr; arr = new int[SIZE]; // allocation delete [] arr; // deallocation
case of 2D arrays cout << "Enter numRows and numCols: "; cin >> numRows >> numCols; int **arr2D; arr2D = new int* [numRows]; // allocation for(i=0; i<numRows; i++) arr2D[i] = new int[numCols]; for(i=0; i<numRows; i++) // deallocation delete [] arr2D[i]; delete [] arr2D; (individual elements can be accessed using indices!! (e.g., arr2D[0][2]=10;))
case of 2D arrays (cont.) Very Important diagram; don’t memorize it, Understand it !!
Passing an array to a function • When an array is passed to a function, its address is the only item actually passed to the function. Passing a 1D array to a function #include <iostream.h> float find_average(int *, int); void main() { int *arr; arr = new int[numElems]; arr[0] = 2; arr[1] = 18; arr[2] = 1; arr[3] = 27; arr[4]= 16; // or using static memory allocation: const numElems = 5; int arr[numElems] = {2, 18, 1, 27, 16}; cout << "The average is " << find_average(arr, numElems) << endl; } (continues)
Passing a 1D array to a function (cont.) float find_average(int *vals, int n) { int i; float avg; avg=0.0; for(i=0; i<n; i++) avg += vals[i]; avg = avg/n; return avg; }
Passing a 2D array to a function #include <iostream.h> float find_average(int **, int, int); void main() { int **arr2D; float average; arr2D = new int*[numRows]; for(i=0; i<numRows; i++) arr2D[i] = new int[numCols]; // using static array allocation will not work in this case !! //const numRows = 2; // const numCols = 6; // int arr2D[numRows][numCols] = { {25, 29, 15, 95, 22, 21}, // {105, 254, 125, 25, 925, 253} }; (continues)
Passing a 2D array to a function (cont.) average = find_average(arr2D, numRows, numCols); cout << "The average is " << average << endl; } float find_average(int **vals, int n, int m) { int i, j; float avg; avg=0.0; for(i=0; i<n; i++) for(j=0; j<m; j++) avg += vals[i][j]; avg = avg/(n*m); return avg; }