Data types in C Programming

This article is a Series on the C programming tutorial and carries the discussion on C language programming and its implementation. In our last tutorial, we have seen Bitwise Operators in C programming. In this article, we are explaining the basic concept of the C program (Data types in C Language). It aims to provide easy and practical examples for understanding the C program.

When we want to learn C language programming, we need to start from the very basics. First, we need to understand the data types of the C language.

Data types in C

What are Data Types in C? 

The data type is a type of data that tells the compiler what type of data is going to be stored in the memory. It is mainly used to define a variable or function in the C program.   A data type is an attribute that tells the machine or computer or micro-controllers how to read and store the value.

In simple terms, the variable is the name of the memory area. The data type is the type of data that needs to be stored in that memory.


int a = 15; :- it stores integer-type data.

char b = ‘g’; :- it stores character-type data.

float c = 9.7000000; :- it stores float-type data.

double d= 6.800300000000; :- it stores double-type data.

Check the below program.

#include <stdio.h>

int main()
  int age = 15;
  printf ("%d",a);
  return 0;

In the above example, age (variable) is the memory name. And the int is datatype. That means in the memory (variable age), we can store only the integers. We will also see how the values are stored in the memory in the later of this tutorial.

Why do we use Data Types in C?

Data types are used to specify the types of data in which variables are held. We need to use the appropriate data types while creating the variable. We will see that in depth in this tutorial.

What are the types of data types?

Data types are classified into three different types:-

We will see one by one now.

What are Basic/Primitive Data Types in C?

It is the most basic data type that is used to represent simple values like integer, character, float, double, and void.

int (Integer)

Integer or int is a whole number that includes positive and negative numbers. It doesn’t include decimal and fractional numbers.

Valid int values: -10, 0, 10, 23, 35, 2023, etc

Invalid int values: -1.43, 1 3/4, 3.14, .09, and 5,643.1

The size of the int data type can be 4 bytes on 32-bit & 64-bit machines and 2 bytes on 16-bit machines. Because it is system dependent.


int temp_variable = 100;

int age = 9;

int number = -14;

char (Character)

The char keyword is used to create a variable where we can store the characters. The size of the char data type is 1 byte. So, we can store one character in one char variable.


char temp_char = 'T';

char initial = 's';

float (Floating-Point)

Since int or integer is used to store the whole numbers, we need to have a new keyword for decimal and fractional values also. This float is used to create the storage to store the decimal values. Decimal numbers consist of two parts, a whole number, and a fractional part. Both parts will be separated by a decimal point.

For example, 16.56 is a decimal number. In this 16 is a whole number and 0.56 is a fractional number. That’s why we have a separate datatype for this. The size of the float data type is 4 bytes. In this float data type, we can store 6 decimal places.


float  temp_variable = 2.39; //1.390000

float temp = 13.2324; //13.232400

double (Double Precision Floating-Point)

This double keyword is also the same as the float keyword. The only difference is that we can store 15 decimal places. Since the number of decimals has been increased, the size of the double data type is 8 bytes.


double temp_variable = 3.89; //3.890000

double temp = 15.2334; //15.233400


This void datatype is an incomplete datatype. In English, void means, a space or contains nothing, etc. The size of the void data type is 0 bytes. In most of the compilers, there will be no size (bytes) for void data type but in a few compilers like GCC, its size is 1 byte.

Note: No one will declare the variable using void. This void is mostly used for the pointers (void pointers). And also we use this void in functions that return nothing, and the functions which don’t take any arguments.


/* Function with no return and no argument */
void temp_function( void )
  /* code here */

/* void pointer */
void *ptr;

The below table summarizes the size and format specifier of the basic data types.

TypeSize (bytes)Format Specifier
int2, usually 4%d, %i
void0, usually 1_

What are Derived Data Types in C Programming?

These derived data types are derived from the primitive or basic data types that we have discussed above. The derived data types are

