Pointer
Pointer
Pointers C++
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:
#include <iostream>
int main ()
{
int var1;
char var2[10];
return 0;
}
When the above code is compiled and executed, it produces the following result:
type *var-name;
108
C++
Here, type is the pointer's base type; it must be a valid C++ type and var-name is the
name of the pointer variable. The asterisk you used to declare a pointer is the same
asterisk that you use for multiplication. However, in this statement the asterisk is being
used to designate a variable as a pointer. Following are the valid pointer declaration:
The actual data type of the value of all pointers, whether integer, float, character, or
otherwise, is the same, a long hexadecimal number that represents a memory address.
The only difference between pointers of different data types is the data type of the variable
or constant that the pointer points to.
#include <iostream>
int main ()
{
int var = 20; // actual variable declaration.
int *ip; // pointer variable
return 0;
}
When the above code is compiled and executed, it produces result something as follows:
Pointers in C++
Pointers have many but easy concepts and they are very important to C++ programming.
There are following few important pointer concepts which should be clear to a C++
programmer:
Concept Description
C++ Null Pointers C++ supports null pointer, which is a constant with
a value of zero defined in several standard libraries.
C++ pointer arithmetic There are four arithmetic operators that can be used
on pointers: ++, --, +, -
C++ array of pointers You can define arrays to hold a number of pointers.
C++ pointer to pointer C++ allows you to have pointer on a pointer and so
on.
Return pointer from functions C++ allows a function to return a pointer to local
variable, static variable and dynamically allocated
memory as well.
110
C++
Null Pointers
It is always a good practice to assign the pointer NULL to a pointer variable in case you do
not have exact address to be assigned. This is done at the time of variable declaration. A
pointer that is assigned NULL is called a null pointer.
The NULL pointer is a constant with a value of zero defined in several standard libraries,
including iostream. Consider the following program:
#include <iostream>
int main ()
{
int *ptr = NULL;
return 0;
}
When the above code is compiled and executed, it produces the following result:
On most of the operating systems, programs are not permitted to access memory at
address 0 because that memory is reserved by the operating system. However, the
memory address 0 has special significance; it signals that the pointer is not intended to
point to an accessible memory location. But by convention, if a pointer contains the null
(zero) value, it is assumed to point to nothing.
Thus, if all unused pointers are given the null value and you avoid the use of a null pointer,
you can avoid the accidental misuse of an uninitialized pointer. Many times, uninitialized
variables hold some junk values and it becomes difficult to debug the program.
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 -
111
C++
To understand pointer arithmetic, let us consider that ptr is an integer pointer which points
to the address 1000. Assuming 32-bit integers, let us perform the following arithmatic
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.
Incrementing a Pointer
We prefer using a pointer in our program instead of an array because the variable pointer
can be incremented, unlike the array name which cannot be incremented because it is a
constant pointer. The following program increments the variable pointer to access each
succeeding element of the array:
#include <iostream>
int main ()
{
int var[MAX] = {10, 100, 200};
int *ptr;
When the above code is compiled and executed, it produces result something as follows:
Decrementing a Pointer
The same considerations apply to decrementing a pointer, which decreases its value by
the number of bytes of its data type as shown below:
#include <iostream>
int main ()
{
int var[MAX] = {10, 100, 200};
int *ptr;
When the above code is compiled and executed, it produces result something as follows:
Pointer Comparisons
Pointers may be compared by using relational operators, such as ==, <, and >. If p1 and
p2 point to variables that are related to each other, such as elements of the same array,
then p1 and p2 can be meaningfully compared.
The following program modifies the previous example one by incrementing the variable
pointer so long as the address to which it points is either less than or equal to the address
of the last element of the array, which is &var[MAX - 1]:
#include <iostream>
int main ()
{
int var[MAX] = {10, 100, 200};
int *ptr;
114
C++
When the above code is compiled and executed, it produces result something as follows:
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:
#include <iostream>
int main ()
{
int var[MAX] = {10, 100, 200};
int *ptr;
When the above code is compiled and executed, it produces result something as follows:
However, pointers and arrays are not completely interchangeable. For example, consider
the following program:
#include <iostream>
int main ()
{
int var[MAX] = {10, 100, 200};
116
C++
It is perfectly acceptable to apply the pointer operator * to var but it is illegal to modify
var value. The reason for this is that var is a constant that points to the beginning of an
array and can not be used as l-value.
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.
Array of Pointers
Before we understand the concept of array of pointers, let us consider the following
example, which makes use of an array of 3 integers:
#include <iostream>
int main ()
{
int var[MAX] = {10, 100, 200};
When the above code is compiled and executed, it produces the following result:
Value of var[0] = 10
Value of var[1] = 100
Value of var[2] = 200
There may be a situation, when we want to maintain an array, which can store pointers to
an int or char or any other data type available. Following is the declaration of an array of
pointers to an integer:
int *ptr[MAX];
117
C++
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:
#include <iostream>
int main ()
{
int var[MAX] = {10, 100, 200};
int *ptr[MAX];
When the above code is compiled and executed, it produces the following result:
Value of var[0] = 10
Value of var[1] = 100
Value of var[2] = 200
You can also use an array of pointers to character to store a list of strings as follows:
#include <iostream>
int main ()
118
C++
{
char *names[MAX] = {
"Zara Ali",
"Hina Ali",
"Nuha Ali",
"Sara Ali",
};
When the above code is compiled and executed, it produces the following result:
Pointer to a Pointer
A pointer to a pointer is a form of multiple indirection or a chain of pointers. Normally, a
pointer contains the address of a variable. When we define a pointer to a pointer, the first
pointer contains the address of the second pointer, which points to the location that
contains the actual value as shown below.
A variable that is a pointer to a pointer must be declared as such. This is done by placing
an additional asterisk in front of its name. For example, following is the declaration to
declare a pointer to a pointer of type int:
int **var;
When a target value is indirectly pointed to by a pointer to a pointer, accessing that value
requires that the asterisk operator be applied twice, as is shown below in the example:
119
C++
#include <iostream>
int main ()
{
int var;
int *ptr;
int **pptr;
var = 3000;
return 0;
}
When the above code is compiled and executed, it produces the following result:
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:
120
C++
#include <iostream>
#include <ctime>
int main ()
{
unsigned long sec;
getSeconds( &sec );
return 0;
}
When the above code is compiled and executed, it produces the following result:
The function which can accept a pointer, can also accept an array as shown in the following
example:
#include <iostream>
using namespace std;
// function declaration:
double getAverage(int *arr, int size);
121
C++
int main ()
{
// an int array with 5 elements.
int balance[5] = {1000, 2, 3, 17, 50};
double avg;
return 0;
}
return avg;
}
When the above code is compiled together and executed, it produces the following result:
122
C++
int * myFunction()
{
.
.
.
}
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 staticvariable.
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.
#include <iostream>
#include <ctime>
return r;
}
int main ()
{
// a pointer to an int.
int *p;
p = getRandom();
for ( int i = 0; i < 10; i++ )
{
cout << "*(p + " << i << ") : ";
cout << *(p + i) << endl;
}
return 0;
}
When the above code is compiled together and executed, it produces result something as
follows:
624723190
1468735695
807113585
976495677
613357504
1377296355
1530315259
1778906708
1820354158
667126415
*(p + 0) : 624723190
*(p + 1) : 1468735695
*(p + 2) : 807113585
*(p + 3) : 976495677
*(p + 4) : 613357504
*(p + 5) : 1377296355
*(p + 6) : 1530315259
*(p + 7) : 1778906708
*(p + 8) : 1820354158
*(p + 9) : 667126415
124
19. References C++
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.
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.
int i = 17;
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:
#include <iostream>
int main ()
{
// declare simple variables
int i;
double d;
125
C++
i = 5;
cout << "Value of i : " << i << endl;
cout << "Value of i reference : " << r << endl;
d = 11.7;
cout << "Value of d : " << d << endl;
cout << "Value of d reference : " << s << endl;
return 0;
}
When the above code is compiled together and executed, it produces the following result:
Value of i : 5
Value of i reference : 5
Value of d : 11.7
Value of d reference : 11.7
References are usually used for function argument lists and function return values. So
following are two important subjects related to C++ references which should be clear to a
C++ programmer:
Concept Description
Reference as return value You can return reference from a C++ function like
any other data type.
References as Parameters
We have discussed how we implement call by reference concept using pointers. Here is
another example of call by reference which makes use of C++ reference:
#include <iostream>
126
C++
// function declaration
void swap(int& x, int& y);
int main ()
{
// local variable declaration:
int a = 100;
int b = 200;
return 0;
}
return;
}
When the above code is compiled and executed, it produces the following result:
When a function returns a reference, it returns an implicit pointer to its return value. This
way, a function can be used on the left side of an assignment statement. For example,
consider this simple program:
#include <iostream>
#include <ctime>
{
cout << "vals[" << i << "] = ";
cout << vals[i] << endl;
}
return 0;
}
When the above code is compiled together and executed, it produces the following result:
When returning a reference, be careful that the object being referred to does not go out
of scope. So it is not legal to return a reference to local var. But you can always return a
reference on a static variable.
int& func() {
int q;
//! return q; // Compile time error
static int x;
return x; // Safe, x lives outside this scope
}
129