Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Unit 3 of C

Download as pdf or txt
Download as pdf or txt
You are on page 1of 91

C Pointers

The pointer in C language is a variable which stores the address of another variable. This
variable can be of type int, char, array, function, or any other pointer. The size of the
pointer depends on the architecture. However, in 32-bit architecture the size of a
pointer is 2 byte.

Consider the following example to define a pointer which stores the address of an
integer.

1. int n = 10;
2. int* p = &n; // Variable p of type pointer is pointing to the address of the variable n of t
ype integer.

Declaring a pointer
The pointer in c language can be declared using * (asterisk symbol). It is also known as
indirection pointer used to dereference a pointer.

1. int *a;//pointer to int


2. char *c;//pointer to char

Pointer Example
An example of using pointers to print the address and value is given below.
As you can see in the above figure, pointer variable stores the address of number
variable, i.e., fff4. The value of number variable is 50. But the address of pointer variable
p is aaa3.

By the help of * (indirection operator), we can print the value of pointer variable p.

Let's see the pointer example as explained for the above figure.

1. #include<stdio.h>
2. int main(){
3. int number=50;
4. int *p;
5. p=&number;//stores the address of number variable
6. printf("Address of p variable is %x \n",p); // p contains the address of the number theref
ore printing p gives the address of number.
7. printf("Value of p variable is %d \n",*p); // As we know that * is used to dereference a po
inter therefore if we print *p, we will get the value stored at the address contained by p.

8. return 0;
9. }

Output

Address of number variable is fff4


Address of p variable is fff4
Value of p variable is 50

Pointer to array

1. int arr[10];
2. int *p[10]=&arr; // Variable p of type pointer is pointing to the address of an integer arr
ay arr.

Pointer to a function

1. void show (int);


2. void(*p)(int) = &display; // Pointer p is pointing to the address of a function
Pointer to structure

1. struct st {
2. int i;
3. float f;
4. }ref;
5. struct st *p = &ref;

Advantage of pointer
1) Pointer reduces the code and improves the performance, it is used to retrieving
strings, trees, etc. and used with arrays, structures, and functions.

2) We can return multiple values from a function using the pointer.

3) It makes you able to access any memory location in the computer's memory.

Usage of pointer
There are many applications of pointers in c language.

1) Dynamic memory allocation

In c language, we can dynamically allocate memory using malloc() and calloc() functions
where the pointer is used.

2) Arrays, Functions, and Structures

Pointers in c language are widely used in arrays, functions, and structures. It reduces the
code and improves the performance.

Address Of (&) Operator


The address of operator '&' returns the address of a variable. But, we need to use %u to
display the address of a variable.
1. #include<stdio.h>
2. int main(){
3. int number=50;
4. printf("value of number is %d, address of number is %u",number,&number);
5. return 0;
6. }

Output

value of number is 50, address of number is fff4

NULL Pointer
A pointer that is not assigned any value but NULL is known as the NULL pointer. If you
don't have any address to be specified in the pointer at the time of declaration, you can
assign NULL value. It will provide a better approach.

int *p=NULL;

In the most libraries, the value of the pointer is 0 (zero).

Pointer Program to swap two numbers without using


the 3rd variable.
1. #include<stdio.h>
2. int main(){
3. int a=10,b=20,*p1=&a,*p2=&b;
4.
5. printf("Before swap: *p1=%d *p2=%d",*p1,*p2);
6. *p1=*p1+*p2;
7. *p2=*p1-*p2;
8. *p1=*p1-*p2;
9. printf("\nAfter swap: *p1=%d *p2=%d",*p1,*p2);
10.
11. return 0;
12. }

Output
Before swap: *p1=10 *p2=20
After swap: *p1=20 *p2=10

Reading complex pointers


There are several things which must be taken into the consideration while reading the
complex pointers in C. Lets see the precedence and associativity of the operators which
are used regarding pointers.

Operator Precedence Associativity

(), [] 1 Left to right

*, identifier 2 Right to left

Data type 3 -

Here,we must notice that,

o (): This operator is a bracket operator used to declare and define the function.
o []: This operator is an array subscript operator
o * : This operator is a pointer operator.
o Identifier: It is the name of the pointer. The priority will always be assigned to this.
o Data type: Data type is the type of the variable to which the pointer is intended
to point. It also includes the modifier like signed int, long, etc).

How to read the pointer: int (*p)[10].

To read the pointer, we must see that () and [] have the equal precedence. Therefore,
their associativity must be considered here. The associativity is left to right, so the
priority goes to ().

Inside the bracket (), pointer operator * and pointer name (identifier) p have the same
precedence. Therefore, their associativity must be considered here which is right to left,
so the priority goes to p, and the second priority goes to *.

Assign the 3rd priority to [] since the data type has the last precedence. Therefore the
pointer will look like following.
o char -> 4
o * -> 2
o p -> 1
o [10] -> 3

The pointer will be read as p is a pointer to an array of integers of size 10.

Example

How to read the following pointer?

1. int (*p)(int (*)[2], int (*)void))

Explanation
This pointer will be read as p is a pointer to such function which accepts the first
parameter as the pointer to a one-dimensional array of integers of size two and the
second parameter as the pointer to a function which parameter is void and return type
is the integer.

C Double Pointer (Pointer to Pointer)


As we know that, a pointer is used to store the address of a variable in C. Pointer
reduces the access time of a variable. However, In C, we can also define a pointer to
store the address of another pointer. Such pointer is known as a double pointer (pointer
to pointer). The first pointer is used to store the address of a variable whereas the
second pointer is used to store the address of the first pointer. Let's understand it by the
diagram given below.

The syntax of declaring a double pointer is given below.

1. int **p; // pointer to a pointer which is pointing to an integer.


Consider the following example.

1. #include<stdio.h>
2. void main ()
3. {
4. int a = 10;
5. int *p;
6. int **pp;
7. p = &a; // pointer p is pointing to the address of a
8. pp = &p; // pointer pp is a double pointer pointing to the address of pointer p
9. printf("address of a: %x\n",p); // Address of a will be printed
10. printf("address of p: %x\n",pp); // Address of p will be printed
11. printf("value stored at p: %d\n",*p); // value stoted at the address contained by p i.e. 1
0 will be printed
12. printf("value stored at pp: %d\n",**pp); // value stored at the address contained by th
e pointer stoyred at pp
13. }

Output
address of a: d26a8734
address of p: d26a8738
value stored at p: 10
value stored at pp: 10

C double pointer example


Let's see an example where one pointer points to the address of another pointer.
As you can see in the above figure, p2 contains the address of p (fff2), and p contains
the address of number variable (fff4).

1. #include<stdio.h>
2. int main(){
3. int number=50;
4. int *p;//pointer to int
5. int **p2;//pointer to pointer
6. p=&number;//stores the address of number variable
7. p2=&p;
8. printf("Address of number variable is %x \n",&number);
9. printf("Address of p variable is %x \n",p);
10. printf("Value of *p variable is %d \n",*p);
11. printf("Address of p2 variable is %x \n",p2);
12. printf("Value of **p2 variable is %d \n",*p);
13. return 0;
14. }

Output
Address of number variable is fff4
Address of p variable is fff4
Value of *p variable is 50
Address of p2 variable is fff2
Value of **p variable is 50

Q. What will be the output of the following program?


1. #include<stdio.h>
2. void main ()
3. {
4. int a[10] = {100, 206, 300, 409, 509, 601}; //Line 1
5. int *p[] = {a, a+1, a+2, a+3, a+4, a+5}; //Line 2
6. int **pp = p; //Line 3
7. pp++; // Line 4
8. printf("%d %d %d\n",pp-p,*pp - a,**pp); // Line 5
9. *pp++; // Line 6
10. printf("%d %d %d\n",pp-p,*pp - a,**pp); // Line 7
11. ++*pp; // Line 8
12. printf("%d %d %d\n",pp-p,*pp - a,**pp); // Line 9
13. ++**pp; // Line 10
14. printf("%d %d %d\n",pp-p,*pp - a,**pp); // Line 11
15. }

Explanation

In the above question, the pointer arithmetic is used with the double pointer. An array
of 6 elements is defined which is pointed by an array of pointer p. The pointer array p is
pointed by a double pointer pp. However, the above image gives you a brief idea about
how the memory is being allocated to the array a and the pointer array p. The elements
of p are the pointers that are pointing to every element of the array a. Since we know
that the array name contains the base address of the array hence, it will work as a
pointer and can the value can be traversed by using *(a), *(a+1), etc. As shown in the
image, a[0] can be accessed in the following ways.

o a[0]: it is the simplest way to access the first element of the array
o *(a): since a store the address of the first element of the array, we can access its
value by using indirection pointer on it.
o *p[0]: if a[0] is to be accessed by using a pointer p to it, then we can use
indirection operator (*) on the first element of the pointer array p, i.e., *p[0].
o **(pp): as pp stores the base address of the pointer array, *pp will give the value
of the first element of the pointer array that is the address of the first element of
the integer array. **p will give the actual value of the first element of the integer
array.

Coming to the program, Line 1 and 2 declare the integer and pointer array relatively.
Line 3 initializes the double pointer to the pointer array p. As shown in the image, if the
address of the array starts from 200 and the size of the integer is 2, then the pointer
array will contain the values as 200, 202, 204, 206, 208, 210. Let us consider that the base
address of the pointer array is 300; the double pointer pp contains the address of
pointer array, i.e., 300. Line number 4 increases the value of pp by 1, i.e., pp will now
point to address 302.

Line number 5 contains an expression which prints three values, i.e., pp - p, *pp - a, **pp.
Let's calculate them each one of them.

o pp = 302, p = 300 => pp-p = (302-300)/2 => pp-p = 1, i.e., 1 will be printed.
o pp = 302, *pp = 202, a = 200 => *pp - a = 202 - 200 = 2/2 = 1, i.e., 1 will be
printed.
o pp = 302, *pp = 202, *(*pp) = 206, i.e., 206 will be printed.

