0% found this document useful (0 votes)
739 views54 pages

Data Structures Power Point Presentation

Pointers are variables that store memory addresses. They allow indirect access to values stored at those addresses. Pointer variables must be declared with a data type and initialized by assigning the address of another variable before they can be used. Dereference operators (*) are used to access the value stored at the address a pointer points to. Pointers enable dynamic memory allocation and are useful for implementing data structures like linked lists.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
739 views54 pages

Data Structures Power Point Presentation

Pointers are variables that store memory addresses. They allow indirect access to values stored at those addresses. Pointer variables must be declared with a data type and initialized by assigning the address of another variable before they can be used. Dereference operators (*) are used to access the value stored at the address a pointer points to. Pointers enable dynamic memory allocation and are useful for implementing data structures like linked lists.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 54

Data Structures

IS0403
Pointers
Introduction
 Pointer is a derived data type, built from one of the
fundamental data types available in C.
 Pointers are variables that contain memory addresses as their
values.
 A variable name directly references a value.
 A pointer indirectly references a value. Referencing a value
through a pointer is called indirection.
 A pointer variable must be declared before it can be used.
 Pointer is used to access and manipulate data stored in
memory
Benefits of Pointers
 More efficient in handling arrays and data tables
 Used to return multiple values from a function via function argument
 Permit references to functions and there by facilitating passing of
functions as arguments to other functions.
 Support dynamic memory management
 Provide an efficient tool for manipulating dynamic data structures
such as structures, linked lists, queues, stacks and trees.
 Reduce length and complexity of programs.
 Increase execution speed and thus reduce execution time.
Understanding Pointers
 Computer memory is a sequential collection of storage
cells.
 Each cell known as byte, has a number called address
associated with it.
 Addresses are numbered consecutively, starting from zero.
 Last address depends on the memory size.
 When a variable is declared ,the system allocates
somewhere in the memory an appropriate location to hold
the value of the variable.
Cont . . .
 Example:
int number = 229;
 Statement instructs the system to find a location for the integer variable
number, and put the value 229. (assume 5000 as address)
 During execution, the system always associates the name number with the
address 5000.
 May access the value 229 using name or address.
 As memory address are simply numbers, can be assigned to some variables,
that can be stored in memory.
 Variables that hold memory addresses are called pointer variables.
Cont . . .
 Pointer variable is nothing but a variable that contains
address, which is a location of another variable in memory.
 Since a pointer is a variable, its value is also stored in the
memory in another location
 If we assign the address of number to a variable p.
 The link between p and number is

Variable Value Address


number 229 5000
p 5000 5048
Cont . . .
 The value of p is the address of number, we may access the
value of number by using the value of p
 Therefore we say the variable p points to variable number,
thus p gets the name pointer
Underlying concepts of pointers
 Pointers are built on the three concepts.
• Pointer Constants
• Pointer Values
• Pointer Variables
 Memory addresses within a computer are referred to as pointer constants,
cannot change them, can only use them.
 Cannot save the value of a memory address directly, can only obtain the
value through the variable stored there using the address operator (&).
 Value thus obtained is known as pointer value, may change from one run to
another.
 Pointer value can be stored into another variable.
 The variable that contains a pointer value is called a pointer variable
Accessing the Address of a Variable
 Actual location of a variable in the memory is system dependent.
 Address of a variable is not known immediately.
 Address of a variable can be obtained with the help of & operator.
 The & operator immediately preceding a variable returns the address of the
variable associated with it.
 Example:
p = &quantity;
• Will assign the address 5000(location of quantity) to the variable p
• The & operator can be remembered as ‘address of ’.
Cont . . .
 & operator can be used only with a simple variable or an
array element.
 Following are illegal use of address operator.
• &125
• Pointing at constants
• int x[10];
&x
• Pointing at array names
• &(x+y)
• Pointing at expressions
 If x is an array, expression such as &x[0] and &x[i+3] are valid
 Represents the addresses of 0th and (i+3)th elements of x
