FAQ | Newsboard | Telnet | Email TA | Lectures | Assignments | Man pages | Help |
---|
Pointers are used everywhere in C/C++, and if you have a good understanding of them C/C++ should not pose a problem. If, however, you have never seen pointers before, or feel uncomfortable with them, you may want to schedule an appointment to talk to me. C/C++ pointers are basically the same as Pascal pointers except they are used much more freely in C/C++.
C++ uses pointers in three main ways. First, they are used to create dynamic data structures: data structures built up from blocks of memory allocated from the heap at run-time. This is the only visible way that Pascal uses pointers. Second, C++ uses pointers to handle variable parameters passed to functions. And third, pointers in C++ provide an alternative means of accessing information stored in arrays, which is especially valuable when you work with strings. There is an intimate link between arrays and pointers in C/C++.
In many cases, C/C++ programmers use pointers because they make the code slightly more efficient. Sometimes, however, they simply seem to make the code harder to understand. Once you have mastered the three uses of pointers in C/C++, however, you "know" C/C++ for all practical purposes.
Please note that the address of a variable is different from the value of a variable.
#include <stdio.h> int main() { int num1, num2j; int *ptr; /* declaring a pointer to an integer */ ptr = &num1; /* The address-of operator */ *ptr = 5; /* Dereferencing a pointer */ num2 = num1; cout << num1 << num2 << *ptr ; }
Note: We must associate a pointer to a particular type: You can't assign the address of a char to an int, for instance.
You cannot use a pointer before you make it point to a variable. For example:
int *iptr; *iptr = 5;can cause your program to crash, since you are trying to put the value 5 at the memory location pointed to by iptr; and iptr doesn't point anywhere.
int number, *iptr; iptr = &number; *iptr = 30;is perfectly legal.
Here are some things you can and cannot do with pointers. The pictures in this section provide example values for the memory locations at which variables are stored. These values are for helping your understanding only. In practice, we seldom deal with memory addresses values, dealing instead with pointer variables.
int main(void) { ... int num1, num2; int *ip1, *ip2; ip1 = 20; /* shouldn't do this */ *ip1 = 20; /* will cause a run time error */ num1 = 45; ip1 = &num1; ip2 = ip1; /* ip1 and ip2 both point to the same location */ cout << "The location pointed to by ip2 contains " << *ip2; cout << "The location pointed to by ip1 contains " << *ip1; cout << " num1 contains " << num1; ... }The first statement tries to make ip1 point to the memory address 20. Since we don't know what memory addresses our variables are stored at, trying to assign some number to a pointer variable is not recommended. The second statement tries to store the value 20 at memory location 20 (the location pointed to be ip1). Since the memory location probably does not belong to our program, the statement will cause a segmentation fault and crash our executable.
If we do things right, and let ip1 point to a variable (num1), assigning ip2 the current value of ip1, makes both ip2 and ip1 point to num1. All three print statements will therefore print the same value.
Another example :
int main(void) { float rel1, rel2, *fp1, *fp2; fp2 = &rel1 ; rel1 = 50.7; /* picture this */ cout << "The location pointed to by fp2 contains " << *fp2; }
Consider the following program that uses pointers to pointers, pointers to pointers to pointers, and pointers to pointers to pointers to pointers!
/* Program 7-6 : A Multiple Addressing Scheme */ #include <iostream.h> int main(void) { int that = 15; int *this1, **this2, ***this3, ****this4; this1 = & that; this2 = & this1; this3 = & this2; this4 = & this3; cout << "The value of ****this4 is: " << ****this4; cout << "The value of ****this4 is: " << ***this3; cout << "The value of ****this4 is: " << **this2; cout << "The value of ****this4 is: " << *this1; return 0; }this4 points to this3 which points to this2 which points to this1 which points to that. this4 is a pointer to (a pointer to a pointer to a pointer to an integer). To get to the integer value stored in that you need to do four (4) dereferences! Here is a picture.
Here's another way of writing the swap function that we used in our sort code. In other words we can pass parameters by reference using pointers in addition to doing it the way we have been doing (declaring function paramters with type & variable-name). The invoking function would invoke swap with pointers to the integers whose values are to be swapped. For example, if we wanted to swap the values of two integer variables num1 and num2 we could invoke swap() as follows:
int main(void) { int num1, num2; num1 = 5; num2 = 9; swap(&num1, &num2); cout << " num1 = " << num1 << " num2 = " << num2; }and swap() would work with these pointers and change the values pointed to by the pointers without changing the values of the pointers themselves. The pointers are passed by valuu, but we can access the contents of the locations pointed to by the pointers by reference through the copied pointers.
void swap (int *ip1, int *ip2) { int tmp; tmp = *ip1; *ip1 = *ip2; *ip2 = tmp; }Thus although we are not changing the values of ip1 and ip2, we are changing the values of the locations pointed to by ip1 and ip2. This picture will help visualize what is going on with the local copies of ip1 and ip2 and the values in num1 and num2 in main().
If we want to use swap() with our selsrt function it
would be invoked as swap(&vec[i], &vec[maxIndx]) to
do the swapping of elements that are in the wrong order.
Passing an array is just a special case of passing pointers. When you pass an array name in C/C++ you are actually passing in the address of the first element of the array. That is, you are passing a pointer to the beginning of the array. Thus cout << array[0]; is the same as cout << *array ; if you had declared an int array[10] and initialized it.