1 / 43

Pointers

Pointers. CSCS 200 – Data Structures. Pointers. What is the most important thing to do when you use pointers in your programs? Why? Explain your answer with a small example. Pointers.

hachi
Download Presentation

Pointers

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Pointers CSCS 200 – Data Structures

  2. Pointers • What is the most important thing to do when you use pointers in your programs? Why? Explain your answer with a small example.

  3. Pointers • Answer: Initialize the pointer before using it. The pointer when declared would be pointing to some junk address and modifying what the pointer points to could cause unexpected results or an exception. • As an example suppose that the un-initialized pointer points to the code segment of the program. Now changing the contents of the memory location pointed to by this pointer could lead to a change in the code and thus corrupt the program.

  4. 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; }

  5. Storing addresses • We can store addresses in suitably declared variables num_addr = &num; • The variable num_addr is called a pointer variable • Pointers are simply variables that are used to store the addresses of other variables.

  6. Storing addresses (cont.)

  7. 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;

  8. 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; }

  9. 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; }

  10. Reference variables (cont.) • Very useful for calling a function by reference. void newval(float& xnum, float& ynum) { xnum = 89.5; ynum = 99.5; }

  11. 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 *).

  12. 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;

  13. 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!!

  14. 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; }

  15. 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; }

  16. 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.

  17. Array names as pointers (cont.) *arr is equivalent to arr[0]

  18. 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)

  19. 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; }

  20. Static Array Allocation • Static 2D arrays are stored in the memory as 1D arrays..

  21. 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.

  22. case of 1D arrays cout << "Enter array size: "; cin >> SIZE; int *arr; arr = new int[SIZE]; // allocation delete [] arr; // deallocation

  23. 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;))

  24. case of 2D arrays (cont.) Very Important diagram; don’t memorize it, Understand it!!

  25. 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)

  26. 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; }

  27. 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)

  28. 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; }

  29. Structures/Classes CMP210 – Data Structures

  30. What is a structure? • It is an aggregate data type built using elements of other types. • Declaring a structure requires declaring its members and their data types. struct rectangle { float height; float width; int xpos; int ypos; };

  31. Structure variables • They are declared like variables of any other type. rectangle rc; rectangle &rcRef = rc; rectangle *rcPtr = &rc;

  32. Accessing members of structures • dot operator (.): rc.height = 15.89; rcRef.height = 15.89; • arrow operator (->): rcPtr -> height = 15.89; or (*rcPtr).height = 15.89; • Important: the parentheses around *rcPtr are necessary since the member operator . takes precedence over the dereference operator.

  33. Member functions (methods) • Functions which operate on the data of the structure. • The prototype of a member function appears within the structure definition. struct rectangle { float height; float width; int xpos; int ypos; void draw(); // draw member function void posn(int, int); // position member function void move(int, int); // move member function };

  34. Member function declaration • Usually, they are declared outside the structure. data_type structure_name::function_name(arguments);   ( :: is the "scope resolution operator") void rectangle::draw() { cout << "position is " << xpos << ypos << endl; } void rectangle::posn(int x, int y) { xpos = x; ypos = y; } void rectangle::move(int dx, int dy) { xpos += dx; ypos += dy; }

  35. Referring to a member function • We refer to a member function just as any other variable of the structure. rc.draw(); rc.posn(100, 100); rc.move(50, 50);

  36. Information Hiding

  37. Philosophy behind information hiding • The actual data representation used within a structure is of no concern to the structure's clients. • Protects data members from receiving invalid values. • It promotes program modifiability (if the representation of data changes, only the member functions need to change).

  38. Controlling access to members • Most common member access specifiers are: public and private struct rectangle { private: float height; float width; int xpos; int ypos; • The private keyword specifies that the structure members following it are private to the structure and can only be accessed by member functions (and by friend functions) • public: • void draw(); // draw member function • void posn(int, int); // position member function • void move(int, int); // move member function • };

  39. Controlling access to members (cont.) • The public keyword specifies that the structure members following it are public to the structure and may be accessed from outside the structure. void main() { rectangle rc; rc.height = 20; // Error: not accessible } • Another way to access private data members is by using get-set member functions which are public to the structure.

  40. Classes

  41. What is a class? • Practically, there are no differences between structures and classes: (i) A class is a structure which has all of its members private by default. (ii) Structures have all of their members public by default. class rectangle { private: // not needed but included for clarity float height; float width; int xpos; int ypos; public: void draw(); // draw member function void posn(int, int); // position member function void move(int, int); // move member function };

  42. What is an object? • An instance or an object is a variable of type class.

  43. Class-based programming • Data and functions co-exist inside a class. • Member functions are called without passing the data members of the class to them. • There is far less chance of misusing functions by passing them the wrong data.

More Related