Therefore as the result of line 5, The output 1, 1, 206 will be printed on the console. On
line 6, *pp++ is written. Here, we must notice that two unary operators * and ++ will
have the same precedence. Therefore, by the rule of associativity, it will be evaluated
from right to left. Therefore the expression *pp++ can be rewritten as (*(pp++)). Since,
pp = 302 which will now become, 304. *pp will give 204.

On line 7, again the expression is written which prints three values, i.e., pp-p, *pp-a, *pp.
Let's calculate each one of them.

o pp = 304, p = 300 => pp - p = (304 - 300)/2 => pp-p = 2, i.e., 2 will be printed.
o pp = 304, *pp = 204, a = 200 => *pp-a = (204 - 200)/2 = 2, i.e., 2 will be printed.
o pp = 304, *pp = 204, *(*pp) = 300, i.e., 300 will be printed.

Therefore, as the result of line 7, The output 2, 2, 300 will be printed on the console. On
line 8, ++*pp is written. According to the rule of associativity, this can be rewritten as,
(++(*(pp))). Since, pp = 304, *pp = 204, the value of *pp = *(p[2]) = 206 which will now
point to a[3].

On line 9, again the expression is written which prints three values, i.e., pp-p, *pp-a, *pp.
Let's calculate each one of them.
o pp = 304, p = 300 => pp - p = (304 - 300)/2 => pp-p = 2, i.e., 2 will be printed.
o pp = 304, *pp = 206, a = 200 => *pp-a = (206 - 200)/2 = 3, i.e., 3 will be printed.
o pp = 304, *pp = 206, *(*pp) = 409, i.e., 409 will be printed.

Therefore, as the result of line 9, the output 2, 3, 409 will be printed on the console. On
line 10, ++**pp is writen. according to the rule of associativity, this can be rewritten as,
(++(*(*(pp)))). pp = 304, *pp = 206, **pp = 409, ++**pp => *pp = *pp + 1 = 410. In
other words, a[3] = 410.

On line 11, again the expression is written which prints three values, i.e., pp-p, *pp-a,
*pp. Let's calculate each one of them.

o pp = 304, p = 300 => pp - p = (304 - 300)/2 => pp-p = 2, i.e., 2 will be printed.
o pp = 304, *pp = 206, a = 200 => *pp-a = (206 - 200)/2 = 3, i.e., 3 will be printed.
o On line 8, **pp = 410.

Therefore as the result of line 9, the output 2, 3, 410 will be printed on the console.

At last, the output of the complete program will be given as:

Output

1 1 206
2 2 300
2 3 409
2 3 410

Pointer Arithmetic in C
We can perform arithmetic operations on the pointers like addition, subtraction, etc.
However, as we know that pointer contains the address, the result of an arithmetic
operation performed on the pointer will also be a pointer if the other operand is of type
integer. In pointer-from-pointer subtraction, the result will be an integer value.
Following arithmetic operations are possible on the pointer in C language:

o Increment
o Decrement
o Addition
o Subtraction
o Comparison

Incrementing Pointer in C
If we increment a pointer by 1, the pointer will start pointing to the immediate next
location. This is somewhat different from the general arithmetic since the value of the
pointer will get increased by the size of the data type to which the pointer is pointing.

We can traverse an array by using the increment operation on a pointer which will keep
pointing to every element of the array, perform some operation on that, and update
itself in a loop.

The Rule to increment the pointer is given below:

1. new_address= current_address + i * size_of(data type)

Where i is the number by which the pointer get increased.

32-bit
For 32-bit int variable, it will be incremented by 2 bytes.

64-bit
For 64-bit int variable, it will be incremented by 4 bytes.

Let's see the example of incrementing pointer variable on 64-bit architecture.

1. #include<stdio.h>
2. int main(){
3. int number=50;
4. int *p;//pointer to int
5. p=&number;//stores the address of number variable
6. printf("Address of p variable is %u \n",p);
7. p=p+1;
8. printf("After increment: Address of p variable is %u \n",p); // in our case, p will get incre
mented by 4 bytes.
9. return 0;
10. }

Output

Address of p variable is 3214864300


After increment: Address of p variable is 3214864304

Traversing an array by using pointer

1. #include<stdio.h>
2. void main ()
3. {
4. int arr[5] = {1, 2, 3, 4, 5};
5. int *p = arr;
6. int i;
7. printf("printing array elements...\n");
8. for(i = 0; i< 5; i++)
9. {
10. printf("%d ",*(p+i));
11. }
12. }

Output

printing array elements...


1 2 3 4 5

Decrementing Pointer in C
Like increment, we can decrement a pointer variable. If we decrement a pointer, it will
start pointing to the previous location. The formula of decrementing the pointer is given
below:

1. new_address= current_address - i * size_of(data type)

32-bit
For 32-bit int variable, it will be decremented by 2 bytes.

64-bit
For 64-bit int variable, it will be decremented by 4 bytes.

Let's see the example of decrementing pointer variable on 64-bit OS.

1. #include <stdio.h>
2. void main(){
3. int number=50;
4. int *p;//pointer to int
5. p=&number;//stores the address of number variable
6. printf("Address of p variable is %u \n",p);
7. p=p-1;
8. printf("After decrement: Address of p variable is %u \n",p); // P will now point to the im
midiate previous location.
9. }

Output

Address of p variable is 3214864300


After decrement: Address of p variable is 3214864296

C Pointer Addition
We can add a value to the pointer variable. The formula of adding value to pointer is
given below:

1. new_address= current_address + (number * size_of(data type))

32-bit
For 32-bit int variable, it will add 2 * number.

64-bit

For 64-bit int variable, it will add 4 * number.

Let's see the example of adding value to pointer variable on 64-bit architecture.
1. #include<stdio.h>
2. int main(){
3. int number=50;
4. int *p;//pointer to int
5. p=&number;//stores the address of number variable
6. printf("Address of p variable is %u \n",p);
7. p=p+3; //adding 3 to pointer variable
8. printf("After adding 3: Address of p variable is %u \n",p);
9. return 0;
10. }

Output

Address of p variable is 3214864300


After adding 3: Address of p variable is 3214864312

As you can see, the address of p is 3214864300. But after adding 3 with p variable, it is
3214864312, i.e., 4*3=12 increment. Since we are using 64-bit architecture, it increments
12. But if we were using 32-bit architecture, it was incrementing to 6 only, i.e., 2*3=6. As
integer value occupies 2-byte memory in 32-bit OS.

C Pointer Subtraction
Like pointer addition, we can subtract a value from the pointer variable. Subtracting any
number from a pointer will give an address. The formula of subtracting value from the
pointer variable is given below:

1. new_address= current_address - (number * size_of(data type))

32-bit
For 32-bit int variable, it will subtract 2 * number.

64-bit
For 64-bit int variable, it will subtract 4 * number.

Let's see the example of subtracting value from the pointer variable on 64-bit
architecture.
1. #include<stdio.h>
2. int main(){
3. int number=50;
4. int *p;//pointer to int
5. p=&number;//stores the address of number variable
6. printf("Address of p variable is %u \n",p);
7. p=p-3; //subtracting 3 from pointer variable
8. printf("After subtracting 3: Address of p variable is %u \n",p);
9. return 0;
10. }

Output

Address of p variable is 3214864300


After subtracting 3: Address of p variable is 3214864288

You can see after subtracting 3 from the pointer variable, it is 12 (4*3) less than the
previous address value.

However, instead of subtracting a number, we can also subtract an address from


another address (pointer). This will result in a number. It will not be a simple arithmetic
operation, but it will follow the following rule.

If two pointers are of the same type,

1. Address2 -
Address1 = (Subtraction of two addresses)/size of data type which pointer points

Consider the following example to subtract one pointer from an another.

1. #include<stdio.h>
2. void main ()
3. {
4. int i = 100;
5. int *p = &i;
6. int *temp;
7. temp = p;
8. p = p + 3;
9. printf("Pointer Subtraction: %d - %d = %d",p, temp, p-temp);
10. }

Output

Pointer Subtraction: 1030585080 - 1030585068 = 3

Illegal arithmetic with pointers


There are various operations which can not be performed on pointers. Since, pointer
stores address hence we must ignore the operations which may lead to an illegal
address, for example, addition, and multiplication. A list of such operations is given
below.

o Address + Address = illegal


o Address * Address = illegal
o Address % Address = illegal
o Address / Address = illegal
o Address & Address = illegal
o Address ^ Address = illegal
o Address | Address = illegal
o ~Address = illegal

Pointer to function in C
As we discussed in the previous chapter, a pointer can point to a function in C. However,
the declaration of the pointer variable must be the same as the function. Consider the
following example to make a pointer pointing to the function.

1. #include<stdio.h>
2. int addition ();
3. int main ()
4. {
5. int result;
6. int (*ptr)();
7. ptr = &addition;
8. result = (*ptr)();
9. printf("The sum is %d",result);
10. }
11. int addition()
12. {
13. int a, b;
14. printf("Enter two numbers?");
15. scanf("%d %d",&a,&b);
16. return a+b;
17. }

Output

Enter two numbers?10 15


The sum is 25

Pointer to Array of functions in C


To understand the concept of an array of functions, we must understand the array of
function. Basically, an array of the function is an array which contains the addresses of
functions. In other words, the pointer to an array of functions is a pointer pointing to an
array which contains the pointers to the functions. Consider the following example.

1. #include<stdio.h>
2. int show();
3. int showadd(int);
4. int (*arr[3])();
5. int (*(*ptr)[3])();
6.
7. int main ()
8. {
9. int result1;
10. arr[0] = show;
11. arr[1] = showadd;
12. ptr = &arr;
13. result1 = (**ptr)();
14. printf("printing the value returned by show : %d",result1);
15. (*(*ptr+1))(result1);
16. }
17. int show()
18. {
19. int a = 65;
20. return a++;
21. }
22. int showadd(int b)
23. {
24. printf("\nAdding 90 to the value returned by show: %d",b+90);
25. }

Output

printing the value returned by show : 65


Adding 90 to the value returned by show: 155

