C Data Types

In C programming, data types define the type of data that a variable can hold. They determine the amount of memory allocated for the variable and the operations that can be performed on it.


Categories of Data Types in C

C data types are categorized into:

  • Primary (Basic) Data Types
  • Derived Data Types
  • User-Defined Data Types

1 Primary (Basic) Data Types

These are the fundamental data types provided by C:

a. Integer Types

Used to store whole numbers (both positive and negative). Variants include:

TypeStorage SizeValue RangeFormat Specifier
int2 or 4 bytes-215 to 215-1 (2 bytes)
or
-231 to 231-1 (4 bytes)
%d
unsigned int2 or 4 bytes0 to 216-1 (2 bytes)
or
0 to 232-1 (4 bytes)
%u
short2 bytes-215 to 215-1 %hd
unsigned short2 bytes0 to 216-1 %hu
long4 or 8 bytes-231 to 231-1 (4 bytes)
or
-263 to 263-1 (8 bytes)
%ld
unsigned long4 or 8 bytes0 to 232-1 (4 bytes)
or
0 to 264-1 (8 bytes)
%lu

Example:

</>
Copy
#include <stdio.h>

int main() {
    int a = 100;
    unsigned int b = 200;
    short c = -50;
    unsigned short d = 50;
    long e = 1234567890;
    unsigned long f = 1234567890;

    printf("int a = %d\n", a);
    printf("unsigned int b = %u\n", b);
    printf("short c = %hd\n", c);
    printf("unsigned short d = %hu\n", d);
    printf("long e = %ld\n", e);
    printf("unsigned long f = %lu\n", f);

    return 0;
}

Output:

int a = 100
unsigned int b = 200
short c = -50
unsigned short d = 50
long e = 1234567890
unsigned long f = 1234567890

b. Floating-Point Types

Used to store real numbers (numbers with fractional parts). Variants include:

TypeStorage SizePrecisionFormat Specifier
float4 bytes6 decimal places%f
double8 bytes15 decimal places%lf
long double10 bytes19 decimal places%Lf

Example:

</>
Copy
#include <stdio.h>

int main() {
    float f = 3.14159;
    double d = 3.14159265358979;
    long double ld = 3.14159265358979323846;

    printf("float f = %.5f\n", f);
    printf("double d = %.14lf\n", d);
    printf("long double ld = %.20Lf\n", ld);

    return 0;
}

Output:

float f = 3.14159
double d = 3.14159265358979
long double ld = 3.14159265358979323846

c. Character Type

The char type is used to store single characters. It takes 1 byte of memory and stores ASCII values. Examples are a, b, z, 8, $. char is supposed to store characters only not numbers, so why should it holds range?

In the memory characters are stored in their ASCII codes. For example, the character ‘B’ has the ASCII code 66. In the memory ‘B’ will not be stored as ‘B’ but as 66.

We have unsigned char and signed char.We don’t have negative characters, then why should we have such datatypes?

We used signed and unsigned char to ensure portability of programs that store non character data as char.

TypeStorage SizeValue RangeFormat Specifier
char1 byte-128 to 127 (signed) or 0 to 255 (unsigned)%c

Example:

</>
Copy
#include <stdio.h>

int main() {
    char letter = 'A';
    printf("Character: %c\n", letter);
    printf("ASCII Value: %d\n", letter);

    return 0;
}

Output:

Character: A
ASCII Value: 65

d. Void Type

The void type represents “no type” and is mainly used in:

  • Functions that do not return any value.
  • Generic pointers (void *) that can point to any type.

Example:

</>
Copy
#include <stdio.h>

void greet() {
    printf("Hello, World!\n");
}

int main() {
    greet();
    return 0;
}

Output:

Hello, World!

2 Derived Data Types

Derived data types in C are built upon primary data types and allow for more complex data management. These include:

  • Arrays: A collection of elements of the same data type stored in contiguous memory locations. Arrays allow efficient indexing but have a fixed size once declared.
  • Pointers: Variables that store the memory address of another variable. Pointers enable dynamic memory allocation, function argument passing by reference, and efficient data manipulation.

