Data Types in C
Data type is a very important concept in C programming language. Simply, “A data type is the classification of data values that a data item can have.” We need to declare the variable in C along with its data type before we use that variable in the program.
Data type of an entity (variable) describes:
- The values the entity can hold or store
- The format in which the value is stored
- The operations it can perform
- Determines the meaning of the data it represents
Types of Data Types

Primary |
Derived |
User-defined |
Empty
|
Int Char Float Double |
Arrays Pointers Functions |
Structures Unions Enum |
|
There are several classifications of data types. Basically, they are classified into four different types:
- Primary or Scalar Data types
- Derived or Secondary Data types
- User-defined data types
- Empty data type
1. Primary or Scalar Data types:
These are the predefined or in-built data types in the system. These are further classified into the four most used data types in C:
- int
- char
- float
- double
- int data type:
Just like the name suggests, this data type stores only integers. It occupies 2 bytes of memory (16 bits) in a 16-bit operating system, 4 bytes in a 32-bit operating system and 8 bytes in a 64-bit operating system.
Example program:
#include<stdio.h>
void main()
{
int a = -45;
signed int b = -78;
int d = 89.9876;
unsigned int c = 90;
printf(“a has %d, b has %d and c has %d”,a,b,c);
printf(“\nd has %d”,d);
}
Output:
a has -45, b has -78 and c has 90
d has 89
Here, a and b can store any integer but as it is declared unsigned, it can’t store negative integers.
- We can’t store decimal values in int. Even if we use, the decimal part will be gone and only the whole number part will be stored.
Modifiers:
There are some keywords in C which we use with the data type that manipulates or changes some attributes like the memory space occupied by that data type etc…
- long
- short
- unsigned and
- signed are such keywords.
For a clear view, the memory required to store int data type is 4 bytes in a 32 bit processor system. We can use “short” keyword to decrease the memory to 2 bytes. By using these keywords, the maximum value the data type can store also changes.
If we use “unsigned”, it restricts the data type to store only positive values. By using signed, both the negative and positive values can be stored. “signed” is the default system data type if we didn’t specify any keyword.
short int <= int <= long int
Here is a table to give a clear version:
Data type | Memory required | Range | Format Specifier |
int | 4 bytes | -2,147,483,648 to 2,147,483,647 | %d |
short int | 2 bytes | -32,768 to 32,767 | %hd |
long int | 4 bytes | -2,147,483,648 to 2,147,483,647 | %ld |
signed int | 4 bytes | -2,147,483,648 to 2,147,483,647 | %d |
unsigned int | 4 bytes | 0 to 4,294,967,295 | %u |
unsigned short int | 2 bytes | 0 to 65,535 | %hu |
unsigned long int | 4 bytes | 0 to 4,294,967,295 | %lu |
long long int | 8 bytes | -(2^63) to (2^63)-1 | %lld |
Unsigned long long int | 8 bytes | 0 to 18,446,744,073,709,551,615 | %llu |
- If a variable is not given a value in the declaration i.e., not initialized, then by default it takes a garbage value. Some compilers like gcc initializes zero by default.
- char data type:
The char data type is used to store characters (Individual characters). It needs one byte i.e., 8 bits of memory. It is denoted inside single quotes.
Example: ‘d’,’e’ etc…
It can’t be enlarged to multiple lines. When we declare a character in our program, the compiler turns or translates the character into its ASCII value (American Standard Code for Information technologies).
Some Important ASCII values:
‘A’ to ‘Z’ -> 65 – 90
‘a’ to ‘z’ -> 97 – 122
‘0’ to ‘9’ -> 48 – 57
Null -> 0
Space -> 32
Syntax:
char ch = ‘A’;
Here, char is the data type, ch is the variable and A is the character value stored in ch.
Example program:
#include<stdio.h>
Void main()
{
char gender1 = “M”;
printf(“I am a male(%c)”,gender1);
char gender2 = “F”;
printf(“\nI am a female(%c)”,gender2);
}
Output:
I am a male(M)
I am a female(F)
Modifiers and Ranges:
-128 to +127 -> signed char
0 to 255 -> unsigned char
-128 to +127 -> normal char
- Float Data type:
This data type stores the decimal values. It occupies 4 bytes (32 bits) of memory. It is accurate up to a precision of 6 digits after the decimal point.
Syntax:
float num1 = 6.1;
Here float is the data type, num1 is assumed to be the name of the variable and 6.1 is the value given to the variable.
Example program:
#include<stdio.h>
void main()
{
float num1 = 6.7;
printf(“The float number num1 is storing is: %f”,num1);
float num2 = 5;
printf(“\n5 is int but as we gave float, it stores in the
format %f”,num2);
}
Output:
The float number num1 is storing is: 6.7
5 is int but as we gave float, it stores in the format 5.0
Range: 3.4E-38 to 3.4E+38
Here, note that E means 10 to the power of.
Format Specifier: %f
- Double Data Type:
As mentioned above, float is accurate only up to about 6 decimal places. To increase this accuracy, double data type comes into picture. It has a precision of 14 digits. It occupies 8 bytes of memory.
Syntax:
double num1 = 8.845643345;
Here, double is the data type, num1 is assumed to be the name of the variable, and it stores that given value.
Example Program:
#include<stdio.h>
void main()
{
double num1 = 6.78567;
printf(“The value of num1 is %lf\n”,num1);
double num2 = 7.896544;
printf(“The value of num2 is %lf\n”,num2);
double sum = num1 + num2;
printf(”The sum of num1 and num2 is
%lf”,sum);
}
Output:
The value of num1 is 6.78567
The value of num2 is 7.896544
The sum of num1 and num2 is 14.682214
Range: 1.7E-308 to 1.7E+308
Format Specifier : %lf
- Long Double:
Extending the precision even more, long double is introduced. It has more accuracy than that of double but its value varies with every single OS. It allocates 10 bytes( 80 bits) of memory to store the values approximately.
Range: 3.4E-4932 to 1.1E+4932
Format Specifier: %Lf
2. Derived data types:
As the name suggests, these are the data types derived from the fundamental data types. They append more functionality to the existing data types. These are the derived data type in C:
- Arrays
- Pointers
- Functions
- Arrays:
Assume you are the class representative of your class. You are given a task to collect the marks of all the 40 students and note them. In order to work with all the 40 different values, you have to initialize 40 different int variables and then assign values to all the variables.
It’s complicated. Isn’t it? This is where arrays come into picture.
When we want to store multiple values of the same data type, arrays are the options we’ll be left with.
To define it, Arrays are ordered sequences of data items of the same data type (Homogeneous) stored under the same name. The elements in an array are stored in contiguous memory locations.
Syntax:
data_type name[size] = {value1, value2,…};
data_type name[size];
Example:
int arr[10];
arr[0] | arr[1] | arr[2] | arr[3] | arr[4] | arr[5] | arr[6] | arr[7] | arr[8] | arr[9] |
As shown in the representations, the elements in the array can be accessed by the indices of the array which starts from 0 to size-1, which means arr[size] or arr[10] is wrong. It ends with arr[size-1] or arr[9].
Storing the values:
Assume arr[5] = {1,2,3,4,5};
1 | 2 | 3 | 4 | 5 |
Here, arr[0] = 1, arr[1] = 2, arr[2] = 3, arr[3] = 4, arr[4] = 5
Contiguous memory locations means that suppose in this array, all are of int data type and it needs 2 bytes (16 bit). Suppose, the first element is stored in an address 34567, it takes 2 bytes of space and the second one is stored in 34569 and goes on till the last element.
Example program:
#include<stdio.h>
void main()
{
int arr[10], i;
arr[10] = {1,2,3,4,5,6,7,8,9,10};
printf(“The value at arr[6] is %d\n”,arr[6]);
int arr1[3];
printf(“Enter the elements into arr1: “);
for(i=0;i<3;i++)
{
scanf(“%d”,&arr1[i]);
}
printf(“\narr1 has elements: “);
for(i=0;i<3;i++)
{
printf(“ %d”,arr1[i]);
}
}
Output:
The value at arr[6] is 7
Enter the elements into arr1:
4
5
6
arr1 has elements: 4 5 6
Arrays also have types based on the sub-script:
- One dimensional
- Two dimensional
- Three dimensional arrays
- Pointers:
It is a mandatory concept in C. It is in simple sense, a variable which refers to a memory location or the address of another variable or another pointer.