void pointer in C
Till now, we have studied that the address assigned to a pointer should be of the same
type as specified in the pointer declaration. For example, if we declare the int pointer,
then this int pointer cannot point to the float variable or some other type of variable,
i.e., it can point to only int type variable. To overcome this problem, we use a pointer to
void. A pointer to void means a generic pointer that can point to any data type. We can
assign the address of any data type to the void pointer, and a void pointer can be
assigned to any type of the pointer without performing any explicit typecasting.

Syntax of void pointer

1. void *pointer name;

Declaration of the void pointer is given below:

1. void *ptr;

In the above declaration, the void is the type of the pointer, and 'ptr' is the name of the
pointer.
Let us consider some examples:

int i=9; // integer variable initialization.

int *p; // integer pointer declaration.

float *fp; // floating pointer declaration.

void *ptr; // void pointer declaration.

p=fp; // incorrect.

fp=&i; // incorrect

ptr=p; // correct

ptr=fp; // correct

ptr=&i; // correct

Size of the void pointer in C


The size of the void pointer in C is the same as the size of the pointer of character type.
According to C perception, the representation of a pointer to void is the same as the
pointer of character type. The size of the pointer will vary depending on the platform
that you are using.

Let's look at the below example:

1. #include <stdio.h>
2. int main()
3. {
4. void *ptr = NULL; //void pointer
5. int *p = NULL;// integer pointer
6. char *cp = NULL;//character pointer
7. float *fp = NULL;//float pointer
8. //size of void pointer
9. printf("size of void pointer = %d\n\n",sizeof(ptr));
10. //size of integer pointer
11. printf("size of integer pointer = %d\n\n",sizeof(p));
12. //size of character pointer
13. printf("size of character pointer = %d\n\n",sizeof(cp));
14. //size of float pointer
15. printf("size of float pointer = %d\n\n",sizeof(fp));
16. return 0;
17. }

Output

Advantages of void pointer


Following are the advantages of a void pointer:

o The malloc() and calloc() function return the void pointer, so these functions can
be used to allocate the memory of any data type.

1. #include <stdio.h>
2. #include<malloc.h>
3. int main()
4. {
5. int a=90;
6.
7. int *x = (int*)malloc(sizeof(int)) ;
8. x=&a;
9. printf("Value which is pointed by x pointer : %d",*x);
10. return 0;
11. }
Output

o The void pointer in C can also be used to implement the generic functions in C.

Some important points related to void pointer are:

o Dereferencing a void pointer in C

The void pointer in C cannot be dereferenced directly. Let's see the below example.

1. #include <stdio.h>
2. int main()
3. {
4. int a=90;
5. void *ptr;
6. ptr=&a;
7. printf("Value which is pointed by ptr pointer : %d",*ptr);
8. return 0;
9. }

In the above code, *ptr is a void pointer which is pointing to the integer variable 'a'. As
we already know that the void pointer cannot be dereferenced, so the above code will
give the compile-time error because we are printing the value of the variable pointed by
the pointer 'ptr' directly.

Output
Now, we rewrite the above code to remove the error.

1. #include <stdio.h>
2. int main()
3. {
4. int a=90;
5. void *ptr;
6. ptr=&a;
7. printf("Value which is pointed by ptr pointer : %d",*(int*)ptr);
8. return 0;
9. }

In the above code, we typecast the void pointer to the integer pointer by using the
statement given below:

(int*)ptr;

Then, we print the value of the variable which is pointed by the void pointer 'ptr' by
using the statement given below:

*(int*)ptr;

Output

o Arithmetic operation on void pointers

We cannot apply the arithmetic operations on void pointers in C directly. We need to


apply the proper typecasting so that we can perform the arithmetic operations on the
void pointers.

Let's see the below example:

1. #include<stdio.h>
2. int main()
3. {
4. float a[4]={6.1,2.3,7.8,9.0};
5. void *ptr;
6. ptr=a;
7. for(int i=0;i<4;i++)
8. {
9. printf("%f,",*ptr);
10. ptr=ptr+1; // Incorrect.
11.
12. }}

The above code shows the compile-time error that "invalid use of void expression" as
we cannot apply the arithmetic operations on void pointer directly, i.e., ptr=ptr+1.

Let's rewrite the above code to remove the error.

1. #include<stdio.h>
2. int main()
3. {
4. float a[4]={6.1,2.3,7.8,9.0};
5. void *ptr;
6. ptr=a;
7. for(int i=0;i<4;i++)
8. {
9. printf("%f,",*((float*)ptr+i));
10. }}

The above code runs successfully as we applied the proper casting to the void pointer,
i.e., (float*)ptr and then we apply the arithmetic operation, i.e., *((float*)ptr+i).

Output
Why we use void pointers?
We use void pointers because of its reusability. Void pointers can store the object of any
type, and we can retrieve the object of any type by using the indirection operator with
proper typecasting.

Let's understand through an example.

1. #include<stdio.h>
2. int main()
3. {
4. int a=56; // initialization of a integer variable 'a'.
5. float b=4.5; // initialization of a float variable 'b'.
6. char c='k'; // initialization of a char variable 'c'.
7. void *ptr; // declaration of void pointer.
8. // assigning the address of variable 'a'.
9. ptr=&a;
10. printf("value of 'a' is : %d",*((int*)ptr));
11. // assigning the address of variable 'b'.
12. ptr=&b;
13. printf("\nvalue of 'b' is : %f",*((float*)ptr));
14. // assigning the address of variable 'c'.
15. ptr=&c;
16. printf("\nvalue of 'c' is : %c",*((char*)ptr));
17. return 0;
18. }

Output

C dereference pointer
As we already know that "what is a pointer", a pointer is a variable that stores the
address of another variable. The dereference operator is also known as an indirection
operator, which is represented by (*). When indirection operator (*) is used with the
pointer variable, then it is known as dereferencing a pointer. When we dereference a
pointer, then the value of the variable pointed by this pointer will be returned.

Why we use dereferencing pointer?


Dereference a pointer is used because of the following reasons:

o It can be used to access or manipulate the data stored at the memory location,
which is pointed by the pointer.
o Any operation applied to the dereferenced pointer will directly affect the value of
the variable that it points to.

Let's observe the following steps to dereference a pointer.

o First, we declare the integer variable to which the pointer points.

1. int x =9;

o Now, we declare the integer pointer variable.

1. int *ptr;

o After the declaration of an integer pointer variable, we store the address of 'x'
variable to the pointer variable 'ptr'.

1. ptr=&x;

o We can change the value of 'x' variable by dereferencing a pointer 'ptr' as given
below:

1. *ptr =8;

The above line changes the value of 'x' variable from 9 to 8 because 'ptr' points to the 'x'
location and dereferencing of 'ptr', i.e., *ptr=8 will update the value of x.

Let's combine all the above steps:


1. #include <stdio.h>
2. int main()
3. {
4. int x=9;
5. int *ptr;
6. ptr=&x;
7. *ptr=8;
8. printf("value of x is : %d", x);
9. return 0;}

Output

Let's consider another example.

1. #include <stdio.h>
2. int main()
3. {
4. int x=4;
5. int y;
6. int *ptr;
7. ptr=&x;
8. y=*ptr;
9. *ptr=5;
10. printf("The value of x is : %d",x);
11. printf("\n The value of y is : %d",y);
12. return 0;
13. }

In the above code:


o We declare two variables 'x' and 'y' where 'x' is holding a '4' value.
o We declare a pointer variable 'ptr'.
o After the declaration of a pointer variable, we assign the address of the 'x'
variable to the pointer 'ptr'.
o As we know that the 'ptr' contains the address of 'x' variable, so '*ptr' is the same
as 'x'.
o We assign the value of 'x' to 'y' with the help of 'ptr' variable, i.e., y=*ptr instead
of using the 'x' variable.

Note: According to us, if we change the value of 'x', then the value of 'y' will also get
changed as the pointer 'ptr' holds the address of the 'x' variable. But this does not happen,
as 'y' is storing the local copy of value '5'.

Output

Let's consider another scenario.

1. #include <stdio.h>
2. int main()
3. {
4. int a=90;
5. int *ptr1,*ptr2;
6. ptr1=&a;
7. ptr2=&a;
8. *ptr1=7;
9. *ptr2=6;
10. printf("The value of a is : %d",a);
11. return 0;
12. }
In the above code:

o First, we declare an 'a' variable.


o Then we declare two pointers, i.e., ptr1 and ptr2.
o Both the pointers contain the address of 'a' variable.
o We assign the '7' value to the *ptr1 and '6' to the *ptr2. The final value of 'a'
would be '6'.

Note: If we have more than one pointer pointing to the same location, then the change
made by one pointer will be the same as another pointer.

Output

Dynamic memory allocation in C


The concept of dynamic memory allocation in c language enables the C programmer
to allocate memory at runtime. Dynamic memory allocation in c language is possible by
4 functions of stdlib.h header file.

1. malloc()
2. calloc()
3. realloc()
4. free()

Before learning above functions, let's understand the difference between static memory
allocation and dynamic memory allocation.

static memory allocation dynamic memory allocation

memory is allocated at compile time. memory is allocated at run time.

memory can't be increased while executing memory can be increased while executing
program. program.

used in array. used in linked list.


Now let's have a quick look at the methods used for dynamic memory allocation.

malloc() allocates single block of requested memory.

calloc() allocates multiple block of requested memory.

realloc() reallocates the memory occupied by malloc() or calloc() functions.

free() frees the dynamically allocated memory.

malloc() function in C
The malloc() function allocates single block of requested memory.

It doesn't initialize memory at execution time, so it has garbage value initially.

It returns NULL if memory is not sufficient.

The syntax of malloc() function is given below:

1. ptr=(cast-type*)malloc(byte-size)

Let's see the example of malloc() function.

1. #include<stdio.h>
2. #include<stdlib.h>
3. int main(){
4. int n,i,*ptr,sum=0;
5. printf("Enter number of elements: ");
6. scanf("%d",&n);
7. ptr=(int*)malloc(n*sizeof(int)); //memory allocated using malloc
8. if(ptr==NULL)
9. {
10. printf("Sorry! unable to allocate memory");
11. exit(0);
12. }
13. printf("Enter elements of array: ");
14. for(i=0;i<n;++i)
15. {
16. scanf("%d",ptr+i);
17. sum+=*(ptr+i);
18. }
19. printf("Sum=%d",sum);
20. free(ptr);
21. return 0;
22. }

