You are on page 1of 119

C Programming Pointer Overview:

Consider above Diagram which clearly shows pointer concept in c programming –

1. i is the name given for particular memory location of ordinary variable.

2. Let us consider it‘s Corresponding address be 65624 and the Value stored in

variable „i‟ is 5

3. The address of the variable „i‟ is stored in another integer variable whose

name is „j‟ and which is having corresponding address 65522

thus we can say that –

j =&i;

i.e.

j = Address of i

Here j is not ordinary variable; it is special variable and called pointer variable as it

stores the address of another ordinary variable. We can summarize it like –

1
Variable Name Variable Value Variable Address

I 5 65524

J 65524 65522

#include <stdio.h>
intmain()
{
int*ptr, i;
i =11;

/* address of i is assigned to ptr */


ptr =&i;

/* show i's value using ptr variable */


printf("Value of i : %d",*ptr);

return0;
}

You will get value of i = 11 in the above program.

Pointer Declaration Tips:

1. Pointer is declared with preceding *:

int *ptr; //Here ptr is Integer Pointer Variable

int ptr; //Here ptr is Normal Integer Variable

2. Whitespace while Writing Pointer:

2
pointer variable name and asterisk can contain whitespace because whitespace is

ignored by compiler.

int*ptr;

int* ptr;

int* ptr;

All the above syntax are legal and valid. We can insert any number of spaces or

blanks inside declaration. We can also split the declaration on multiple lines.

Key points for Pointer:

1. Unlike ordinary variables pointer is special type of variable which stores the

address of ordinary variable.

2. Pointer can only store the whole or integer number because address of any

type of variable is considered as integer.

3. It is good to initialize the pointer immediately after declaration

4. & symbol is used to get address of variable

5. * symbol is used to get value from the address given by pointer.

Pointer Summary:

1. Pointer is Special Variable used to Reference and de-reference memory.

(*Will be covered in upcoming chapter)

2. When we declare integer pointer then we can only store address of integer

variable into that pointer.

3
3. Similarly if we declare character pointer then only the address of character

variable is stored into the pointer variable.

Pointer storing the address of following DT Pointer is called as

Integer Integer Pointer

Character Character Pointer

Double Double Pointer

Float Float Pointer

Understanding pointers in c?

In the previous chapter we have learnt about Basic Concept of Pointer. In this

chapter we are looking more into pointer.

We know that –

1. Pointer is a variable which stores the address of another variable

2. Since Pointer is also a kind of variable , thus pointer itself will be stored at

different memory location.

2 Types of Variables:

1. Simple Variable that stores a value such as integer, float, character

2. Complex Variable that stores address of simple variable i.e. pointer variables

Example #1:

#include<stdio.h>
4
intmain()
{
int a =3;
int*ptr;
ptr =&a;
return(0);
}
Explanation of Example:

Point Variable 'a' Variable 'ptr'

Name of Variable A ptr

Type of Value that it holds Integer Address of Integer 'a'

Value Stored 3 2001

Address of Variable 2001 (Assumption) 4001 (Assumption)

Example #2:

#include<stdio.h>
intmain()
{
int a =3;
int*ptr,**pptr;
ptr =&a;
pptr = &ptr;
return(0);
}

5
Explanation of Example

With reference to above program –

We have following associated points –

Variable Variable Variable


Point
'a' 'ptr' 'pptr'

Name of Variable a Ptr pptr

Type of Value that it


Integer Address of 'a' Address of 'ptr'
holds

Value Stored 3 2001 4001

Address of Variable 2001 4001 6001

Pointer address operator in C Programming

1. Pointer address operator is denoted by ‗&‘ symbol

2. When we use ampersand symbol as a prefix to a variable name ‗&‘, it gives

the address of that variable.

6
lets take an example –

&n - It gives an address on variable n

Working of address operator

#include<stdio.h>
voidmain()
{
int n =10;
printf("\nValue of n is : %d",n);
printf("\nValue of &n is : %u",&n);
}
Output:

Value of n is: 10

Value of &n is: 1002

Consider the above example, where we have used to print the address of the

variable using ampersand operator.

In order to print the variable we simply use name of variable while to print the

address of the variable we use ampersand along with %u

printf("\nValue of &n is : %u",&n);

Understanding address operator

Consider the following program –

#include<stdio.h>
int main()
{
int i =5;
7
int*ptr;
ptr =&i;
printf("\nAddress of i : %u",&i);
printf("\nValue of ptr is : %u",ptr);
return(0);
}
After declaration memory map will be like this –

int i =5;

int*ptr;

after Assigning the address of variable to pointer , i.e after the execution of this

statement –

ptr =&i;

Invalid Use of pointer address operator

Address of literals

8
In C programming using address operator over literal will throw an error. We cannot

use address operator on the literal to get the address of the literal.

&75

Only variables have an address associated with them, constant entity does not have

corresponding address. Similarly we cannot use address operator over character

literal –

&('a')

Character ‗a‘ is literal, so we cannot use address operator.

Address of expressions

(a+b) will evaluate addition of values present in variables and output of (a+b)is

nothing but Literal, so we cannot use Address operator

&(a+b)

Memory Organization for Pointer Variable:

1. When we use variable in program then Compiler keeps some memory for

that variable depending on the data type

2. The address given to the variable is Unique with that variable name

3. When Program execution starts the variable name is automatically

translated into the corresponding address.

9
Explanation:

1. Pointer Variable is nothing but a memory address which holds another

address.

2. In the above program ―i‖ is name given for memory location for

human understanding, but compiler is unable to recognize ―i‖. Compiler

knows only address.

How much Memory required to store Pointer variable?

1. Pointer Variable Stores the address of the variable

2. Variable may be integer, character, float but the address of the variable

is always integer so Pointer requires 2 bytes of memory in Turbo C

Compiler.

3. If we run same program in any other IDE then the output may differ.

4. This requirement is different for different Compilers

Program 1: Size of Integer Pointer

#include<stdio.h>
intmain()
{
int a =10,*ptr;
ptr =&a;
10
printf("\nSize of Integer Pointer : %d",sizeof(ptr));
return(0);
}
Output :

Size of Integer Pointer:2

Program 2 : Size of Character Pointer

#include<stdio.h>
intmain()
{
char a ='a',*cptr;
cptr =&a;
printf("\nSize of Character Pointer : %d",sizeof(cptr));
return(0);
}
Output :

Size of Character Pointer:2

Program 3 : Size of Float Pointer

#include<stdio.h>
intmain()
{
float a =3.14,*fptr;
fptr =&a;
printf("\nSize of Character Pointer : %d",sizeof(fptr));
return(0);
}
Output :

11
Size of Float Pointer: 2

Size of Pointer variable in C

Pointer is the variable that stores the address of another variable.

Size calculation

Consider the following memory map before declaring the variable.In the memory

comprise of blocks of 1 byte.

Whenever we declare any variable then random block of memory is chosen and

value will be stored at that memory location.

Similarly whenever we declare any pointer variable then random block of memory

will be used as pointer variable which can hold the address of another variable.

Program

#include<stdio.h>
12
intmain()
{
int*iptr =NULL;
float*fptr =NULL;
char*cptr =NULL;

printf("\nSize of Integer Pointer : %d Bytes",sizeof(iptr));


printf("\nSize of Character Pointer : %d Bytes",sizeof(cptr));
printf("\nSize of Float Pointer : %d Bytes",sizeof(fptr));

return0;
}
Output :

Size of Integer Pointer:4 Bytes

Size of Character Pointer:4 Bytes

Size of Float Pointer:4 Bytes

Explanation

1. Pointer stores the address of the Variable.

2. Size of Pointer Variable can be evaluated by using sizeof operator

3. Address of variable is considered as integer value.

4. For Borland C/C++ Compiler, for storing integer value 2 bytes are required.

5. Thus Pointer variable requires 2 bytes of memory.

Size of pointer in different IDE

13
Compiler Size of Integer Size of Integer Pointer

Borland C/C++ 2 Bytes 2 Bytes

Turbo C/C++ 2 Bytes 2 Bytes

Visual C++ 4 Bytes 4 bytes

Pointer Program : Size of Integer Far Pointer

Program :

#include<stdio.h>
intmain(){
intfar *ptr;
printf("Size of Integer Far Pointer : %d",sizeof(ptr));
return(0);
}
Output :

Size of IntegerFar Pointer:4

Pointer Program : Size of Pointer to Structure

Program :

#include<stdio.h>
typedefstructXYZ{
intfar *fptr;
doubledvar;
unsignedcharch;
}xyz;

14
intmain(){
xyz *ptr=(XYZ *)1000;
printf("Size of Pointer to structure : %d",sizeof(ptr));
return(0);
}
Output :

Size of Pointer tostructure:2

Pointer Operator in C Program:

Operator Operator Name Purpose

* Value at Operator Gives Value stored at Particular address

& Address Operator Gives Address of Variable

In order to create pointer to a variable we use ―*‖ operator and to find the address

of variable we use ―&‖ operator.

Don‘t Consider ―&‖ and ―*‖ operator as Logical AND and Multiplication Operator in

Case of Pointer.

Important Notes :

1. ‗&‘ operator is called as address Operator

2. „*‟ is called as „Value at address‟ Operator

3. ‗Value at address‟ Operator gives ‗Value stored at Particular address.

4. „Value at address‟ is also called as „Indirection Operator‟

Pointer Operators : Live Program

15
#include<stdio.h>
intmain()
{
int n =20;
printf("\nThe address of n is %u",&n);
printf("\nThe Value of n is %d",n);
printf("\nThe Value of n is %d",*(&n));
}
Output:

The address of n is 1002

The Value of n is 20

The Value of n is 20

How *(&n) is same as printing the value of n?

&n Gives address of the memory location whose name is ‗n‘

* means value at Operator gives value at address specified by &n.

m= Address of n is stored in m , but remember that m is not ordinary variable


&n like ‗n‘

So C compiler must provide space for it in memory. Below is Step by Step

Calculation to compute the value –

m = * ( &n )
= * ( Address of Variable 'n')
= * ( 1000 )
= Value at Address 1000
= 20
16
What Does following declaration tells compiler ?

