0% found this document useful (0 votes)
42 views43 pages

Unit 5

Uploaded by

dharani2004d
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
42 views43 pages

Unit 5

Uploaded by

dharani2004d
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 43

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.

How to Use Pointers?


The use of pointers in C can be divided into three steps:
1. Pointer Declaration
2. Pointer Initialization
3. Pointer Dereferencing

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 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.

Dereferencing a Pointer in C

C Pointer Example
• C

// C program to illustrate Pointers


#include <stdio.h>
void geeks()
{
int var = 10;

// declare pointer variable


int* ptr;

// note that data type of ptr and var must be same


ptr = &var;

// assign the address of a variable to a pointer


printf("Value at ptr = %p \n", ptr);
printf("Value at var = %d \n", var);
printf("Value at *ptr = %d \n", *ptr);
}

// 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

The pointer pointing to the structure type is called Structure Pointer or


Pointer to Structure. It can be declared in the same way as we declare the
other primitive data types.
Syntax
struct struct_name *ptr;
In C, structure pointers are used in data structures such as linked lists, trees,
etc.

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

In constant pointers, the memory address stored inside the pointer is


constant and cannot be modified once it is defined. It will always point to
the same memory address.
Syntax
data_type * const pointer_name;

10. Pointer to Constant

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 Pointers and Arrays


In C programming language, pointers and arrays are closely related. An
array name acts like a pointer constant. The value of this pointer constant is
the address of the first element. For example, if we have an array named val
then val and &val[0] can be used interchangeably.
If we assign this value to a non-constant pointer of the same type, then we
can access the elements of the array using this pointer.

Example 1: Accessing Array Elements using Pointer with Array


Subscript

• C

// C Program to access array elements using pointer


