Pointers
Pointers
ENGINEERING COLLEGE
(AUTONOMOUS)
| VISAKHAPATNAM
I B.Tech I Semester
PSPC
1
Syllabus
Arrays,
Pointers
Introduction, Operations on Arrays, Two Dimensional Arrays,
Multidimensional Arrays. Pointers: Concept of a Pointer, Declaring
and Initializing Pointer Variables, Pointer Expressions and
Address
Arithmetic, Null Pointers, Generic Pointers, Pointers and Arrays,
Pointer to Pointer, Command Line Arguments.
Array:
• An array is a collection of similar type of data items and each
data item is called an element of the array.
• The data type of the elements may be any valid data type like char, int
or float.
• The elements of array share the same variable name but each element
has a different index number known as subscript.
• For the above problem we can take an array variable age[100] of type
int. The size of this array variable is 100 so it is capable of storing 100
integer values. The individual elements of this array are-
age[0], age[l], age[2], age[3], age[4], ……….. age[98], age[99]
• In C, the subscripts start from zero, so age[0] is the first element,
age[1] is the second element of array and so on.
• Arrays can be single dimensional or multidimensional. The number of
subscripts determines the dimensional of array.
• A one-dimensional array has one subscript, two dimensional array has
two subscripts and so on.
• The one-dimensional arrays are known as vectors and
two- dimensional arrays are known as matrices.
One Dimensional Array:
1) Declaration of 1-D Array:
Syntax:
data_type array_name[size];
Here array_name denotes the name of the array and it can be any valid
C identifier, data_type is the data type of the elements of array. The size
of the array specifies the number of elements that can be stored in the
array.
Ex:
• int age[100]; .
• float sal[15];
• char grade[20];
• When the array is declared, the compiler allocates space in the
memory sufficient to hold all the elements of the array, so the compiler
should know the size of array at the compile time.
• The symbolic constants can also be used to specify the size of array.
For example-
#define SIZE 10
int main(
{
float sal
[SIZE] ; /
*Valid*/
….
}
2 Accessing 1-D Array Elements:
• The elements of an array can be accessed by specifying the array name
followed by subscript in brackets. In C, the array subscripts start
from
0. Hence if there is an array of size 5 then the valid subscripts will be
from 0 to 4.
• Let us take an array int
arr[5]; /*Size of array arr is 5, can hold five integer elements*/
• The elements of this array are-
arr[0], arr[l], arr[2], arr[3], arr[4]
• The subscript can be any expression that yields an integer value. It can
be any integer constant, integer variable, integer expression or return
value(int from a function call.
• For example, if i and j are integer variables then these are some valid
subscripted array elements-
arr[3]
arr[i]
arr[i+j]
arr[2*j]
arr[i+
+]
3 Processing 1-D Arrays:
• For processing arrays we generally use a for loop and the loop variable
is used at the place of subscript.
• The initial value of loop variable is taken 0 since array subscripts start
from zero.
• The loop variable is increased by 1 each time so that we can access and
process the next element in the array. The total number of passes in the
loop will be equal to the number of elements in the array
Ex: Program to count the even and odd numbers in a
array
#include<stdio.h
> #define SIZE 5
int main( {
int arr[SIZE], i,
even=0,
odd=0;
for(i=0;
i<SIZE; i++
{
printf ("Enter the value for arr[%d]:", i;
scanf("%d", &arr[i];
if(arr[i]%2 == 0
even++;
else
odd++;
4 Initialization of I-D Array:
• After declaration, the elements of a local array have garbage value. We can explicitly
initialize arrays at the time of declaration.
• The syntax for initialization of an array
is-
data_type array_name[size]={valuel,
value2, …… valueN };
• For example
int marks[5] = {50, 85, 70, 65, 95};
• The values of the array elements after this
initialization are
marks[0] : 50, marks[1]: 85,
marks[2]: 70, marks[3]: 65,
marks[4]: 95
• While initializing 1-D arrays, it is optional to specify the size of the array. If the size is
omitted during initialization then the compiler assumes the size of array equal to the
• If during initialization the number of initializers is less than the size of
array then, all the remaining elements of array are assigned value zero.
For example-
int marks[5] = {99, 78};
• Here the size of array is 5 while there are only 2 initializers. After this
initialization the value of the elements are as-
marks[0] : 99, marks[l] : 78, marks[2] : 0, marks[3] : 0, marks[4] : 0
• We can't copy all the elements of an array to another array by simply
assigning it to the other array:.
• For example if we have two arrays a[5] and b[5] then
int a[5] = {1, 2, 3, 4, 5}; We'll have to copy all the elements of array one by
one, using a for loop.
int b[5];
for( i = 0; i < 5; i++
b = a; /*Not valid*/ b[i] = a[i]; /* Valid */
Two Dimensional Array
1 Declaration and Accessing Individual Elements of a 2-D array:
• The syntax of declaration of a 2-D array is similar to that of I-D
arrays, but here we have two subscripts.
data_type array_name[rowsize][columnsize];
• Here· rowsize specifies the number of rows and columnsize represents
the number of columns in the array. The total number of elements in
the array are rowsize * columnsize.
• For example
int arr[4][5];
• Example
int var = 10;
int *ptr;
ptr = &var;
Pointer Dereferencing:
• Dereferencing a pointer is the process of accessing the value stored in
the memory address specified in the pointer. We use the same (*
dereferencing operator that we used in the pointer declaration.
Ex 1:
#include <stdio.h>
int main(
{
int var = 10;
int* ptr;
ptr = &var;
printf("Value at ptr = %u \n", ptr;
printf("Value at var = %d \n", var;
printf("Value at *ptr = %d \n", *ptr;
return 0;
}
Ex 2:
int *iptr, age = 30;
float *fptr, sal = 1500.50;
iptr = &age;
fptr = &sal;
• Now iptr contains the address of variable age i.e. it points to variable age,
similarly fptr points to variable sal. Since iptr is declared as a pointer of
type int, we should assign address of only integer variables to it. If we
assign .address of some other data type then compiler won't show any error
,but the output will be incorrect.
Pointer Expressions and Address
Arithmetic:
• All types of arithmetic operations are not possible with pointers. The only
valid operations that can be performed are as-
(1) Addition of an integer to a pointer and increment operation.
Ex: p1+3, p++
(2) Subtraction of an integer from a pointer and decrement operation.
Ex: p1-2, p--
(3) Subtraction of a pointer from another pointer of same type.
Ex: p1-p2
Note: When a pointer is incremented/decremented, it increases/decreases it's
value by the length of the data type it points to. (For characters 1 byte,
integer 2 bytes, Float 4 bytes and double 8 bytes
• But pointers can be used to perform arithmetic operations on the
value they point to.
e.g.: a= *p1 * *p2 / *p3; ...same as ((*p1 * (*p2/(*p3
b= 10 - *p3/ *p2; ...same as ( 10 -(*p3/(*p2
Note: Keep a space between / and to not to make compiler interpret it to be
a comment.
• Pointers can also be compared using relational operators.
Ex: p1>p2, p1==p2, p1 != p2
• Pointers cannot be divided or multiplied or added
Ex: p1 / p2 or p1 * p2 or p1/3 or p1+p2
Ex:
int a = 5, *pi = &a; Suppose the address of variables a, b and c are 1000,
float b = 2.2, *pf = &b; 4000 and 5000 respectively, so initially values of pi, pf,
pc will be 1000, 4000 and 5000.
char c = 'x', *pc= &c;
Introduction to Programming
Example program to understand the postfix/prefix increment/decrement
in a pointer variable of base type int:
#include<stdio.h
> int main( {
int a=5;
int *p;
p=&a;
printf ("Value of p = Address of a = %u\n", p;
printf ("Value of p = %u\n", ++p;
printf ("Value of p = %u\n", p++;
printf ("Value of p = %u\n", --p;
printf ("Value of p = %u\n", p--;
printf ("Value of p = %u\n", p;
}
• Suppose ptr is an integer pointer and x in an integer variable. Now we'll see how
the
pointer
i) x = expressions
*ptr++; given below are interpreted.
Let us take an example and understand how these expressions are
ii) x = *++ptr;
interpreted. Suppose value at address 2000 is 25, value at address
iii) x = ++*ptr; 2002 is 38, ptr is an integer pointer that contains address 2000
iv) x = (*ptr++; hence value of *ptr is 25. Now we'll see what will be the results in
the above four cases, if this is the initial condition in all cases.
(i x =*ptr++;
The expression *ptr++ is equivalent to *(ptr++, since these operators associate
from right to left. Hence the increment operator will be applied to ptr, and not to
*ptr. The increment operator is postfix, so first the value of ptr will be used in the
expression and then it will be incremented. Hence firstly the integer pointed to by
ptr will be dereferenced and assigned to x and then ptr will be incremented. This is
same as-
x = *ptr;
ptr = ptr + 1;
Value of x = 25, Address contained in ptr = 2002, *ptr = 38
ii) x = *++ptr;
The expression *++ptr is equivalent to *(++ptr. Here also the increment operator is
applied to ptr. The increment operator is prefix, so first rtr will be incremented and
then its new value will be used in the expression. Hence firstly the value of ptr is
incremented, then value at the new address is dereferenced and assigned to x. This is
same as-
ptr = ptr+ 1;
x = *ptr;
Value of x = 38,
Address contained
in ptr = 2002, *ptr
= 38
iii) x = ++*ptr;
The expression ++*ptr is equivalent to ++(*ptr. Here the increment operator is
applied over *ptr and not ptr. So here the value of pointer will not change but the
value pointed to by the pointer will change i.e., *ptr will increment. Since the
increment operator is prefix hence first the value of *ptr will increment and then this
value will be assigned to x. This is same as-
*ptr = *ptr + 1;
iv x = (*ptr++;
. Here also the increment operator is applied over *ptr and since it is postfix
increment hence first the value of *ptr will be assigned to x and then it will be
incremented. This is same as-
x = *ptr;
*ptr = *ptr+1;
Value of x = 25, Address contained in ptr = 2000, *ptr = 26
NULL
pointer:
• A null pointer is a pointer that does not point to any memory location.
It is a special value used to indicate that the pointer is not intended to
point to a valid object or memory address.
• Dereferencing a null pointer (trying to access the memory it points to
often leads to undefined behavior, crashes, or runtime errors.
• The syntax of a null pointer can be defined in two ways
int *pointer_var = NULL;
OR
int *pointer_var =0
Ex:
#include <stdio.h>
int main( {
int *ptr = NULL; // Initializing a pointer with NULL
int value = *ptr; // Attempting to dereference a null pointer, This will result in undefined
//behavior
printf("Value: %d\n", value; // The following line might cause a crash or unexpected
//behavior
return 0;
}
Generic Pointers:
• In C, a generic pointer is a void pointer (void *. A void pointer is
a special type of pointer that can point to objects of any data type.
• The syntax of declaration of a void pointer
is- void *vpt;
• Here void is a keyword and vpt is declared as a pointer of void type.
For example,
• We can assign address of any data type to a void pointer and a void
pointer can be assigned to a pointer of any data type.
• A void pointer can't be dereferenced simply by using indirection
operator. Before dereferencing, it should be type cast to appropriate
pointer data type. For example if vpt is a void pointer and it holds the
address of an integer variable then we can't dereference it just by
writing *vpt. We'll have to write *(int *vpt,.where leftmost asterisk is
the indirection, operator and (int * is used for typecasting.
Example program to understand the dereferencing of a void pointer:
#include<stdio.h>
int main(
{
int a=3;
float b=3.4,*fp=&b;
void *vpt;
vpt=&a;
printf("Value of a =
%d\n",*(int *vpt;
*(int *vpt=12;
printf("Value of a = %d\n",*(int *vpt;
vpt=fp;
printf("Value of b %f\n",*(float *vpt;
return 0;
}
Pointers and
1Arrays:
Pointers and One Dimensional Arrays:
• The elements of an array are stored in contiguous memory
locations. Suppose we have an array arr[5] of type int.
int arr[5] = {1, 2, 3, 4, 5};
This is stored in memory as-
• Here 5000 is the address of first element, and since each element (type int
takes 2 bytes so address of next-element is 5002, and so on. The address of
first element of the array is also known as the base address of the array.
• The name of the array 'arr' denotes the address of 0th element of array
which is 2000. The address of 0th element can also be given by &arr[0],
so arr and &arr[0] represent the same address.
• The name of an array is a constant pointer, and according to. pointer
arithmetic when an integer is added to a pointer then we get the
address of next element of same base type. Hence (arr+1 will denote the
address of the next element arr[l]. Similarly (arr+2 denotes the address
of arr[2] and so on.
In general we can write,
• The pointer expression (arr + i denotes the same address as &arr[i].
• Now if we dereference arr, then we get the 0th element of array, i.e.
expression *arr or *(arr+0 represents 0th element of array. Similarly on
dereferencing (arr+ 1 we get the 1st element and so on.
Example Program to print the value and address of elements of an
array using pointer notation:
#include<stdio.h>
int main (
{
int arr[5]={5,10,15,20,25};
int i;
for(i=0;i<5;i++
{
printf ("Value
of arr [%d] =
%d\
t",i,*(arr+i;
printf("Addre
ss of arr[%d]
= %u\n",i,
arr+i;
• Accessing array elements by pointer notation is faster than accessing
them by subscript notation, because the compiler ultimately changes
the subscript notation to pointer notation and then accesses the array
elements.
• Array subscripting is commutative, i.e. arr[i] is same as i[arr].
• We had seen earlier that-
arr[i] is equivalent to *(arr + i
• Now *(arr + i is same as *(i + arr, so we can write. the above
statement as
arr[i] is equivalent to *(i + arr
2 Pointers And Two Dimensional Arrays:
• In a two dimensional array we can access each element by using two subscripts, where
first subscript represents row number and second subscript represents the column number.
• The elements of 2-D array can be accessed with the help of pointer notation also. Suppose
arr is a 2-D array, then we can access any element arr[i][j] of this array using the pointer
expression *( *(arr+i + j .
• Let us take a two dimension array arr[3][4]-
int arr[3][4] = { {10, 11, 12, 13}, {20, 21, 22, 23}, {30, 31, 32, 33} };
The following figure shows how the above 2-D array will be stored in memory.
• arr points to the 0th 1-D array, (arr+1 points to the 1st 1-D array and (arr+2 points to
the 2nd 1-D array.
• In general we can write, arr+i Points to ith element of arr Points to ith 1-D array.
• *(arr+i gives us the base address of ith 1-D array.
• In general we can write- *(arr+i, arr[i] - Base address of ith l-D array - Points to 0th
element of ith 1-D array
Pointer to Pointer:
• We can store the address of a pointer variable in some other variable, which is
known as a pointer to pointer variable.
• The syntax of declaring a pointer to pointer is as-
data_type **pptr;
• Here variable pptr is a pointer to pointer and it can point to a pointer pointing to a
variable of type data_type. The double asterisk used in the declaration inforins the
compiler that a pointer to poinfer
• is being declared. Now let us take an example
int a = 5;
int *pa = &a;
int **ppa = &pa;
• Here type of variable a is int, type of variable pa is (int* or pointer to int, and type
of variable ppa is (int ** or pointer to pointer to int.
Ex: Program to understand pointer to pointer
#include<stdio.h>
int main(
{
int a=5;
int *pa;
int **ppa;
pa=&a;
ppa=&pa;
printf ("Address of a = %u\n", &a;
printf("Value of pa = Address of a = %u\n",pa;
printf ("Value of *pa = Value of a = %d\n", *pa;
printf ("Address of pa = %u\n" ,&pa ;
printf ("Value of ppa = Address of pa = %u\n" ,ppa;
printf ("Value of *ppa = Value of pa= %u\n", *ppa;
printf("Value of **ppa = Value of a = %d\n", **ppa;
printf("Address of ppa = %u\n",&ppa;
return 0;
}
Command-line arguments:
• Command-line arguments are the values given after the name of the
program in the command-line shell of Operating Systems. Command-
line arguments are handled by the main( function of a C program.
• To pass command-line arguments, we typically define main( with two
arguments: the first argument is the number of command-line
arguments and the second is a list of command-line arguments.
• Syntax:
int main(int argc, char *argv[] int main(int argc, char **argv
{
/* ... */ or {
/* ... */
} }
Here,
• argc (ARGument Count is an integer variable that stores the number
of command-line arguments passed by the user including the name of
the program. So if we pass a value to a program, the value of argc would
be 2 (one for argument and one for program name
• The value of argc should be non-negative.
• argv (ARGument Vector is an array of character pointers listing
all the arguments.
• If argc is greater than zero, the array elements from argv[0] to argv[argc-
1] will contain pointers to strings.
• argv[0] is the name of the program , After that till argv[argc-1]
every element is command -line arguments.
Example program to demonstrate Command Line
Arguments:
#include <stdio.h>
int main(int argc, char* argv[]
{
printf("You have entered %d arguments:\n", argc;
for (int i = 0; i < argc; i++ {
if (i==0
printf("Program name is %s\n",
argv[i];
else
printf("%s\n", argv[i];
}
return 0;
}