Skip to main content

Data Types in C

A data type defines what kind of data a variable can store. It helps the compiler understand how much memory to allocate and what operations are allowed on that data. Think of data types like different containers — a water bottle stores liquids, a box stores solids. Similarly, int stores whole numbers, float stores decimals, and char stores characters. Choosing the right data type means efficient memory use.

Categories of Data Types

CategoryDescriptionExamples
PrimitiveBasic built-in typesint, char, float, double
DerivedBuilt from primitive typesarray, pointer, function
User-DefinedDefined by the programmerstruct, union, enum
C data types hierarchy: Data Types split into Primitive and Non-Primitive, where Non-Primitive splits further into Derived and User-Defined

Primitive Data Types

Integer (int)

  • Stores whole numbers (positive, negative, or zero)
  • Can be signed (default) or unsigned
  • Size: 4 bytes
  • Range (signed): −2,147,483,648 to 2,147,483,647
  • Range (unsigned): 0 to 4,294,967,295
How to calculate range:
  • Signed: min = −2^(n−1), max = 2^(n−1) − 1
  • Unsigned: min = 0, max = 2^n − 1
Out of range example:
#include <stdio.h>
int main() {
    int num = 2147483648;  // exceeds max signed int
    printf("%d", num);
    return 0;
}
// Output: -2147483648  (wraps around)
Diagram showing a signed 32-bit integer wrapping around: 2,147,483,647 plus 1 becomes -2,147,483,648

Character (char)

  • Stores a single character enclosed in single quotes: 'A', 'z', '3'
  • Internally stored as its ASCII value (an integer)
  • Size: 1 byte
  • Range (signed): −128 to 127 | Range (unsigned): 0 to 255
Real-world uses of char:
  • Attendance: 'P' for Present, 'A' for Absent
  • Voting: 'Y' for Yes, 'N' for No
  • Product sizes: 'S', 'M', 'L'

Float (float)

  • Stores decimal numbers with single precision (~6–7 significant digits)
  • Size: 4 bytes | Range: 1.2E−38 to 3.4E+38
  • Used when decimal values are needed but high precision isn’t critical

Double (double)

  • Stores decimal numbers with double precision (~15–16 significant digits)
  • Size: 8 bytes | Range: 1.7E−308 to 1.7E+308
  • long double provides even higher precision (10–16 bytes)
Float vs Double precision:
#include <stdio.h>
int main() {
    float f  = 1.1234567890123456f;
    double d = 1.1234567890123456;
    printf("Float : %.15f\n", f);
    printf("Double: %.15lf\n", d);
    return 0;
}
// Output:
// Float : 1.123456716537476   (less accurate)
// Double: 1.123456789012346   (more accurate)
When to use double:
DomainUse Case
Banking SoftwareAccurate money calculations
GPS / NavigationHigh-precision latitude and longitude
Scientific InstrumentsMeasuring small/large physical values
Medical DevicesDosage and vital sign measurement

Void (void)

void represents no value. It has three main uses:
  • No return type: void display() — function returns nothing
  • Void pointer: void *ptr — can hold address of any type
  • No parameters: int main(void) — function takes no arguments

Data Modifiers

Modifiers adjust the size or sign of a base data type:
ModifierEffect
shortReduces size of int to 2 bytes
longIncreases size of int or double
signedAllows positive and negative values (default)
unsignedAllows only non-negative values; doubles the max range

Non-Primitive Data Types

CategoryTypeDescription
DerivedArraySame-type elements
DerivedPointerAddress of a variable
DerivedFunctionReusable code block
User-DefinedStructGroups different types
User-DefinedUnionShared memory members
User-DefinedEnumNamed integer constants
User-DefinedTypedefAlias for a type