In order to remember the usages of the pointer, I summarize it.
1st. What is a pointer?
Pointer variables, simply called pointers, are declared to hold memory addresses as their values.
2nd. To declare a pointer
For example:
The following statements declare pointers named pCount, pStatus, pLetter and pString which can point to an int variable, a short variable, a char variable, and a string, respectively.
int* pCount;
short* pStatus;
char* pLetter;
string* pString;
3rd. To assign a pointer
Assign the address of a variable to the pointer
For instance:
int count;
int* pcount = &count;
Actually, &count is the address of count.
& symbol is called the address operator when placed in front of a variable. It is a unary operator that returns the variable’s address.
Attention:
Like a local variable, a local pointer is assigned an arbitrary value if you don’t initialize it. To prevent errors, you should always initialize pointers.
eg:
int* pCount1 = 0;
int* pCount2 = NULL; // A number of C++ libraries
//including <iostream> define
//NULL as a constant with value 0
4th. To reference a value through a pointer

The asterisk (*) used in the preceding statement is known as the indirection operator (間接引用運算符) or dereference operator (解引用運算符). When a pointer is dereferenced, the value at the address stored in the pointer is retrieved.
For example:
int count = 5;
int* pCount = &count;
cout << "The value of count is " << count << endl;
cout << "The address of count is " << &count << endl;
cout << "The address of count is " << pCount << endl;
cout << "The value of count is " << *pCount << endl;
The results are:
The value of count is 5
The address of count is 0x6dfef8
The address of count is 0x6dfef8
The value of count is 5
5th. The usage of typedef
For instance:
typedef int integer;
integer value = 40;
typedef int* intPointer;
intPointer p; //which is the same as int* p;
One advantage of using a pointer type name is to avoid the errors involving missing asterisks.
int* p1, p2; //p1 is pointer, p2 is int
typedef int* intPointer;
intPointer p1, p2;//p1 and p2 are pointers
6th. Constant pointer
A constant pointer points to a constant memory location, but the actual value in the memory location can be changed.
To declare a constant pointer:
double radius = 5;
double* const p = &radius;
p is a constant pointer. It must be declared and initialized in the same statement. You cannot assign a new address to p later.
Though p is a constant, the data pointed to by p is not constant. You can change it.
double radius = 5;
double* const p = &radius; //p is a constant pointer.
(*p) = 7; //radius = 7, radius is 7 now
double r2 = 10;
p = &r2; //error: assignment of read-only variable 'p'
Also, we can declare the dereferenced data to be a constant:
In this case, the pointer is a constant, and the data pointed to by the pointer is also a constant.
Several Examples:
double radius = 5;
double* const p = &radius;
double length = 5;
*p = 6; // OK
p = &length; // Wrong because p is constant pointer
const double* p1 = &radius;
*p1 = 6; // Wrong because p1 points to a constant data
p1 = &length; // OK
const double* const p2 = &radius;
*p2 = 6; // Wrong because p2 points to a constant data
p2 = &length; // Wrong because p2 is a constant pointer
7th. Arrays and pointers
A C++ array name is actually a constant pointer to the first element in the array.
-
Name of an array represents the starting address:
myList = &myList[0];
- A pointer for an array can be used just like an array. You can even use pointer with index.
int list[6] = {11, 12, 13, 14, 15, 16};
int* p = list;
for (int i = 0; i < 6; i++)
cout << "address: " << (list + i) <<
" value: " << *(list + i) << " " <<
" value: " << list[i] << " " <<
" value: " << *(p + i) << " " <<
" value: " << p[i] << endl;
- The difference between pointer and array name is that Array name is a constant address:
int array[10];
int* ptr = array;
for (int i = 0;i < 5; i ++) {
cout<< *(ptr++) << " "; // OK
cout<< *(array++) << " "; // Wrong
}
8th. Pointers in functions
If we define a function:
Now,let’s consider invoking function f(q1, q2) with two pointers q1 and q2:
1. The pointer q1 is passed to p1 by value. So *p1 and *q1 point to the same contents. If function f changes *p1 (e.g., *p1 = 20), *q1 is changed too. However, if function f changes p1 (e.g., p1 = somePointerVariable), q1 is not changed.
2. The pointer q2 is passed to p2 by reference. So q2 and p2 are now aliases. They are essentially the same. If function f changes *p2 (e.g., *p2 = 20), *q2 is changed too. If function f changes p2 (e.g., p2 = somePointerVariable), q2 is changed too.
The address stored in a pointer is returned. Suppose you want to write a function that passes an array argument, reverses it, and returns the array.
eg:
int* reverse(int* list, int size)
{
for (int i = 0, j = size - 1; i < j; i++, j--) {
// Swap list[i] with list[j]
int temp = list[j];
list[j] = list[i];
list[i] = temp;
}
return list;
}
void main(){
int list[] = {1, 2, 3, 4, 5, 6};
int* p = reverse(list, 6);
for (int i = 0; i < size; i++)
cout << list[i] << " ";
return 0;
}
- Remember, don’t return a local pointer! It becomes invalid after the return!
9th. Several useful array functions
The min_element, max_element, sort, random_shuffle, and find functions can be used for arrays (#include <algorithm>).
Especially, All these functions use pointers in the arguments and in the return value.
eg:
int list[] = {4, 2, 3, 6, 5, 1};
int* min = min_element(list, list + 6);
int* max = max_element(list, list + 6);
cout<< "The min value is " <<*min<< " at index " <<(min - list)<<endl;
random_shuffle(list, list + 6);
sort(list, list + 6);
int key = 4;
int* p = find(list, list + 6, key);
if (p != list + 6)
cout << *p << " is found at position " << (p - list) << endl;
else
cout << *p << " is not found" << endl;
10th. Dynamic persistent memory allocation
The new operator can be used to create persistent memory at runtime for primitive type values, arrays, and objects.
For example:
int* p1 = new int(4);//int number
//Dynamic array:
int* p2 = new int[10];//int array
int* p3 = new int[size];//int array
To explicitly free the memory created by the new operator, use the delete operator.
For instance:
delete p1; // delete operator for a pointer
delete [] p2; // delete operator for an array
Note: As a good programming practice, every call to new should be matched by a call to delete!
However, it will cause memory leak with the following code:
int* p = new int;
*p = 45;
p = new int;
Last!!!
對于曾經Pascal選手來講,指針真的不會用。。。正好臨近考試,總結出來指針的用法(雖然是英文),對于那麼聰明的你們來講,一定可以有辦法把它翻譯成中文的吧!
Especially:
At last, thanks to my teacher Assoc Prof. Qian SUN’s slides!