We will discuss these derived data types in our future tutorials.

What are User-defined Data Types?

These are the data types that are defined by the user himself by combining the Primitive/Basic data types and Derived data types. User is free to customize or create new data types based on the user application use cases.

What is Structure?

The structure is a collection of variables of the same or different data types. So, we can create a package of different data types under one roof.

Example:- A student’s record must show its name, roll number, marks, etc.

struct student
  char name[20];
  int id;
  int roll_no;
  float marks;

We have explained the in-depth of the structure in this tutorial already. Please check that out.

What is Union?

It is defined as a user-defined data type that can be containing elements of the different data types in the same memory location.


union car
  char name[50];
  int price;

We will go in-depth about the union in the other tutorial.

What is Enum?

It is a special kind of data type that is defined by the user. It comprises constant integrals that are given names by a user.


enum cars

We have discussed the Enum in this tutorial already.

Data Type Modifiers

What are data type modifiers?

Data type modifier is one of the keywords of the C language which is used to modify the below things of the basic or primitive data types.

  • Range of data types and
  • Size of the memory space allocated to the variable

In the C language, the below data type modifiers are available.

Data type modifiers in C

  • short
  • long
  • signed
  • unsigned

Short and long data type modifiers are used to change the size of the variables. Short is used to decrease the memory size of the variable and long is used to increase the memory of the variable.

Signed and unsigned keywords are used to change the sign (positive or negative) of the variables. If we use signed keyword, then that variable can hold both positive (+ve) and negative (-ve) numbers. If we use unsigned keyword, then the variable can only hold the positive (+ve) numbers.

Note: If we don’t use signed or unsigned keyword before the data type, the compiler will use the signed data type modifier during the compilation by default.

We can add these data type modifiers before the data types. And also we can we can combine the modifiers.

We have given the below examples of the modifiers which is used with the data types.


  • signed int
  • signed char
  • unsigned int
  • unsigned char
  • signed short int
  • signed long int
  • signed long long int
  • unsigned short int
  • unsigned long int
  • unsigned long long int
  • long double

The below table shows the minimum and maximum values of the data types and format specifiers of the data types.

Yes, you might ask what the format specifier is. Format specifiers are used to specify the format of the variable. For example, if we want to print the value of the variable, these format specifiers will be used in the printf() function. And also, we use the format specifiers in scanf(), sscanf(), etc.

TypeSizeRangeFormat Specifier
signed char1 byte (8-bits)-127 to +127%c
unsigned char1 byte (8-bits)0 to 255%c
signed int4 bytes (32-bits)2,147,483,647 to 2,147,483,647%d, %i
unsigned int4 bytes (32-bits)0 to 4,294,967,295%u
float4 bytes (32-bits)-3.4e38 to +3.4e38%f
double8 bytes (64-bits)-1.7e308 to +1.7e308%lf
long8 bytes (64-bits)-2,147,438,648 to +2,147,438,647%l
long long8 bytes (64-bits)-(2^63) to (2^63)-1%ll
signed short int2 bytes (16-bits)-32,768 to +32,767%hd
unsigned short int2 bytes (16-bits)0 to 65,535%hu
unsigned long8 bytes (64-bits)0 to 2^64%lu

How are we finding the range of the variable?

Let us consider the unsigned char which is consuming 8 bits. If we fill all bits to 0, then it is the minimum value. If we fill all bits to 1, then that is the maximum value.

Minimum value of unsigned char (8-bits)

Bit 7 (MSB)Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0 (LSB)

The value of the above 8-bit is 0. So, the minimum value is 0.

Maximum value of unsigned char (8-bits)

Bit 7 (MSB)Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0 (LSB)

The value of the above 8-bit is 255. So, the maximum value of the unsigned char is 255. Simple we can use this formula to calculate the maximum value.

maximum value = ( 2^available bits to store the data ) - 1

For unsigned char, the formula will be,

