PF Deitel Deitel Chapter7
PF Deitel Deitel Chapter7
Umer Shahid
Department of Electrical Engineering,
UET Lahore
1 / 37
Overview
1. Introduction to Pointers
2 / 37
What is a Pointer?
3 / 37
Pointer Variable Declaration & Initialization
4 / 37
Pointer Operators
5 / 37
Demonstration of Pointer Operators
Example Code
1 # include < stdio .h >
2 int main () {
3 int a = 20;
4 int * p = & a ;
5 printf ( " Value of a : % d \ n " , a ) ;
6 printf ( " Address of a : % p \ n " , & a ) ;
7 printf ( " Pointer p stores address : % p \ n " , p ) ;
8 printf ( " Value at address stored in p : % d \ n " , * p ) ;
9 return 0;
10 }
11
6 / 37
More Examples on Pointers
7 / 37
Why Pass by Reference?
8 / 37
Passing Arguments to Functions by Reference
• Uses pointers to pass variables by reference.
• Changes inside the function reflect in the caller.
Example: Swapping Two Numbers
1 # include < stdio .h >
2 void swap ( int *a , int * b ) {
3 int temp = * a ;
4 *a = *b;
5 * b = temp ;
6 }
7 int main () {
8 int x = 5 , y = 10;
9 printf ( " Before swap : x = %d , y = % d \ n " , x , y ) ;
10 swap (& x , & y ) ;
11 printf ( " After swap : x = %d , y = % d \ n " , x , y ) ;
12 return 0;
13 }
14
9 / 37
Passing Arrays by Reference
• Arrays are always passed by reference in C.
• Function receives the base address of the array.
Example: Modifying Array Elements
1 # include < stdio .h >
2 void modifyArray ( int arr [] , int size ) {
3 for ( int i = 0; i < size ; i ++) {
4 arr [ i ] *= 2;
5 }
6 }
7 int main () {
8 int numbers [] = {1 , 2 , 3 , 4 , 5};
9 int size = sizeof ( numbers ) / sizeof ( numbers [0]) ;
10 modifyArray ( numbers , size ) ;
11 for ( int i = 0; i < size ; i ++) {
12 printf ( " % d " , numbers [ i ]) ;
13 }
14 return 0;
10 / 37
Pass by Value vs Pass by Reference
• Pass by Value: Function gets a copy of the variable, changes do not affect the caller.
• Pass by Reference: Function gets the memory address, changes reflect in the caller.
11 / 37
Example: Pass by Value vs Pass by Reference
Demonstration Code
1 # include < stdio .h >
2 void passByValue ( int x ) {
3 x = 100;
4 }
5 void passByReference ( int * x ) {
6 * x = 100;
7 }
8 int main () {
9 int a = 10 , b = 10;
10 passByValue ( a ) ;
11 passByReference (& b ) ;
12 printf ( " After passByValue : a = % d \ n " , a ) ;
13 printf ( " After passByReference : b = % d \ n " , b ) ;
14 return 0;
15 }
16
12 / 37
Why Use const with Pointers?
13 / 37
Different Types of Pointers with const
14 / 37
Non-constant Pointer to Non-constant Data
Example
1 # include < stdio .h >
2 int main () {
3 int x = 10 , y = 20;
4 int * ptr = & x ;
5 * ptr = 30; // Allowed
6 ptr = & y ; // Allowed
7 printf ( " x = %d , y = % d \ n " , x , y ) ;
8 return 0;
9 }
10
15 / 37
Constant Pointer to Non-constant Data
Example
1 # include < stdio .h >
2 int main () {
3 int x = 10;
4 int * const ptr = & x ;
5 * ptr = 20; // Allowed
6 // ptr = & y ; // Not allowed ( uncommenting will cause an error )
7 printf ( " x = % d \ n " , x ) ;
8 return 0;
9 }
10
16 / 37
Non-constant Pointer to Constant Data
Example
1 # include < stdio .h >
2 int main () {
3 int x = 10 , y = 20;
4 const int * ptr = & x ;
5 // * ptr = 30; // Not allowed ( uncommenting will cause an error )
6 ptr = & y ; // Allowed
7 printf ( " y = % d \ n " , * ptr ) ;
8 return 0;
9 }
10
17 / 37
Constant Pointer to Constant Data
Example
1 # include < stdio .h >
2 int main () {
3 int x = 10;
4 const int * const ptr = & x ;
5 // * ptr = 20; // Not allowed ( uncommenting will cause an error )
6 // ptr = & y ; // Not allowed ( uncommenting will cause an error )
7 printf ( " x = % d \ n " , * ptr ) ;
8 return 0;
9 }
10
18 / 37
Using sizeof with Pointers
• The sizeof operator returns the memory size (in bytes) of a variable or data type.
• It can be used with pointers to determine the size of the pointer itself and the data it
points to.
Example
1 # include < stdio .h >
2 int main () {
3 int * ptr ;
4 printf ( " Size of pointer : % lu \ n " , sizeof ( ptr ) ) ;
5 printf ( " Size of int : % lu \ n " , sizeof (* ptr ) ) ;
6 return 0;
7 }
8
19 / 37
Pointer Arithmetic
Example
1 # include < stdio .h >
2 int main () {
3 int arr [] = {10 , 20 , 30 , 40};
4 int * ptr = arr ;
5 printf ( " First value : % d \ n " , * ptr ) ;
6 ptr ++;
7 printf ( " Second value : % d \ n " , * ptr ) ;
8 return 0;
9 }
10
20 / 37
Pointer Arithmetic Operators
• ptr + n moves the pointer forward by n elements.
• ptr - n moves the pointer backward by n elements.
• ptr2 - ptr1 computes the number of elements between two pointers.
Example
1 # include < stdio .h >
2 int main () {
3 int arr [] = {5 , 10 , 15 , 20};
4 int * ptr1 = & arr [0];
5 int * ptr2 = & arr [3];
6 printf ( " Distance : % ld \ n " , ptr2 - ptr1 ) ;
7 return 0;
8 }
9
21 / 37
Assigning Pointers
• One pointer can be assigned to another if they are of the same type.
• Useful for traversing arrays and managing dynamic memory.
Example
1 # include < stdio .h >
2 int main () {
3 int a = 10 , b = 20;
4 int * ptr1 = &a , * ptr2 = & b ;
5 ptr1 = ptr2 ;
6 printf ( " Value of ptr1 : % d \ n " , * ptr1 ) ;
7 return 0;
8 }
9
22 / 37
Pointers and Arrays
Example
1 # include < stdio .h >
2 int main () {
3 int arr [] = {10 , 20 , 30};
4 int * ptr = arr ;
5 printf ( " First element : % d \ n " , * ptr ) ;
6 printf ( " Second element : % d \ n " , *( ptr + 1) ) ;
7 return 0;
8 }
9
23 / 37
Pointer Offset Notation
Example
1 # include < stdio .h >
2 int main () {
3 int arr [] = {5 , 15 , 25};
4 printf ( " Using array subscript : % d \ n " , arr [1]) ;
5 printf ( " Using pointer offset : % d \ n " , *( arr + 1) ) ;
6 return 0;
7 }
8
24 / 37
Copying Arrays: Different Methods
25 / 37
Copying with Array Subscript Notation
Example
1 # include < stdio .h >
2 void copyArray ( int dest [] , int src [] , int size ) {
3 for ( int i = 0; i < size ; i ++) {
4 dest [ i ] = src [ i ];
5 }
6 }
7 int main () {
8 int source [] = {1 , 2 , 3};
9 int destination [3];
10 copyArray ( destination , source , 3) ;
11 return 0;
12 }
13
26 / 37
Copying with Pointers
Example
1 # include < stdio .h >
2 void copyArray ( int * dest , int * src , int size ) {
3 for ( int i = 0; i < size ; i ++) {
4 *( dest + i ) = *( src + i ) ;
5 }
6 }
7 int main () {
8 int source [] = {4 , 5 , 6};
9 int destination [3];
10 copyArray ( destination , source , 3) ;
11 return 0;
12 }
13
27 / 37
Additional Examples on Pointer Arithmetic
Example
1 # include < stdio .h >
2 int main () {
3 int arr [] = {1 , 2 , 3 , 4 , 5};
4 int * ptr = arr ;
5 while ( ptr <= & arr [4]) {
6 printf ( " % d " , * ptr ) ;
7 ptr ++;
8 }
9 return 0;
10 }
11
28 / 37
Arrays of Pointers
Example
1 # include < stdio .h >
2 int main () {
3 const char * names [] = { " Alice " , " Bob " , " Charlie " };
4 printf ( " First name : % s \ n " , names [0]) ;
5 return 0;
6 }
7
29 / 37
Accessing Arrays of Pointers
Example
1 # include < stdio .h >
2 int main () {
3 const char * names [] = { " Alice " , " Bob " , " Charlie " };
4 for ( int i = 0; i < 3; i ++) {
5 printf ( " Name [% d ]: % s \ n " , i , names [ i ]) ;
6 }
7 return 0;
8 }
9
30 / 37
Function Pointers
Example
1 # include < stdio .h >
2 void greet () { printf ( " Hello !\ n " ) ; }
3 int main () {
4 void (* funcPtr ) () = greet ;
5 funcPtr () ;
6 return 0;
7 }
8
31 / 37
Passing Function Pointers to Functions
Example
1 # include < stdio .h >
2 void printMessage () {
3 printf ( " Executing function pointer !\ n " ) ;
4 }
5 void execute ( void (* func ) () ) {
6 func () ;
7 }
8 int main () {
9 execute ( printMessage ) ;
10 return 0;
11 }
12
32 / 37
Sorting with Function Pointers
• Function pointers allow dynamic selection of comparison functions.
Example
1 # include < stdio .h >
2 # include < stdlib .h >
3 int ascending ( const void *a , const void * b ) {
4 return (*( int *) a - *( int *) b ) ;
5 }
6 int descending ( const void *a , const void * b ) {
7 return (*( int *) b - *( int *) a ) ;
8 }
9 void printArray ( int arr [] , int size ) {
10 for ( int i = 0; i < size ; i ++) {
11 printf ( " % d " , arr [ i ]) ;
12 }
13 printf ( " \ n " ) ;
14 }
15
33 / 37
Sorting with Function Pointers
Example
1 # include < stdio .h >
2 # include < stdlib .h >
3 int main () {
4 int arr [] = {3 , 1 , 4 , 1 , 5};
5 qsort ( arr , 5 , sizeof ( int ) , ascending ) ;
6 printArray ( arr , 5) ;
7 qsort ( arr , 5 , sizeof ( int ) , descending ) ;
8 printArray ( arr , 5) ;
9 return 0;
10 }
11
34 / 37
Arrays of Function Pointers
• Store multiple function addresses in an array.
Example
1 # include < stdio .h >
2 void add () { printf ( " Addition \ n " ) ; }
3 void sub () { printf ( " Subtraction \ n " ) ; }
4 void mul () { printf ( " Multiplication \ n " ) ; }
5 int main () {
6 void (* operations [3]) () = { add , sub , mul };
7 for ( int i = 0; i < 3; i ++) {
8 operations [ i ]() ;
9 }
10 return 0;
11 }
12
35 / 37
Callback Functions with Function Pointers
Example
1 # include < stdio .h >
2 void sayHello () {
3 printf ( " Hello !\ n " ) ;
4 }
5 void executeCallback ( void (* callback ) () ) {
6 callback () ;
7 }
8 int main () {
9 executeCallback ( sayHello ) ;
10 return 0;
11 }
12
36 / 37
Function Pointers in Menu-Driven Programs
Example
1 # include < stdio .h >
2 void option1 () { printf ( " You selected Option 1\ n " ) ; }
3 void option2 () { printf ( " You selected Option 2\ n " ) ; }
4 int main () {
5 void (* menu []) () = { option1 , option2 };
6 int choice ;
7 printf ( " Enter option (0 or 1) : " ) ;
8 scanf ( " % d " , & choice ) ;
9 if ( choice >= 0 && choice < 2) menu [ choice ]() ;
10 else printf ( " Invalid choice !\ n " ) ;
11 return 0;
12 }
13
37 / 37