#include <stdio.h>
void geeks()
{
// Declare an array
int val[3] = { 5, 10, 15 };

// Declare pointer variable


int* ptr;

// Assign address of val[0] to ptr.


// We can use ptr=&val[0];(both are same)
ptr = val;

printf("Elements of the array are: ");

printf("%d, %d, %d", ptr[0], ptr[1], ptr[2]);

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.

Structure using Pointer


The structure pointer points to the address of a memory block where the Structure is
being stored. Like a pointer that tells the address of another variable of any data type
(int, char, float) in memory. And here, we use a structure pointer which tells the address
of a structure in memory by pointing pointer variable ptr to the structure variable.

Declare a Structure Pointer


The declaration of a structure pointer is similar to the declaration of the structure
variable. So, we can declare the structure pointer and variable inside and outside of
the main() function. To declare a pointer variable in C, we use the asterisk (*) symbol
before the variable's name.

1. struct structure_name *ptr;

After defining the structure pointer, we need to initialize it, as the code is shown:

Initialization of the Structure Pointer

1. ptr = &structure_variable;

We can also initialize a Structure Pointer directly during the declaration of a pointer.

1. struct structure_name *ptr = &structure_variable;

As we can see, a pointer ptr is pointing to the address structure_variable of the


Structure.

Access Structure member using pointer:


There are two ways to access the member of the structure using Structure pointer:

1. Using ( * ) asterisk or indirection operator and dot ( . ) operator.


2. Using arrow ( -> ) operator or membership operator.

Program to access the structure member using structure pointer


and the dot operator
Let's consider an example to create a Subject structure and access its members using
a structure pointer that points to the address of the Subject variable in C.

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:

Subject Name: Computer Science


Subject Id: 1201
Duration of the Subject: 6 Months
Type of the Subject: Multiple Choice Question

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:

Enter the name of the Employee (emp1): John


Enter the id of the Employee (emp1): 1099
Enter the age of the Employee (emp1): 28
Enter the gender of the Employee (emp1): Male
Enter the city of the Employee (emp1): California

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

Display the Details of the Employee using Structure Pointer


Details of the Employee (emp1)
Name: John
Id: 1099
Age: 28
Gender: Male
City: California

Details of the Employee (emp2) Name: Maria


Id: 1109
Age: 23
Gender: Female
City: Los Angeles

In the above program, we have created an Employee structure containing two


structure variables emp1 and emp2, with the pointer variables *ptr1 and *ptr2. The
structure Employee is having the name, id, age, gender, and city as the member. All
the Employee structure members take their respective values from the user one by one
using the pointer variable and arrow operator that determine their space in memory.

Function using Pointer


As we know that we can create a pointer of any data type such as int, char, float, we
can also create a pointer pointing to a function. The code of a function always resides
in memory, which means that the function has some address. We can get the address
of memory by using the function pointer.

Declaration of a function pointer


Till now, we have seen that the functions have addresses, so we can create pointers
that can contain these addresses, and hence can point them.

Syntax of function pointer

1. return type (*ptr_name)(type1, type2…);

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.

1. float (*fp) (float);

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.

We can observe that the declaration of a function is similar to the declaration of a


function pointer except that the pointer is preceded by a '*'. So, in the above
declaration, fp is declared as a function rather than a pointer.

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.

1. float (*fp) (int , int); // Declaration of a function pointer.


2. float func( int , int ); // Declaration of function.
3. fp = func; // Assigning address of func to the fp pointer.

In the above declaration, 'fp' pointer contains the address of the 'func' function.

Note: Declaration of a function is necessary before assigning the address of a


function to the function pointer.

Calling a function through a function pointer


We already know how to call a function in the usual way. Now, we will see how to call
a function using a function pointer.

Suppose we declare a function as given below:

1. float func(int , int); // Declaration of a function.

Calling an above function using a usual way is given below:

1. result = func(a , b); // Calling a function using usual ways.

Calling a function using a function pointer is given below:

1. result = (*fp)( a , b); // Calling a function using function pointer.

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.

Let's understand the function pointer through an example.

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.

Let's understand through an example.

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:

ptr = (int*) malloc(100 * sizeof(int));


Since the size of int is 4 bytes, this statement will allocate 400 bytes of
memory. And, the pointer ptr holds the address of the first byte in the
allocated memory.

If space is insufficient, allocation fails and returns a NULL pointer.


Example of malloc() in C
• C

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

int main()
{

// This pointer will hold the


// base address of the block created
int* ptr;
int n, i;

// Get the number of elements for the array


printf("Enter number of elements:");
scanf("%d",&n);
printf("Entered number of elements: %d\n", n);

// Dynamically allocate memory using malloc()


ptr = (int*)malloc(n * sizeof(int));

// Check if the memory has been successfully


// allocated by malloc or not
if (ptr == NULL) {
printf("Memory not allocated.\n");
exit(0);
}
else {

// Memory has been successfully allocated


printf("Memory successfully allocated using
malloc.\n");

// Get the elements of the array


for (i = 0; i < n; ++i) {
ptr[i] = i + 1;
}

// Print the elements of the array


printf("The elements of the array are: ");
for (i = 0; i < n; ++i) {
printf("%d, ", ptr[i]);
}
}

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.

If space is insufficient, allocation fails and returns a NULL pointer.


Example of calloc() in C
• C

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

int main()
{

// This pointer will hold the


// base address of the block created
int* ptr;
int n, i;

// Get the number of elements for the array


n = 5;
printf("Enter number of elements: %d\n", n);

// Dynamically allocate memory using calloc()


ptr = (int*)calloc(n, sizeof(int));

// Check if the memory has been successfully


// allocated by calloc or not
if (ptr == NULL) {
printf("Memory not allocated.\n");
exit(0);
}
else {

// Memory has been successfully allocated


printf("Memory successfully allocated using
calloc.\n");

// Get the elements of the array


for (i = 0; i < n; ++i) {
ptr[i] = i + 1;
}

// Print the elements of the array


printf("The elements of the array are: ");
for (i = 0; i < n; ++i) {
printf("%d, ", ptr[i]);
}
}

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()
{

// This pointer will hold the


// base address of the block created
int *ptr, *ptr1;
int n, i;

// Get the number of elements for the array


n = 5;
printf("Enter number of elements: %d\n", n);

// Dynamically allocate memory using malloc()


ptr = (int*)malloc(n * sizeof(int));

// Dynamically allocate memory using calloc()


ptr1 = (int*)calloc(n, sizeof(int));

// Check if the memory has been successfully


// allocated by malloc or not
if (ptr == NULL || ptr1 == NULL) {
printf("Memory not allocated.\n");
exit(0);
}
else {

// Memory has been successfully allocated


printf("Memory successfully allocated using
malloc.\n");

// Free the memory


free(ptr);
printf("Malloc Memory successfully freed.\n");

// Memory has been successfully allocated


printf("\nMemory successfully allocated using
calloc.\n");

// Free the memory


free(ptr1);
printf("Calloc Memory successfully freed.\n");
}

return 0;
}

Output
Enter number of elements: 5
Memory successfully allocated using malloc.
Malloc Memory successfully freed.

Memory successfully allocated using calloc.


Calloc Memory successfully freed.
C realloc() method
“realloc” or “re-allocation” method in C is used to dynamically change the
memory allocation of a previously allocated memory. In other words, if the
memory previously allocated with the help of malloc or calloc is insufficient,
realloc can be used to dynamically re-allocate memory. re-allocation of
memory maintains the already present value and new blocks will be
initialized with the default garbage value.
Syntax of realloc() in C
ptr = realloc(ptr, newSize);
where ptr is reallocated with new size 'newSize'.

If space is insufficient, allocation fails and returns a NULL pointer.


Example of realloc() in C
• C

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

int main()
{

// This pointer will hold the


// base address of the block created
int* ptr;
int n, i;

// Get the number of elements for the array


n = 5;
printf("Enter number of elements: %d\n", n);

// Dynamically allocate memory using calloc()


ptr = (int*)calloc(n, sizeof(int));

// Check if the memory has been successfully


// allocated by malloc or not
if (ptr == NULL) {
printf("Memory not allocated.\n");
exit(0);
}
else {

// Memory has been successfully allocated


printf("Memory successfully allocated using
calloc.\n");

// Get the elements of the array


for (i = 0; i < n; ++i) {
ptr[i] = i + 1;
}

// Print the elements of the array


printf("The elements of the array are: ");
for (i = 0; i < n; ++i) {
printf("%d, ", ptr[i]);
}

// Get the new size for the array


n = 10;
printf("\n\nEnter the new size of the array: %d\n", n);

// Dynamically re-allocate memory using realloc()


ptr = (int*)realloc(ptr, n * sizeof(int));

// Memory has been successfully allocated


printf("Memory successfully re-allocated using
realloc.\n");

// Get the new elements of the array


for (i = 5; i < n; ++i) {
ptr[i] = i + 1;
}

// Print the elements of the array


printf("The elements of the array are: ");
for (i = 0; i < n; ++i) {
printf("%d, ", ptr[i]);
}

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,

Enter the new size of the array: 10


Memory successfully re-allocated using realloc.
The elements of the array are: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,

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

To specify the storage class for a variable, the following syntax is to be


followed:
storage_class var_data_type var_name;

Example

Functions follow the same syntax as given above for variables. Have a look
at the following C example for further clarification:
• C

// A C program to demonstrate different storage


// classes
#include <stdio.h>

// declaring the variable which is to be made extern


// an initial value can also be initialized to x
int x;

void autoStorageClass()
{

printf("\nDemonstrating auto class\n\n");

// declaring an auto variable (simply


// writing "int a=32;" works as well)
auto int a = 32;

// printing the auto variable 'a'


printf("Value of the variable 'a'"
" declared as auto: %d\n",
a);

printf("--------------------------------");
}

void registerStorageClass()
{

printf("\nDemonstrating register class\n\n");

// declaring a register variable


register char b = 'G';

// printing the register variable 'b'


printf("Value of the variable 'b'"
" declared as register: %d\n",
b);

printf("--------------------------------");
}

void externStorageClass()
{
printf("\nDemonstrating extern class\n\n");

// telling the compiler that the variable


// x is an extern variable and has been
// defined elsewhere (above the main
// function)
extern int x;

// printing the extern variables 'x'


printf("Value of the variable 'x'"
" declared as extern: %d\n",
x);

// value of extern variable x modified


x = 2;

// printing the modified values of


// extern variables 'x'
printf("Modified value of the variable 'x'"
" declared as extern: %d\n",
x);

printf("--------------------------------");
}

void staticStorageClass()
{
int i = 0;

printf("\nDemonstrating static class\n\n");

// using a static variable 'y'


printf("Declaring 'y' as static inside the loop.\n"
"But this declaration will occur only"
" once as 'y' is static.\n"
"If not, then every time the value of 'y' "
"will be the declared value 5"
" as in the case of variable 'p'\n");

printf("\nLoop started:\n");

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

// Declaring the static variable 'y'


static int y = 5;
// Declare a non-static variable 'p'
int p = 10;

// Incrementing the value of y and p by 1


y++;
p++;

// printing value of y at each iteration


printf("\nThe value of 'y', "
"declared as static, in %d "
"iteration is %d\n",
i, y);

// printing value of p at each iteration


printf("The value of non-static variable 'p', "
"in %d iteration is %d\n",
i, p);
}

printf("\nLoop ended:\n");

printf("--------------------------------");
}

int main()
{

printf("A program to demonstrate"


" Storage Classes in C\n\n");

// To demonstrate auto Storage Class


autoStorageClass();

// To demonstrate register Storage Class


registerStorageClass();

// To demonstrate extern Storage Class


externStorageClass();

// To demonstrate static Storage Class


staticStorageClass();

// exiting
printf("\n\nStorage Classes demonstrated");

return 0;
}

// This code is improved by RishabhPrabhu

Output
A program to demonstrate Storage Classes in C

Demonstrating auto class

Value of the variable 'a' declared as auto: 32


--------------------------------
Demonstrating register class

Value of the variable 'b' declared as register: 71


--------------------------------
Demonstrating extern class

Value of the variable 'x' declared as extern: 0


Modified value of the variable 'x' declared as extern: 2
--------------------------------
Demonstrating static class

Declaring 'y' as static inside the loop.


But this declaration will occur only once as 'y' is static.
If not, then every time the value of 'y' will be the declared value
5 as in the case of variable 'p'

Loop started:

The value of 'y', declared as static, in 1 iteration is 6


The value of non-static variable 'p', in 1 iteration is 11

The value of 'y', declared as static, in 2 iteration is 7


The value of non-static variable 'p', in 2 iteration is 11

The value of 'y', declared as static, in 3 iteration is 8


The value of non-static variable 'p', in 3 iteration is 11

The value of 'y', declared as static, in 4 iteration is 9


The value of non-static variable 'p', in 4 iteration is 11

Loop ended:

FILE HANDLING IN C

Why Do We Need File Handling in C?


There are times when the output generated out of a program after its
compilation and running do not serve our intended purpose. In such cases,
we might want to check the program’s output various times. Now,
compiling and running the very same program multiple times becomes a
tedious task for any programmer. It is exactly where file handling becomes
useful.

Let us look at a few reasons why file handling makes programming easier
for all:

• Reusability: File handling allows us to preserve the information/data


generated after we run the program.
• Saves Time: Some programs might require a large amount of input from their
users. In such cases, file handling allows you to easily access a part of a code
using individual commands.
• Commendable storage capacity: When storing data in files, you can leave
behind the worry of storing all the info in bulk in any program.
• Portability: The contents available in any file can be transferred to another one
without any data loss in the computer system. This saves a lot of effort and
minimises the risk of flawed coding.
Types of Files in a C Program
When referring to file handling, we refer to files in the form of data files.
Now, these data files are available in 2 distinct forms in the C language,
namely:

• 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.

To solve these problems, we have a different type of file in C programs,


known as binary files.

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.

Here’s a list of functions that allow you to do so:

Description of Function Function in Use

used to open an existing file or a new file fopen()

writing data into an available file fprintf()

reading the data available in a file fscanf()

writing any character into the program file fputc()

reading the character from an available file fgetc()

used to close the program file fclose()

used to set the file pointer to the intended file fseek()


position

writing an integer into an available file fputw()

used to read an integer from the given file fgetw()

used for reading the current position of a file ftell()


sets an intended file pointer to the file’s rewind()
beginning itself

Note: It is important to know that we must declare a file-type pointer when


we are working with various files in a program. This helps establish direct
communication between a program and the files.

Here is how you can do it:

FILE *fpointer;

Out of all the operations/functions mentioned above, let us discuss some


of the basic operations that we perform in the C language.

Operations Done in File Handling


The process of file handling enables a user to update, create, open, read,
write, and ultimately delete the file/content in the file that exists on the C
program’s local file system. Here are the primary operations that you can
perform on a file in a C program:

• Opening a file that already exists


• Creating a new file
• Reading content/ data from the existing file
• Writing more data into the file
• Deleting the data in the file or the file altogether

Opening a File in the Program – to create and edit data


We open a file with the help of the fopen() function that is defined in the
header file- stdio.h.

Here is the syntax that we follow when opening a file:

ptr = fopen (“openfile” , “openingmode”);

Let us take a look at an example for the same,

fopen (“E:\\myprogram\\recentprogram.txt” , “w”);

fopen (“E:\\myprogram\\previousprogram.bin” , “rb”);


• Here, if we suppose that the file – recentprogram.txt doesn’t really exist in the
E:\\myprogram location. Here, we have used the mode “w”. Thus, the first
function will create a new file with the name recentprogram.txt and then open
it for writing (since we have used the “w” mode).
• The “w” here refers to writing mode. It allows a programmer to overwrite/edit
and create the contents in a program file.
• Now, let us take a look at the second binary previousprogram.bin file that is
present in the E:\\myprogram location. Thus, the second function here will
open the file (that already exists) for reading in the “rb” binary mode.
• The “rb” refers to the reading mode. It only allows you to read a file, but not
overwrite it. Thus, it will only read this available file in the program.

Let us take a look at a few more opening modes used in the C programs:

Opening Modes of C in Standard I/O of a Program

Mode in Meaning of Mode When the file doesn’t exist


Program

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.

In case the file doesn’t


exist in the location, then
it will create a new file.

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.

In case the file doesn’t


exist in the location, then
it will create a new file.

wb+ Open a file for both writing and reading the In case the file exists, its
content in binary mode. contents are overwritten.

In case the file doesn’t


exist in the location, then
it will create a new file.

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.

How do we close a file?


Once we write/read a file in a program, we need to close it (for both binary
and text files). To close a file, we utilise the fclose() function in a program.

Here is how the program would look like:

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.

How do we read and write the data to the text file?


We utilise the fscanf() and fprintf() to write and read the data to the text
file. These are basically the file versions of the scanf() and printf(). But
there is a major difference, i.e., both fscanf() and fprintf() expect a pointer
pointing towards the structure FILE in the program.

Example #1: Writing Data to the Text File in a Program


#include <stdio.h>

#include <stdlib.h>

int main()

int val;

FILE *fptr;

// if you are using Linux or MacOS, then you must use appropriate locations

fptr = fopen (“C:\\currentprogram.txt”,”w”);

if(fptr == NULL)
{

printf(“File type invalid!”);

exit(1);

printf(“Please enter the val: “);

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.

Swap two numbers using call by reference


AIM:
To write a C program to swap two numbers using call by reference.

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.

C program to sort an array using pointers


Below is the step by step descriptive logic to sort an array using pointer.

1. Input size and elements in array. Store them in some variable


say size and arr.
2. Declare two function with prototype int sortAscending(int *
num1, int * num2) and int sortDescending(int * num1, int *
num2).
Both the functions are used to compare two elements and arrange it in
either ascending or descending order. sortAscending() returns
negative value if num1 is less than num2, positive value if num1 is
greater than num2 and zero if both are equal.

Similarly, sortDescending() returns negative value if num1 is greater


than num2, positive value if num2 is greater than num1 and zero if both
are equal.

3. Declare another function to sort array with prototype void sort(int *


arr, int size, int (* compare)(int *, int *)).
It takes three parameter, where first parameter is the array to sort,
second is size of array and third is a function pointer.

#include <stdio.h>

void sort(int n, int* ptr)

int i, j, t;

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

for (j = i + 1; j < n; j++) {

if (*(ptr + j) < *(ptr + i)) {


t = *(ptr + i);

*(ptr + i) = *(ptr + j);

*(ptr + j) = t;

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

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

int main()

int n = 5;

int arr[] = { 0, 23, 14, 12, 9 };

sort(n, arr);

return 0;

Finding sum of array elements using Dynamic Memory Allocation


Suppose we have a number n. We shall have to make an array of size n dynamically and
take n numbers one by one, then find the sum. To make the array we can use malloc() or
calloc() function which is present inside the stdlib.h header file. The value of n is also
provided as input through stdin.
So, if the input is like n = 6, and array elements 9, 8, 7, 2, 4, 3, then the output will be 33
because sum of 9 + 8 + 7 + 2 + 4 + 3 = 33.

To solve this, we will follow these steps −

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

You might also like