Here, assume A is a normal variable with the value 45 and its address is 5678. Assume B is a pointer with address 8970. B is pointing towards the address of A. It stores that address.
Two important facts to keep in mind:
*-> value at
&->address of
So, here we give the address of A to B which means
B = &A;
Now, if we access:
*B->45 which means it is showing the value at the address it is pointing to. If we print B we get the value of B which is the address of A.
Example:
#include<stdio.h>
void main()
{
int *p1,a;
p1 = &a;
a = 4;
printf(“The value of a is %d”,a);
printf(“\nAddress of a is %d”,&a);
printf(“\nThe value of p1 is %d”,p1);
printf(“\np1 is pointing to %d”,*p1);
}
Assuming the value &a = 5678,
Output:
The value of a is 4
Address of a is 5678
The value of p1 is 5678
p1 is pointing to 4
Functions:
There are two types of functions:
- Built-in functions
- User-defined functions
Built-in functions are predefined in the system that we keep using like main(), printf() and scanf() for reading and writing, there are a lot of functions available in different libraries in C.
User-defined functions:
Functions are considered a data type but it’s a different concept. Precisely, Functions are used to reuse the code that is needed frequently, other than typing the code again and again.
There are three parts in every function:
- Function definition
- Function call
- Function declaration
First, we tell the compiler, there is a function in the code and then we declare it and write the code in the body and we call it. The control from the main function goes to the function call and then the function is executed, it gives the control back to the main function.
3. User-defined Data types:
These are the data types derived from already existing data types with some additional updates and customizations according to the need of the programmer.
- Structures
- Unions
- Enum
- Structures:
As mentioned above, Arrays only store data of the same data type. Structures, on the other hand, create its own data type, that is used to group different items of different data types into a single type.
Creating a Structure:
- “struct” keyword is used.
struct employee
{
char name[50];
int ID;
char gender;
int age;
}emp;
Here, different details of different data types are stored under the so-called data type employee. emp is the variable used to access the members of the structure in the body of the program. It is called the “Structure Variable”.
Memory allocation:
In the structure, memory is allocated to all the items in order. For example, from the above program,
char name[50] -> 1*50 = 50 bytes
int ID -> 2 bytes
char gender -> 1 byte
age -> 2 bytes
name (50 bytes) | ID (2 bytes) | gender (1 byte) | age (2 bytes) |
Total of 50+2+1+2 = 55 bytes is allocated the structure employee.
- Unions:
Unions are similar to Structures. The difference is that in structure, memory is allocated to all the data items inside, but in a union, the memory required to store the largest data item is given and all the items are placed in that space.
But, how are all the items stored in that space?
Taking the same example in Structures,
union employee
{
char name[50];
int ID;
char gender;
int age;
}emp;
Here, the data item that takes more memory space is name[50]. So, the total space for the union is 50 bytes. Then, the ID is stored upon this stored name and over it, gender and then age are stored.
age |
gender |
ID |
name[50] |
Arrangement varies with respect to the situation.
So, all the items are stored upon each other, giving us access to only one data item at a time. This is the other difference, in structure, we can access multiple data items at the same time, while in union, we can access only one data type at a time.
- Enumeration (enum):
It is used to assign name to constants, to help make the program easy to maintain and read. The keyword “enum” is used for the declaration.
Example:
#include<stdio.h>
enum year{Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec};
void main()
{
enum year month;
month = Feb;
printf(“%d”, month);
}
Output:
1
Here, we gave a set of names in order. These names are stores in order of integer constants from 0 to n-1. Now, we can access the names by integer constants.