EEE 145 POINTERS AND REFERENCES 2 C Pointers

  • Slides: 27
Download presentation
EEE 145 POINTERS AND REFERENCES 2

EEE 145 POINTERS AND REFERENCES 2

C++ Pointers • C++ pointers are easy and fun to learn. Some C++ tasks

C++ Pointers • C++ pointers are easy and fun to learn. Some C++ tasks are performed more easily with pointers, and other C++ tasks, such as dynamic memory allocation, cannot be performed without them. • As you know every variable is a memory location and every memory location has its address defined which can be accessed using ampersand (&) operator which denotes an address in memory. Consider the following which will print the address of the variables defined: 1

C++ Pointers #include <iostream> using namespace std; int main () { int var 1;

C++ Pointers #include <iostream> using namespace std; int main () { int var 1; char var 2[10]; cout << "Address of var 1 variable: "; cout << &var 1 << endl; cout << "Address of var 2 variable: "; cout << &var 2 << endl; return 0; Address of var 1 variable: 0 xbfebd 5 c 0 } Address of var 2 variable: 0 xbfebd 5 b 6 2

What are Pointers A pointer is a variable whose value is the address of

What are Pointers A pointer is a variable whose value is the address of another variable. Like any variable or constant, you must declare a pointer before you can work with it. Pointer variable declaration: type *var-name; Following are the valid pointer declaration: int *ip; // pointer to an integer double *dp; // pointer to a double float *fp; // pointer to a float char *ch // pointer to character 3

Using Pointers in C++ • • • • #include <iostream> using namespace std; int

Using Pointers in C++ • • • • #include <iostream> using namespace std; int main () { int var = 20; int *ip; ip = &var; cout << "Value of variable: "; cout << var << endl; cout << "Address stored in ip variable: "; cout << ip << endl; cout << "Value of *ip variable: "; cout << *ip << endl; return 0; Value of variable: 20 } Address stored in ip variable: 0 xbfc 601 ac Value of *ip variable: 20 4

Pointer Arithmetic As you understood pointer is an address which is a numeric value;

Pointer Arithmetic As you understood pointer is an address which is a numeric value; therefore, you can perform arithmetic operations on a pointer just as you can a numeric value. There are four arithmetic operators that can be used on pointers: ++, --, +, and To understand pointer arithmetic, let us consider that ptr is an integer pointer which points to the address 1000. 5

Pointer Arithmetic Assuming 32 -bit integers, let us perform the following arithmetic operation on

Pointer Arithmetic Assuming 32 -bit integers, let us perform the following arithmetic operation on the pointer: ptr++ the ptr will point to the location 1004 because each time ptr is incremented, it will point to the next integer. This operation will move the pointer to next memory location without impacting actual value at the memory location. If ptr points to a character whose address is 1000, then above operation will point to the location 1001 because next character will be available at 1001. 6

Incrementing a Pointer • • • • #include <iostream> using namespace std; const int

Incrementing a Pointer • • • • #include <iostream> using namespace std; const int MAX = 3; int main (){ int var[MAX] = {10, 100, 200}; int *ptr; ptr = var; for (int i = 0; i < MAX; i++){ cout << "Address of var[" << i << "] = "; cout << ptr << endl; cout << "Value of var[" << i << "] = "; cout << *ptr << endl; Address of var[0] Value of var[0] = ptr++; Address of var[1] } Value of var[1] = return 0; Address of var[2] } Value of var[2] = = 0 xbfa 088 b 0 10 = 0 xbfa 088 b 4 100 = 0 xbfa 088 b 8 200 7

Decrementing a Pointer • • • • • #include <iostream> using namespace std; const

Decrementing a Pointer • • • • • #include <iostream> using namespace std; const int MAX = 3; int main () { int var[MAX] = {10, 100, 200}; int *ptr; ptr = &var[MAX-1]; for (int i = MAX; i > 0; i--) { cout << "Address of var[" << i << "] = "; cout << ptr << endl; cout << "Value of var[" << i << "] = "; cout << *ptr << endl; Address of var[3] = 0 xbfdb 70 f 8 ptr--; Value of var[3] = 200 } Address of var[2] = 0 xbfdb 70 f 4 return 0; Value of var[2] = 100 } Address of var[1] = 0 xbfdb 70 f 0 Value of var[1] = 10 8

Pointer comparisons • • • • • #include <iostream> using namespace std; const int