Output

Enter elements of array: 3


Enter elements of array: 10
10
10
Sum=30

calloc() function in C
The calloc() function allocates multiple block of requested memory.

It initially initialize all bytes to zero.

It returns NULL if memory is not sufficient.

The syntax of calloc() function is given below:

1. ptr=(cast-type*)calloc(number, byte-size)

Let's see the example of calloc() function.

1. #include<stdio.h>
2. #include<stdlib.h>
3. int main(){
4. int n,i,*ptr,sum=0;
5. printf("Enter number of elements: ");
6. scanf("%d",&n);
7. ptr=(int*)calloc(n,sizeof(int)); //memory allocated using calloc
8. if(ptr==NULL)
9. {
10. printf("Sorry! unable to allocate memory");
11. exit(0);
12. }
13. printf("Enter elements of array: ");
14. for(i=0;i<n;++i)
15. {
16. scanf("%d",ptr+i);
17. sum+=*(ptr+i);
18. }
19. printf("Sum=%d",sum);
20. free(ptr);
21. return 0;
22. }

Output

Enter elements of array: 3


Enter elements of array: 10
10
10
Sum=30

realloc() function in C
If memory is not sufficient for malloc() or calloc(), you can reallocate the memory by
realloc() function. In short, it changes the memory size.

Let's see the syntax of realloc() function.

1. ptr=realloc(ptr, new-size)

free() function in C
The memory occupied by malloc() or calloc() functions must be released by calling free()
function. Otherwise, it will consume memory until program exit.

Let's see the syntax of free() function.


1. free(ptr)

Why use structure?


In C, there are cases where we need to store multiple attributes of an entity. It is not
necessary that an entity has all the information of one type only. It can have different
attributes of different data types. For example, an entity Student may have its name
(string), roll number (int), marks (float). To store such type of information regarding an
entity student, we have the following approaches:

o Construct individual arrays for storing names, roll numbers, and marks.
o Use a special data structure to store the collection of different data types.

Let's look at the first approach in detail.

1. #include<stdio.h>
2. void main ()
3. {
4. char names[2][10],dummy; // 2-
dimensioanal character array names is used to store the names of the students
5. int roll_numbers[2],i;
6. float marks[2];
7. for (i=0;i<3;i++)
8. {
9.
10. printf("Enter the name, roll number, and marks of the student %d",i+1);
11. scanf("%s %d %f",&names[i],&roll_numbers[i],&marks[i]);
12. scanf("%c",&dummy); // enter will be stored into dummy character at each iteration
13. }
14. printf("Printing the Student details ...\n");
15. for (i=0;i<3;i++)
16. {
17. printf("%s %d %f\n",names[i],roll_numbers[i],marks[i]);
18. }
19. }
Output

Enter the name, roll number, and marks of the student 1Arun 90 91
Enter the name, roll number, and marks of the student 2Varun 91 56
Enter the name, roll number, and marks of the student 3Sham 89 69

Printing the Student details...


Arun 90 91.000000
Varun 91 56.000000
Sham 89 69.000000

The above program may fulfill our requirement of storing the information of an entity
student. However, the program is very complex, and the complexity increase with the
amount of the input. The elements of each of the array are stored contiguously, but all
the arrays may not be stored contiguously in the memory. C provides you with an
additional and simpler approach where you can use a special data structure, i.e.,
structure, in which, you can group all the information of different data type regarding an
entity.

What is Structure
Structure in c is a user-defined data type that enables us to store the collection of
different data types. Each element of a structure is called a member. Structures ca;
simulate the use of classes and templates as it can store various information

The ,struct keyword is used to define the structure. Let's see the syntax to define the
structure in c.

1. struct structure_name
2. {
3. data_type member1;
4. data_type member2;
5. .
6. .
7. data_type memeberN;
8. };

Let's see the example to define a structure for an entity employee in c.

1. struct employee
2. { int id;
3. char name[20];
4. float salary;
5. };

The following image shows the memory allocation of the structure employee that is
defined in the above example.

Here, struct is the keyword; employee is the name of the structure; id, name,
and salary are the members or fields of the structure. Let's understand it by the diagram
given below:
Declaring structure variable
We can declare a variable for the structure so that we can access the member of the
structure easily. There are two ways to declare structure variable:

1. By struct keyword within main() function


2. By declaring a variable at the time of defining the structure.

1st way:

Let's see the example to declare the structure variable by struct keyword. It should be
declared within the main function.

1. struct employee
2. { int id;
3. char name[50];
4. float salary;
5. };

Now write given code inside the main() function.

1. struct employee e1, e2;

The variables e1 and e2 can be used to access the values stored in the structure. Here,
e1 and e2 can be treated in the same way as the objects in C++ and Java.

2nd way:

Let's see another way to declare variable at the time of defining the structure.

1. struct employee
2. { int id;
3. char name[50];
4. float salary;
5. }e1,e2;

Which approach is good


If number of variables are not fixed, use the 1st approach. It provides you the flexibility
to declare the structure variable many times.

If no. of variables are fixed, use 2nd approach. It saves your code to declare a variable in
main() function.

Accessing members of the structure


There are two ways to access structure members:

1. By . (member or dot operator)


2. By -> (structure pointer operator)

Let's see the code to access the id member of p1 variable by. (member) operator.

1. p1.id

C Structure example
Let's see a simple example of structure in C language.

1. #include<stdio.h>
2. #include <string.h>
3. struct employee
4. { int id;
5. char name[50];
6. }e1; //declaring e1 variable for structure
7. int main( )
8. {
9. //store first employee information
10. e1.id=101;
11. strcpy(e1.name, "Sonoo Jaiswal");//copying string into char array
12. //printing first employee information
13. printf( "employee 1 id : %d\n", e1.id);
14. printf( "employee 1 name : %s\n", e1.name);
15. return 0;
16. }
Output:

employee 1 id : 101
employee 1 name : Sonoo Jaiswal

Let's see another example of the structure in C language to store many employees
information.

1. #include<stdio.h>
2. #include <string.h>
3. struct employee
4. { int id;
5. char name[50];
6. float salary;
7. }e1,e2; //declaring e1 and e2 variables for structure
8. int main( )
9. {
10. //store first employee information
11. e1.id=101;
12. strcpy(e1.name, "Sonoo Jaiswal");//copying string into char array
13. e1.salary=56000;
14.
15. //store second employee information
16. e2.id=102;
17. strcpy(e2.name, "James Bond");
18. e2.salary=126000;
19.
20. //printing first employee information
21. printf( "employee 1 id : %d\n", e1.id);
22. printf( "employee 1 name : %s\n", e1.name);
23. printf( "employee 1 salary : %f\n", e1.salary);
24.
25. //printing second employee information
26. printf( "employee 2 id : %d\n", e2.id);
27. printf( "employee 2 name : %s\n", e2.name);
28. printf( "employee 2 salary : %f\n", e2.salary);
29. return 0;
30. }

Output:

employee 1 id : 101
employee 1 name : Sonoo Jaiswal
employee 1 salary : 56000.000000
employee 2 id : 102
employee 2 name : James Bond
employee 2 salary : 126000.000000

typedef in C
The typedef is a keyword used in C programming to provide some meaningful names
to the already existing variable in the C program. It behaves similarly as we define the
alias for the commands. In short, we can say that this keyword is used to redefine the
name of an already existing variable.

Syntax of typedef

1. typedef <existing_name> <alias_name>

In the above syntax, 'existing_name' is the name of an already existing variable while
'alias name' is another name given to the existing variable.

For example, suppose we want to create a variable of type unsigned int, then it
becomes a tedious task if we want to declare multiple variables of this type. To
overcome the problem, we use a typedef keyword.

1. typedef unsigned int unit;

In the above statements, we have declared the unit variable of type unsigned int by
using a typedef keyword.

Now, we can create the variables of type unsigned int by writing the following
statement:

1. unit a, b;

instead of writing:
1. unsigned int a, b;

Till now, we have observed that the typedef keyword provides a nice shortcut by
providing an alternative name for an already existing variable. This keyword is useful
when we are dealing with the long data type especially, structure declarations.

Let's understand through a simple example.

1. #include <stdio.h>
2. int main()
3. {
4. typedef unsigned int unit;
5. unit i,j;
6. i=10;
7. j=20;
8. printf("Value of i is :%d",i);
9. printf("\nValue of j is :%d",j);
10. return 0;
11. }

Output

Value of i is :10
Value of j is :20

Using typedef with structures


Consider the below structure declaration:

1. struct student
2. {
3. char name[20];
4. int age;
5. };
6. struct student s1;

In the above structure declaration, we have created the variable of student type by
writing the following statement:
1. struct student s1;

The above statement shows the creation of a variable, i.e., s1, but the statement is quite
big. To avoid such a big statement, we use the typedef keyword to create the variable
of type student.

1. struct student
2. {
3. char name[20];
4. int age;
5. };
6. typedef struct student stud;
7. stud s1, s2;

In the above statement, we have declared the variable stud of type struct student. Now,
we can use the stud variable in a program to create the variables of type struct
student.

The above typedef can be written as:

1. typedef struct student


2. {
3. char name[20];
4. int age;
5. } stud;
6. stud s1,s2;

From the above declarations, we conclude that typedef keyword reduces the length of
the code and complexity of data types. It also helps in understanding the program.

Let's see another example where we typedef the structure declaration.

1. #include <stdio.h>
2. typedef struct student
3. {
4. char name[20];
5. int age;
6. }stud;
7. int main()
8. {
9. stud s1;
10. printf("Enter the details of student s1: ");
11. printf("\nEnter the name of the student:");
12. scanf("%s",&s1.name);
13. printf("\nEnter the age of student:");
14. scanf("%d",&s1.age);
15. printf("\n Name of the student is : %s", s1.name);
16. printf("\n Age of the student is : %d", s1.age);
17. return 0;
18. }

Output

Enter the details of student s1:


Enter the name of the student: Peter
Enter the age of student: 28
Name of the student is : Peter
Age of the student is : 28

Using typedef with pointers


