Chapter 3 Pointers
Chapter 3 Pointers
Pointers
1
Objectives
● This chapter aims for the students to
● Understand concept of pointers
● Declare pointer variables
● Initialize/assign values to pointer variables
● Understand pointer arithmetics
● Modify pointer variables
● Relate pointers and arrays
● Understand advantages of pointers
● Understand challenges of void pointers
Chapter 3: Pointers 2
Introduction
● Variables are memory cells that can access by an
identifier.
● variables are stored in concrete places of the computer
memory.
● the computer memory is only a succession of 1 byte
cells (the minimum size for a datum), each one with a
unique address.
● A pointer is a variable which stores the address of
another variable.
● The only difference between pointer variable and
regular variable is the data they hold.
Chapter 3: Pointers 3
Basic concept of pointers
There are two pointer operators in C++:
○ & the address of operator
○ * the dereference operator
● The & literally mean “address of.” always produces the memory
address of whatever it precedes.
● The * operator, when used with pointers, either declares a
pointer variable or dereferences the pointer’s value.
● The dereference operator can be literally translated to
"value pointed to by" .
● A pointer is simply the address of an object in memory.
● Generally, objects can be accessed in two ways:
○ directly by their symbolic name, or
○ indirectly through a pointer.
● The act of getting to an object via a pointer to it, is called
dereferencing the pointer.
Chapter 3: Pointers 4
Basic concept of pointers cont’d
● Pointer variables are defined to point to objects of a specific
type so that when the pointer is dereferenced, a typed object
is obtained.
● We generally do not decide where the variable is to be placed
– it is done automatically done by the compiler and the
operating system on runtime.
● But there are some cases in which we may be interested in
knowing where the variable is stored.
● Solution??? preceding the variable identifier by an ampersand
sign (&) "address of”.
○ For example: ptr= &var;
● This would assign to variable ptr the address of variable var ,
since when preceding the name of the variable var with the
ampersand ( & ) character we are no longer talking about the
content of the variable, but about its address in memory.
Chapter 3: Pointers 5
Basic concept of pointers cont’d
● We are going to suppose that var has been placed in the
memory address 1776 and that we write the following:
int var=25;
int x=var;
int * ptr = &var;
● The result is shown below:
Chapter 3: Pointers 6
Declaring pointers
● Is reserving a memory location for a
pointer variable in the heap.
● Syntax: type * pointer_name ;
declare a pointer variable called p_age:
int * p_age;
● Whenever the dereference operator, *,
appears in a variable declaration, the
variable being declared is always a pointer
variable.
Chapter 3: Pointers 7
Assigning values to pointers
● p_age is an integer pointer. The type of a pointer is very
important.
● p_age can point only to integer values, never to floating-
point or other types.
● To assign p_age the address of a variable:
int age = 26; int * p_age; p_age = &age;
OR
int age = 26; int * p_age = & age;
● Two ways to print the value of age:
Chapter 3: Pointers 9
Dereference pointers cont’d
#...
int main (){
int num = 123; // a regular integer variable
Chapter 3: Pointers 10
Dereference pointers cont’d
#...
int main()
{ float v1 = 679.54;
float v2 = 900.18;
float * p_v;
p_v = &v1;
cout<< “\nthe first value is ”<<*p_v;
p_v = &v2;
cout<< “\nthe second value is ”<<*p_v;
}
Chapter 3: Pointers 11
Dereference pointers cont’d
● You can use pointer notation and reference pointers as arrays
with array notation. The inner workings of arrays and pointer
notation.
void main() { int ctr;
int iara[5] = {10,20,30,40,50};
int *iptr;
iptr = iara; //makes iprt point to array’s first element. Or iptr
= &iara[0]
cout<< “using array subscripts:\n”
cout<< “iara\tiptr\n”;
for(ctr=0;ctr<5;ctr++) {
cout<<iara[ctr]<< “\t”<< iptr[ctr]<< “\n”;
}
cout<< “\nUsing pointer notation\n”;
for(ctr=0;ctr<5;ctr++) {
cout<< *(iara+ctr) << “\t” << *(iptr+ctr)<< “\n”;
}
}
Chapter 3: Pointers 12
Pointers to void
● note that we can’t assign the address of a float type variable to
an integer pointer variable and similarly the address of an
integer variable can not be stored in a float or character
pointer.
■ flaot y;
■ int x;
■ int *ip;
■ float *fp;
void *p;
int x;
float y;
Chapter 3: Pointers 14
Array of pointers
● If you have to reserve many pointers for
many different values, you might want to
declare an array of pointers.
Chapter 3: Pointers 16
Array and pointers cont’d
● Because numbers is an array (constant pointer), and no
values can be assigned to constant identifiers.
● The array name always points to the first element stored
in the array.
int ara[5] = {10,20,30,40,50};
cout<< *(ara + 2); //prints ara[2];
● The expression *(ara+2) is not vague at all if you
remember that an array name is just a pointer that
always points to the array’s first element.
● Consider the following character array:
Chapter 3: Pointers 17
Array and pointers cont’d
● What output do the following cout
statements produce?
cout<<name[0]; // ____C__
cout<<*name; // _____C__
cout<<*(name+3); //_________
cout<<*(name+0); //____C____
Question
● What is the two uses of * operator?
● Name its use?
Chapter 3: Pointers 18
Pointer advantages
● You can’t change the value of an array name,
because you can’t change constants. This
explains why you can’t assign an array a new
value during a program’s execution:
● eg: if Cname is array of characters then:
Cname = “Football”; //invalid array assignment;
● Unlike arrays, you can change a pointer variable.
By changing pointers, you can make them point
to different values in memory.
● Have a look at the following code
Chapter 3: Pointers 19
Pointer advantages cont’d
● Suppose that you want to store a persons name
and print it. Rather than using arrays, you can
use a character pointer.
void main()
{
char *c = “Meseret Belete”; cin.getline(c,10);
cout<< “your name is : ”<<c;
}
Chapter 3: Pointers 20
Pointer advantages cont’d
● Suppose that you must change a string pointed to by a character
pointer, if the persons name in the above code is changed to
Meseter Alemu: look at the following code:
void main() {
c = “Meseret Alemu”;
}
● If c were a character array, you could never assign it directly because
an array name can’t be changed.
Chapter 3: Pointers 21
Character pointer
● char * c = "here is an sample text“; cout<<c;
● In C++, a character pointer is a variable that points to a
location in memory containing a character value.
● When you assign a string literal to a character pointer,
you are essentially copying the string into a contiguous
block of memory. The character pointer then points to
the starting address of this block of memory.
● When you cout << c;, you are telling the cout object to
print the contents of the memory location pointed to
by the character pointer c. Since c points to the starting
address of the string "here is an sample text", cout will
print the entire string.
Chapter 3: Pointers 22
Character pointer cont’d
● A character pointer is a variable that stores the memory address
of a character.
● This means that the pointer itself does not contain the actual
character value, but rather a reference to the location where the
character value is stored in memory.
● Character pointers are often used to manipulate strings, which are
sequences of characters.
● A literal string is a sequence of characters enclosed in double
quotes.
● Literal strings are used to initialize character arrays and to pass
strings as arguments to functions.
● When a literal string is assigned to a character pointer, the
compiler automatically creates a character array in memory and
initializes the array with the characters of the literal string.
● The character pointer is then initialized to point to the starting
address of the character array.
Chapter 3: Pointers 23
Pointer arithmetic
● To conduct arithmetical operations on pointers is a little
different than to conduct them on other integer data types.
● To begin, only addition and subtraction operations are
allowed to be conducted, the others make no sense in the
world of pointers.
● But both addition and subtraction have a different
behavior with pointers according to the size of the data
type to which they point to.
● When we see the different data types that exist, we saw
that some occupy more or less space than others in the
memory. For example, in the case of integer numbers, char
occupies 1 byte, short occupies 2 bytes and long occupies 4.
Chapter 3: Pointers 24
Pointer arithmetic cont’d
● Let's suppose that we have 3 pointers:
char *mychar;
short *myshort;
long *mylong;
● And that we know that they point to memory locations 1000 , 2000 and
3000 respectively. So if we write:
mychar++;
myshort++;
mylong++;
● mychar , as you may expect, would contain the value 1001 .
Nevertheless, myshort would contain the value 2002 , and mylong
would contain 3004 . The reason is that when adding 1 to a pointer we
are making it to point to the following element of the same type with
which it has been defined, and therefore the size in bytes of the type
pointed is added to the pointer.
Chapter 3: Pointers 25
Pointer arithmetic cont’d
Chapter 3: Pointers 26
Pointer arithmetic cont’d
● This is applicable both when adding and subtracting any number
to a pointer.
● It is important to warn you that both increase ( ++ ) and decrease
( -- ) operators have a greater priority than the reference
operator asterisk ( * ), therefore the following expressions may
lead to confusion:
*p++;
*p++ = *q++; //Check it
● The first one is equivalent to *(p++) and what it does is to
increase p (the address where it points to - not the value that
contains).
The second, because both increase operators ( ++ ) are after the
expressions to be evaluated and not before, first the value of *q
is assigned to *p and then they are both q and p increased by
one. It is equivalent to:
*p = *q; p++;
q++; Chapter 3: Pointers 27
Pointer arithmetic cont’d
● Now let us have a look at a code that
shows increments through an integer
array:
void main() {
int iara[] = {10,20,30,40,50};
int * ip = iara;
cout<<*ip<<endl;
ip++;
cout<<*ip<<endl;
ip++;
cout<<*ip<<endl;
ip++;
cout<<*ip<<endl;
Chapter 3: Pointers } 28
Pointer and string
● If you declare a character table with 5 rows and 20
columns, each row would contain the same number of
characters.
● You can define the table as:
Char names[5][20]={{“George”},{“Mesfin”},{“John”} ,{“Kim”},
{“Barbara”}};
● will create the following table in memory
G e o r g e \0
M e s f i n \0
J o h n \0
K i m \0
B a r b a r a \
0
Chapter 3: Pointers 29
Pointer and string cont’d
Chapter 3: Pointers 30
Pointer and string cont’d
● This array is a single dimensional array.
● The asterisk before names makes this array an array
of pointers.
● Each string takes only as much memory as is needed
by the string and its terminating zero.
● To print the first string, we should use:
Chapter 3: Pointers 33
Pointer to pointers cont’d
Have a look at the following code:
void main() {
int data;
int *p1;
int **p2;
data = 15;
cout<< “data = ”<<data<<endl;
p1 = &data;
p2 = &p1;
cout<< “data through p1 = ”<<*p1<<endl;
cout<< “data through p2 = ”<< **p2<<endl;}
Chapter 3: Pointers 34
Dynamic Memory
● Until now, in our programs, we have only had as much memory as we
have requested in declarations of variables, arrays and other objects
that we included, having the size of all of them to be fixed before the
execution of the program.
● But, What if we need a variable amount of memory that can only be
determined during the program execution (runtime)? For example, in
case that we need a user input to determine the necessary amount of
space.
● The answer is dynamic memory, for which C++ integrates the operators
new and delete.
● Pointers are useful for creating dynamic objects during program
execution. Unlike normal (global and local) objects which are allocated
storage on the runtime stack, a dynamic object is allocated memory
from a different storage area called the heap. Dynamic objects do not
obey the normal scope rules. Their scope is explicitly controlled by the
programmer.
Chapter 3: Pointers 35
The new operator
● In C++ new operator can create space dynamically i.e at
run time, and similarly delete operator is also available
which releases the memory taken by a variable and
return memory to the operating system.
● When the space is created for a variable at compile
time this approach is called static.
● If memory space is created at run time for a variable,
this approach is called dynamic. See the following two
lines:
int a[10];//creation of static array
int *a;
a = new int[10];//creation of dynamic array
● Lets have another example:
int * ptr3;
ptr3 = new int [5];
Chapter 3: Pointers 36
The new operator cont’d
• In this case, the operating system has assigned
space for 5 elements of type int in the heap and
it has returned a pointer to its beginning that
has been assigned to ptr3 . Therefore, now,
ptr3 points to a valid block of memory with
space for 5 int elements.
Chapter 3: Pointers 37
The new operator cont’d
● You could ask what is the difference between declaring
a normal array and assigning memory to a pointer as
we have just done.
● The most important one is that the size of an array
must be a constant value, which limits its size to what
we decide at the moment of designing the program
before its execution, whereas the dynamic memory
allocation allows assigning memory during the
execution of the program using any variable, constant
or combination of both as size.
● The dynamic memory is generally managed by the
operating system, and in the multi-task interfaces can
be shared between several applications,
Chapter 3: Pointers 38
The new operator cont’d
● There is a possibility that the memory exhausts.
● If this happens and the operating system cannot assign
the memory that we request with the operator new , a
null pointer will be returned.
● For that reason it is recommendable to always verify if
after a call to instruction new the returned pointer is null:
int * ptr3;
ptr3 = new int [5];
if (ptr3 == NULL) {
// error assigning memory. Take measures.
}
● if ptr3 is NULL, it means that there is no enough memory location
in the heap to be given for ptr3.
Chapter 3: Pointers 39
The delete operator
● Since the necessity of dynamic memory is usually limited to
concrete moments within a program, once this one is no longer
needed it shall be freed so that it become available for future
requests of dynamic memory. For this exists the operator delete ,
whose form is:
delete pointer ;
or
delete [] pointer ;
● The first expression should be used to delete memory allocated for
a single element, and the second one for memory allocated for
multiple elements (arrays).
● In most compilers both expressions are equivalent and can be used
without distinction, although indeed they are two different
operators and so must be considered for operator overloading.
Chapter 3: Pointers 40
The delete operator cont’d
Chapter 3: Pointers 41
The delete operator cont’d
#include <iostream.h>
#include <stdlib.h>
#include<conio.h>
int main ()
{
char input [100];
int i,n;
long * num;// total = 0;
cout << "How many numbers do you want to
type in? ";
● NULL is a constant value
cin.getline (input,100); defined in C++ libraries
i=atoi (input); specially designed to
num= new long[i]; indicate null pointers.
if (num == NULL) ● In case that this constant is
{ not defined you can do it
cout<<"\nno enough memory!";
yourself by defining it to 0:
}
Chapter 3: Pointers 42
The delete operator cont’d
for (n=0; n<i; n++)
{
cout << "Enter number: ";
cin.getline (input,100);
num[n]=atol (input);
}
cout << "You have entered: ";
for (n=0; n<i; n++)
cout << num[n] << ", ";
delete[] num;
return 0;
}
Chapter 3: Pointers 43
Exercise
● What is the output produced by the following code?
int *p1, *p2;
p1 = new int;
p2 = new int;
*p1 = 10;
*p2 = 20;
cout << *p1 << " " << *p2 << endl;
p1 = p2;
cout << *p1 << " " << *p2 << endl;
*p1 = 30;
cout << *p1 << " " << *p2 << endl;
Chapter 3: Pointers 44
Exercise
Chapter 3: Pointers 46