Declaring pointer variables
 Every variable must be declared for its type.
 As pointer variables contain addresses that belong to a
separate data type, they must be declared as pointers before
using them.
 Syntax:
data_type *pt_name;
• The asterisk (*) tells that the variable pt_name is a pointer variable
• pt_name needs a memory location
• pt_name points to a variable of type data_type
Cont . . .
 Example:
int *p; // integer pointer
• Declares the variable p as a pointer variable that points to an
integer data type.
• The type int refers to the data type of the variable being pointed
to by p
• Not the type of the value of the pointer
float *x; // float pointer
• declares x as a pointer to a floating point variable.
 Declaration cause the compiler to allocate memory locations for the
pointer variables p and x.
 As memory locations have not been assigned any values, these
locations may contain some unknown values
Pointer declaration style
 Pointer variable are declared similarly as normal variables
except for the addition of unary * operator.
 This symbol can appear anywhere between the type name
and the printer variable name
 Different styles are
int* p;
int *p; //popular usage
int * p;
Initialization of pointer variable
 Process of assigning the address of a variable to a pointer variable is
known as initialization.
 Uninitialized pointers will have some unknown values that will be
interpreted as memory addresses.
 Programs with uninitialized pointers will produce erroneous results.
 So it is important to initialize pointer variables carefully before they
are used in the program.
 Example:
int quantity; int *p; p=&quantity; or
int *p = &quantity; //quantity must be declared before use
Cont . . .
 Example:
float a, b;
int x, *p;
p = &a;
b = * p;
 Will result in erroneous output
 Because we are trying to assign the address of a float
variable to an integer pointer.
 Also possible to combine the declaration of data variable,
pointer variable and initialization of the pointer variable in
one step
 Example: int x, *p = &x;
Pointer Flexibility
 Pointers are flexible
 Can make the same pointer to point to different data
variables in different statements.
 Example:
int x, y, z, *p;
.......
p = &x;
.......
p = &y;
.......
p = &z;
Cont . . .
 Can also use different pointers to point to the same
variable.
 Example:
int x;
int *p1 = &x;
int *p2 = &x;
int *p3 = &x;
.......
.......
Accessing a variable through its pointer
 Once a pointer has been assigned the address of a variable,
how to access the value of the variable using the pointer?
 It is done by using unary operator *, known as the
indirection operator, also called as dereferencing operator.
 * can be remembered as value at address.
 Example:
int quantity, *p, n;
quantity = 179;
p = &quantity;
n = *p;
Cont . . .
 Statements p = &quantity;
n = *p;
 Is equivalent to n = *&quantity;
 In turn equal to n = quantity;
 Assignment of pointers and addresses is always done
symbolically.
 Cannot access the value stored at address 5368 by writing
*5368
 Program shows how we can change the value of a variable
indirectly using a pointer and the indirection operator.
Chain of pointers
 Possible to make a pointer to point to another pointer.
 Thus creating a chain of pointers.
p2 p1 Variable

Address 2 Address 1 Value


 The pointer variable p2 contains the address of pointer
variable p1, which points to the location that contains the
desired value.
 This is know as multiple indirections.
Cont . . .
 Variable that is a pointer to a pointer must be declared
using additional indirection operator symbol.
 Example: int **p2;
 This declaration tells the compiler that p2 is a pointer to a
pointer of int type
 Pointer p2 is not a pointer to an integer, but rather a
pointer to an integer pointer.
Pointer Expressions
 Pointer variables can be used in expressions.
 Example:
• If p1 and p2 are properly declared and initialized pointers, then
the following statements are valid
y = *p1 * *p2;
sum = sum + *p1;
z = 5 * - *p2/ *p1;