We can also provide another name or alias name to the pointer variables with the help
of the typedef.

For example, we normally declare a pointer, as shown below:

1. int* ptr;

We can rename the above pointer variable as given below:

1. typedef int* ptr;

In the above statement, we have declared the variable of type int*. Now, we can create
the variable of type int* by simply using the 'ptr' variable as shown in the below
statement:

1. ptr p1, p2 ;
In the above statement, p1 and p2 are the variables of type 'ptr'.

C Array of Structures
Why use an array of structures?
Consider a case, where we need to store the data of 5 students. We can store it by using
the structure as given below.

1. #include<stdio.h>
2. struct student
3. {
4. char name[20];
5. int id;
6. float marks;
7. };
8. void main()
9. {
10. struct student s1,s2,s3;
11. int dummy;
12. printf("Enter the name, id, and marks of student 1 ");
13. scanf("%s %d %f",s1.name,&s1.id,&s1.marks);
14. scanf("%c",&dummy);
15. printf("Enter the name, id, and marks of student 2 ");
16. scanf("%s %d %f",s2.name,&s2.id,&s2.marks);
17. scanf("%c",&dummy);
18. printf("Enter the name, id, and marks of student 3 ");
19. scanf("%s %d %f",s3.name,&s3.id,&s3.marks);
20. scanf("%c",&dummy);
21. printf("Printing the details....\n");
22. printf("%s %d %f\n",s1.name,s1.id,s1.marks);
23. printf("%s %d %f\n",s2.name,s2.id,s2.marks);
24. printf("%s %d %f\n",s3.name,s3.id,s3.marks);
25. }
Output

Enter the name, id, and marks of student 1 James 90 90


Enter the name, id, and marks of student 2 Adoms 90 90
Enter the name, id, and marks of student 3 Nick 90 90
Printing the details....
James 90 90.000000
Adoms 90 90.000000
Nick 90 90.000000

In the above program, we have stored data of 3 students in the structure. However, the
complexity of the program will be increased if there are 20 students. In that case, we will
have to declare 20 different structure variables and store them one by one. This will
always be tough since we will have to declare a variable every time we add a student.
Remembering the name of all the variables is also a very tricky task. However, c enables
us to declare an array of structures by using which, we can avoid declaring the different
structure variables; instead we can make a collection containing all the structures that
store the information of different entities.

Array of Structures in C
An array of structres in C can be defined as the collection of multiple structures variables
where each variable contains information about different entities. The array of structures
in C are used to store information about multiple entities of different data types. The
array of structures is also known as the collection of structures.

PlayNext
Unmute

Current Time 0:00

Duration 18:10
Loaded: 2.94%
Â
Fullscreen
Let's see an example of an array of structures that stores information of 5 students and
prints it.

1. #include<stdio.h>
2. #include <string.h>
3. struct student{
4. int rollno;
5. char name[10];
6. };
7. int main(){
8. int i;
9. struct student st[5];
10. printf("Enter Records of 5 students");
11. for(i=0;i<5;i++){
12. printf("\nEnter Rollno:");
13. scanf("%d",&st[i].rollno);
14. printf("\nEnter Name:");
15. scanf("%s",&st[i].name);
16. }
17. printf("\nStudent Information List:");
18. for(i=0;i<5;i++){
19. printf("\nRollno:%d, Name:%s",st[i].rollno,st[i].name);
20. }
21. return 0;
22. }

Output:

Enter Records of 5 students


Enter Rollno:1
Enter Name:Sonoo
Enter Rollno:2
Enter Name:Ratan
Enter Rollno:3
Enter Name:Vimal
Enter Rollno:4
Enter Name:James
Enter Rollno:5
Enter Name:Sarfraz

Student Information List:


Rollno:1, Name:Sonoo
Rollno:2, Name:Ratan
Rollno:3, Name:Vimal
Rollno:4, Name:James
Rollno:5, Name:Sarfraz

Nested Structure in C
C provides us the feature of nesting one structure within another structure by using
which, complex data types are created. For example, we may need to store the address
of an entity employee in a structure. The attribute address may also have the subparts
as street number, city, state, and pin code. Hence, to store the address of the employee,
we need to store the address of the employee into a separate structure and nest the
structure address into the structure employee. Consider the following program.

1. #include<stdio.h>
2. struct address
3. {
4. char city[20];
5. int pin;
6. char phone[14];
7. };
8. struct employee
9. {
10. char name[20];
11. struct address add;
12. };
13. void main ()
14. {
15. struct employee emp;
16. printf("Enter employee information?\n");
17. scanf("%s %s %d %s",emp.name,emp.add.city, &emp.add.pin, emp.add.phone);
18. printf("Printing the employee information....\n");
19. printf("name: %s\nCity: %s\nPincode: %d\nPhone: %s",emp.name,emp.add.city,emp.a
dd.pin,emp.add.phone);
20. }

Output

Enter employee information?

Arun

Delhi

110001

1234567890

Printing the employee information....

name: Arun
City: Delhi

Pincode: 110001

Phone: 1234567890

The structure can be nested in the following ways.

1. By separate structure
2. By Embedded structure

1) Separate structure
Here, we create two structures, but the dependent structure should be used inside the
main structure as a member. Consider the following example.

PauseNext
Unmute

Current Time 0:33

Duration 18:10
Loaded: 7.70%
Â
Fullscreen

1. struct Date
2. {
3. int dd;
4. int mm;
5. int yyyy;
6. };
7. struct Employee
8. {
9. int id;
10. char name[20];
11. struct Date doj;
12. }emp1;
As you can see, doj (date of joining) is the variable of type Date. Here doj is used as a
member in Employee structure. In this way, we can use Date structure in many
structures.

2) Embedded structure
The embedded structure enables us to declare the structure inside the structure. Hence,
it requires less line of codes but it can not be used in multiple data structures. Consider
the following example.

1. struct Employee
2. {
3. int id;
4. char name[20];
5. struct Date
6. {
7. int dd;
8. int mm;
9. int yyyy;
10. }doj;
11. }emp1;

Accessing Nested Structure


We can access the member of the nested structure by
Outer_Structure.Nested_Structure.member as given below:

1. e1.doj.dd
2. e1.doj.mm
3. e1.doj.yyyy

C Nested Structure example


Let's see a simple example of the nested structure in C language.

1. #include <stdio.h>
2. #include <string.h>
3. struct Employee
4. {
5. int id;
6. char name[20];
7. struct Date
8. {
9. int dd;
10. int mm;
11. int yyyy;
12. }doj;
13. }e1;
14. int main( )
15. {
16. //storing employee information
17. e1.id=101;
18. strcpy(e1.name, "Sonoo Jaiswal");//copying string into char array
19. e1.doj.dd=10;
20. e1.doj.mm=11;
21. e1.doj.yyyy=2014;
22.
23. //printing first employee information
24. printf( "employee id : %d\n", e1.id);
25. printf( "employee name : %s\n", e1.name);
26. printf( "employee date of joining (dd/mm/yyyy) : %d/%d/%d\n", e1.doj.dd,e1.doj.mm,e
1.doj.yyyy);
27. return 0;
28. }

Output:

employee id : 101
employee name : Sonoo Jaiswal
employee date of joining (dd/mm/yyyy) : 10/11/2014

Passing structure to function


Just like other variables, a structure can also be passed to a function. We may pass the
structure members into the function or pass the structure variable at once. Consider the
following example to pass the structure variable employee to a function display() which
is used to display the details of an employee.

1. #include<stdio.h>
2. struct address
3. {
4. char city[20];
5. int pin;
6. char phone[14];
7. };
8. struct employee
9. {
10. char name[20];
11. struct address add;
12. };
13. void display(struct employee);
14. void main ()
15. {
16. struct employee emp;
17. printf("Enter employee information?\n");
18. scanf("%s %s %d %s",emp.name,emp.add.city, &emp.add.pin, emp.add.phone);
19. display(emp);
20. }
21. void display(struct employee emp)
22. {
23. printf("Printing the details....\n");
24. printf("%s %s %d %s",emp.name,emp.add.city,emp.add.pin,emp.add.phone);
25. }

Union in C
Union can be defined as a user-defined data type which is a collection of different
variables of different data types in the same memory location. The union can also be
defined as many members, but only one member can contain a value at a particular
point in time.

Union is a user-defined data type, but unlike structures, they share the same memory
location.

Let's understand this through an example.

1. struct abc
2. {
3. int a;
4. char b;
5. }

The above code is the user-defined structure that consists of two members, i.e., 'a' of
type int and 'b' of type character. When we check the addresses of 'a' and 'b', we found
that their addresses are different. Therefore, we conclude that the members in the
structure do not share the same memory location.

When we define the union, then we found that union is defined in the same way as the
structure is defined but the difference is that union keyword is used for defining the
union data type, whereas the struct keyword is used for defining the structure. The
union contains the data members, i.e., 'a' and 'b', when we check the addresses of both
the variables then we found that both have the same addresses. It means that the union
members share the same memory location.

Let's have a look at the pictorial representation of the memory allocation.

The below figure shows the pictorial representation of the structure. The structure has
two members; i.e., one is of integer type, and the another one is of character type. Since
1 block is equal to 1 byte; therefore, 'a' variable will be allocated 4 blocks of memory
while 'b' variable will be allocated 1 block of memory.

The below figure shows the pictorial representation of union members. Both the
variables are sharing the same memory location and having the same initial address.
In union, members will share the memory location. If we try to make changes in any of
the member then it will be reflected to the other member as well. Let's understand this
concept through an example.

1. union abc
2. {
3. int a;
4. char b;
5. }var;
6. int main()
7. {
8. var.a = 66;
9. printf("\n a = %d", var.a);
10. printf("\n b = %d", var.b);
11. }

In the above code, union has two members, i.e., 'a' and 'b'. The 'var' is a variable of
union abc type. In the main() method, we assign the 66 to 'a' variable, so var.a will print
66 on the screen. Since both 'a' and 'b' share the memory location, var.b will print 'B'
(ascii code of 66).

Deciding the size of the union


The size of the union is based on the size of the largest member of the union.

Let's understand through an example.