int*ptr;

1. ‗ptr‘ is declared as that ‗ptr‘ will be used only for storing the address of the

integer valued variables

2. We can also say that ‗ptr‘ points to integer

3. Value at the address contained in ‗ptr‘ is integer .

Memory
Declaration Explanation
Required

p is going to store address of integer


1 int *p 2 bytes
value

q is going to store address of


2 float *q 2 bytes
floating value

ch is going to store address of


3 char *ch 2 bytes
character variable

Syntax for Pointer Declaration in C :

data_type *<pointer_name>;

Explanation:

data_type

 Type of variable that the pointer points to

 OR data type whose address is stored in pointer_name

Asterisk(*)
17
 Asterisk is called as Indirection Operator

 It is also called as Value at address Operator

 It Indicates Variable declared is of Pointer type

pointer_name

 Must be any Valid C identifier

 Must follow all Rules of Variable name declaration

Ways of Declaring Pointer Variable :

* can appears anywhere between Pointer_name and Data Type

int *p;
int * p;
int * p;
Example of Declaring Integer Pointer :

int n =20;

int*ptr;

Example of Declaring Character Pointer :

char ch ='A';

char*cptr;

Example of Declaring Float Pointer :

float fvar =3.14;

float*fptr;

How to Initialize Pointer in C Programming ?

18
pointer=&variable;

Above is the syntax for initializing pointer variable in C.

Initialization of Pointer can be done using following 4 Steps :

1. Declare a Pointer Variable and Note down the Data Type.

2. Declare another Variable with Same Data Type as that of Pointer Variable.

3. Initialize Ordinary Variable and assign some value to it.

4. Now Initialize pointer by assigning the address of ordinary variable to pointer

variable.

below example will clearly explain the initialization of Pointer Variable.

#include<stdio.h>
intmain()
{
int a;// Step 1
int*ptr;// Step 2
a =10;// Step 3
ptr =&a;// Step 4
return(0);
}

Explanation of Above Program :

 Pointer should not be used before initialization.

 ―ptr‖ is pointer variable used to store the address of the variable.

 Stores address of the variable „a‟ .

19
 Now ―ptr‖ will contain the address of the variable ―a‖ .

Note:

Pointers are always initialized before using it in the program

Example: Initializing Integer Pointer

#include<stdio.h>
intmain()
{
int a =10;
int*ptr;
ptr =&a;
printf("\nValue of ptr : %u",ptr);
return(0);
}

Output :

Value of ptr :4001

Dereferencing Pointer in C Programming Language :

1. Asterisk(*) indirection operator is used along with pointer variable while

Dereferencing the pointer variable.

2. Asterisk Operator is also called as value at operator

3. When used with Pointer variable, it refers to variable being pointed to,this is

called as Dereferencing of Pointers

What is Dereferencing Pointer ?

20
1. Dereferencing Operation is performed to access or manipulate data contained

in memory location pointed to by a pointer

2. Any Operation performed on the de-referenced pointer directly affects the

value of variable it pointes to.

Live Example : Dereferencing Pointer

// Sample Code for Dereferencing of Pointer


int n =50, x ;

int*ptr ;// Un-initialized Pointer

ptr =&n;// Stores address of n in ptr

x =*ptr;// Put Value at ptr in x


Evaluation :

// Sample Code for Dereferencing of Pointer

*(ptr)= value at (ptr)


= value at (2001)
=50

//Address in ptr is nothing but address of n


Summary:

1. Name of Normal Variable always points to the Value of variable

2. Pointer variable always Stores Address of variable

3. *ptr and num will give us same value.

21
Variable Value in it

num 50

&num 1002

ptr 1002

*ptr 50

Void Pointers in C: Definition

1. Suppose we have to declare integer pointer,character pointer and float

pointer then we need to declare 3 pointer variables.

2. Instead of declaring different types of pointer variable it is feasible to declare

single pointer variable which can act as integer pointer,character pointer.

Void Pointer Basics:

1. In C General Purpose Pointer is called as void Pointer.

2. It does not have any data type associated with it

3. It can store address of any type of variable

22
4. A void pointer is a C convention for a raw address.

5. The compiler has no idea what type of object a void Pointer really points to ?

Declaration of Void Pointer:

void * pointer_name;

Void Pointer Example :

void*ptr;// ptr is declared as Void pointer

char cnum;
int inum;
float fnum;

ptr =&cnum;// ptr has address of character data


ptr =&inum;// ptr has address of integer data
ptr =&fnum;// ptr has address of float data

Explanation:

void*ptr;

1. Void pointer declaration is shown above.

2. We have declared 3 variables of integer, character and float type.

3. When we assign address of integer to the void pointer, pointer will become

Integer Pointer.

4. When we assign address of Character Data type to void pointer it will

become Character Pointer.

5. Similarly we can assign address of any data type to the void pointer.
23
6. It is capable of storing address of any data type

Summary: void Pointer

Scenario Behavior

When We assign address of integer Void Pointer Becomes


variable to void pointer Integer Pointer

When We assign address of character Void Pointer Becomes


variable to void pointer Character Pointer

When We assign address of floating Void Pointer Becomes


variable to void pointer Floating Pointer

C dereferencing void pointer

Void Pointer is called as General Purpose Pointer.

Why it is necessary to use Void Pointer ?

Reason 1 : Re-usability of Pointer

float*ptr;
int num;

ptr =&num ;// Illegal Use of Pointer


In the above example we have declared float pointer which is of no use in the

program. We cannot use float pointer to store the integer pointer so So in order to

increase the re-usability of the Pointer it is necessary to declared pointer variable as

void Pointer.

Dereferencing Void Pointer:

24
Consider this example –

void*ptr;// ptr is declared as Void pointer


char cnum;
int inum;
float fnum;
Suppose we have assigned integer Address to void pointer then –

ptr =&inum;// ptr has address of integer data

then to De-reference this void pointer we should use following syntax –

*((int*)ptr)

Similarly we should use following for Character and float –

*((float*)ptr)// De-reference Float Value

*((char*)ptr)// De-reference Character Value

Following table will summarize all details –

Type of Address Stored in Void Dereferencing Void


Pointer Pointer

Integer *((int*)ptr)

Charcter *((char*)ptr)

Floating *((float*)ptr)

Live Example : Dereferencing Void Pointer

#include<stdio.h>
intmain()

25
{
int inum =8;
float fnum =67.7;
void*ptr;
ptr =&inum;
printf("\nThe value of inum = %d",*((int*)ptr));
ptr =&fnum;
printf("\nThe value of fnum = %f",*((float*)ptr));
return(0);
}
Output :

The value of inum =8

The value of fnum =67.7

Explanation : Void Pointer Program

ptr =&inum;

printf("\nThe value of inum = %d",*((int*)ptr));

Here we are assigning the address of integer variable to void pointer so that void

pointer can act as Integer pointer.

ptr =&fnum;

printf("\nThe value of fnum = %f",*((float*)ptr));

And now we are storing the address of floating point variable to void pointer , thus

void pointer becomes floating pointer.

What is the size of Void Pointer variable in C ?

Pointer :
26
Pointer is the variable that stores the address of another variable .

How to calculate size of Pointer ?

1. Size of Void Pointer can be evaluated by using sizeof operator

2. Pointer stores the address of the Variable .

3. Address of variable is nothing but the integer value .

4. In C , for storing integer value 2 bytes are required .

5. So void Pointer variable requires 2 bytes of memory.

int main(void)
{
int num = 0;
void *ptr;
num = 15;
ptr = &num;
/* Output the size */

printf("Size of Pointer : %d Bytes",sizeof(pointer));


return 0;
}

Output :

Size of Pointer : 2 Bytes

Address Arithmetic

Address arithmetic is a method of calculating the address of an object with

the help of arithmetic operations on pointers and use of pointers in comparison

operations. Address arithmetic is also called pointer arithmetic.

27
According to C and C++ language standards, the result address must remain

strictly within the bounds of a single array object (or just after it). Adding or

subtracting from a pointer moves it by a multiple of the size of the data type it

points to. For example, assume we have a pointer to an array of 4-byte integers.

Incrementing this pointer will increment its value by 4 (the size of the element).

This effect is often used to increment a pointer to point at the next element in a

contiguous array of integers.

Pointer arithmetic cannot be performed on void pointers because the void

type has no size, and thus the pointed address cannot be added to. However, there

are non-standard compiler extensions allowing byte arithmetic on void* pointers.

Pointers and integer variables are not interchangeable. Null constant is the

only exception from this rule: it can be assigned to the pointer, and the pointer can

be compared to null constant. As a rule, to show that null is a special value for the

pointer, NULL constant is written instead of number "0".

Pointer arithmetic provides the programmer with a single way of dealing with

different types: adding and subtracting the number of elements required instead of

the actual offset in bytes. In particular, the C definition explicitly declares that the

syntax A[i], which is the i-th element of the array A, is equivalent to *(A+i), which

is the content of the element pointed by A+i. This also implies that i[A] is

equivalent to A[i].

At the same time, powerful pointer arithmetic can be a source of errors. Address

arithmetic is a restrictive stage in the process of mastering 64-bit systems for the

old C/C++ program code can contain a lot of errors relating to the use of pointers.

28
To learn more about this problem see the article "20 issues of porting C++ code on

the 64-bit platform".

Because of the challenges of using pointers, many modern high level