maximum value = 2^8 – 1 = 255.

What about the signed char? As Bit 7 (MSB) will be used to store the sign, it has only 7 bits (Bit 0 to Bit 6) to store the data. Maximum value = 2^7 – 1 = 127. So, we can store the data that ranges from -127 to +127. Like this, we can calculate for other data types.

The below program is used to find the size of the data types.

#include <stdio.h>  

void main() 
  printf("sizeof char is: %d bytes \n", sizeof(char));
  printf("sizeof unsigned char is: %d bytes \n", sizeof(unsigned char));
  printf("sizeof int is: %d bytes \n", sizeof(int));
  printf("sizeof unsigned int is: %d bytes \n", sizeof(unsigned int));
  printf("sizeof short int is: %d bytes \n", sizeof(short int));
  printf("sizeof unsigned short int is: %d bytes \n", sizeof(unsigned short int));
  printf("sizeof float is: %d bytes \n", sizeof(float));
  printf("sizeof double is: %d bytes \n", sizeof(double));
  printf("sizeof void is: %d bytes \n", sizeof(void));
  printf("sizeof long is: %d bytes \n", sizeof(long));
  printf("sizeof unsigned long is: %d bytes \n", sizeof(unsigned long));
  printf("sizeof long double is: %d bytes \n", sizeof(long double));
  printf("sizeof long long is: %d bytes \n", sizeof(long long));
  printf("sizeof long int is: %d bytes \n", sizeof(long int));
  printf("sizeof long long int is: %d bytes \n", sizeof(long long int));

The output of the above program is given below.

sizeof char is: 1 bytes 
sizeof unsigned char is: 1 bytes 
sizeof int is: 4 bytes 
sizeof unsigned int is: 4 bytes 
sizeof short int is: 2 bytes 
sizeof unsigned short int is: 2 bytes 
sizeof float is: 4 bytes 
sizeof double is: 8 bytes 
sizeof void is: 1 bytes 
sizeof long is: 8 bytes 
sizeof unsigned long is: 8 bytes 
sizeof long double is: 16 bytes 
sizeof long long is: 8 bytes 
sizeof long int is: 8 bytes 
sizeof long long int is: 8 bytes 

I hope you have understood the data types. Now we are going to see how the values are being stored in the variable memory with different data types.

How the data is stored in the memory?

First, we will see how the unsigned values are stored in the memory.

Unsigned values

For this example, we will consider unsigned char whose size is 8 bits. This is pretty straightforward.

unsigned char a = 'S';

The ASCII value of the ‘S’ is 0x53. So, the data will be stored like below.

Bit 7 (MSB)Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0 (LSB)

Like this, all the unsigned values like, unsigned int, unsigned long values will be stored.

Signed values

For this scenario also we will consider signed char whose size will be 8 bits. MSB will be used to store the sign and the remaining 7 bits used to store the data. So, we can store the positive and negative numbers from -127 to 127.

Positive numbers will be represented directly in memory whereas negative numbers will be represented in 2’s complimentary form.

Consider the below example.

signed char a = -21;

As the above value is a negative number, it will be stored in 2’s complimentary form.

 21     = 0001 0101
~21     = 1110 1010
~21 + 1 = 1110 1011
-21     = 1110 1011
Bit 7 (MSB)Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0 (LSB)

The value of -21 will be stored like above. This is how the signed values will be stored in the memory.

Float and Double values

The floating-point number does not store directly in the memory. Therefore the binary numbers of floating-point convert into standard form and then those converted binary numbers are stored in the memory. Floating point representations may vary from machine to machine. In this article, we will discuss one of the standard methods called IEEE 754 floating-point number representation.

What is IEEE 754 standard representation?