1. union abc{
2. int a;
3. char b;
4. float c;
5. double d;
6. };
7. int main()
8. {
9. printf("Size of union abc is %d", sizeof(union abc));
10. return 0;
11. }

As we know, the size of int is 4 bytes, size of char is 1 byte, size of float is 4 bytes, and
the size of double is 8 bytes. Since the double variable occupies the largest memory
among all the four variables, so total 8 bytes will be allocated in the memory. Therefore,
the output of the above program would be 8 bytes.

Accessing members of union using pointers


We can access the members of the union through pointers by using the (->) arrow
operator.

Let's understand through an example.

1. #include <stdio.h>
2. union abc
3. {
4. int a;
5. char b;
6. };
7. int main()
8. {
9. union abc *ptr; // pointer variable declaration
10. union abc var;
11. var.a= 90;
12. ptr = &var;
13. printf("The value of a is : %d", ptr->a);
14. return 0;
15. }

In the above code, we have created a pointer variable, i.e., *ptr, that stores the address
of var variable. Now, ptr can access the variable 'a' by using the (->) operator. Hence the
output of the above code would be 90.

Why do we need C unions?


Consider one example to understand the need for C unions. Let's consider a store that
has two items:
o Books
o Shirts

Store owners want to store the records of the above-mentioned two items along with
the relevant information. For example, Books include Title, Author, no of pages, price,
and Shirts include Color, design, size, and price. The 'price' property is common in both
items. The Store owner wants to store the properties, then how he/she will store the
records.

Initially, they decided to store the records in a structure as shown below:

1. struct store
2. {
3. double price;
4. char *title;
5. char *author;
6. int number_pages;
7. int color;
8. int size;
9. char *design;
10. };

The above structure consists of all the items that store owner wants to store. The above
structure is completely usable but the price is common property in both the items and
the rest of the items are individual. The properties like price, *title, *author, and
number_pages belong to Books while color, size, *design belongs to Shirt.

Let's see how can we access the members of the structure.

1. int main()
2. {
3. struct store book;
4. book.title = "C programming";
5. book.author = "Paulo Cohelo";
6. book.number_pages = 190;
7. book.price = 205;
8. printf("Size is : %ld bytes", sizeof(book));
9. return 0;
10. }

In the above code, we have created a variable of type store. We have assigned the
values to the variables, title, author, number_pages, price but the book variable does not
possess the properties such as size, color, and design. Hence, it's a wastage of memory.
The size of the above structure would be 44 bytes.

We can save lots of space if we use unions.

1. #include <stdio.h>
2. struct store
3. {
4. double price;
5. union
6. {
7. struct{
8. char *title;
9. char *author;
10. int number_pages;
11. } book;
12.
13. struct {
14. int color;
15. int size;
16. char *design;
17. } shirt;
18. }item;
19. };
20. int main()
21. {
22. struct store s;
23. s.item.book.title = "C programming";
24. s.item.book.author = "John";
25. s.item.book.number_pages = 189;
26. printf("Size is %ld", sizeof(s));
27. return 0;
28. }

In the above code, we have created a variable of type store. Since we used the unions in
the above code, so the largest memory occupied by the variable would be considered
for the memory allocation. The output of the above program is 32 bytes. In the case of
structures, we obtained 44 bytes, while in the case of unions, the size obtained is 44
bytes. Hence, 44 bytes is greater than 32 bytes saving lots of memory space.

Self-referential structure
The self-referential structure is a structure that points to the same type of structure. It
contains one or more pointers that ultimately point to the same structure.

o Structures are a user-defined data structure type in C and C++.


o The main benefit of creating structure is that it can hold the different predefined
data types.
o It is initialized with the struct keyword and the structure's name followed by this
struct keyword.
o We can easily take the different data types like integer value, float, char, and
others within the same structure.
o It reduces the complexity of the program.
o Using a single structure can hold the values and data set in a single place.
o In the C++ programming language, placing struct keywords is optional or not
mandatory, but it is mandatory in the C programming language.
o Self-referential structure plays a very important role in creating other data
structures like Linked list.
o In this type of structure, the object of the same structure points to the same data
structure and refers to the data types of the same structure.
o It can have one or more pointers pointing to the same type of structure as their
member.
o The self-referential structure is widely used in dynamic data structures such
as trees, linked lists, etc.
Why do we require a Self-referential structure?
Self-referential structure plays a vital role in the linked list, trees, graphs, and many more
data structures. By using the structure, we can easily implement these data structures
efficiently. For defining a particular node, the structure plays a very important role. In a
linked list, the structure is used to store the data information and the address of the
next node in the given linked list. Mainly the data part is of integer type, and the link
address part is of pointer type, which holds the address of the next node, so that it can
for the Link ultimately.

As we all know, the role of a linked list is used to store the data elements of the same
type, in which address locations are not at the consecutive difference. In this linear
linked list, the current node holds the address of the next node so that it ultimately
forms the Link between the current node and the next node.

Here in the linked list, we will define a common structure, which contains the data and
address pointer to carry the address of the next node, so to form the multiple nodes, we
from each node using the node structure.
Unlike a static data structure such as an array where the size of the array limits the
number of elements that can easily to inserted into the array, a self-referential structure
can dynamically be expanded or contracted.

Operations like the insertion or deletion of nodes in a self-referential structure involve


straightforward alteration of pointers.

Linked list
o A linked list is a useful data storage method, and it is very easy to implement it in
C programming Language.
o Several kinds of linked lists, including single linked lists, double linked
lists, and binary trees.
o Each type is suited for certain types of data storage.
o The one thing that these lists have in common is that the links between data
items are defined by the information contained in the items themselves, in the
form of pointers.
o The linked list is distinctly different from arrays, in which the links between data
items result from the layout and storage of the array.

Here, we will discuss the self-referential structure in more detail using the linked list
concepts.

Let's understand the concept of self-referential structure in more detail using the
example mentioned below:

Example 1: Creating a random self-referential structure in the C programming


language.

1. // Dummy Self-referential structure in C language


2. struct node // Creating a node of structure type contains data

3. // part of integer type and a pointer of structure type to


4. // hold the address of the next node
5. {
6. int d1 ; // data 1 of integer type
7. int d2 ; // data 2 of integer type
8. struct node * link ; // Self referential structure link is pointing the same
9. // structure of the type node
10. } ;
11. Int main()
12. {
13. Struct node obj; // Creating an object of the node type, this o
bject is // consists of three parts one is data 1 and
14. // second is of data 2, and third is of link type pointer
15. // carries the address of the next node.
16. Return 0 ;
17. }

Example 2: Creating a random self-referential structure in a python programming


language.

1. # Dummy Self-referential structure in python language


2. class node: # Creating a node that contains data
3. # part of and a pointer of node type to
4. # hold the address of the next node
5. def __init__(self):
6. self.data1=0
7. self.data2=' '
8. self.link=None # Self-referential structure link is pointing the same
9. # structure of the type node
10.
11.
12. if __name__ == '__main__':
13. ob=node()
14. # Creating a object of node type, this object is
15. # consists of three parts one is data 1 and
16. # second is of data 2 and third is of link type pointer
17. # carries the address of the next node

Types of self-referential structure


1. Single Link self-referential structure
2. Multiple Link self-referential structures

Single Link self-referential structure


As the name suggests, we can easily predict that these structures consist of a single Link,
mainly the only one pointer link of structure type pointing to the same structure. To
better understand it, we can connect this concept with the singly linked list.

In a singly linked list, there is only a single pointer that carries the address of the next
node, and that pointer variable is of the structure node type itself. It is mainly used when
we want to store the different data items by fetching out them from various addresses
and connecting all of them by storing the address of one data item into the linked part
of the other node. In this way, we can easily connect all the data items by using these
connecting links.

Let's look at the working of single link self-referential structure with the help of an
example:

1. // Single link self-referential structure implementation in C language