computer languages (for example, Java or C#) do not permit direct access to

memory using addresses.

Pointer Arithmetic

Pointer arithmetic is very important to understand, if you want to have complete

knowledge of pointer. In this topic we will study how the memory addresses change

when you increment a pointer.

16 bit Machine ( Turbo C )

In a 16 bit machine, size of all types of pointer, be it int*, float*, char* or double*

is always 2 bytes. But when we perform any arithmetic function like increment on

a pointer, changes occur as per the size of their primitive data type.

Size of datatypes on 16-bit Machine :

Type Size(bytes)

int or signed int 2

Char 1

Long 4

Float 4

Double 8

29
long double 10

Examples for Pointer Arithmetic

Now lets take a few examples and understand this more clearly.

int* i;
i++;
In the above case, pointer will be of 2 bytes. And when we increment it, it will

increment by 2 bytes because intis also of 2 bytes.

float* i;
i++;
In this case, size of pointer is still 2 bytes. But now, when we increment it, it will

increment by 4 bytes becausefloat is of 4 bytes.

double* i;

i++;

Similarly, in this case, size of pointer is still 2 bytes. But now, when we increment

it, it will increment by 8 bytes because its data type is double.

32 bit Machine ( Visual Basic C++ )

The concept of pointer arithmetic remains exact same, but the size of pointer and

various data types is different in a 32 bit machine. Pointer in 32 bit machine is

of 4 bytes.

And, following is a table for Size of datatypes on 32-bit Machine :

30
Type Size(bytes)

int or signed int 4

Char 2

Long 8

Float 8

Double 16

Consider below table, We have declared some of the variables and also assumed

some address for declared variables.

Data Initial Address after Required


Operation
Type Address Operations Bytes

int 4000 ++ 4002 2

int 4000 -- 3998 2

char 4000 ++ 4001 1

char 4000 -- 3999 1

float 4000 ++ 4004 4

float 4000 -- 3996 4

long 4000 ++ 4004 4

long 4000 -- 3996 4

We can see address of an variable after performing arithmetic operations.

Expression Result

31
Expression Result

Address + Number Address

Address – Number Address

Address – Address Number

Address + Address Illegal

Above table clearly shows that we can add or subtract address and integer number

to get valid address. We can even subtract two addresses but we cannot add two

addresses. Here are some pointer tutorials on Arithmetic Operations –

Incrementing Pointer :

1. Incrementing Pointer is generally used in array because we have contiguous

memory in array and we know the contents of next memory location.

2. Incrementing Pointer Variable Depends Upon data type of the Pointer variable

Formula : ( After incrementing )

new value = current address + i * size_of(data type)

Three Rules should be used to increment pointer –

Address +1= Address


Address++= Address
++Address = Address

32
Pictorial Representation :

Data Older Address Next Address stored in pointer


Type stored in pointer after incrementing (ptr++)

int 1000 1002

float 1000 1004

char 1000 1001

Explanation : Incremeting Pointer

 Incrementing a pointer to an integer data will cause its value to be

incremented by 2.

 This differs from compiler to compiler as memory required to store

integer vary compiler to compiler

Note to Remember : Increment and Decrement Operations on pointer should be

used when we have Continues memory (in Array).

Live Example 1 : Increment Integer Pointer

#include<stdio.h>
intmain(){
int*ptr=(int*)1000;

33
ptr=ptr+1;
printf("New Value of ptr : %u",ptr);
return0;
}

Output :

New Value of ptr :1002

Live Example 2 : Increment Double Pointer

#include<stdio.h>
intmain(){
double*ptr=(double*)1000;
ptr=ptr+1;
printf("New Value of ptr : %u",ptr);
return0;
}

Output :

New Value of ptr :1004

Live Example 3 : Array of Pointer

#include<stdio.h>
intmain(){
float var[5]={1.1f,2.2f,3.3f};
float(*ptr)[5];
ptr=&var;
printf("Value inside ptr : %u",ptr);
ptr=ptr+1;
34
printf("Value inside ptr : %u",ptr);
return0;
}
Output :

Value inside ptr :1000


Value inside ptr :1020

Explanation :

Address of ptr[0] = 1000

We are storing Address of float array to ptr[0]. –

Address of ptr[1]

= Address of ptr[0] + (Size of Data Type)*(Size of Array)

= 1000 + (4 bytes) * (5)

= 1020

Address of Var[0]…Var[4] :

35
Address of var[0] = 1000

Address of var[1] = 1004

Address of var[2] = 1008

Address of var[3] = 1012

Address of var[4] = 1016

C decrementing pointer

Formula : ( After decrementing )

new_address =(current address)- i * size_of(data type)


Decrementation of Pointer Variable Depends Upon: data type of the Pointer variable

Example :

Data Older Address Next Address stored in pointer


Type stored in pointer after incrementing (ptr–)

int 1000 0998

float 1000 0996

char 1000 0999

Explanation :
36
 Decrementing a pointer to an integer data will cause its value to be

decremented by 2

 This differs from compiler to compiler as memory required to store integer

vary compiler to compiler

Pointer Program : Difference between two integer Pointers

#include<stdio.h>
intmain(){
float*ptr1=(float*)1000;
float*ptr2=(float*)2000;
printf("\nDifference : %d",ptr2-ptr1);
return0;
}
Output :

Difference :250

Explanation :

 Ptr1 and Ptr2 are two pointers which holds memory address of Float Variable.

 Ptr2-Ptr1 will gives us number of floating point numbers that can be stored.

ptr2 - ptr1 = (2000 - 1000) / sizeof(float)


= 1000 / 4
= 250
Live Example 2:

#include<stdio.h>
struct var{
char cvar;
int ivar;
37
float fvar;
};
intmain(){
struct var *ptr1,*ptr2;
ptr1 =(struct var *)1000;
ptr2 =(struct var *)2000;
printf("Difference= %d",ptr2-ptr1);
return0;
}
Output :

Difference = 142

Explanation:

ptr2-ptr1 = (2000 - 1000)/Sizeof(struct var)


= 1000 / (1+2+4)
= 1000 / 7
= 142

C pointer addition

Adding integer value with Pointer

In C Programming we can add any integer number to Pointer variable. It is perfectly

legal in c programming to add integer to pointer variable.

In order to compute the final value we need to use following formulae :

final value =(address)+(number * size of data type)


38
Consider the following example –

int*ptr , n;
ptr =&n ;
ptr = ptr +3;
Live Example 1 : Increment Integer Pointer

#include<stdio.h>
intmain(){
int*ptr=(int*)1000;
ptr=ptr+3;
printf("New Value of ptr : %u",ptr);
return0;
}
Output :

New Value of ptr :1006

Explanation of Program :

In the above program –

int*ptr=(int*)1000;

this line will store 1000 in the pointer variable considering 1000 is memory location

for any of the integer variable.

Formula:

ptr = ptr +3*(sizeof(integer))


=1000+3*(2)
=1000+6
=1006
Similarly if we have written above statement like this –

39
float*ptr=(float*)1000;

then result may be

ptr = ptr +3*(sizeof(float))


=1000+3*(4)
=1000+12
=1012
C subtracting integer value from pointer

Suppose we have subtracted ―n‖ from pointer of any data type having initial addess

as ―init_address‖ then after subtraction we can write –

ptr = initial_address - n *(sizeof(data_type))

Subtracting integer value with Pointer

int*ptr , n;
ptr =&n ;
ptr = ptr -3;
Live Example 1 : Decrement Integer Pointer

#include<stdio.h>
intmain(){
int*ptr=(int*)1000;
ptr=ptr-3;
printf("New Value of ptr : %u",ptr);
return0;
}
Output :

New Value of ptr :994

Formula:

40
ptr = ptr -3*(sizeof(integer))
=1000-3*(2)
=1000-6
=994
Summary:

Pointer-Pointer= Integer

Pointer- Integer =Pointer

C subtracting pointers

Differencing Pointer in C Programming Language :

1. Differencing Means Subtracting two Pointers.

2. Subtraction gives the Total number of objects between them .

3. Subtraction indicates ―How apart the two Pointers are ?‖

C Program to Compute Difference Between Pointers :

#include<stdio.h>

intmain()
{
int num ,*ptr1 ,*ptr2 ;
ptr1 =&num ;
ptr2 = ptr1 +2;
printf("%d",ptr2 - ptr1);
return(0);
}
Output :

41
 ptr1 stores the address of Variable num

 Value of ptr2 is incremented by 4 bytes

 Differencing two Pointers

Important Observations :

Suppose the Address of Variable num = 1000.

Statement Value of Ptr1 Value of Ptr2

int num ,*ptr1 ,*ptr2 ; Garbage Garbage

ptr1 =&num ; 1000 Garbage

ptr2 = ptr1 +2; 1000 1004

ptr2 - ptr1 1000 1004

Computation of Ptr2 – Ptr1:

Remember the following formula while computing the difference between two

pointers –

Final Result = (ptr2 - ptr1)/ Size of Data Type

Step 1 : Compute Mathematical Difference (Numerical Difference)

ptr2 - ptr1 = Value of Ptr2 - Value of Ptr1


=1004-1000

42
=4
Step 2 : Finding Actual Difference (Technical Difference)

Final Result =4/ Size of Integer


=4/2
=2
1. Numerically Subtraction ( ptr2-ptr1 ) differs by 4

2. As both are Integers they are numerically Differed by 4 and Technically by 2

objects

3. Suppose Both pointers of float the they will be differed numerically by 8 and

Technically by 2 objects

Consider the below statement and refer the following table –

int num = ptr2 - ptr1;

and

If Two Pointers are of Numerical Technical


Following Data Type Difference Difference

Integer 2 1

Float 4 1

Character 1 1

Comparison between two Pointers :

43
1. Pointer comparison is Valid only if the two pointers are Pointing to

same array

2. All Relational Operators can be used for comparing pointers of same type

3. All Equality and Inequality Operators can be used with all Pointer types

4. Pointers cannot be Divided or Multiplied

Point 1 : Pointer Comparison

#include<stdio.h>
intmain()
{
int*ptr1,*ptr2;
ptr1 =(int*)1000;
ptr2 =(int*)2000;
if(ptr2 > ptr1)
printf("Ptr2 is far from ptr1");

return(0);
}
Pointer Comparison of Different Data Types :

#include<stdio.h>
intmain()
{
int*ptr1;
float*ptr2;
ptr1 =(int*)1000;
ptr2 =(float*)2000;
if(ptr2 > ptr1)
printf("Ptr2 is far from ptr1");
44
return(0);
}
Explanation :

 Two Pointers of different data types can be compared .

 In the above program we have compared two pointers of different data

types.

 It is perfectly legal in C Programming.

As we know Pointers can store Address of any data type, address of the data type is

―Integer‖ so we can compare address of any two pointers although they are of

different data types.

Following operations on pointers :

> Greater Than

< Less Than

>= Greater Than And Equal To

<= Less Than And Equal To

== Equals

!= Not Equal

Divide and Multiply Operations :

#include<stdio.h>
intmain()

45
{
int*ptr1,*ptr2;
ptr1 =(int*)1000;
ptr2 = ptr1/4;
return(0);
}
Output :

Rules for using Pointer :

1. Pointer Variable Can be Assigned the address of another Variable

intmain(){
int num =10;
int*ptr;
ptr =&num;
return(0);
}

46
2. Pointer Variable Can be Assigned the value of another Pointer Variable

int*sptr,*tptr;
sptr =&num;
tptr = sptr;
3. Pointer Variable Can be initialized with zero or NULL value.

int*sptr,*tptr;
sptr =0;
tptr =NULL;
4. Pointer variable Can be Perform Pre/Post fix Increment/Decrement Operation

int arr[20];
int*ptr;
ptr =&arr;
ptr++;
5. Integer value can be added or Subtracted from Pointer variable

int arr[20];
int*ptr;
ptr =&arr;
ptr = ptr +2;//arr[2] will be accessed
6. When two Pointer points to same array then one Pointer variable can be

Subtracted from another

7. Two Pointers pointing to objects of same data type then they can be

compared using the Relational Operator

8. Value cannot be assigned to arbitrary address

int*ptr;
ptr =100;//Illegal
9. Pointer Variable cannot be multiplied by Constant
47
int*ptr;
ptr = ptr *6;//Illegal
C pointer invalid operations

One can perform different arithmetic operations on Pointer such as increment,

decrement but still we have some more arithmetic operations that cannot be

performed on pointer –

1. Addition of two addresses.

2. Multiplying two addresses.

3. Division of two addresses.

4. Modulo operation on pointer.

5. Cannot perform bitwise AND,OR,XOR operations on pointer.

6. Cannot perform NOT operation or negation operation.

1. Addition of Two Pointers :

#include<stdio.h>
intmain()
{
int var =10;
int*ptr1 =&i;
int*ptr2 =(int*)2000;
printf("%d",ptr1+ptr2);
return0;
}
Output :

Compile Error

48
2. Multiplication of Pointer and number :

#include<stdio.h>
intmain()
{
int var =10;
int*ptr1 =&i;
int*ptr2 =(int*)2000;
printf("%d",ptr1*var);
return0;
}
Output :

Compile Error

3. Multiplication of Two Pointers :

#include<stdio.h>
int main(){
int var =10;
int*ptr1 =&i;
int*ptr2 =(int*)2000;
printf("%d",ptr1*ptr2);
return0;
}
Output :

Compile Error

Similarly we cannot perform following operations –

4. Modulo Operation

int *ptr1 = (int *)1000;

49
int *ptr2 = (int *)2000;
int var = ptr2 % ptr1;
5. Division of pointer

#include<stdio.h>

intmain()
{
int*ptr1,*ptr2;
ptr1 =(int*)1000;
ptr2 = ptr1/4;
return(0);
}
Output :

6.Cannot perform bitwise OR

#include<stdio.h>
intmain(){

50
int i=5,j=10;
int*p=&i;
int*q=&j;
printf("%d",p|q);
return0;
}
7.Negation Operation on Pointer

#include<stdio.h>
intmain(){
int i=5;
int*ptr=&i;
printf("%d",~ptr);
return0;
}
Summary at a glance :

Address + Address = Illegal


Address * Address = Illegal
Address / Address = Illegal
Address % Address = Illegal
Address & Address = Illegal
Address | Address = Illegal
Address ^ Address = Illegal
~Address = Illegal

C precedence of * and & operator

Precedence of Value at Operator :

Value at operator is denoted by ‗*‘. In C Star(*) operator is used for two purposes –

51
 Multiplication

 In Pointer for De-referencing

Some important points about De-Reference Operator :

1. Value at Operator (*) is unary operator when use in pointer.

2. Multiplication Operator (*) is binary operator when used for multiplication.

3. Value at operator ‗*‘ in pointer concept is also called as ―De-reference‖

Operator Or ―Value at Operator―

Precedence of ‗ * ‗ and ‗ & ‗ Operator

1. Both are Unary Operators

2. They have Equal Precedence

3. They Associate from Right –> Left

Meaning of (*++ptr)

Consider the Following Example :

int n = 20 , *ptr ;
ptr = &n;
printf("%d",*++ptr);
Explanation :

1. „++‟ and „*‟ both have Equal Precedence

2. Associativity is from Right to Left ( Expression evaluated from R->L)

3. Both are Unary (Operates on single operand )

4. So ‗ ++ ‗ is Performed First then ‗ * ‗

52
Calculation of Answer :

* ++ptr = *(++ptr )
= *( 3060 )
= Value Stored at Location 3060
Live Program :

#include<stdio.h>
intmain()
{
int n =20,*ptr ;
ptr =&n;
printf("%d",*++ptr);
return(0);
}
Output :

Garbage Value gets printed

Note :
53
1. This operation should not be used in normal operation.

2. Perform this operation if we have consecutive memory i.e Array.

3. If we perform this operation in above example then we will get garbage

value as we dont know the value stored at 3060.

4. Consider following example to get idea , how *++ptr is used in Array –

How to use *++ptr in Array Program ?

#include<stdio.h>
intmain()
{
int arr[5]={10,20,30,40,50};
int*ptr ;
ptr =&arr;
printf("%d",*++ptr);
return(0);
}
Output :

20

Meaning of (++*ptr) pointer

Meaning of (++*ptr) pointer Can be evaluated or drafted by implementing the

below code snippet –

int num =20,*ptr ;


ptr =&num;
printf("%d",++*ptr);
Explanation : Meaning of (++*ptr) pointer

54
1. „++‟ and „*‟ both are having equal precedence and priority. Associativity of

these two operators is from right to left (Expression evaluated from R->L)

2. Both the operators are Unary so they will only works on single operand

3. Dereference operator ‗*‘ will get chance for execution before pre increment

operator ‗++‘.

Visual Understanding

Calculation of Answer :

Consider that variable ‗num‘ is stored at location address 3058 to which pointer ‗ptr‘

is pointing so ‗ptr‘ will have address of variable ‗num‘

++*ptr = ++ ( *ptr )
= ++ ( *3058 )
= ++ ( 20 )
= 21
* Operator will de-reference pointer to get value stored at that address.(i.e 20)

++ ( *3058 )

++ ( 20 )

55
Pre-increment on 20 will perform increment first then assignment

Program : Meaning of (++*ptr) Pointer

#include<stdio.h>
intmain()
{
int n =20,*ptr ;
ptr =&n;
printf("%d",++*ptr);

return(0);
}
Output :

21

Dereferencing Pointer in C Programming Language :

1. Asterisk(*) indirection operator is used along with pointer variable while

Dereferencing the pointer variable.

2. Asterisk Operator is also called as value at operator

3. When used with Pointer variable, it refers to variable being pointed to,this is

called as Dereferencing of Pointers

What is Dereferencing Pointer ?

1. Dereferencing Operation is performed to access or manipulate data contained

in memory location pointed to by a pointer

2. Any Operation performed on the de-referenced pointer directly affects the

value of variable it pointes to.


56
Live Example : Dereferencing Pointer

// Sample Code for Dereferencing of Pointer


int n =50, x ;
int*ptr ;// Un-initialized Pointer
ptr =&n;// Stores address of n in ptr
x =*ptr;// Put Value at ptr in x
Evaluation :

// Sample Code for Dereferencing of Pointer


*(ptr)= value at (ptr)
= value at (2001)
=50
//Address in ptr is nothing but address of n
Summary :

1. Name of Normal Variable always points to the Value of variable

2. Pointer variable always Stores Address of variable

3. *ptr and num will give us same value.

Variable Value in it

num 50

&num 1002

57
ptr 1002

*ptr 50

Incrementing Pointer :

1. Incrementing Pointer is generally used in array because we have contiguous

memory in array and we know the contents of next memory location.

2. Incrementing Pointer Variable Depends Upon data type of the Pointer variable

Formula : ( After incrementing )

new value = current address + i * size_of(data type)

Three Rules should be used to increment pointer –

Address +1= Address


Address++= Address
++Address = Address

Pictorial Representation :

Data Older Address Next Address stored in pointer


Type stored in pointer after incrementing (ptr++)

int 1000 1002

58
Data Older Address Next Address stored in pointer
Type stored in pointer after incrementing (ptr++)

float 1000 1004

char 1000 1001

Explanation : Incremeting Pointer

 Incrementing a pointer to an integer data will cause its value to be

incremented by 2 .

 This differs from compiler to compiler as memory required to store

integer vary compiler to compiler

Note to Remember : Increment and Decrement Operations on pointer should be

used when we have Continues memory (in Array).

Live Example 1 : Increment Integer Pointer

#include<stdio.h>
intmain(){
int*ptr=(int*)1000;
ptr=ptr+1;
printf("New Value of ptr : %u",ptr);
return0;
}
Output :

New Value of ptr :1002

Live Example 2 : Increment Double Pointer

59
#include<stdio.h>
intmain(){
double*ptr=(double*)1000;
ptr=ptr+1;
printf("New Value of ptr : %u",ptr);
return0;
}
Output :

New Value of ptr :1004

Live Example 3 : Array of Pointer

#include<stdio.h>
intmain(){
float var[5]={1.1f,2.2f,3.3f};
float(*ptr)[5];
ptr=&var;
printf("Value inside ptr : %u",ptr);
ptr=ptr+1;
printf("Value inside ptr : %u",ptr);
return0;
}
Output :

Value inside ptr :1000

Value inside ptr :1020

60
Explanation :

Address of ptr[0] = 1000

We are storing Address of float array to ptr[0]. –

Address of ptr[1]
= Address of ptr[0] + (Size of Data Type)*(Size of Array)
= 1000 + (4 bytes) * (5)
= 1020
Address of Var[0]…Var[4] :

Address of var[0] = 1000


Address of var[1] = 1004
Address of var[2] = 1008
Address of var[3] = 1012
Address of var[4] = 1016

C dereferencing void pointer

Void Pointer is called as General Purpose Pointer.


61
Why it is necessary to use Void Pointer ?

Reason 1 : Re-usability of Pointer

float*ptr;
int num;

ptr =&num ;// Illegal Use of Pointer


In the above example we have declared float pointer which is of no use in the

program. We cannot use float pointer to store the integer pointer so So in order to

increase the re-usability of the Pointer it is necessary to declared pointer variable as

void Pointer.

Dereferencing Void Pointer :

Consider this example –

void*ptr;// ptr is declared as Void pointer


char cnum;
int inum;
float fnum;
Suppose we have assigned integer Address to void pointer then –

ptr =&inum;// ptr has address of integer data

then to De-reference this void pointer we should use following syntax –

*((int*)ptr)

Similarly we should use following for Character and float –

*((float*)ptr)// De-reference Float Value

*((char*)ptr)// De-reference Character Value

62
Following table will summarize all details –

Type of Address Stored in Void Dereferencing Void


Pointer Pointer

Integer *((int*)ptr)

Charcter *((char*)ptr)

Floating *((float*)ptr)

Live Example : Dereferencing Void Pointer

#include<stdio.h>
intmain()
{
int inum =8;
float fnum =67.7;
void*ptr;
ptr =&inum;
printf("\nThe value of inum = %d",*((int*)ptr));
ptr =&fnum;
printf("\nThe value of fnum = %f",*((float*)ptr));
return(0);
}
Output :

The value of inum =8


The value of fnum =67.7
Explanation : Void Pointer Program

ptr =&inum;

63
printf("\nThe value of inum = %d",*((int*)ptr));
Here we are assigning the address of integer variable to void pointer so that void

pointer can act as Integer pointer.

ptr =&fnum;
printf("\nThe value of fnum = %f",*((float*)ptr));
And now we are storing the address of floating point variable to void pointer , thus

void pointer becomes floating pointer.

C difference between *ptr++ & ++*ptr

Question : Are *ptr++ and ++*ptr are same ?

Ans : Absolutely Not

*ptr++ means

 Increment the Pointer not Value Pointed by It

++*ptr means

 Increment the Value being Pointed to by ptr

C Are ++*ptr and *ptr++ are same ?

Question : Are ++*ptr and *ptr++ are same ?

Answer :

No

1. ++*ptr Increments the Value being Pointed to by ptr

2. Suppose ptr is Pointing to the Integer Variable having value 10. [ num = 10 ]

3. Now ++*ptr Results in 11

64
4. *ptr++ means Grab the Value of (*ptr) And then Increment It , which

yields again 10 because increment operation will be done in the next

statement because it is post increment operation.

5. This Proves that both are equivalent

Step by Step Explanation of : ++*ptr

Address of Num : 1000


++*ptr = ++ *ptr
= ++ *(1000)
= ++ (Value at address 1000)
= ++ 10
= 11
Step by Step Explanation of : *ptr++

Address of Num : 1000


*ptr++ = *ptr++
= *1000 ++
= Value at address 1000 ++
= 10 ++
= 10
**(Post increment will first assign and then do increment)
Example 1 : Consider ++*ptr

#include<stdio.h>
intmain()
{
int num =10;
int*ptr;
ptr =&num;
printf("Value of ++*ptr : %d",++*ptr);
65
return(0);
}
Output :

11

Example 2 : Consider *ptr++

#include<stdio.h>
intmain()
{
int num =10;
int*ptr;
ptr =&num;
printf("Value of *ptr++ : %d",*ptr++);
return(0);
}
Output :

10

Conclusion :

In short ++*ptr and *ptr++ are not same

C double pointer example

Program :

#include<stdio.h>
#include<conio.h>
voidmain()
{
int i =50;
int**ptr1;
66
int*ptr2;
clrscr();
ptr2 =&i;
ptr1 =&ptr2;
printf("\nThe value of **ptr1 : %d",**ptr1);
printf("\nThe value of *ptr2 : %d",*ptr2);
getch();
}
Output :

The value of **ptr1 :50


The value of *ptr2 :50
Explanation :

1. Variable ‗i‘ is initialized to 50.

2. i is stored at Memory Location 2000.

3. Pointer Variable ‗ptr2‘ stores address of variable ‗i‘.

*ptr2 will print [Value Stored at Address 2000 ] i.e 50

4. Similarly ‗ptr1‘ is also a pointer variable which stores the address of Pointer

variable [i.e ptr2 stores address of integer variable while ptr1 stores address

of another pointer variable].

5. So

67
**ptr1 is used to access actual value.

Pointer to Pointer in C Programming

Declaration : Double Pointer

int **ptr2ptr;

Consider the Following Example :

int num =45,*ptr ,**ptr2ptr ;

ptr =&num;

ptr2ptr =&ptr;

What is Pointer to Pointer ?

1. Double (**) is used to denote the double Pointer

2. Pointer Stores the address of the Variable

3. Double Pointer Stores the address of the Pointer Variable

Statement What will be the Output ?

*ptr 45

**ptr2ptr 45

ptr &n

68
ptr2ptr &ptr

Notes :

1. Conceptually we can have Triple ….. n pointers

2. Example : *****n,****b can be another example

Live Example :

#include<stdio.h>

intmain()
{
int num =45,*ptr ,**ptr2ptr ;
ptr =&num;
ptr2ptr =&ptr;

printf("%d",**ptr2ptr);

return(0);
}
Output :

45

Pointer to Constant Objects :

 Pointer to a Constant Object is called as ‗Pointer to Constant Object‘

Syntax :

const data-type *pointer_name ;

Example :
69
int n =30;
constint ptr;
ptr =&n;
What does it means ?

1. ―const int‖ means integer is constant.

2. We cannot change value of the integer.

3. Pointer to Such Object cannot be changed.

4. We can change address of such pointer so that it will point to new memory

location.

Following is illegal use of const int pointer –

*ptr =20;

however we can use this legally –

ptr++

is valid in this Case !!!

Example 1 : How const int Pointer works ?

#include<stdio.h>
intmain()
{
int num[2]={10,20};
constint*ptr;
ptr =&num[0];
printf("%d",*ptr);
return(0);
}
70
Output:

10

Example 2 : Increment const int Pointer

#include<stdio.h>
intmain()
{
int num[2]={10,20};
constint*ptr;
ptr =&num[0];
ptr++;
printf("%d",*ptr);
return(0);
}
Output :

20

Example 3 : Assigning Value to const int pointer

#include<stdio.h>

intmain()
{
int num[2]={10,20};
constint*ptr;

ptr =&num[0];

*ptr =30;

printf("%d",*ptr);

71
return(0);
}
Output :

Compile Error

What is Constant Pointers [ Const Pointer ] in C Programming :

 As name suggests , Constant Pointers Cannot be modified .

 Modification in Integer to which it Points to is Allowed

 Modification made in Pointer is Not Allowed

Syntax Declaration :

data_type *const Pointer_name = Initial_Address;

Sample Code Snippet :

int num =20;


int*const ptr =&num ;// Declare Constant Pointer

72
*ptr =20;// Valid Statement
ptr ++;// Invalid Statement
Explanation :

1. In the Diagram Shown The at 2001 we have Store the value 15 .

2. Constant Pointer is Pointer to that Variable [Pointer Stores address 2001]

3. We cannot Change the Address stored in Pointer Variable i.e 2001 is

fixed

4. But we can Change the Value at 2001 i.e we can change value 15 to 20

Example 1: Illustrate const pointer in C

#include<stdio.h>
intmain()
{
int num[2]={10,20};
int*const ptr =&num[0];
printf("%d",*ptr);
return(0);
}
Output :
73
10

Explanation :

int*const ptr =&num[0];

We must initialize const pointer at the time of declaration. Otherwise it will

cause error.

int*const ptr;
ptr =&num[0];
above statements will cause error.

Example 2 : We cannot change address stored inside Pointer

#include<stdio.h>
intmain()
{
int num[2]={10,20};
int*const ptr =&num[0];
ptr++;
printf("%d",*ptr);
return(0);
}
Output :

74
Example 3 : We can change value stored at address.

#include<stdio.h>

intmain()
{
int num[2]={10,20};
int*const ptr =&num[0];

*ptr =30;

printf("%d",*ptr);

return(0);
}
75
Output :

30
Summary

We can DO following operations –

 Assigning Value at Address

 Printing Address or Value

 Assigning Address at the time of declaration.

We Can‟t DO following operations on const pointer –

 Adding Integer to const Pointer

 Subtracting Integer to const Pointer.

 Any operation that can change address of pointer.

Pointer to array in C : Pointer pointing to the array of elements

1. Array and Pointer are backbones of the C Programming language

2. Pointer and array , both are closely related

3. We know that array name without subscript points to first element in an

array

Example : One dimensional array

int a[10];

Here a , a[0] both are identical


76
Example : Two dimensional Array

int a[10][10];

Here a , a[0][0] both are identical

Let

1. x is an array ,

2. i is subscript variable

x[i] = *(x+i)
= *(i+x)
= i[x]
Proof of the above Formula :

1 . For first element of array i = 0


x[0] = * ( x + 0)

= *x
Thus we have concluded that , first element of array is equivalent to *x .

2 . Thus *(x+i) will gives us value of ith element.

Summary : Consider following code

main()

int x[] = {1,2,3,4,5};

int *ptr,i ;

ptr = x

for(i=0;i<5;i++)

77
printf("nAddress : %u",&x[i]);

printf("nElement : %d",x[i]);

printf("nElement : %u",*(x+i));

printf("nElement : %d",i[x]);

printf("nElement : %d",*ptr);

Output :

Address : 7600

Element : 1

Element : 1

Element : 1

Element : 1

Address : 7602

Element : 2

Element : 2

Element : 2

Element : 2

Address : 7604

Element : 3

Element : 3

Element : 3

Element : 3

Address : 7606
78
Element : 4

Element : 4

Element : 4

Element : 4

Address : 7608

Element : 5

Element : 5

Element : 5

Element : 5

Following 4 are considered as Equivalent

x[i] *(x + i)

i[x] *ptr

2-D Array can be accessed –


x [ i ][ j ] = *(x[i] + j)
= *( * ( x + i ) + j )
Pointer to array of string : A pointer which pointing to an array which content is

string, is known as pointer to array of strings.

79
In this example

1. ptr : It is pointer to array of string of size 4.

2. array[4] : It is an array and its content are string.

1 : Printing Address of the Character Array

#include<stdio.h>

intmain()
{
int i;

char*arr[4]={"C","C++","Java","VBA"};
char*(*ptr)[4]=&arr;

for(i=0;i<4;i++)
printf("Address of String %d : %u\n",i+1,(*ptr)[i]);

return0;
}
Output :
80
Address of String1=178

Address of String2=180

Address of String3=184

Address of String4=189

2. Printing Contents of character array

#include<stdio.h>

intmain()
{
int i;

char*arr[4]={"C","C++","Java","VBA"};
char*(*ptr)[4]=&arr;

for(i=0;i<4;i++)
printf("String %d : %s\n",i+1,(*ptr)[i]);

return0;
}
Output :

String1= C
String2= C++
String3= Java
String4= VBA

3. Pointer to String and Pre-increment Operator

#include<stdio.h>

81
intmain()
{
int i;

char*arr[4]={"C","C++","Java","VBA"};
char*(*ptr)[4]=&arr;

printf("%s",++(*ptr)[2]);

return0;
}
Output:

ava

What is function Pointer ?

Function pointer : A pointer which keeps address of a function is known as

function pointer.

Example :

#include<stdio.h>

void display();

intmain()
{
void*(*ptr)();
ptr =&display;
(*ptr)();

return(0);
}

82
void display()
{
printf("Hello World");
}
Output :

Hello World

Explanation of C Snippet :

Consider normal program –

Now in the above program we have just called function display(), and we get output

as ―Hello World‖.

Consider Scenario using pointer , We should follow following 3 steps to use pointer

to call function –

1. Declare Pointer which is capable of storing address of function.

2. Initialize Pointer Variable

3. Call function using Pointer Variable.

Step 1 : Declaring Pointer

void*(*ptr)();

 We are simply declaring a double pointer.

 Write () symbol after ―Double Pointer―.

 void represents that , function is not returning any value.

 () represents that , function is not taking any parameter.

83
Above declaration tells us ….

Declare Pointer variable that can store address of function which does not return

anything and doesn‘t take any parameter

Step 2 : Initializing Pointer

ptr =&display;

This statement will store address of function in pointer variable.

Step 3 : Calling a function

(*ptr)();
using (*ptr)() we can call function display();
(*ptr)()=(*ptr)();
=(*&display)();
=(display)();
= display();
thus (*ptr)() is as good as calling function.

Declaration of Initialization of Calling Function


Requirement
Function Pointer Function Pointer using Pointer

Return Type :
None
void*(*ptr)(); ptr =&display; (*ptr)();
Parameter :
None

Return Type :
Integer int result;
int*(*ptr)(); ptr =&display;
Parameter : result =(*ptr)();
None

Return Type : float*(*ptr)(); ptr =&display; float result;

84
Float result =(*ptr)();
Parameter :
None

Return Type :
Char char result;
char*(*ptr)(); ptr =&display;
Parameter : result =(*ptr)();
None

Example 1 : Function having two Pointer Parameters and return type as Pointer

#include<stdio.h>
char* getName(int*,float*);
intmain()
{
char*name;
int num =100;
float marks =99.12;
char*(*ptr)(int*,float*);
ptr=&getName;
name =(*ptr)(&num,&marks);
printf("Name : %s",name);
return0;
}
//-------------------------------------
char*getName(int*ivar,float*fvar)
{
char*str="www.c4learn.com";
str = str +(*ivar)+(int)(*fvar);
return(str);
}
85
Output :

.c4learn.com

C pointer to array of function

#include<stdio.h>
int display();
int(*arr[3])();
int(*(*ptr)[3])();
intmain(){
arr[0]=display;
arr[1]=getch;
ptr=&arr;
printf("%d",(**ptr)());
(*(*ptr+1))();
return0;
}
int display(){
int num =25;
return num;
}
Output :

25

Explanation :

Step 1 : Array of Function

int(*arr[3])();

above statement tell that –

 arr is an array of size 3.

86
 Array stores address of functions

 Array stores address of function having integer as return type and does

not takes any parameter.

Step 2 : Declaring Array of function Pointer

int(*(*ptr)[3])();

 It is array of function pointer which points to ―array of function―.

Step 3 : Store function names inside function array

arr[0]= display;
arr[1]= getch;
Step 4 : Store address of function Array to Function Pointer

ptr =&arr;

Step 5 : Calling Function

following syntax is used to call display function –

(**ptr)();

this syntax is used to call getch function –

(*(*ptr+1))();

What is the size of const Pointer variable in C ?

Pointer :

Pointer is the variable that stores the address of another variable .

How to calculate size of Const Pointer ?

Size of Const Pointer : 2 bytes

87
Accessing Integer using char pointer : will Lose Binary Data !

Some Facts About Pointer Arithmetic :

1. Pointer Always Stores to the memory address of the variable.

2. De-Reference Means Accessing the data from the address being stored in

pointer variable

3. Asterisk(*) is used for De-Reference

4. Memory occupied by pointer is same as memory occupied by integer variable

When Pointer is De-referenced then –

Pointer to the following Number of Bytes accessed by


type Pointer

Integer Data Type 2 Bytes

Character Data Type 1 Byte

Float Data Type 4 Bytes

Live Example of Pointer Accessing :

Suppose we assign the address of integer variable to the character pointer then

some part of value will be lost while accessing the variable using character data

type.

#include<stdio.h>
intmain()
{
int a=320;

88
char*ptr;
ptr=(char*)&a;
printf("%d",*ptr);
return(0);
}
Output of the Code :

64

Explanation of the above Code :

1. Memory required to store integer and character is 2 bytes and 1 byte

respectively

320=000000010100000

2. Representation of 320 in Binary : 00000001 0100000

3. If Pointer is of Integer type , It will Access both bytes (16 bits ) .

4. As Pointer is of Character Type , as stated earlier in table it will access only

one byte i.e ( 0100000 )

5. 0100000 is nothing but the binary Representation of 64.

Binary Representation of 64=0100000

C Programming NULL Pointer

We have already studied the different type of pointer in C. In this tutorial we will be

learning about NULL Pointer in C Programming

What is Null Pointer ?

1. NULL Pointer is a pointer which is pointing to nothing.

89
2. NULL pointer points the base address of segment.

3. In case, if you don‘t have address to be assigned to pointer then you can

simply use NULL

4. Pointer which is initialized with NULL value is considered as NULL pointer.

5. NULL is macro constant defined in following header files –

o stdio.h o mem.h o stdlib.h


o alloc.h o stddef.h

Defining NULL Value

#define NULL 0

We have noticed that 0 value is used by macro pre-processor. It is re-commanded

that you should not use NULL to assign 0 value to a variable.

#include<stdio.h>

intmain(){
int num =NULL;
printf("Value of Number ",++num);
return0;
}
Above program will never print 1, so keep in mind that NULL should be used only

when you are dealing with pointer.

Re-commanded Articles : Declaring pointers | Initializing pointers

Visual Representation

90
Below are some of the variable representations of NULL pointer.

float*ptr =(float*)0;
char*ptr =(char*)0;
double*ptr =(double*)0;
char*ptr ='\0';
int*ptr =NULL;
you can see that we have assigned the NULL to only pointers.

Example of NULL Pointer

#include <stdio.h>
intmain()
{
int*ptr =NULL;
printf("The value of ptr is %u",ptr);

return0;
}
Output :

The value of ptr is 0

You can find some of the frequently asked questions about NULL pointer here

Difference between char *a and char a[]

91
char * and char [] both are used to access character array, Though functionally

both are same , they are syntactically different. See how both works in order to

access string.

How Char a[] Works ?

Consider following sample example for storing and accessing string using character

array –

char a[] = "HELLO";

In the example – String ―Hello‖ is stored in Character Array ‗a‘. Character array is

used to store characters in Contiguous Memory Location. It will take Following

Form after Initialization. We have not specified Array Size in this example.Each

array location will get following values –

a[0] = 'H'
a[1] = 'E'
a[2] = 'L'
a[3] = 'L'
a[4] = 'O'
a[5] = '\0'
It will Looks Like This …

Accessing Individual Element :

92
Suppose we have to find out a[3] then firstly compiler will check whether ‗a‘ is

Array or Pointer ? If ‗a‘ is Array Variable then It starts at the location ―a‖, goes three

elements past it, and returns the character there.In this method element is

accessed Sequentially

How Char *a Works ?

String ―Hello‖ will be stored at any Anonymous location in the form of array. We

even don‘t know the location where we have stored string, However String will have

its starting address.

Syntax of Char *a :

char *a = "HELLO";

the above syntax will take following form –

We have declared pointer of type character i.e pointer variable is able to hold the

address of character variable. Now Base address of anonymous array is stored in

character pointer variable. ‗a‘ Stores Base Address of the Anonymous Array

[Unknown Array]

Address = [Base Address of Anonymous Array] + [i]

Accessing Individual Element :

Consider we have to access a[3] then –

In Short if ‗a‘ is a pointer, it starts at the location ―a‖, gets the pointer value there,
93
adds 3 to the pointer value, and gets the character pointed to by that value

In both Cases a[3] returns same Character but Procedure is Different.

C reading complex pointer expression

Before We Learn How to Read Complex Array we should first know precedence and

associative .

 Precedence : Operator precedence describes the order in which C reads

expressions

 Associativity : Order operators of equal precedence in an expression are

applied

Before Reading Article You Should know Precedence and Associative Table

Operator Precedence Associative

(),[] 1 Left to Right

*,Identifier 2 Right to Left

Data Type 3 –

Different Terms From Table –

() Bracket operator OR function operator.

[] Array subscription operator

* Pointer operator

Identifier Name of Pointer Variable

94
Data type Type of Pointer

How to Read ?

char (* ptr)[5]

Step 1 :

 Observe Above Precedence Table

 [] and () have Same Priority

 Using Associativity , Highest Priority Element is decided

 Associativity is from Left to Right First Priority is Given to “()”

Step 2 :

 Between Pair of Brackets again we have to decide which one has highest

priority ? ‗*‘ or ‗ptr‘ ?

 * and Identifier ptr have Same Priority

 Associativity is from Right to Left First Priority is Given to “ptr”

95
Step 3 :

 Assign third Priority to [].

 Write 3 under []

Step 4 :

 Here Char is Data Type

 Assign Priority 4 to char

Read it as –

ptr is pointer to a one dimensional array having size five which can store

data of type char

C Programming Pointer Mistake

We all know that pointer is used to store the address of a variable. Pointer

Variable stores the address of variable. Below are some of the common mistakes

committed by Novice programmer.

Pointer Mistake 1 : Assigning Value to Pointer Variable

96
int* ptr , m =100;

ptr = m ;// Error on This Line

Correction :

1. ptr is pointer variable which is used to store the address of the variable.

2. Pointer Variable ―ptr‖ contain the address of the variable of type „int‟ as

we have declared pointer variable with data type ‗int‘.

3. We are assigning value of Variable to the Pointer variable, instead of Address.

4. In order to resolve this problem we should assign address of variable to

pointer variable

Write it like this –

ptr = &m ;

Pointer Mistake 2 : Assigning Value to Uninitialized Pointer

We are assigning the value to the pointer variable. We all know that pointer is

special kind of variable which is used to store the address of another variable. So

we can store only address of the variable to the pointer variable.

int * ptr , m = 100 ;

*ptr = m ; // Error on This Line

We are going to update the value stored at address pointed by uninitialized pointer

variable. Instead write it as –

int * ptr , m = 100 ,n = 20;

ptr = &n;
97
*ptr = m ;

Firstly initialize pointer by assigning the address of integer to Pointer variable. After

initializing pointer we can update value.

Pointer Mistake 3 : Not De-referencing Pointer Variable

De-referencing pointer is process of getting the value from the address to whom

pointer is pointing to.

int* ptr , m =100;

ptr =&m ;

printf("%d",ptr);

In the above example, You will not get any compiler or run time error but it is

considered as common mistake by novice user to de-reference pointer variable

without using asterisk (*)

Pointer Mistake 4 : Assigning Address of Un-initialized Variable

int*ptr,m;

ptr =&m;

Best practice while using pointer is to initialize pointer before using it.

We can assign any valid address to pointer variable but if you assign the address of

un-initialized variable to pointer then it will print garbage value while de-referencing

it.

Re-commanded Article : How storage class determines the default initial value

Pointer Mistake 5 : Comparing Pointers that point to different objects

98
We cannot compare two pointer variables. Because variables may have random

memory location. We cannot compare memory address.

char str1[10],str2[10];
char*ptr1 = str1;
char*ptr2 = str2;

if(ptr1>ptr2).....// Error Here


{
....
....
}
Dangling Pointer in C

1. Dangling pointers arise when an object is deleted or de-allocated, without

modifying the value of the pointer, so that the pointer still points to the

memory location of the de-allocated memory.

2. In short pointer pointing to non-existing memory location is called dangling

pointer.

Examples of dangling pointer

There are different ways where Pointer acts as dangling pointer.

Way 1 : Using free or de-allocating memory

#include<stdlib.h>
{
char*ptr =malloc(Constant_Value);
.......
.......

99
.......
free(ptr);/* ptr now becomes a dangling pointer */
}
We have declared the character pointer in the first step. After execution of some

statements we have de-allocated memory which is allocated previously for the

pointer.

As soon as memory is de-allocated for pointer, pointer becomes dangling pointer

Problem : If any pointer is pointing the memory address of any variable but after

some variable has deleted from that memory location while pointer is still pointing

such memory location. Such pointer is known as dangling pointer and this

problem is known as dangling pointer problem.

How to Ensure that Pointer is no Longer Dangling ?

#include<stdlib.h>
{
char *ptr = malloc(Constant_Value);
.......
.......
.......
free (ptr); /* ptr now becomes a dangling pointer */
ptr = NULL /* ptr is no more dangling pointer */
}
After de-allocating memory, initialize pointer to NULL so that pointer will be no

longer dangling. Assigning NULL value means pointer is not pointing to any memory

location

Re-commanded Tutorial : NULL pointer in C Programming

100
Way 2 :Out of Scope

#include<stdlib.h>
void main()
{
char *ptr = NULL;
.....
.....
{
char ch;
ptr = &ch;
}
..... /* dp is now a dangling pointer */
}
1. Character Pointer is Declared in the first Step.

2. Pointer Variable ‗ptr‘ is pointing to Character Variable ‗ch‘ declared in the

inner block .

3. As character variable is non-visible in Outer Block , then Pointer is Still

Pointing to Same Invalid memory location in Outer block , then Pointer

becomes “Dangling”

Way 3 : Function Call

int * func ( void )


{
int num = 14;
/* ... */
return &num;
}

101
Attempts to read from the pointer may still return the correct value (1234) for a

while after calling func, but any functions called thereafter will overwrite the stack

storage allocated for num with other values and the pointer would no longer work

correctly. If a pointer to num must be returned, num must have scope beyond the

function—it might be declared as static.

Pointer Applications in C Programming

Pointer is used for different purposes. Pointer is low level construct in programming

which is used to perform high level task. Some of the pointer applications are listed

below

A. Passing Parameter by Reference

First pointer application is to pass the variables to function using pass by reference

scheme.

void interchange(int*num1,int*num2)
{
int temp;
temp =*num1;
*num1 =*num2;
*num2 =*num1;
}
Pointer can be used to simulate passing parameter by reference. Pointer is used to

pass parameter to function. In this scheme we are able to modify value at direct

memory location.

Re-commanded Article : Ways of function calling

Accessing Array element

102
intmain()
{
int a[5]={1,2,3,4,5};
int*ptr;
ptr = a;

for(i=0;i<5;i++){
printf("%d",*(ptr+i));
}

return(0);
}
We can access array using pointer. We can store base address of array in pointer.

ptr = a;

Now we can access each and individual location using pointer.

for(i=0;i<5;i++){

printf("%d",*(ptr+i));

Dynamic Memory Allocation :

Another pointer application is to allocate memory dynamically.

We can use pointer to allocate memory dynamically. Malloc and calloc function is

used to allocate memory dynamically.

#include <stdio.h>
#include <stdlib.h>

103
intmain()
{
char*str;

str =(char*)malloc(15);
strcpy(str,"mahesh");

printf("String = %s, Address = %u\n", str, str);


free(str);

return(0);
}
consider above example where we have used malloc() function to allocate memory

dynamically.

Reducing size of parameter

struct student {
char name[10];
int rollno;
};
Suppose we want to pass the above structure to the function then we can pass

structure to the function using pointer in order to save memory.

Suppose we pass actual structure then we need to allocate (10 + 4 = 14 Bytes(*))

of memory. If we pass pointer then we will require 4 bytes(*) of memory.

Some other pointer applications :

1. Passing Strings to function

104
2. Provides effective way of implementing the different data structures such as

tree,graph,linked list

[Note :* Above example is written by considering the 64 bit compiler.)

Q1 – which pointer require more space ?

Which pointer require more memory space int or character pointer ?

1. Size of Pointer Variable does not depends upon data type

2. Pointer variable only stores the address of the variable .

3. Address of variable is of integer type

4. So Size of Pointers variables of any type is 2 byte

Q2 – difference constant to pointer and pointer to constant ?

What is the difference between constant to pointer and pointer to constant?

No Pointer to Constant Constant Pointers

*ptr = 20 Statement is Invalid *ptr = 20 is Absolutely Valid in


1 in Pointer to Constant i.e Constant Pointers i.e Assigning
Assigning Value is Illegal Value is Perfectly legal

ptr ++ Statement is Valid in ptr ++ Statement is invalid in


2
Pointer to Constant Constant Pointers

Pointer Can be Incremented and Pointer Cannot be Incremented


3
Decremented and Decremented

Pointer is Pointing to Constant Constant Pointer is Pointing to


4
Data Object Data Objects

5 Declaration : const int *ptr ; Declaration : int * const ptr ;

105
Add numbers using function pointer

Recommanded Articles : Function pointer | Function pointer reference

How to add two numbers using function pointer ?

#include<stdio.h>

int sum (int n1,int n2);

intmain()
{
int num1 =10;
int num2 =20;
int result;

int*(*ptr)(int,int);
ptr =&sum;
result =(*ptr)(num1,num2);

printf("Addition : %d",result);

return(0);
}

int sum (int n1,int n2)


{
return(n1 + n2);
}
Output :
106
Addition : 20
Explanation :

 Write whole program using normal function call i.e sum(num1,num2);

 After you write whole code, just erase line in which we have called function

and replace that line with following line –

Step 1 : Declaring Pointer Variable

int*(*ptr)(int,int);

means –

Declare pointer variable which is capable of storing address of function which have

integer as return type and which takes 2 arguments

Step 2 : Initializing function Pointer

ptr =&sum;

using above statement we will be storing address of function in function pointer

Step 3 : Calling Function

result =(*ptr)(num1,num2);

It will call function sum(num1,num2). Above statement will be elaborated as –

result =(*ptr)(num1,num2);

result =(*&sum)(num1,num2);

result =(*&sum)(num1,num2);

result =(sum)(num1,num2);

107
result = sum(num1,num2);

Pointer Arithmetic

Arbitrary Pointer Casting

Because most ISAs use the same number of bits as integers, it's not so uncommon

to cast integers as pointers.

Here's an example.

// Casting 32 bit int, 0x0000ffff, to a pointer

char * ptr = reinterpret_cast<char *>( 0x0000ffff ) ;

char * ptr2 = reinterpret_cast<char *>( 0x0000ffff ) ;

In general, this is one of the pitfalls of C. Arbitrary pointer casting allows you to

point anywhere in memory.

Unfortunately, this is not good for safe programs. In a safe programming language

(say, Java), the goal is to access objects from pointers only when there's an object

there. Furthermore, you want to call the correct operations based on the object's

type.

Arbitrary pointer casting allows you to access any memory location and do anything

you want at that location, regardless of whether you can access that memory

location or whether the data is valid at that memory location.

Arrays and Pointer Arithmetic

In C, arrays have a strong relationship to pointers.

Consider the following declaration.

108
int arr[ 10 ] ;

What type does arr have? You might say "it's an int array". And, so it is.

However, arr, by itself, without any index subscripting, can be assigned to an

integer pointer.

OK, now what do you think of arr[ i ]? What is that? (Assume i is some int). You

might say, it's the ith element of the array. That's correct too. What type

does arr[i] have?

It's an int! (Beginning programming students often think arr[ i ] is not the same

as an int, because it uses brackets. It takes a while to convince them they have the

same type as a plain int variable).

Do you know, however, that arr[ i ] is defined using pointer arithmetic?

In particular:

arr[ i ] == * ( arr + i )

Let's take a closer look at arr + i. What does that mean? arr is a pointer to arr[ 0

]. In fact, it is defined to be & arr[ 0 ].