According to Wikipedia, The IEEE Standard for Floating-Point Arithmetic (IEEE 754) is a technical standard for floating-point arithmetic established in 1985 by the Institute of Electrical and Electronics Engineers (IEEE). The standard addressed many problems found in the diverse floating-point implementations that made them difficult to use reliably and portably. Many hardware floating-point units use the IEEE 754 standard. This IEEE 754 format has three components.

  • Sign part
  • Exponent part
  • Mantissa part

The sign part occupies 1 bit that is used to tell the number is whether positive (+ve) or negative (-ve).

The size of the float is 4 bytes and the double is 8 bytes. It is classified into two formats.

  1. Float Data types in a single precision format which is 32 bits.
  2. Double Data types double precision format which is 64 bits.

Let’s consider these two formats


Represent in single and double precision format.

STEP 1: Convert Decimal number to Binary

0.12 * 2= 0.25= 0

0.25 * 2 = 0.5 = 0

0.5 * 2 = 1.0 = 1

0.0 * 2 = 0.0 = 0

Single Precision Format

Its memory size is 32bits


= 10011101011.001

e = 127+10

e = 137 = (10001001) 2

Double Precision Format

Its memory size is 64 Bits


= 10011101011.001

e = 1023 +10

e = 1033 = (10001001) 2

Frequently Asked Questions

Q) What are data types in C?

Data types in C refer to the various types of data that can be used to store and manipulate information in the programming language. In C, data types include integers, floating-point numbers, characters, and pointers, among others. These data types determine the size and format of the data, as well as the operations that can be performed on them. Understanding data types is essential for writing effective and efficient C programs.

Q) What are the types of Data Types in C?

There are three types of data types in the C programming language:

  1. Basic/Primitive Data Types
  2. Derived Data Types
  3. User-defined Data Types

Q) What are Basic or Primitive data types in C?

It is the most basic data type that is used to represent simple values like integer, character, float, double, and void.

Q) What are derived data types in C?

These derived data types are derived from the primitive or basic data types. The derived data types are

Q) What are user-defined data types in C?

These are the data types that are defined by the user himself by combining the Primitive/Basic data types and Derived data types. User is free to customize or create new data types based on the user application use cases.

Q) What are type modifiers in C?

Type modifiers in C are keywords that can be used to modify the behavior of a data type. They can change the range of values that a variable of a particular data type can hold or affect the memory allocation for that variable. Examples of type modifiers in C include “signed“, “unsigned“, “short“, and “long“.

Q) How do you find the range of datatypes in C?

To find the range of datatypes in C, you can refer to this section of this article. The range of datatypes in C can vary depending on the implementation and the size of the datatype. By understanding the range of data types in C, you can effectively handle and manipulate data within the defined limits.

Q) How the variable value is stored in the memory?

We have discussed this in this section of the article. Please refer to that.

In our next tutorial, we will see variables in the C program.

You can also read the below tutorials.

Linux Device Driver TutorialsC Programming Tutorials
FreeRTOS TutorialsNuttX RTOS Tutorials
RTX RTOS TutorialsInterrupts Basics
I2C Protocol – Part 1 (Basics)I2C Protocol – Part 2 (Advanced Topics)
STM32 TutorialsLPC2148 (ARM7) Tutorials
PIC16F877A Tutorials8051 Tutorials
Unit Testing in C TutorialsESP32-IDF Tutorials
Raspberry Pi TutorialsEmbedded Interview Topics
Reset Sequence in ARM Cortex-M4BLE Basics
VIC and NVIC in ARMSPI – Serial Peripheral Interface Protocol
STM32F7 Bootloader TutorialsRaspberry PI Pico Tutorials
STM32F103 Bootloader TutorialsRT-Thread RTOS Tutorials
Zephyr RTOS Tutorials – STM32Zephyr RTOS Tutorials – ESP32
AUTOSAR TutorialsUDS Protocol Tutorials
Product ReviewsSTM32 MikroC Bootloader Tutorial
VHDL Tutorials
Notify of

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Inline Feedbacks
View all comments
Table of Contents