Pointer comparisons • • • • • #include <iostream> using namespace std; const int MAX = 3; int main (){ int var[MAX] = {10, 100, 200}; int *ptr; ptr = var; int i = 0; while ( ptr <= &var[MAX - 1] ){ cout << "Address of var[" << i << "] = "; cout << ptr << endl; cout << "Value of var[" << i << "] = "; cout << *ptr << endl; Address of var[0] ptr++; Value of var[0] = i++; } Address of var[1] return 0; Value of var[1] = } Address of var[2] = 0 xbfce 42 d 0 10 = 0 xbfce 42 d 4 100 = 0 xbfce 42 d 8 Value of var[2] = 200 9

Pointers vs. arrays Pointers and arrays are strongly related. In fact, pointers and arrays

Pointers vs. arrays Pointers and arrays are strongly related. In fact, pointers and arrays are interchangeable in many cases. For example, a pointer that points to the beginning of an array can access that array by using either pointer arithmetic or array-style indexing. Consider the following program: 10

Pointers vs. arrays • • • • • #include <iostream> using namespace std; const

Pointers vs. arrays • • • • • #include <iostream> using namespace std; const int MAX = 3; int main () { int var[MAX] = {10, 100, 200}; int *ptr; ptr = var; for (int i = 0; i < MAX; i++) { cout << "Address of var[" << i << "] = "; cout << ptr << endl; cout << "Value of var[" << i << "] = "; cout << *ptr << endl; Address of var[0] = 0 xbfa 088 b 0 ptr++; Value of var[0] = 10 } Address of var[1] = 0 xbfa 088 b 4 return 0; Value of var[1] = 100 } Address of var[2] = 0 xbfa 088 b 8 Value of var[2] = 200 11

Pointers vs. arrays However, pointers and arrays are not completely interchangeable. For example, consider

Pointers vs. arrays However, pointers and arrays are not completely interchangeable. For example, consider the following program: • • • #include <iostream> using namespace std; const int MAX = 3; int main (){ int var[MAX] = {10, 100, 200}; for (int i = 0; i < MAX; i++){ *var = i; // This is a correct syntax var++; // This is incorrect. } return 0; } It is perfectly acceptable to apply the pointer operator * to var but it is illegal to modify var value. 12

Pointers vs. arrays Because an array name generates a pointer constant, it can still

Pointers vs. arrays Because an array name generates a pointer constant, it can still be used in pointer-style expressions, as long as it is not modified. For example, the following is a valid statement that assigns var[2] the value 500: *(var + 2) = 500; Above statement is valid and will compile successfully because var is not changed. 13

Array of pointers There may be a situation, when we want to maintain an

Array of pointers There may be a situation, when we want to maintain an array, which can store pointers to an int or char or another data type available. Following is the declaration of an array of pointers to an integer: int *ptr[MAX]; This declares ptr as an array of MAX integer pointers. Thus, each element in ptr, now holds a pointer to an int value. Following example makes use of three integers which will be stored in an array of pointers as follows: 14

Array of pointers • • • • #include <iostream> using namespace std; const int

Array of pointers • • • • #include <iostream> using namespace std; const int MAX = 3; int main () { int var[MAX] = {10, 100, 200}; int *ptr[MAX]; for (int i = 0; i < MAX; i++){ ptr[i] = &var[i]; } for (int i = 0; i < MAX; i++){ cout << "Value of var[" << i << "] = "; cout << *ptr[i] << endl; } Value of var[0] = 10 return 0; Value of var[1] = 100 } Value of var[2] = 200 15

Passing pointers to functions in C++ allows you to pass a pointer to a

Passing pointers to functions in C++ allows you to pass a pointer to a function. To do so, simply declare the function parameter as a pointer type. Following a simple example where we pass an unsigned long pointer to a function and change the value inside the function which reflects back in the calling function: 16

Passing pointers to functions in C++ • • • • #include <iostream> #include <ctime>

Passing pointers to functions in C++ • • • • #include <iostream> #include <ctime> using namespace std; void get. Seconds(unsigned long *par); int main (){ unsigned long sec; get. Seconds( &sec ); cout << "Number of seconds : " << sec << endl; return 0; } void get. Seconds(unsigned long *par) { // get the current number of seconds *par = time( NULL ); return; Number of seconds : 1294450468 } 17

Passing pointers to functions in C++ • • • • • #include <iostream> using

Passing pointers to functions in C++ • • • • • #include <iostream> using namespace std; double get. Average(int *arr, int size); int main (){ int balance[5] = {1000, 2, 3, 17, 50}; double avg; avg = get. Average( balance, 5 ) ; cout << "Average value is: " << avg << endl; return 0; } double get. Average(int *arr, int size){ int i, sum = 0; double avg; for (i = 0; i < size; ++i){ sum += arr[i]; } Average value is: 214. 4 avg = double(sum) / size; return avg; } 18

Return pointer from functions in C++ As we have seen before how C++ allows