A pointer is an address in memory. arr contains an address in memory---the

address where arr[ 0 ] is located.

What is arr + i? If arr is a pointer to arr[ 0 ] then arr + i is a pointer to arr[ i ].

Perhaps this is easier shown in a diagram.

109
We assume that each int takes up 4 bytes of memory. If arr is at address 1000,

then arr + 1 is address 1004, arr + 2 is address 1008, and in general, arr + i is

address 1000 + (i * 4).

Now that you see the diagram, something may strange. Why is arr + 1 at address

1004 and not 1001?

That's pointer arithmetic in action. arr + 1 points to one element past arr. arr +

3 is points to 3 elements past arr. Thus, arr + i points to i elements past arr.

The idea is to have arr + i point to i elements after arr regardless of what type of

element the array holds.

The Type's the Thing

Suppose the array had contained short where a short is only 2 bytes. If arr is at

address 1000, then, arr + 1 is address 1002 (instead of 1004). arr + 2 is at

address 1004 (instead of 1008), and in general arr + i is at address 1000 + (2 *

i).

Here's a diagram of that.

Notice that arr + 1 is now 2 bytes after arr and arr + 2 is 4 bytes. When we had

an int array, arr + 1 was 4 bytes after arr and arr + 2 was 8 bytes afterwards.