2. #include<stdio.h>
3. #include<stdlib.h>
4. struct node
5. {
6. int info ;
7. struct node *link ; // Self-referential structure link is pointing the same
8. // structure of the type node
9. };
10.
11. struct node *START = NULL ; // start pointer to control the linked list //
12. struct node* createnode() ;
13. void insertatlast() ; // insert node at last //
14. void deleteatfirst() ; // delete node at first //
15. void viewlist() ;
16. void insertatfirst() ;
17. int getlength() ;
18. int menu() ;
19. void insertafteranynode() ;
20. void deleteatlast() ;
21. void deleteatposition() ;
22.
23. struct node* createnode() // create node dynamically //
24. {
25. struct node *n ;
26. n = malloc( sizeof(struct node) ) ;
27. return ( n ) ;
28. }
29. void insertatlast()
30. {
31. struct node *temp ,*t ;
32. temp = createnode() ;
33. printf( "Enter the data in node \n " ) ;
34. scanf( " %d" , &temp->info ) ;
35. temp->link = NULL ;
36. if ( START == NULL )
37. START = temp ;
38. else
39. {
40. t = START ;
41. while ( t->link != NULL )
42. {
43. t = t->link ;
44. }
45. t->link = temp ;
46. }
47. }
48. void deleteatfirst() // delete node at first //
49. {
50. if ( START == NULL )
51. printf ( "List is empty \n " ) ;
52. else
53. {
54. struct node *q ;
55. q = START ;
56. START = START->link ;
57. free( q ) ;
58. }
59. }
60. void viewlist()
61. { struct node* t ;
62. if ( START == NULL )
63. {
64. printf ( "No List \n " ) ;
65. }
66. else
67. {
68. t = START ;
69. while ( t != NULL )
70. {
71. printf ( " %d" , t->info ) ;
72. t = t->link ;
73. }
74. }
75. }
76. void insertatfirst()
77. { struct node*New ;
78. New = createnode() ;
79. printf ( "Enter the data in node \n " ) ;
80. scanf ( " %d" , &New->info ) ;
81.
82. if ( START == NULL )
83. START = New ;
84. else
85. {
86. New->link = START ;
87. START = New ;
88. }
89. }
90. int getlength()
91. {
92. int count = 0 ;
93. struct node* t ;
94. if ( START == NULL )
95. printf ( "List is empty \n " ) ;
96. else
97. {
98. t =START ;
99. while ( t != NULL )
100. {
101. count = count + 1 ;
102. t = t->link ;
103. }
104. }
105. return count ;
106. }
107. void insertafteranynode()
108. {
109. int position ;
110. struct node* newnode ,*t ;
111. if ( START == NULL )
112. printf ( "List is empty \n " ) ;
113. else
114. {
115. printf ( "Enter position after which you want to add: \n " ) ;
116. scanf ( " %d" , &position ) ;
117. if ( position > getlength() )
118. {
119. printf ( "Wrong position \n " ) ;
120. insertafteranynode() ; // recursion //
121.
122. }
123. else
124. {
125. int i = 1 ;
126. newnode = createnode() ;
127. printf ( "Enter Data \n " ) ;
128. scanf ( " %d" , &newnode->info ) ;
129. newnode->link = NULL ;
130. if ( START == NULL )
131. START = newnode ;
132. else
133. {
134. t = START ;
135. while ( i < position )
136. {
137. t = t->link ;
138. i++ ;
139. }
140. newnode->link = t->link ;
141. t->link = newnode ;
142. }
143. }
144. }
145. }
146. void deleteatlast()
147. {
148. struct node* t , *q ;
149. if ( START == NULL )
150. {
151. printf ( "List is empty \n " ) ;
152. }
153. else
154. {
155. t = START ;
156. q = START ;
157. while ( t->link != NULL )
158. {
159. q=t;
160. t = t->link ;
161. }
162. if ( t == START )
163. {
164. START == NULL ;
165. }
166. else
167. {
168. q->link = NULL ;
169. free( t ) ;
170. }
171. }
172. }
173. void deleteatposition()
174. {
175. struct node *t , *q ;
176. int position , i = 1 ;
177. t = START ;
178. if ( START == NULL)
179. {
180. printf ( "List is empty \n " ) ;
181. }
182. else
183. {
184. printf ( "Enter position after which you want to delete: \n " ) ;
185. scanf ( " %d" , &position ) ;
186. if ( position > getlength() )
187. {
188. printf ( "Wrong position \n " ) ;
189. deleteatposition() ; // recursion //
190.
191. }
192. else
193. {
194. while ( i < position )
195. {
196. q=t;
197. t = t->link ;
198. i++ ;
199. }
200. if ( t == START )
201. {
202. START == NULL ;
203. }
204. else
205. {
206. q->link = t->link ;
207. free( t ) ;
208. }
209. }
210. }
211. }
212. int menu()
213. {
214. int ch ;
215. printf ( " \t \t \t 1.ADD NODE LAST IN LINK \n " ) ;
216. printf ( " \t \t \t 2.ADD NODE AT FIRST IN LINK \n " ) ;
217. printf ( " \t \t \t 3.VIEW LIST IN LINK \n " ) ;
218. printf ( " \t \t \t 4.DELETE NODE AT FIRST IN LINK \n " ) ;
219. printf( " \t \t \t 5. TO SEE THE LENGTH OF LIST \n " ) ;
220. printf ( " \t \t \t 6. INSERT NODE IN BETWEEN \n " ) ;
221. printf ( " \t \t \t 7.DELETE NODE AT LAST IN LINK \n " ) ;
222. printf ( " \t \t \t 8.DELETE NODE AT SPECIFIC POSITION IN LINK \n " ) ;
223. printf ( " \t \t \t 9.EXIT \n " ) ;
224. printf ( "ENTER THE CHOICE \n " ) ;
225. scanf ( " %d" , &ch ) ;
226. return( ch ) ;
227. }
228. void main()
229. { int k ;
230. while ( 1 )
231. {
232. switch ( menu() )
233. {
234. case 1 :
235. insertatlast() ;
236. break ;
237. case 2 :
238. insertatfirst() ;
239. break ;
240. case 3 :
241. viewlist() ;
242. break ;
243. case 4 :
244. deleteatfirst() ;
245. break ;
246. case 5 :
247. k = getlength() ;
248. printf ( "THE LENGTH OF THE LIST IS %d \n " , k ) ;
249. break ;
250. case 6 :
251. insertafteranynode() ;
252. break ;
253. case 7 :
254. deleteatlast() ;
255. break ;
256. case 8 :
257. deleteatposition() ;
258. break ;
259. case 9 :
260. exit( 0 ) ;
261. break ;
262. default :
263. printf ( " Not available \n " ) ;
264. }
265. }
266. }

The output of the above program is:


1. # Single link self-referential structure implementation in Python language
2. class node:
3. def __init__(self):
4. self.d1=0
5. self.d2=0
6. self.link=None
7.
8. if __name__ == '__main__':
9. obj1=node() # Node1
10.
11. # Initialization
12. obj1.link = None
13. obj1.d1 = 17
14. obj1.d2 = 14
15.
16. obj2=node() # Node2
17.
18. # Initialization
19. obj2.link = None
20. obj2.d1 = 36
21. obj2.d2 = 24
22.
23. # Linking obj1 and obj2
24. obj1.link = obj2
25.
26. # Accessing data members of obj2 using obj1
27. print(obj1.link.d1)
28. print(obj1.link.d2)

The output of the above program is:

36

24

Multiple Link self-referential structures


As the name suggests, we can easily predict that these types of the structure consist of
multiple Link, here we will make use of two pointer links of structure type which is
pointing to the same structure, to understand it better, we can connect this concept
with a doubly-linked list.

In a doubly-linked list, two single pointers carry the address of the next node and the
previous node, and that pointer variable is of the structure node type itself. It is mainly
used when we want to store the different data items by fetching out them from various
addresses and connecting all of them by storing the address of one data item into the
linked part of the other node; in this way, we can easily connect all the data items by
using these connecting links.

Let us look at the working of, multiple link self-referential structure with the help of an
example:
1. // Multiple link self-referential structure implementation in C language
2. #include<stdio.h>
3. #include<stdlib.h>
4. struct node
5. {
6. int info ;
7. struct node *prev ; // Self-referential structure link is pointing the same
8. // structure of the type node but to the previous node
9.
10. struct node *next; // Self-referential structure link is pointing the same
11. // structure of the type node but to the next node
12.
13. } ;
14.
15. struct node * START = NULL ; // Start pointer of the list and initially it must be nu
ll, // represents that no node is present
16. void insertnodeatfirst() ;
17. void deleteatfirst() ;
18. void viewlist() ;
19. int menu() ;
20. void insertnodeatfirst() // Inserting the node at first
21. {
22. struct node * newnode ;
23. newnode = malloc( sizeof( struct node ) ) ;
24. printf ( "Enter Data: \n " ) ;
25. scanf ( " %d" , &newnode->info ) ;
26. newnode->prev = NULL ;
27. newnode->next = NULL ;
28. if ( START == NULL )
29. START = newnode ;
30. else
31. {
32. START->prev = newnode ;
33. newnode->next = START ;
34. START = newnode ;
35. }
36. }
37. void deleteatfirst() // deleting the first node
38. {
39. struct node * temp ;
40. if ( START == NULL )
41. printf ( "List is empty \n " ) ;
42. else
43. {
44. temp = START ;
45. START = START->next ;
46. START->prev = NULL ;
47. free( temp ) ;
48. }
49. }
50. void viewlist() // displaying all the nodes in the list
51. {
52. struct node * t ;
53. if ( START == NULL )
54. printf ( "List is empty \n " ) ;
55. else
56. {
57. t = START ;
58. while ( t != NULL )
59. {
60. printf ( " %d \n " , t->info ) ;
61. t = t->next ;
62. }
63. }
64. }
65. int menu()
66. { int n ;
67. printf ( " \t \t \t 1. VIEW LIST \n " ) ;
68. printf ( " \t \t \t 2. INSERT AT FIRST IN LIST \n " ) ;
69. printf ( " \t \t \t 3. DELETE AT FIRST IN LIST \n " ) ;
70. printf ( " \t \t \t 4. EXIT \n " ) ;
71. printf ( "ENTER YOUR CHOICE \n " ) ;
72. scanf ( " %d" , &n ) ;
73. return ( n ) ;
74. }
75. int main()
76. {
77. while ( 1 )
78. {
79. switch ( menu() )
80. {
81. case 1 :
82. viewlist() ;
83. break ;
84. case 2 :
85. insertnodeatfirst() ;
86. break ;
87. case 3 :
88. deleteatfirst() ;
89. break ;
90. case 4 :
91. exit ( 1 ) ;
92. break ;
93. default :
94. printf ( " NOT AVAILABLE \n " ) ;
95. }
96. }
97. }

The output of the above program is:


1. # Multiple link self-referential structure implementation in Python language
2. class node:
3. def __init__(self):
4. self.data = 0
5. self.prev = None
6. self.next = None
7.
8. if __name__ == '__main__':
9. obj1=node() # Node1
10.
11. # Initialization
12. obj1.prev = None
13. obj1.next = None
14. obj1.data = 15
15.
16. obj2=node() # Node2
17.
18. # Initialization
19. obj2.prev = None
20. obj2.next = None
21. obj2.data = 20
22.
23. obj3 = node() # Node3
24.
25. # Initialization
26. obj3.prev = None
27. obj3.next = None
28. obj3.data = 25
29.
30. # Forward links
31. obj1.next = obj2
32. obj2.next = obj3
33.
34. # Backward links
35. obj2.prev = obj1
36. obj3.prev = obj2
37.
38. # Accessing data of obj1, obj2 and obj3 by
obj1
39. print(obj1.data , end='\t')
40. print(obj1.next.data , end='\t')
41. print(obj1.next.next.data)
42.
43. # Accessing data of obj1, obj2 and obj3 by o
bj2
44. print(obj2.prev.data , end='\t')
45. print(obj2.data , end='\t')
46. print(obj2.next.data)
47.
48. # Accessing data of obj1, obj2 and obj3 by o
bj3
49. print(obj3.prev.prev.data , end='\t')
50. print(obj3.prev.data , end='\t')
51. print(obj3.data)

The output of the above program is:

15 20 25
15 20 25
15 20 25