Return pointer from functions in C++ As we have seen before how C++ allows to return an array from a function, similar way C++ allows you to return a pointer from a function. To do so, you would have to declare a function returning a pointer as in the following example: int * my. Function() {. . } Second point to remember is that, it is not good idea to return the address of a local variable to outside of the function, so you would have to define the local variable as static variable. Now, consider the following function, which will generate 10 random numbers and return them using an array name which represents a pointer i. e. , address of first array element. 19

Return pointer from functions in C++ • • • • • • #include <iostream>

Return pointer from functions in C++ • • • • • • #include <iostream> #include <ctime> using namespace std; int * get. Random( ){ static int r[10]; srand( (unsigned)time( NULL ) ); for (int i = 0; i < 10; ++i){ r[i] = rand(); cout << r[i] << endl; } return r; } int main (){ int *p; p = get. Random(); for ( int i = 0; i < 10; i++ ){ cout << "*(p + " << i << ") : "; cout << *(p + i) << endl; } return 0; } 624723190 1468735695 807113585 976495677 613357504 1377296355 1530315259 1778906708 1820354158 667126415 *(p + 0) : *(p + 1) : *(p + 2) : *(p + 3) : *(p + 4) : *(p + 5) : *(p + 6) : *(p + 7) : *(p + 8) : *(p + 9) : 624723190 1468735695 807113585 976495677 613357504 1377296355 1530315259 1778906708 1820354158 667126415 20

References • A reference variable is an alias, that is, another name for an

References • A reference variable is an alias, that is, another name for an already existing variable. Once a reference is initialized with a variable, either the variable name or the reference name may be used to refer to the variable. 21

C++ References vs Pointers • References are often confused with pointers but three major

C++ References vs Pointers • References are often confused with pointers but three major differences between references and pointers are: • You cannot have NULL references. You must always be able to assume that a reference is connected to a legitimate piece of storage. • Once a reference is initialized to an object, it cannot be changed to refer to another object. Pointers can be pointed to another object at any time. • A reference must be initialized when it is created. Pointers can be initialized at any time. 22

Creating References in C++ • Think of a variable name as a label attached

Creating References in C++ • Think of a variable name as a label attached to the variable's location in memory. You can then think of a reference as a second label attached to that memory location. Therefore, you can access the contents of the variable through either the original variable name or the reference. For example, suppose we have the following example: int i = 17; • We can declare reference variables for i as follows. int& r = i; • Read the & in these declarations as reference. Thus, read the first declaration as "r is an integer reference initialized to i" and read the second declaration as "s is a double reference initialized to d. ". • Following example makes use of references on int and double: 23

 • • • • • #include <iostream> using namespace std; int main ()

• • • • • #include <iostream> using namespace std; int main () { // declare simple variables int i; double d; // declare reference variables int& r = i; double& s = d; i = 5; cout << "Value of i : " << i << endl; cout << "Value of i reference : " << r d = 11. 7; cout << "Value of d : " << d << endl; cout << "Value of d reference : " << s return 0; Value of } Value of << endl; i i Value of d 11. 7 : 5 reference : 5 : 11. 7 reference : 24

Passing parameters as references • • • • • • #include <iostream> using namespace

Passing parameters as references • • • • • • #include <iostream> using namespace std; void swap(int& x, int& y); int main () { int a = 100; int b = 200; cout << "Before swap, value of a : " << a << endl; cout << "Before swap, value of b : " << b << endl; swap(a, b); cout << "After swap, value of a : " << a << endl; cout << "After swap, value of b : " << b << endl; return 0; } void swap(int& x, int& y) { int temp; Before swap, value of a : 100 temp = x; x = y; Before swap, value of b : 200 y = temp; After swap, value of a : 200 return; After swap, value of b : 100 } 25

Returning values by reference • • #include <iostream> using namespace std; double vals[] =

Returning values by reference • • #include <iostream> using namespace std; double vals[] = {10. 1, 12. 6, 33. 1, 24. 1, 50. 0}; double& set. Values( int i ) { return vals[i]; // return a reference to the ith element } • • • • int main (){ cout << "Value before change" << endl; for ( int i = 0; i < 5; i++ ) { cout << "vals[" << i << "] = "; cout << vals[i] << endl; } set. Values(1) = 20. 23; // change 2 nd element set. Values(3) = 70. 8; // change 4 th element cout << "Value after change" << endl; for ( int i = 0; i < 5; i++ ) { cout << "vals[" << i << "] = "; cout << vals[i] << endl; } return 0; } Value before change vals[0] = 10. 1 vals[1] = 12. 6 vals[2] = 33. 1 vals[3] = 24. 1 vals[4] = 50 Value after change vals[0] = 10. 1 vals[1] = 20. 23 vals[2] = 33. 1 vals[3] = 70. 8 vals[4] = 50 26