Why is there a difference? What's the differnce between arr before and now?

The difference is in the type. Before, arr had (roughly) type int * and now arr has

type short *.

110
In C, a pointer is not only an address, it tells you what (in principle) the data type

at that address is. Thus, int * is a pointer to an int. Not only does it tell you the

data type, but you can also determine the data type's size.

You can find out the data type's size with the sizeof() operator.

sizeof( int ) ==> 4

sizeof( short ) ==> 4

That's important, because that's how pointer arithmetic computes address. It uses

the size of the data type, which it knows from the pointer's type.

Here's the formula for computing the address of ptr + i where ptr has type T *.

then the formula for the address is:

addr( ptr + i ) = addr( ptr ) + [ sizeof( T ) * i ]

T can be a pointer

How does pointer arithmetic work if you have an array of pointers, for example:

int * arr[ 10 ] ;

int ** ptr = arr ;

In this case, arr has type int **. Thus, T has type int *. All pointers have the

same size, thus the address of ptr + i is:

addr( ptr + i ) = addr( ptr ) + [ sizeof( int * ) * i ]

= addr( ptr ) + [ 4 * i ]

Static arrays are constant

When you declare


111
int arr[ 10 ] ;

arr is a constant. It is defined to be the address, & arr[ 0 ].

You can't do the following:

int arr[ 10 ] ;

arr = arr + 1 ; // NO! Can't reassign to arr--it's constant

However, you can declare a pointer variable.

int arr[ 10 ] ;

int * ptr ;

ptr = arr + 1 ; // This is OK. ptr is a variable.

Parameter Passing an Array

If you pass an array to a function, it's type changes.

void foo( int arr[ 10 ], int size ) {

// code here

The compiler translates arrays in a parameter list to:

void foo( int * arr, int size ) {

// code here

}
112
Thus, it becomes arr becomes a pointer variable.

Why doesn't this cause problems? After all, won't we pass arr as an argument?

Isn't arr a constant?

Yes, it is. However, we pass a copy of the address to arr the parameter. Thus, the

copy can be manipulated while the original pointer address that was passed during

the function call is unchanged.

Subtraction

We can also compute ptr - i. For example, suppose we have an int array called arr.

int arr[ 10 ] ;

int * p1, * p2 ;

p1 = arr + 3 ; // p1 == & arr[ 3 ]

p2 = p1 - 2 ; // p1 == & arr[ 1 ]

We can have a pointer point to the middle of the array (like p1). We can then

create a new pointer that is two elements back of p1.

As it turns out, we can even point way past the end of the array.

int arr[ 10 ] ;

int * p1, * p2 ;

p1 = arr + 100 ; // p1 == & arr[ 100 ]

113
p2 = arr - 100 ; // p1 == & arr[ -100 ]

The compiler still computes an address, and does not core dump. For example,

if arr is address 1000ten, then p1 is address 1400ten and p2 is address 600ten. The

compiler still uses the formula for pointer arithmetic to compute the address.

Passing the Array Size

This is why it's usually important to keep track of the array size and pass it in as a

parameter. When you're in a function, you can't tell the size of the array. All you

have is a pointer, and that's it. No indication of how big that array is.

If you try to compute the array's size using sizeof, you just get 4.

// Compiler translates arr's type to int *

void foo ( int arr[], int size ) {

// Prints 4

cout << sizeof( arr ) ;

int arr2[ 10 ] ;

// Prints 40

cout << sizeof( arr2 ) ;

114
If you declare a local array (not using dynamic memory allocation), you can get the

size of the array. However, once you pass that array, all that's passed is the

address. There's no information about the array size anymore.

Two dimensional Arrays

Suppose you declare:

int arr[ 10 ][ 12 ] ;

What type is arr? You may have been told that it's int **, but that's incorrect. Two

dimensional arrays (as declared above) are contiguous in memory. If you create an

array of pointers to dynamically allocated arrays, such as:

int * arr[ 10 ] ;

then, arr has type int ** (or at least has a type compatible with int **).

The type is rather complicated, and is due to the fact that arr[ 0 ] = & arr[ 0 ][ 0

], arr[ 1 ] = & arr[ 1 ][ 0 ], and in general, arr[ i ] = & arr[ i ][ 0 ].

Pointer arithmetic says that arr + i gives you & arr[ i ], yet this skips an entire

row of 12 elements, i.e., skips 48 bytes times i. Thus, if arr is address 1000ten,

then arr + 2 is address 1096ten.

If the array's type were truly int **, pointer arithmetic would say the address

is 1008ten, so that doesn't work.

So, what's the lesson?

A two-dimensional array is not the same as an array of pointers to 1D

arrays

115
The actual type for a two-dimensional array, is declared as:

int (*ptr)[ 10 ] ;

Which is a pointer to an array of 10 elements. Thus, when you do pointer

arithmetic, it can compute the size of the array and handle it correctly. The

parentheses are NOT optional above. Without the parentheses, ptr becomes an

array of 10 pointers, not a pointer to an array of 10 ints.

If you have a conventional two dimensional array, and you want to compute the

address for arr[ row ][ col ] and you have ROWS rows (where ROWS is some

constant) and COLS columns, then the formula for the address in memory is:

addr( & arr[ row ][ col ] ) = addr( arr ) + [ sizeof( int ) * COLS * row ]

+ [ sizeof( int ) * col ]

Two dimensional arrays are stored in row major order, that is, row by row. Each row

contains COLS elements, which is why you see COLS in the formula. In fact, you

don't see ROWS.

When you have a 2D array as a parameter to a function, there's no need to specify

the number of rows. You just need to specify the number of columns. The reason is

the formula above. The compiler can compute the address of an element in a 2D

array just knowing the number of columns.

Thus, the following is valid in C, i.e. it compiles:

void sumArr( int arr[][ COLS ], int numRows, int numCols ) {

The following is also valid in C.


116
void sumArr( int arr[ ROWS ][ COLS ], int numRows, int numCols ) {

The compiler ignores ROWS. Thus, any 2D array with the COLS columns and any

number of rows can be passed to this function.

The following, however, is NOT valid in C:

void sumArr( int arr[][], int numRows, int numCols ) {

It's not syntactically valid to declare int arr[][] in C.

However, it's OK to write:

void sumArr( int **arr, int numRows, int numCols ) {

Note that int **arr is an array of pointers (possibly to 1D arrays), while int arr[][

COLS ] is a 2D array. They are not the same type, and are not interchangeable.

Pointer Subtraction

It turns out you can subtract two pointers of the same type. The result is the

distance (in array elements) between the two elements.

For example:

int arr[ 10 ] ;

int * p1 = arr + 2 ;

int * p2 = arr + 5 ;

117
cout << ( p2 - p1 ) ; // Prints 3

cout << ( p1 - p3 ) ; // Prints -3

The formula used is rather simple. Assume that p1 and p2 are both pointers of

type T *. Then, the value computed is:

( p2 - p1 ) == ( addr( p2 ) - addr( p1 ) ) / sizeof( T )

This can result in negative values if p2 has a smaller address than p1.

p2 and p1 need not point to valid elements in an array. The formula above still

works even when p2 and p1 contain invalid addresses (because they

contain some address).

Pointer subtraction isn't used very much, but can be handy to determine the

distances between two array elements (i.e., the difference in the array indexes).

You may not know exactly which element you're pointing to using pointer

subtraction, but you can tell relative distances.

Dereferencing causes problems

In general, you can make a pointer point anywhere. For example, arr + 1000 is

valid, even if the array has only ten elements. arr - 1000 is also valid. That is, you

can compute it, and it won't core dump.

However, dereferencing pointers to invalid memory causes problems. Thus, *( arr -

1000 ) core dumps because you are trying to access the address.

Here's an analogy. You can write down anyone's address on a piece of paper,

however, you can't just go inside the person's house at that address (which is like
118
dereferencing). Thus, computing addresses is fine, dereferencing it may cause

problems if the address is not a valid address in memory.

119

You might also like