z = (5 * (- (*p2)))/ (*p1);
*p2 = *p2 + 10;
Cont . . .
z = 5 * - *p2 /*p1;  is valid or invalid???
 /* means beginning of comment, so statement is invalid.
 Expressions like p1 + 4, p2 – 2, p1 – p2 are all allowed and
valid.
 If p1 and p2 are both pointers to the same array, then p2 –
p1 gives the number of elements between p1 and p2.
 Shorthand operators can be used with pointers.
• Example: p1++; -p2; sum += *p2;
Cont . . .
 Pointers can also be compared using relational operators.
• Example: p1 > p2; p1 == p2; p1 != p2;
 We may not use pointers in division or multiplication
• Example: p1 / p2 or p1 * p2 or p1 / 3 are not allowed
 Two pointers cannot be added.
• Example: p1 + p2 is illegal
Pointer Increments and Scale Factor
 Pointers can be incremented like
p1 = p2 + 2; p1 = p1 + 1;
 However an expression like p1++; will cause the pointer
p1 to point to the next value of its type.
 Example:
• If p1 is an integer pointer with an initial value of 2800, after increment
its value will be 2802 and not 2801.
• When a pointer is incremented, its value is incremented by the length of
the data type that it points to, called as scale factor.
 Number of bytes used to store various data types depends on the
system and can be found by using sizeof operator
Rules of Pointer Operations
 Pointer variable can be
• Assigned the address of another variable
• Assigned the values of another pointer variable
• Initialized with NULL or zero value
• Pre-fixed or post fixed with increment or decrement operator
• Integer value may be added or subtracted from a pointer variable
• Pointer variable cannot be multiplied by a constant
• Two pointer variables cannot be added
• Value cannot be assigned to an arbitrary address(&x=10; is illegal)
• When two pointer point to the same array, one pointer variable can be
subtracted from another.
• When two pointers point to the objects of the same data types, they can be
compared using relational operator.
Pointers and arrays
 When an array is declared, the compiler allocates a base address and
sufficient amount of storage to contain all the elements of the array
in contiguous memory locations.
 Base address is the location of the first element of the array.
 Compiler also defines the array name as a constant pointer to the first
element.
 Example:
int x[5] = { 1, 2, 3, 4, 5 };
Elements  x[0] x[1] x[2]x[3] x[4]
Value 
Address 1000 1002 1004 1006 1008
1 2 3 4 5

Base Address
Cont . . .
 x is defined as a constant pointer pointing to the first element x[0]
 Therefore the value of x is 1000, the location where x[0] is stored.
Ex: x = &x[0] = 1000
 If p is declared as an integer pointer, then pointer p is pointed to the
array x by
p = x;  p = &x[0];
 Every value of x can be accessed by using p++, to move from one
element to another.
Ex: address of x[3] = base address + (3 * scale factor of int)
= 1000 + (3 * 2) = 1006
Cont . . .
 When handling arrays, instead of using array indexing,
pointers can be used to access array elements.
 * (p + 3) gives the value of x[3].
 The pointer accessing method is much faster than array
indexing.
Cont . . .
 Pointers can be used to manipulate two dimensional arrays
as well.
 In one dimensional array x, the expression *(x +i) or *(p+i)
represents the element x[i]
 Similarly an element in a two dimensional array can be
represented by the pointer expression
* ( * ( a + i ) + j ) or * ( * ( p + i ) + j )
Cont . . .
Columns
0 1 2 3 4 5
0 p
1 p+1
Rows 2
3
4 4,0 4,3 p+4
5
6 p+6
* (p + 4) * (p + 4) + 3
p  pointer to first row p + i  pointer to ith row
*(p + i)  pointer to first element in ith row
*(p + i) +j  pointer to jth element in ith row
* ( *(p + i) + j)  value stored in the cell (i, j)
Cont . . .
 The base address of the array a is &a[0][0] and starting at
this address, the compiler allocates contiguous space for all
the elements row-wise.
 First element of the second row is placed immediately after
the last element of the row and so on.
 If array a is declared as follows:
int a[3][4] = { {15,27,11,35}
{22,19,31,17}
{31,23,14,36}};
Cont . . .
 Then elements of a is stored as:
row 0 row 1 row 2
15 27 11 35 22 19 31 17 31 23 14 36

address = & a[0][0]


 If we declare p as an int pointer with the initial address of &a[0][0],
then a[i][j] is equal to *(p+4 x i+j)
 If we increment i by 1, p is incremented by 4, size of each row.
 When a two dimensional array is declared, it is essential to specify the
size of each row so that the compiler can determine correct storage
mapping.
Array of Pointers
 Important use of pointers is in handling of a table of
strings.
 Consider the following array of strings:
char name [3] [25];
 This tells that the name is a table containing three names,
each with a maximum length of 25 characters (including
null character)
 Total storage requirements for the name table is 75 bytes.
 Each individual strings are rarely equal, so the pointer to a
string can be of varying length.
Cont . . .
Example: char *name[3] = { “New Zealand”,
“Australia”, “India” };
 Declares name to be an array of three pointers to
characters, each pointer pointing to a particular name as:
name[0]  New Zealand
name[1]  Australia
name[2]  India
This declaration allocates only 28 bytes, sufficient to hold all
the characters, including null character (\0)
Cont . . .
 Following statement would print all the three names:
for ( i=0; i<=2; i++ )
printf (“%s\n”,name [i]);
 To access the jth character in the ith name, the statement
* (name [i] + j) is used.
 Character arrays with the rows of varying length are called
ragged arrays and are better handled by pointers.
Pointers as Function Arguments
 When an array is passed to a function as an argument, only the
address of the first element of the array is passed, but not the
actual values of the array element.
 If x is an array, when sort(x) is called, the address of x[0] is
passed to the function sort.
 Function uses this address for manipulating the array elements.
 When addresses is passed to a function, the parameters
receiving the addresses should be pointers.
 Process of calling a function using pointers to pass the
addresses of variables is known as ‘call by reference’
 Function which is called by reference can change the
value of the variable used in the call.
Cont . . .
 Example:
main( )
{ int x; x =20;
change (&x);
printf (“%d\n”,x);
}
change ( int *p)
{ *p = *p + 10;
}
Cont . . .
 When the function change ( ) is called, the address of the variable x, is passed into
the function change( ), not its value.
 Inside change ( ), the variable p is declared as a pointer and therefore P is the
address of the variable x.
 Statement *p = *p + 10;
• Means, add 10 to the value stored at the address p.
• Because p represents the address of x, the value of x is changed from 20
to 30.
• So the output will be 30 not 20.
 Call by reference provides a mechanism by which the function can
change the stored values in the calling function.
 This mechanism is known as call by address or pass by pointers.
Cont . . .
 Points to remember:
• Function parameters are declared as pointers
• Dereferenced pointers are used in the function body
• When the function is called, the addresses are passed as actual
arguments.
Functions Returning Pointers
 Function can return a single value by its name or return
multiple values through pointer parameters.
 As pointers are a data type in C, a function can be forced to
return a pointer to the calling function .

 Function larger receives the addresses of the variables a and b,


decides which one is larger using the pointers x and y and then
returns the address of its location.
 Returned value is then assigned to the pointer variable p in the calling
function.
Cont . . .
 So the address of b is returned and assigned to p.
 Therefore the output will be the value of b, i.e 20.
 The address returned must be the address of a variable in
the calling function.
 It is an error to return a pointer to a local variable in the
called function.
Pointers To Functions
 A function, like a variable, has a type and an address
location in the memory
 Therefore it is possible to declare a pointer to a function
which can then be used as an argument in another function.
 Pointer to a function is declared as follows:
type (*fptr) ( );
 Tells the compiler that fptr is a pointer to a function, which
returns type value.
 Can make a function pointer to point to a specific function
by simply assigning the name of the function to the
pointer.
Cont . . .
 Example:
double mul (int, int);
double (*p1) ( );
p1 = mul;
• Declare p1 as a pointer to a function
• mul as a function and then make p1 to point to the function mul
• To call the function mul, use the pointer p1 with the list of
parameters.
(*p1) (x, y) or mul (x, y)
Compatibility and Casting
 Variable declared as a pointer is not just a pointer type variable.
 It is also a pointer to a specific fundamental data type, such as a
character.
 Pointer always has a type associated with it.
 Cannot assign a pointer of one type to another, known as
incompatibility of pointers.
 An exception is the void pointer (void *), which is a generic
pointer that can represent any pointer type.
 All pointer types can be assigned to void pointer and vice versa
without casting.
 Created void *vp; it cannot be dereferenced
Troubles with Pointers
 Pointers give tremendous power and flexibility.
 They become nightmare if not used correctly.
 Major problem is, the compiler may not detect error and
therefore the program gives unexpected results.
 Assigning values to uninitialized pointers
int * p, m=100; *p=m; //error
 Assigning values to a pointers variable
int *p, m=100; p=m; //error
 Not dereferencing a pointer when required
int *p, x=100; p=&x; printf (“%d”, p); //error
 Assigning the address of an uninitialized variable
int m, *p; p=&m; //error
Dynamic Memory Allocation
 When the number of data items keeps changing during
execution, dynamic allocation is used.
 Required number of memory blocks can be obtained from the
heap.
 Heap is a memory, which is available to the user.
 Getting a block of memory and returning to the free pool
(availability) can be done by taking services of memory related
functions such as malloc(), calloc(), realloc(), free().
 Process of allocating memory space at run time when required
is known as dynamic memory allocation.
Cont . . .

Function Task
Allocates request size of bytes and returns a pointer to
malloc the first byte of the allocated space

Allocates space for an array of elements, initializes


calloc them to zero and then returns a pointer to the memory

free Frees previously allocated space


Modifies the size of previously allocated space
realloc
Allocating a block of memory: malloc
 A block of memory may be allocated using the function malloc.
 This reserves a block of memory of specified size and returns a
pointer of type void, means this can be assigned to any type of
pointer.
 Syntax:
ptr = (cast–type *) malloc (byte-size);
• ptr is a pointer of type cast–type.
• malloc returns a pointer to an area of memory with size byte–size
 Example:
x = (int *) malloc ( 100 * sizeof (int));
Allocating multiple blocks of memory: calloc
 calloc is another memory allocation function, normally
used for requesting memory space at run time for storing
derived data type such as arrays and structures.
 calloc allocates multiple blocks of storage, of same size,
and sets all bytes to zero.
 Syntax:
ptr = (cast–type *) calloc (n, elem-size);
• Allocates contiguous space for n blocks, each of size elem-size
bytes.
• All bytes are initialized to zero and a pointer to the forst byte of
the allocated region is returned.
Releasing the used space: free
 Compile time storage of a variable is allocated and released by
the system with its storage class.
 With the dynamic run time allocation, it is our responsibility to
release the space when it is not required.
 Data stored in a block of memory is not needed in future, that
block is released for future use, by using free function.
 Syntax:
free (ptr);
• ptr is a pointer to a memory block, which has already been created
by malloc of calloc.
Altering the size of a block: realloc
 It is likely to be discovered later, that allocated memory is not
sufficient and more space is needed.
 Also possible that the memory allocated is much larger than required,
so needs to be reduced.
 In both cases, memory size already allocated can be changed with the
help of the function realloc, process is called as reallocation of
memory.
 Syntax:
ptr = malloc (size);
ptr = realloc ( ptr, newsize);
• Allocates a new memory space of size newsize to the ptr and returns
a pointer to the first byte of the new memory block.
• newsize may be larger or smaller than the size

You might also like