File Handling in C
In programming, we may require some specific input data to be generated several
numbers of times. Sometimes, it is not enough to only display the data on the console.
The data to be displayed may be very large, and only a limited amount of data can be
displayed on the console, and since the memory is volatile, it is impossible to recover
the programmatically generated data again and again. However, if we need to do so, we
may store it onto the local file system which is volatile and can be accessed every time.
Here, comes the need of file handling in C.

File handling in C enables us to create, update, read, and delete the files stored on the
local file system through our C program. The following operations can be performed on
a file.

o Creation of the new file


o Opening an existing file
o Reading from the file
o Writing to the file
o Deleting the file

Functions for file handling


There are many functions in the C library to open, read, write, search and close the file. A
list of file functions are given below:

No. Function Description

1 fopen() opens new or existing file

2 fprintf() write data into the file

3 fscanf() reads data from the file

4 fputc() writes a character into the file

5 fgetc() reads a character from file

6 fclose() closes the file

7 fseek() sets the file pointer to given position

8 fputw() writes an integer to file

9 fgetw() reads an integer from file

10 ftell() returns current position

11 rewind() sets the file pointer to the beginning of the file

Opening File: fopen()


We must open a file before it can be read, write, or update. The fopen() function is used
to open a file. The syntax of the fopen() is given below.

Backward Skip 10sPlay VideoForward Skip 10s

1. FILE *fopen( const char * filename, const char * mode );


The fopen() function accepts two parameters:

o The file name (string). If the file is stored at some specific location, then we must
mention the path at which the file is stored. For example, a file name can be
like "c://some_folder/some_file.ext".
o The mode in which the file is to be opened. It is a string.

We can use one of the following modes in the fopen() function.

Mode Description

r opens a text file in read mode

w opens a text file in write mode

a opens a text file in append mode

r+ opens a text file in read and write mode

w+ opens a text file in read and write mode

a+ opens a text file in read and write mode

rb opens a binary file in read mode

wb opens a binary file in write mode

ab opens a binary file in append mode

rb+ opens a binary file in read and write mode

wb+ opens a binary file in read and write mode

ab+ opens a binary file in read and write mode

The fopen function works in the following way.

o Firstly, It searches the file to be opened.


o Then, it loads the file from the disk and place it into the buffer. The buffer is used
to provide efficiency for the read operations.
o It sets up a character pointer which points to the first character of the file.

Consider the following example which opens a file in write mode.

1. #include<stdio.h>
2. void main( )
3. {
4. FILE *fp ;
5. char ch ;
6. fp = fopen("file_handle.c","r") ;
7. while ( 1 )
8. {
9. ch = fgetc ( fp ) ;
10. if ( ch == EOF )
11. break ;
12. printf("%c",ch) ;
13. }
14. fclose (fp ) ;
15. }

Output

The content of the file will be printed.

#include;
void main( )
{
FILE *fp; // file pointer
char ch;
fp = fopen("file_handle.c","r");
while ( 1 )
{
ch = fgetc ( fp ); //Each character of the file is read and stored in the
character file.
if ( ch == EOF )
break;
printf("%c",ch);
}
fclose (fp );
}

Closing File: fclose()


The fclose() function is used to close a file. The file must be closed after performing all
the operations on it. The syntax of fclose() function is given below:

1. int fclose( FILE *fp );

C fprintf() and fscanf()


C fprintf() and fscanf() example

C fputc() and fgetc()


C fputc() and fgetc() example

C fputs() and fgets()


C fputs() and fgets() example

C fseek()

C fprintf() and fscanf()

Writing File : fprintf() function


The fprintf() function is used to write set of characters into file. It sends formatted
output to a stream.

Syntax:

1. int fprintf(FILE *stream, const char *format [, argument, ...])

Example:
1. #include <stdio.h>
2. main(){
3. FILE *fp;
4. fp = fopen("file.txt", "w");//opening file
5. fprintf(fp, "Hello file by fprintf...\n");//writing data into file
6. fclose(fp);//closing file
7. }

Reading File : fscanf() function


The fscanf() function is used to read set of characters from file. It reads a word from the
file and returns EOF at the end of file.

Backward Skip 10sPlay VideoForward Skip 10s

Syntax:

1. int fscanf(FILE *stream, const char *format [, argument, ...])

Example:

1. #include <stdio.h>
2. main(){
3. FILE *fp;
4. char buff[255];//creating char array to store data of file
5. fp = fopen("file.txt", "r");
6. while(fscanf(fp, "%s", buff)!=EOF){
7. printf("%s ", buff );
8. }
9. fclose(fp);
10. }

Output:

Hello file by fprintf...


C File Example: Storing employee information
Let's see a file handling example to store employee information as entered by user from
console. We are going to store id, name and salary of the employee.

1. #include <stdio.h>
2. void main()
3. {
4. FILE *fptr;
5. int id;
6. char name[30];
7. float salary;
8. fptr = fopen("emp.txt", "w+");/* open for writing */
9. if (fptr == NULL)
10. {
11. printf("File does not exists \n");
12. return;
13. }
14. printf("Enter the id\n");
15. scanf("%d", &id);
16. fprintf(fptr, "Id= %d\n", id);
17. printf("Enter the name \n");
18. scanf("%s", name);
19. fprintf(fptr, "Name= %s\n", name);
20. printf("Enter the salary\n");
21. scanf("%f", &salary);
22. fprintf(fptr, "Salary= %.2f\n", salary);
23. fclose(fptr);
24. }

Output:

Enter the id
1
Enter the name
sonoo
Enter the salary
120000
Now open file from current directory. For windows operating system, go to TC\bin
directory, you will see emp.txt file. It will have following information.

emp.txt

Id= 1
Name= sonoo
Salary= 120000

C fputc() and fgetc()

Writing File : fputc() function


The fputc() function is used to write a single character into file. It outputs a character to
a stream.

Syntax:

1. int fputc(int c, FILE *stream)

Example:

1. #include <stdio.h>
2. main(){
3. FILE *fp;
4. fp = fopen("file1.txt", "w");//opening file
5. fputc('a',fp);//writing single character into file
6. fclose(fp);//closing file
7. }

file1.txt

Reading File : fgetc() function


The fgetc() function returns a single character from the file. It gets a character from the
stream. It returns EOF at the end of file.

Syntax:

1. int fgetc(FILE *stream)

Example:

1. #include<stdio.h>
2. #include<conio.h>
3. void main(){
4. FILE *fp;
5. char c;
6. clrscr();
7. fp=fopen("myfile.txt","r");
8.
9. while((c=fgetc(fp))!=EOF){
10. printf("%c",c);
11. }
12. fclose(fp);
13. getch();
14. }

myfile.txt

this is simple text message

C fputs() and fgets()


The fputs() and fgets() in C programming are used to write and read string from stream.
Let's see examples of writing and reading file using fgets() and fgets() functions.

Writing File : fputs() function


The fputs() function writes a line of characters into file. It outputs string to a stream.
Syntax:

1. int fputs(const char *s, FILE *stream)

Example:

Backward Skip 10sPlay VideoForward Skip 10s

1. #include<stdio.h>
2. #include<conio.h>
3. void main(){
4. FILE *fp;
5. clrscr();
6.
7. fp=fopen("myfile2.txt","w");
8. fputs("hello c programming",fp);
9.
10. fclose(fp);
11. getch();
12. }

myfile2.txt

hello c programming

Reading File : fgets() function


The fgets() function reads a line of characters from file. It gets string from a stream.

Syntax:

1. char* fgets(char *s, int n, FILE *stream)

Example:

1. #include<stdio.h>
2. #include<conio.h>
3. void main(){
4. FILE *fp;
5. char text[300];
6. clrscr();
7.
8. fp=fopen("myfile2.txt","r");
9. printf("%s",fgets(text,200,fp));
10.
11. fclose(fp);
12. getch();
13. }

Output:

hello c programming

C fseek() function
The fseek() function is used to set the file pointer to the specified offset. It is used to
write data into file at desired location.

Syntax:

1. int fseek(FILE *stream, long int offset, int whence)

There are 3 constants used in the fseek() function for whence: SEEK_SET, SEEK_CUR and
SEEK_END.

Example:

1. #include <stdio.h>
2. void main(){
3. FILE *fp;
4.
5. fp = fopen("myfile.txt","w+");
6. fputs("This is javatpoint", fp);
7.
8. fseek( fp, 7, SEEK_SET );
9. fputs("sonoo jaiswal", fp);
10. fclose(fp);
11. }

myfile.txt

This is sonoo jaiswal

C rewind() function
The rewind() function sets the file pointer at the beginning of the stream. It is useful if
you have to use stream many times.

Syntax:

1. void rewind(FILE *stream)

Example:

File: file.txt

1. this is a simple text

File: rewind.c

1. #include<stdio.h>
2. #include<conio.h>
3. void main(){
4. FILE *fp;
5. char c;
6. clrscr();
7. fp=fopen("file.txt","r");
8.
9. while((c=fgetc(fp))!=EOF){
10. printf("%c",c);
11. }
12.
13. rewind(fp);//moves the file pointer at beginning of the file
14.
15. while((c=fgetc(fp))!=EOF){
16. printf("%c",c);
17. }
18.
19. fclose(fp);
20. getch();
21. }

Output:

this is a simple textthis is a simple text

As you can see, rewind() function moves the file pointer at beginning of the file that is
why "this is simple text" is printed 2 times. If you don't call rewind() function, "this is
simple text" will be printed only once.

C ftell() function
The ftell() function returns the current file position of the specified stream. We can use
ftell() function to get the total size of a file after moving file pointer at the end of file.
We can use SEEK_END constant to move the file pointer at the end of file.

Syntax:

1. long int ftell(FILE *stream)

Example:

File: ftell.c

1. #include <stdio.h>
2. #include <conio.h>
3. void main (){
4. FILE *fp;
5. int length;
6. clrscr();
7. fp = fopen("file.txt", "r");
8. fseek(fp, 0, SEEK_END);
9.
10. length = ftell(fp);
11.
12. fclose(fp);
13. printf("Size of file: %d bytes", length);
14. getch();
15. }

Output:

Size of file: 21 bytes

You might also like