Example: Using an Array

This example demonstrates how to declare and use an integer array.

</>
Copy
#include <stdio.h>

int main() {
    int numbers[5] = {10, 20, 30, 40, 50};

    // Accessing elements using a loop
    for (int i = 0; i < 5; i++) {
        printf("%d ", numbers[i]);
    }

    return 0;
}

Output:

10 20 30 40 50

Example: Using a Pointer

This example demonstrates how a pointer stores and accesses a variable’s memory address.

</>
Copy
#include <stdio.h>

int main() {
    int num = 10;
    int *ptr = # // Pointer stores the address of num

    printf("Value of num: %d\n", num);
    printf("Value using pointer: %d\n", *ptr);

    return 0;
}

Output:

Value of num: 10
Value using pointer: 10

3 User-Defined Data Types

User-defined data types in C allow programmers to create more structured and readable code by defining custom types based on primitive data types. This enhances code clarity and reusability. The most common user-defined data types in C are:

  • typedef: Creates an alias (alternative name) for an existing data type, making declarations more readable.
  • enum: Defines a set of named integer constants, improving code readability and reducing errors.
  • struct: Groups multiple variables of different data types into a single entity.
  • union: Similar to a structure but with shared memory among all members.

a. Using typedef

The typedef keyword creates a new name (alias) for an existing type, simplifying complex type declarations.

Example: Creating a new name for unsigned int

</>
Copy
#include <stdio.h>

typedef unsigned int uint; // Defining an alias for unsigned int

int main() {
    uint age = 25; // Now we can use uint instead of unsigned int
    printf("Age: %u\n", age);
    return 0;
}

Output:

Age: 25

b. Using enum (Enumeration)

An enum (enumeration) is used to define a set of named integer constants, making code more readable and manageable.

Example: Defining an enumeration for days of the week

</>
Copy
#include <stdio.h>

enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };

int main() {
    enum Day today = WEDNESDAY;
    
    printf("Today is day number %d of the week.\n", today);
    return 0;
}

Output:

Today is day number 3 of the week.

c. Using struct (Structure)

A struct (structure) allows grouping multiple related variables of different types under a single name.

Example: Defining a structure for a student

</>
Copy
#include <stdio.h>

struct Student {
    char name[50];
    int age;
    float marks;
};

int main() {
    struct Student s1 = {"Alice", 20, 88.5};

    printf("Name: %s\n", s1.name);
    printf("Age: %d\n", s1.age);
    printf("Marks: %.2f\n", s1.marks);

    return 0;
}

Output:

Name: Alice
Age: 20
Marks: 88.50

d. Using union

A union is similar to a structure but with shared memory for all its members. Only one member can hold a value at a time, making it memory-efficient.

Example: Defining a union

</>
Copy
#include <stdio.h>

union Data {
    int i;
    float f;
    char str[20];
};

int main() {
    union Data data;

    data.i = 10;
    printf("Integer: %d\n", data.i);

    data.f = 20.5;
    printf("Float: %.2f\n", data.f);

    return 0;
}

Output:

Integer: 10
Float: 20.50

Since a union shares memory, modifying one member affects the others.

Void

Void data type variables doesn’t have a value of any type. Void means no value.

Theoretically the void type should use no manipulable memory on stack when defined. That is to say, a variable declared with a “void” type shouldn’t be capable of storing any data, and therefore has a size of zero.

Basically void data type are used in some special places and some of them are following :

  • To specify return type of a function(when function returns no value).
  • To specify the parameters of a function(when the function accepts no argument from the caller)
  • To create generic pointers.

Conclusion

In this tutorial, we covered:

  1. The three main categories of data types in C.
  2. Basic data types such as integers, floating-point numbers, and char.
  3. Derived and user-defined data types.