Pointer variables allow programmers to indirectly access and manipulate the memory addresses where variables are stored. Pointers must be declared with a data type and initialized by assigning the address of an existing variable using the address-of operator (&). Pointer variables can then be used to read from and write to the memory location of the variable being pointed to using indirection (*). Pointers enable operations like traversing arrays, passing arguments by reference, and dynamically allocating memory. Key pointer concepts covered include declaration, initialization, dereferencing, arithmetic, comparisons, NULL pointers, and their usage with arrays.
Interactive Powerpoint_How to Master effective communication
COM1407 Computer Programming Lecture 11 Working with Pointers
1. COM1407
Computer Programming
Lecture 11
Working with Pointers
K.A.S.H. Kulathilake
B.Sc. (Hons) IT, MCS , M.Phil., SEDA(UK)
Rajarata University of Sri Lanka
Department of Physical Sciences
1
2. Objectives
• At the end of this lecture students should be able to;
▫ Define the C pointers and its usage in computer
programming.
▫ Describe pointer declaration and initialization.
▫ Apply C pointers for expressions.
▫ Experiment on pointer operations.
▫ Identify NULL pointer concept.
▫ Experiment on pointer to pointer, pointer arrays,
arrays with pointers and functions with pointers.
▫ Apply taught concepts for writing programs.
2
3. Introduction
• To understand how to use pointers, you must have a
basic knowledge of how a computer stores
information in memory.
• Pointers closely relate to memory manipulation.
• Basically, a personal computer RAM consists
thousands of sequential storage locations, with each
location being identified by a unique address.
• Computer’s processor also has their own memory,
normally called registers and cache.
• They differ in term of access speed, price and their
usage.
3
4. Introduction (Cont…)
• Computer memory is used for storage, when
program runs on the computer and for processing
data and instructions.
• In a very simple way, each program requires two
portions of the memory that is: (2+2)
1. Data portion – for data or operands. (2,2)
2. The instruction code portion – what to do to the data
such as operators etc. (+)
• Each portion is referred to as a memory segment, so
there is:
1. A data segment (normally called data segment).
2. An instruction code segment (normally called text
segment).
4
5. Introduction (Cont…)
• When the programmer declares a variable in a
C/C++ program, the compiler sets aside a memory
location with a unique address to store that variable.
• The compiler associates that address with the
variable’s name.
• When the program uses the variable name, it
automatically accesses the proper memory location.
• The locations address remains hidden from the
programmer, and the programmer need not be
concerned with it.
• What we are going to do is to manipulate the
memory addresses by using pointers.
5
6. Introduction (Cont…)
• Let say we declare one variable named rate of
type integer and assign an initial value as
follows:
int rate = 100;
• Memory allocation for the above variable can be
depicted as follows
6
7. Introduction (Cont…)
• You can see, the memory address of the variable
rate (or any other variable) is a number, so can
be treated like any other number in C/C++.
• Normally the number is in hexadecimal format.
• Then, if a variable’s memory address is known,
the programmer can create a second variable for
storing a memory address of the first variable.
• We can declare another variable to hold the
memory address of variable rate; let say, s_rate
7
8. Introduction (Cont…)
• At the beginning, s_rate is uninitialized.
• So, storage has been allocated for s_rate, but its
value is undetermined, as shown below.
8
9. Introduction (Cont…)
• Let store the memory address of variable rate, in
variable s_rate, so, s_rate now contains the
memory address of rate, which indicates its
storage location in memory where the actual
data (100) is stored.
• Finally, in C/C++ vocabulary, s_rate is pointing
to rate or is said a pointer to rate.
9
11. Declaring a Pointer Variable
• So the declaration of the pointer variable
becomes something like this:
int *s_rate;
• The asterisk (*) is used to show that is it the
pointer variable instead of normal variable.
• A pointer is a variable that contains the
memory address of another variable,
where, the actual data is stored.
11
12. Declaring a Pointer Variable (Cont…)
• A pointer is a numeric variable and like other
variables, must be declared and initialized before it
can be used.
• The following is a general form for declaring a
pointer variable:
data_type *pointer_variable_name;
For e.g.
char* x;
int * type_of_car;
float *value;
12
x is a pointer to a variable of type char.
*, is valid for all the three positions
The asterisk (*) is called indirection
operator,
13. Declaring a Pointer Variable (Cont…)
• Pointers can be declared along with non
pointer variables as shown below:
char *ch1, *ch2;
// ch1 and ch2 both are pointers to type char.
float *value, percent;
// value is a pointer to type float, and percent
is an ordinary float variable.
13
14. Initializing Pointers
• Once a pointer is declared, the programmer must
initialize the pointer, that is, make the pointer point
to something.
• Don’t make it point to nothing; it is
dangerous.
• Like regular variables, uninitialized pointers will not
cause a compiler error, but using an
uninitialized pointer could result in
unpredictable and potentially disastrous
outcomes.
• Until pointer holds an address of a variable,
it isn’t useful.
14
15. Initializing Pointers (Cont…)
• C/C++ uses two pointer operators:
1. Indirection operator (*) – has been explained.
2. Address-of-operator (&) – means return the
address of.
• When & placed before the name of a
variable, the address-of-operator returns
the memory address of the
variable/operand
15
16. Initializing Pointers (Cont…)
• Hence, a pointer variable can be initialize as
follows;
pointer_variable_name = &variable;
e.g.
s_rate = &rate;
16
17. Initializing Pointers (Cont…)
#include <stdio.h>
int main ()
{
int n;
int *x;
printf("n===> %in",n);
printf("&n==> %in",&n);
n =10;
printf("n===> %in",n);
printf("&n==> %in",&n);
x = &n;
printf("x===> %in",x);
printf("*x ==> %in",*x);
return 0;
}
17
18. Initializing Pointers (Cont…)
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int *m;
int location = 200;
m = &location;
printf("The data, *m = %in",*m);
printf("The address where the data pointed to,
m = %in", m);
system("pause");
return 0;
}
18
19. Initializing Pointers (Cont…)
• Pointer variable m receives the address of
variable location or the memory address of the
variable location is assigned to pointer variable
m.
19
20. Initializing Pointers (Cont…)
#include <stdio.h>
int main (void)
{
/*Following declaration is also legal*/
int count = 10, x,*int_pointer;
int_pointer = &count;
x = *int_pointer;
printf ("count = %i, x = %in",
count, x);
return 0;
}
20
22. Initializing Pointers (Cont…)
• Where Pointers?
▫ The * operator appears before a pointer
variable in only two places:
When declaring a pointer variable.
When dereferencing a pointer variable (to find the
data it points to).
22
23. Using Pointers in Expressions
#include <stdio.h>
int main ()
{
int var = 34;
int *ptr,*ptr2;
ptr = &var;
printf("Direct access, var = %in", var);
printf("Indirect access, *ptr = %in", *ptr);
printf("The memory address of variable var = %in", &var);
printf("Pointing address of ptr = %in", ptr);
ptr2=ptr;
printf("The value of ptr2 %in",*ptr2);
printf("Pointing address of ptr2 %in",ptr2);
return 0;
}
23
24. Using Pointers in Expressions (Cont…)
• From the above example, we can:
1. Access the contents of a variable by using the
variable name (var) and is called direct access.
2. Access the contents of a variable by using a pointer
to the variable (*ptr or *ptr2) and is called indirect
access or indirection.
24
25. Using Pointers in Expressions (Cont…)
#include <stdio.h>
int main (void)
{
int i1, i2;
int *p1, *p2;
i1 = 5;
p1 = &i1;
i2 = *p1 / 2 + 10;
p2 = p1;
printf ("i1 = %i, i2 = %i, *p1 = %i,
*p2 = %in", i1, i2, *p1, *p2);
return 0;
}
25
26. The Keyword const and Pointers
char c = 'X';
char *charPtr = &c;
• The pointer variable charPtr is set pointing to the
variable c.
• If the pointer variable is always set pointing to c, it
can be declared as a const pointer as follows:
char * const charPtr = &c;
• Read this as “charPtr is a constant pointer to a
character.”
• So, a statement like this:
charPtr = &d; // not valid
*charPtr = 'Y‘; // valid
26
27. The Keyword const and Pointers
(Cont…)
• Now if, instead, the location pointed to by charPtr will
not change through the pointer variable charPtr, that
can be noted with a declaration as follows:
const char *charPtr = &c;
• Read this as “charPtr points to a constant character.”
• Now of course, that doesn’t mean that the value cannot
be changed by the variable c, which is what charPtr is set
pointing to.
• It means, however, that it won’t be changed with a
subsequent statement like this:
*charPtr = 'Y'; // not valid
charPtr = &d // valid
27
28. The Keyword const and Pointers
(Cont…)
#include <stdio.h>
int main ()
{
char c = 'X', d = 'T';
char * const charPtr = &c;
const char *charPtr2 = &c;
charPtr = &d; //invalid statement
*charPtr = 'Y'; // Valid statement
charPtr2 = &d; // Valid statement
*charPtr2 = 'Y'; // Invalid statement
return 0;
}
28
29. Pointer Operation
• Only two arithmetic operations, that are
addition and subtraction available
• Addition Operation (Increment)
▫ Each time the pointer is incremented, it points to
the next integer and similarly, when a pointer is
decremented, it points to the previous integer.
• Differencing
▫ For example, two pointers that point to different
elements of the same array can be subtracted to
find out how far apart they are.
29
30. Pointer Operation (Cont…)
#include <stdio.h>
const int MAX = 3;
int main () {
int var[] = {10, 100, 200};
int i, *ptr;
/* let us have array address in pointer */
ptr = var;
for ( i = 0; i < MAX; i++)
{
printf("Address of var[%d] = %xn", i, ptr );
printf("Value of var[%d] = %in", i, *ptr );
/* move to the next location */
ptr++;
}
return 0;
}
30
31. Pointer Operation (Cont…)
#include <stdio.h>
const int MAX = 3;
int main ()
{
int var[] = {10, 100, 200};
int i, *ptr;
/* let us have array address in pointer */
ptr = &var[MAX-1];
for ( i = MAX; i > 0; i--)
{
printf("Address of var[%d] = %xn", i-1, ptr );
printf("Value of var[%d] = %dn", i-1, *ptr );
/* move to the previous location */
ptr--;
}
return 0;
}
31
32. Pointer Operation (Cont…)
• Pointer Comparison
▫ The comparison is valid only between pointers that point to
the same array.
▫ Under this circumstances, the following relational
operators work for pointers operation.
==, !=, >, <, >= and <=
▫ A lower array element that is those having a smaller
subscript, always have a lower address than the higher
array elements.
▫ Thus if ptr1 and ptr2 point to elements of the same array,
the following comparison:
ptr1 < ptr2 is TRUE
▫ If ptr1 points to an earlier member of the array than ptr2
does.
32
33. Pointer Operation (Cont…)
#include <stdio.h>
int main ()
{
int *m;
int *n;
int q,r = 35;
m = &q;
n = &r;
printf ("m contains : %in",m);
printf ("n contains : %in",n);
if ( m <n ){
printf ("m before nn");
}
else{
printf ("n before mn");
}
return 0;
}
33
34. Pointer Operation (Cont…)
• Many arithmetic operations that can be performed with
regular variables, such as multiplication and division, do
not work with pointers and will generate errors in
C/C++.
• The following table is a summary of pointer operations.
34
35. NULL Pointers
• It is always a good practice to assign a NULL
value to a pointer variable in case you do not
have an exact address to be assigned.
• This is done at the time of variable declaration.
• A pointer that is assigned NULL is called
a nullpointer.
• The NULL pointer is a constant with a value of
zero defined in several standard libraries.
35
36. NULL Pointers (Cont…)
#include <stdio.h>
int main () {
int *ptr = NULL;
printf("The value of ptr is : %xn", ptr );
printf("The value of ptr is : %in", ptr );
return 0;
}
36
37. NULL Pointers (Cont…)
• In 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.
• To check for a null pointer, you can use an 'if' statement as
follows −
if(ptr) /* succeeds if p is not null */
if(!ptr) /* succeeds if p is null */
• To play safe, you can also set a pointer to NULL to indicate
that it’s no longer in use.
37
38. Pointers & Arrays
• The main reasons for using pointers to arrays
are ones of notational convenience and of
program efficiency.
• Pointers to arrays generally result in code that
uses less memory and executes faster.
• The real power of using pointers to arrays comes
into play when you want to sequence through
the elements of an array.
38
39. Pointers & Arrays (Cont…)
• An array name without brackets is a pointer to the
array’s first element.
• So, if a program declared an array data[], data
(array’s name) is the address of the first array
element and is equivalent to the expression
&data[0] that means references the address of the
array’s first element.
• data equivalent to &data[0] or a pointer to the
array’s first element.
• The array’s name is, therefore a pointer to
the array’s first element.
39
40. Pointers & Arrays (Cont…)
int values [100] = {1,2,…, 100};
int *valuesPtr;
valuesPtr = values;
Or
valuesPtr = &values[0];
If you do following
valuesPtr = &values[1];
It points to second element
40
41. Pointers & Arrays (Cont…)
• Element of an array are stored in sequential
memory locations with the first element in the
lowest address.
• Array of type int occupies 2 byte of memory and
a type float occupies 4 byte.
41
42. Pointers & Arrays (Cont…)
• to access successive elements of an array of a particular data
type, a pointer must be increased by the sizeof(data_type).
• sizeof() function returns the size in bytes of a C/C++ data
type.
42
For example,
relationship
between array
storage and
addresses for a
6-elements int
array and a 3-
elements float
array is
illustrated in
this diagram.
43. Pointers & Arrays (Cont…)
#include <stdio.h>
int main ()
{
int i[10], x;
float f[10];
double d[10];
printf("nArray's el. add of i[x] add of f[x] add of d[x]");
printf("n|================================");
printf("======================|");
for(x=0; x<10; x++)
printf("nElement %i:t%pt%pt%p",x,&i[x],&f[x],&d[x]);
printf("n|================================");
printf("======================|n");
printf("nLegends:");
printf("nel.- element, add - addressn");
printf("ndifferent pc, shows different addressesn");
return 0;
}
43
44. Pointers & Arrays (Cont…)
• Notice the difference between the element addresses.
▫ 0027FF04 – 0027FF08 = 4 bytes for int
▫ 0027FEE0 – 0027FEE4 = 4 bytes float
▫ 0027FE90 – 0027FE98 = 8 bytes double
[The size of the data type depends on the specification of your compiler, whether your target is 16, 32 or 64 bits
systems, the output of the program may be different for different PC]
44
45. Pointers & Arrays (Cont…)
#include <stdio.h>
#define MAX 10
int main()
{
int array1[MAX] = {0,1,2,3,4,5,6,7,8,9};
int *ptr1, count;
float array2[MAX] = {0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9};
float *ptr2;
ptr1 = array1;
ptr2 = array2;
printf("narray1 values array2 values");
printf("n-------------------------");
for(count = 0; count < MAX; count++)
printf("n%itt%f", *ptr1++, *ptr2++);
printf("n-------------------------n");
return 0;
}
45
The increment and
decrement operators are
particularly handy when
dealing with pointers.
Applying the increment
operator to a pointer has
the same effect as adding
one to the pointer, while
applying the decrement
operator has the same
effect as subtracting one
from the pointer.
46. Pointers & Arrays (Cont…)
#include <stdio.h>
int main()
{
char name[50]= "RAJARATA UNIVERSITY OF SRI LANKA";
printf("%snn",name);
printf("%s,%inn",name,&name);
printf("%c,%i,%inn",name[0],name[0],&name[0]);
printf("%c,%i,%inn",name[1],name[1],&name[1]);
return 0;
}
46
47. Pointers & Arrays (Cont…)
• Generally, the relationship is as follows:
*(array1) == array1 [0] //first element
*(array1 + 1) == array1 [1] //second element
*(array1+ 2) == array1 [2] //third element
…
…
*(array1 + n) == array1[n] //the nth element
47
48. Pointers & Arrays (Cont…)
#include <stdio.h>
int main (void)
{
int sum = 0, *ptr;
int values[10] = { 3, 7, -9, 3, 6, -1, 7, 9,
1, -5 };
int * const arrayEnd = values + 10;
for ( ptr = values; ptr < arrayEnd; ++ptr )
sum += *ptr;
printf ("The sum is %in", sum);
return 0;
}
48
49. Pointers & Arrays (Cont…)
• In general, the process of indexing an array takes
more time to execute than does the process of
accessing the contents of a pointer.
• In fact, this is one of the main reasons why pointers
are used to access the elements of an array—the
code that is generated is generally more efficient.
• Of course, if access to the array is not generally
sequential, pointers accomplish nothing, as far as
this issue is concerned, because the expression
*(pointer + j) takes just as long to execute as
does the expression array[j].
49
50. Pointer Arrays
• Pointers may be arrayed like any other data type.
• The declaration for an int pointer array of size 20 is:
int *arrayPtr[20];
• To assign the address of an integer variables called var to the first
element of the array, we could write something like this:
arrayPtr[0] = &var;
• To find the value stored in var, we could write something like this:
*arrayPtr[0]
50
51. Pointers to Pointers
• Graphically, the construct of a pointer to pointer
can be depicted as shown below.
• pointer_one is the first pointer, pointing to the
second pointer, pointer_two and finally
pointer_two is pointing to a normal variable
num that hold integer 10.
51
52. Pointers to Pointers (Cont…)
• In order to indirectly access the target value
pointed to by a pointer to a pointer, the asterisk
operator must be applied twice.
• For example, the following declaration:
int **SecondPtr;
• Tell the compiler that SecondPtr is a pointer to a
pointer of type integer.
• Pointer to pointer is rarely used but you will find
it regularly in programs that accept argument(s)
from command line.
52
53. Pointers to Pointers (Cont…)
• Consider the following declarations:
char chs; /* a normal character variable */
char *ptchs; /* a pointer to a character */
char **ptptchs; /* a pointer to a pointer to a character */
• If the variables are related as shown below:
• We can do some assignment like this:
chs = ‘A’;
ptchs = &chs;
ptptchs = ptchs;
53
54. Pointers to Pointers (Cont…)
#include <stdio.h>
int main ()
{
int **theptr;
int *anotherptr;
int data = 200;
anotherptr = &data;
theptr = &anotherptr;
printf("The actual data, **theptr = %in", **theptr);
printf("The actual data, *anotherptr = %in", *anotherptr);
printf("The theptr holding address = %pn", theptr);
printf("The theptr own address = %pn", &theptr);
printf("The anotherptr holding address = %pn", anotherptr);
printf("The &anotherptr own address = %pn", &anotherptr);
printf("The address of the normal variable = %pn", &data);
printf("Normal variable, the data = %in", data);
return 0;
}
54
55. Pointers & Functions
• You can pass a pointer as an argument to a function in
the normal fashion, and you can also have a function
return a pointer as its result.
• The pointers can be passed as formal parameters to a
function in the same way as a normal pointer variable.
• The value of the pointer is copied into the formal
parameter when the function is called.
• Therefore, any change made to the formal parameter by
the function does not affect the pointer that was passed
to the function.
• Although the pointer cannot be changed by the function,
the data elements that the pointer references can be
changed!
55
56. Pointers & Functions (Cont…)
#include <stdio.h>
void test (int*);
void test (int *int_pointer)
{
*int_pointer = 100;
}
int main (void)
{
int i = 50, *p = &i;
printf ("Before the call to test i = %in", i);
test (p);
printf ("After the call to test i = %in", i);
return 0;
}
56
58. Pointers & Functions (Cont…)
• Similarly, C also allows to return a pointer from a function.
#include<stdio.h>
int *fun();
int main()
{
int *ptr;
ptr=fun();
printf("%i",*ptr);
return 0;
}
int *fun()
{
int *point;
int p = 12;
point=&p;
return point;
}
58
What happen here?
int *fun()
{
int *point;
*point=12; <<< Program is crashed here
return point;
}
In order to get rid from crashing we can write the same
function as follows;
int *fun()
{
int *point =
malloc (sizeof *point);
*point=12;
return point;
}
59. Pointers to Character Strings
• One of the most common applications of using a
pointer to an array is as a pointer to a character
string.
• The reasons are ones of notational convenience
and efficiency.
• To show how easily pointers to character strings
can be used, write a function called copyString to
copy one string into another.
59
60. Pointers to Character Strings (Cont…)
#include <stdio.h>
void copyString (char *, char *);
void copyString (char *to, char *from)
{
for ( ; *from != '0'; ++from, ++to )
*to = *from;
*to = '0';
}
int main (void)
{
char string1[] = "A string to be copied.";
char string2[50];
copyString (string2, string1);
printf ("%sn", string2);
copyString (string2, "So is this.");
printf ("%sn", string2);
return 0;
}
60
pointer to that constant
character string is passed
here.
Whenever a constant
character string is used
in C, it is a pointer to
that character string that
is produced.
61. Pointers to Character Strings (Cont…)
• So, if textPtr is declared to be a character
pointer, as in
char *textPtr;
then the statement
textPtr = "A character string.";
assigns to textPtr a pointer to the constant
character string "A character string."
61
62. Pointers to Character Strings (Cont…)
• Be careful to make the distinction here between
character pointers and character arrays, as the type of
assignment just shown is not valid with a character
array.
• So, for example, if text is defined instead to be an array
of chars, with a statement such as
char text[80];
then you could not write a statement such as
text = "This is not valid.";
• The only time that C lets you get away with performing
this type of assignment to a character array is when
initializing it, as in
char text[80] = "This is okay.";
62
63. Pointers to Character Strings (Cont…)
• If text is a character pointer, initializing text with the
statement
char *text = "This is okay.";
assigns to it a pointer to the character string "This is okay.“
• As another example of the distinction between character
strings and character string pointers, the following sets up an
array called days, which contains pointers to the names of the
days of the week.
char *days[] = { "Sunday", "Monday",
"Tuesday", "Wednesday", "Thursday",
"Friday","Saturday" };
• So days[0] contains a pointer to the character string
"Sunday", days[1] contains a pointer to the string "Monday",
and so on.
63
65. Objective Re-cap
• Now you should be able to:
▫ Define the C pointers and its usage in computer
programming.
▫ Describe pointer declaration and initialization.
▫ Apply C pointers for expressions.
▫ Experiment on pointer operations.
▫ Identify NULL pointer concept.
▫ Experiment on pointer to pointer, pointer arrays,
arrays with pointers and functions with pointers.
▫ Apply taught concepts for writing programs.
65