Unit 5
Unit 5
A pointer is defined as a derived data type that can store the address of
other C variables or a memory location. We can access and manipulate the
data stored in that memory location using pointers.
As the pointers in C store the memory addresses, their size is independent
of the type of data they are pointing to. This size of pointers in C only
depends on the system architecture.
Syntax of C Pointers
The syntax of pointers is similar to the variable declaration in C, but we use
the ( * ) dereferencing operator in the pointer declaration.
datatype * ptr;
where
• ptr is the name of the pointer.
• datatype is the type of data it is pointing to.
The above syntax is used to define a pointer to a variable. We can also
define pointers to functions, structures, etc.
1. Pointer Declaration
In pointer declaration, we only declare the pointer but do not initialize it. To
declare a pointer, we use the ( * ) dereference operator before its name.
Example
int *ptr;
The pointer declared here will point to some random memory address as it
is not initialized. Such pointers are called wild pointers.
2. Pointer Initialization
Pointer initialization is the process where we assign some initial value to the
pointer variable. We generally use the ( & ) addressof operator to get the
memory address of a variable and then store it in the pointer variable.
Example
int var = 10;
int * ptr;
ptr = &var;
We can also declare and initialize the pointer in a single step. This method
is called pointer definition as the pointer is declared and initialized at the
same time.
Example
int *ptr = &var;
Note: It is recommended that the pointers should always be initialized to
some value before starting using it. Otherwise, it may lead to number of
errors.
3. Pointer Dereferencing
Dereferencing a Pointer in C
C Pointer Example
• C
// Driver program
int main()
{
geeks();
return 0;
}
Output
Value at ptr = 0x7fff1038675c
Value at var = 10
Value at *ptr = 10
Types of Pointers in C
Pointers in C can be classified into many different types based on the
parameter on which we are defining their types. If we consider the type of
variable stored in the memory location pointed by the pointer, then the
pointers can be classified into the following types:
1. Integer Pointers
As the name suggests, these are the pointers that point to the integer
values.
Syntax
int *ptr;
These pointers are pronounced as Pointer to Integer.
Similarly, a pointer can point to any primitive data type. It can point also
point to derived data types such as arrays and user-defined data types such
as structures.
2. Array Pointer
Pointers and Array are closely related to each other. Even the array name is
the pointer to its first element. They are also known as Pointer to Arrays.
We can create a pointer to an array using the given syntax.
Syntax
char *ptr = &array_name;
Pointer to Arrays exhibits some interesting properties which we discussed
later in this article.
3. Structure Pointer
4. Function Pointers
Function pointers point to the functions. They are different from the rest of
the pointers in the sense that instead of pointing to the data, they point to
the code. Let’s consider a function prototype – int func (int,
char), the function pointer for this function will be
Syntax
int (*ptr)(int, char);
Note: The syntax of the function pointers changes according to the function
prototype.
5. Double Pointers
In C language, we can define a pointer that stores the memory address of
another pointer. Such pointers are called double-pointers or pointers-to-
pointer. Instead of pointing to a data value, they point to another pointer.
Syntax
datatype ** pointer_name;
Dereferencing Double Pointer
*pointer_name; // get the address stored in the inner level pointer
**pointer_name; // get the value pointed by inner level pointer
Note: In C, we can create multi-level pointers with any number of levels
such as – ***ptr3, ****ptr4, ******ptr5 and so on.
6. NULL Pointer
The Null Pointers are those pointers that do not point to any memory
location. They can be created by assigning a NULL value to the pointer. A
pointer of any type can be assigned the NULL value.
Syntax
data_type *pointer_name = NULL;
or
pointer_name = NULL
It is said to be good practice to assign NULL to the pointers currently not in
use.
7. Void Pointer
The Void pointers in C are the pointers of type void. It means that they do
not have any associated data type. They are also called generic pointers as
they can point to any type and can be typecasted to any type.
Syntax
void * pointer_name;
One of the main properties of void pointers is that they cannot be
dereferenced.
8. Wild Pointers
The Wild Pointers are pointers that have not been initialized with
something yet. These types of C-pointers can cause problems in our
programs and can eventually cause them to crash.
Example
int *ptr;
char *str;
9. Constant Pointers
The pointers pointing to a constant value that cannot be modified are called
pointers to a constant. Here we can only access the data pointed by the
pointer, but cannot modify it. Although, we can change the address stored
in the pointer to constant.
Syntax
const data_type * pointer_name;
Size of Pointers in C
The size of the pointers in C is equal for every pointer type. The size of the
pointer does not depend on the type it is pointing to. It only depends on the
operating system and CPU architecture. The size of pointers in C is
• 8 bytes for a 64-bit System
• 4 bytes for a 32-bit System
The reason for the same size is that the pointers store the memory
addresses, no matter what type they are. As the space required to store the
addresses of the different memory locations is the same, the memory
required by one pointer type will be equal to the memory required by other
pointer types.
Advantages of Pointers
Following are the major advantages of pointers in C:
• Pointers are used for dynamic memory allocation and deallocation.
• An Array or a structure can be accessed efficiently with pointers
• Pointers are useful for accessing memory locations.
• Pointers are used to form complex data structures such as linked
lists, graphs, trees, etc.
• Pointers reduce the length of the program and its execution time
as well.
Disadvantages of Pointers
Pointers are vulnerable to errors and have following disadvantages:
• Memory corruption can occur if an incorrect value is provided to
pointers.
• Pointers are a little bit complex to understand.
• Pointers are majorly responsible for memory leaks in C.
• Pointers are comparatively slower than variables in C.
• Uninitialized pointers might cause a segmentation fault.
• C
return;
}
// Driver program
int main()
{
geeks();
return 0;
}
Output
Elements of the array are: 5 10 15
Not only that, as the array elements are stored continuously, we can pointer
arithmetic operations such as increment, decrement, addition, and
subtraction of integers on pointer to move between array elements.
After defining the structure pointer, we need to initialize it, as the code is shown:
1. ptr = &structure_variable;
We can also initialize a Structure Pointer directly during the declaration of a pointer.
Pointer.c
1. #include <stdio.h>
2.
3. // create a structure Subject using the struct keyword
4. struct Subject
5. {
6. // declare the member of the Course structure
7. char sub_name[30];
8. int sub_id;
9. char sub_duration[50];
10. char sub_type[50];
11. };
12.
13. int main()
14. {
15. struct Subject sub; // declare the Subject variable
16. struct Subject *ptr; // create a pointer variable (*ptr)
17. ptr = ⊂ /* ptr variable pointing to the address of the structure variable sub *
/
18.
19. strcpy (sub.sub_name, " Computer Science");
20. sub.sub_id = 1201;
21. strcpy (sub.sub_duration, "6 Months");
22. strcpy (sub.sub_type, " Multiple Choice Question");
23.
24. // print the details of the Subject;
25. printf (" Subject Name: %s\t ", (*ptr).sub_name);
26. printf (" \n Subject Id: %d\t ", (*ptr).sub_id);
27. printf (" \n Duration of the Subject: %s\t ", (*ptr).sub_duration);
28. printf (" \n Type of the Subject: %s\t ", (*ptr).sub_type);
29.
30. return 0;
31.
32. }
Output:
In the above program, we have created the Subject structure that contains different
data elements like sub_name (char), sub_id (int), sub_duration (char), and sub_type
(char). In this, the sub is the structure variable, and ptr is the structure pointer variable
that points to the address of the sub variable like ptr = &sub. In this way, each *ptr is
accessing the address of the Subject structure's member.
Program to access the structure member using structure pointer
and arrow (->) operator
Let's consider a program to access the structure members using the pointer and arrow
(->) operator in C.
Pointer2.c
1. #include <stdio.h>
2.
3. // create Employee structure
4. struct Employee
5. {
6. // define the member of the structure
7. char name[30];
8. int id;
9. int age;
10. char gender[30];
11. char city[40];
12. };
13.
14. // define the variables of the Structure with pointers
15. struct Employee emp1, emp2, *ptr1, *ptr2;
16.
17. int main()
18. {
19. // store the address of the emp1 and emp2 structure variable
20. ptr1 = &emp1;
21. ptr2 = &emp2;
22.
23. printf (" Enter the name of the Employee (emp1): ");
24. scanf (" %s", &ptr1->name);
25.
26. printf (" Enter the id of the Employee (emp1): ");
27. scanf (" %d", &ptr1->id);
28. printf (" Enter the age of the Employee (emp1): ");
29. scanf (" %d", &ptr1->age);
30. printf (" Enter the gender of the Employee (emp1): ");
31. scanf (" %s", &ptr1->gender);
32. printf (" Enter the city of the Employee (emp1): ");
33. scanf (" %s", &ptr1->city);
34.
35. printf (" \n Second Employee: \n");
36. printf (" Enter the name of the Employee (emp2): ");
37. scanf (" %s", &ptr2->name);
38.
39. printf (" Enter the id of the Employee (emp2): ");
40. scanf (" %d", &ptr2->id);
41. printf (" Enter the age of the Employee (emp2): ");
42. scanf (" %d", &ptr2->age);
43. printf (" Enter the gender of the Employee (emp2): ");
44. scanf (" %s", &ptr2->gender);
45. printf (" Enter the city of the Employee (emp2): ");
46. scanf (" %s", &ptr2->city);
47.
48. printf ("\n Display the Details of the Employee using Structure Pointer");
49. printf ("\n Details of the Employee (emp1) \n");
50. printf(" Name: %s\n", ptr1->name);
51. printf(" Id: %d\n", ptr1->id);
52. printf(" Age: %d\n", ptr1->age);
53. printf(" Gender: %s\n", ptr1->gender);
54. printf(" City: %s\n", ptr1->city);
55.
56. printf ("\n Details of the Employee (emp2) \n");
57. printf(" Name: %s\n", ptr2->name);
58. printf(" Id: %d\n", ptr2->id);
59. printf(" Age: %d\n", ptr2->age);
60. printf(" Gender: %s\n", ptr2->gender);
61. printf(" City: %s\n", ptr2->city);
62. return 0;
63. }
Output:
Second Employee:
Enter the name of the Employee (emp2): Maria
Enter the id of the Employee (emp2): 1109
Enter the age of the Employee (emp2): 23
Enter the gender of the Employee (emp2): Female
Enter the city of the Employee (emp2): Los Angeles
For example:
1. int (*ip) (int);
In the above declaration, *ip is a pointer that points to a function which returns an int
value and accepts an integer value as an argument.
In the above declaration, *fp is a pointer that points to a function that returns a float
value and accepts a float value as an argument.
Till now, we have learnt how to declare the function pointer. Our next step is to assign
the address of a function to the function pointer.
In the above declaration, 'fp' pointer contains the address of the 'func' function.
Or
1. result = fp(a , b); // Calling a function using function pointer, and indirecti
on operator can be removed.
The effect of calling a function by its name or function pointer is the same. If we are
using the function pointer, we can omit the indirection operator as we did in the
second case. Still, we use the indirection operator as it makes it clear to the user that
we are using a function pointer.
1. #include <stdio.h>
2. int add(int,int);
3. int main()
4. {
5. int a,b;
6. int (*ip)(int,int);
7. int result;
8. printf("Enter the values of a and b : ");
9. scanf("%d %d",&a,&b);
10. ip=add;
11. result=(*ip)(a,b);
12. printf("Value after addition is : %d",result);
13. return 0;
14. }
15. int add(int a,int b)
16. {
17. int c=a+b;
18. return c;
19. }
Output
Passing a function's address as an argument to other function
We can pass the function's address as an argument to other functions in the same way
we send other arguments to the function.
1. include <stdio.h>
2. void func1(void (*ptr)());
3. void func2();
4. int main()
5. {
6. func1(func2);
7. return 0;
8. }
9. void func1(void (*ptr)())
10. {
11. printf("Function1 is called");
12. (*ptr)();
13. }
14. void func2()
15. {
16. printf("\nFunction2 is called");
17. }
In the above code, we have created two functions, i.e., func1() and func2(). The func1()
function contains the function pointer as an argument. In the main() method, the
func1() method is called in which we pass the address of func2. When func1() function
is called, 'ptr' contains the address of 'func2'. Inside the func1() function, we call the
func2() function by dereferencing the pointer 'ptr' as it contains the address of func2.
Output
DYNAMIC MEMORY ALLOCATION
Since C is a structured language, it has some fixed rules for programming.
One of them includes changing the size of an array. An array is a collection
of items stored at contiguous memory locations.
As can be seen, the length (size) of the array above is 9. But what if there is
a requirement to change this length (size)? For example,
• If there is a situation where only 5 elements are needed to be
entered in this array. In this case, the remaining 4 indices are just
wasting memory in this array. So there is a requirement to lessen
the length (size) of the array from 9 to 5.
• Take another situation. In this, there is an array of 9 elements with
all 9 indices filled. But there is a need to enter 3 more elements in
this array. In this case, 3 indices more are required. So the length
(size) of the array needs to be changed from 9 to 12.
This procedure is referred to as Dynamic Memory Allocation in C.
Therefore, C Dynamic Memory Allocation can be defined as a procedure in
which the size of a data structure (like Array) is changed during the runtime.
C provides some functions to achieve these tasks. There are 4 library
functions provided by C defined under <stdlib.h> header file to facilitate
dynamic memory allocation in C programming. They are:
1. malloc()
2. calloc()
3. free()
4. realloc()
Let’s look at each of them in greater detail.
C malloc() method
The “malloc” or “memory allocation” method in C is used to dynamically
allocate a single large block of memory with the specified size. It returns a
pointer of type void which can be cast into a pointer of any form. It doesn’t
Initialize memory at execution time so that it has initialized each block with
the default garbage value initially.
Syntax of malloc() in C
ptr = (cast-type*) malloc(byte-size)
For Example:
#include <stdio.h>
#include <stdlib.h>
int main()
{
return 0;
}
Output
Enter number of elements: 5
Memory successfully allocated using malloc.
The elements of the array are: 1, 2, 3, 4, 5,
C calloc() method
1. “calloc” or “contiguous allocation” method in C is used to
dynamically allocate the specified number of blocks of memory of
the specified type. it is very much similar to malloc() but has two
different points and these are:
2. It initializes each block with a default value ‘0’.
3. It has two parameters or arguments as compare to malloc().
Syntax of calloc() in C
ptr = (cast-type*)calloc(n, element-size);
here, n is the no. of elements and element-size is the size of each
element.
For Example:
ptr = (float*) calloc(25, sizeof(float));
This statement allocates contiguous space in memory for 25 elements each
with the size of the float.
#include <stdio.h>
#include <stdlib.h>
int main()
{
return 0;
}
Output
Enter number of elements: 5
Memory successfully allocated using calloc.
The elements of the array are: 1, 2, 3, 4, 5,
C free() method
“free” method in C is used to dynamically de-allocate the memory. The
memory allocated using functions malloc() and calloc() is not de-allocated
on their own. Hence the free() method is used, whenever the dynamic
memory allocation takes place. It helps to reduce wastage of memory by
freeing it.
Syntax of free() in C
free(ptr);
Example of free() in C
• C
#include <stdio.h>
#include <stdlib.h>
int main()
{
return 0;
}
Output
Enter number of elements: 5
Memory successfully allocated using malloc.
Malloc Memory successfully freed.
#include <stdio.h>
#include <stdlib.h>
int main()
{
free(ptr);
}
return 0;
}
Output
Enter number of elements: 5
Memory successfully allocated using calloc.
The elements of the array are: 1, 2, 3, 4, 5,
Storage Classes in C
C Storage Classes are used to describe the features of a variable/function.
These features basically include the scope, visibility, and lifetime which help
us to trace the existence of a particular variable during the runtime of a
program.
C language uses 4 storage classes, namely:
1. auto
This is the default storage class for all the variables declared inside a
function or a block. Hence, the keyword auto is rarely used while writing
programs in C language. Auto variables can be only accessed within the
block/function they have been declared and not outside them (which defines
their scope). Of course, these can be accessed within nested blocks within
the parent block/function in which the auto variable was declared.
However, they can be accessed outside their scope as well using the
concept of pointers given here by pointing to the very exact memory
location where the variables reside. They are assigned a garbage value by
default whenever they are declared.
2. extern
Extern storage class simply tells us that the variable is defined elsewhere
and not within the same block where it is used. Basically, the value is
assigned to it in a different block and this can be overwritten/changed in a
different block as well. So an extern variable is nothing but a global variable
initialized with a legal value where it is declared in order to be used
elsewhere. It can be accessed within any function/block.
Also, a normal global variable can be made extern as well by placing the
‘extern’ keyword before its declaration/definition in any function/block. This
basically signifies that we are not initializing a new variable but instead, we
are using/accessing the global variable only. The main purpose of using
extern variables is that they can be accessed between two different files
which are part of a large program.
3. static
This storage class is used to declare static variables which are popularly
used while writing programs in C language. Static variables have the
property of preserving their value even after they are out of their scope!
Hence, static variables preserve the value of their last use in their scope. So
we can say that they are initialized only once and exist till the termination of
the program. Thus, no new memory is allocated because they are not re-
declared.
Their scope is local to the function to which they were defined. Global static
variables can be accessed anywhere in the program. By default, they are
assigned the value 0 by the compiler.
4. register
This storage class declares register variables that have the same
functionality as that of the auto variables. The only difference is that the
compiler tries to store these variables in the register of the microprocessor if
a free register is available. This makes the use of register variables to be
much faster than that of the variables stored in the memory during the
runtime of the program.
If a free registration is not available, these are then stored in the memory
only. Usually, a few variables which are to be accessed very frequently in a
program are declared with the register keyword which improves the running
time of the program. An important and interesting point to be noted here is
that we cannot obtain the address of a register variable using pointers.
Syntax
Example
Functions follow the same syntax as given above for variables. Have a look
at the following C example for further clarification:
• C
void autoStorageClass()
{
printf("--------------------------------");
}
void registerStorageClass()
{
printf("--------------------------------");
}
void externStorageClass()
{
printf("\nDemonstrating extern class\n\n");
printf("--------------------------------");
}
void staticStorageClass()
{
int i = 0;
printf("\nLoop started:\n");
printf("\nLoop ended:\n");
printf("--------------------------------");
}
int main()
{
// exiting
printf("\n\nStorage Classes demonstrated");
return 0;
}
Output
A program to demonstrate Storage Classes in C
Loop started:
Loop ended:
FILE HANDLING IN C
Let us look at a few reasons why file handling makes programming easier
for all:
• Text Files
• Binary Files
Text Files
The text files are the most basic/simplest types of files that a user can
create in a C program. We create the text files using an extension .txt with
the help of a simple text editor. In general, we can use notepads for the
creation of .txt files. These files store info internally in ASCII character
format, but when we open these files, the content/text opens in a human-
readable form.
Text files are, thus, very easy to access as well as use. But there’s one major
disadvantage; it lacks security. Since a .txt file can be accessed easily,
information isn’t very secure in it. Added to this, text files consume a very
large space in storage.
Binary Files
The binary files store info and data in the binary format of 0’s and 1’s (the
binary number system). Thus, the files occupy comparatively lesser space
in the storage. In simpler words, the binary files store data and info the
same way a computer holds the info in its memory. Thus, it can be
accessed very easily as compared to a text file.
The binary files are created with the extension .bin in a program, and it
overcomes the drawback of the text files in a program since humans can’t
read it; only machines can. Thus, the information becomes much more
secure. Thus, binary files are safest in terms of storing data files in a C
program.
Operators/Functions that We Use for File
Handling in C
We can use a variety of functions in order to open a file, read it, write more
data, create a new file, close or delete a file, search for a file, etc. These are
known as file handling operators in C.
FILE *fpointer;
Let us take a look at a few more opening modes used in the C programs:
r Open a file for reading the content. In case the file doesn’t exist
in the location, then fopen()
will return NULL.
rb Open a file for reading the content in In case the file doesn’t exist
binary mode. in the location, then fopen()
will return NULL.
w Open a file for writing the content. In case the file exists, its
contents are overwritten.
wb Open a file for writing the content in binary In case the file exists, then its
mode. contents will get overwritten.
In case the file doesn’t
exist in the location, then
it will create a new file.
a Open a file for appending the content. In case the file doesn’t exist
in the location, then it will
Meaning, the data of the program is
create a new file.
added to the file’s end in a program.
ab Open a file for appending the content in In case the file doesn’t exist
binary mode. in the location, then it will
create a new file.
Meaning, the data of the program is
added to the file’s end in a program
in a binary mode.
r+ Open a file for both writing and reading the In case the file doesn’t exist
content. in the location, then fopen()
will return NULL.
rb+ Open a file for both writing and reading the In case the file doesn’t exist
content in binary mode. in the location, then fopen()
will return NULL.
w+ Open a file for both writing and reading. In case the file exists, its
contents are overwritten.
wb+ Open a file for both writing and reading the In case the file exists, its
content in binary mode. contents are overwritten.
a+ Open a file for both appending and In case the file doesn’t exist
reading the content. in the location, then it will
create a new file.
ab+ Open a file for both appending and In case the file doesn’t exist
reading the content in binary mode. in the location, then it will
create a new file.
fclose(fptr);
In this case, the fptr refers to the file pointer that is associated with that file
that needs to be closed in a program.
#include <stdlib.h>
int main()
int val;
FILE *fptr;
// if you are using Linux or MacOS, then you must use appropriate locations
if(fptr == NULL)
{
exit(1);
scanf(“%d”,&val);
fprintf(fptr,”%d”,val);
fclose(fptr);
return 0;
The program mentioned here would take the number given by then store it
in the currentprogram.txt file.
Once we compile this program and run it on the system, we will be able to
witness a currentprogram.txt text file created in the C drive of our
computer! Also, when we open this file, then we will be able to see what
integer we entered as an input while coding.
ALGORITHM:
Step 1: Start the program.
Step 2: Set a ← 10 and b ← 20
Step 3: Call the function swap(&a,&b)
Step 3a: Start fuction
Step 3b: Assign t ← *x
Step 3c: Assign *x ← *y
Step 3d: Assign *y ← t
Step 3e: End function
Step 4: Print x and y.
Step 5: Stop the program.
#include <stdio.h>
int i, j, t;
*(ptr + j) = t;
int main()
int n = 5;
sort(n, arr);
return 0;
Step1 : sum := 0
Step2 : take one input and store it to n
Step 3: arr := dynamically create an array of size n
Step 4:for initialize i := 0, when i < n, update (increase i by 1), do:
take an input and store it to arr[i]
Step 5: for initialize i := 0, when i < n, update (increase i by 1), do:
Step 6: sum := sum + arr[i]
Step 7: return sum
#include <stdio.h>
#include <stdlib.h>
int main(){
int *arr;
int n;
int sum = 0;
scanf("%d", &n);
arr = (int*) malloc(n*sizeof(int));
for(int i = 0; i < n; i++){
scanf("%d", (arr+i));
}
for(int i = 0; i < n; i++){
sum += arr[i];
}
printf("%d", sum);
}
Input
6987243
Output
33