๐Ÿ“ฆ 4. Data Types in C

A data type describes the values a variable can hold and the operations that make sense for it. For example, a count uses an integer type, while a measurement may need a floating-point type. Choose a type that can represent the values your program needs.

4.1 What Is a Data Type?

A data type describes the kind of data associated with an object, expression, function return value, or other declaration in C.

For example:

int age = 20;
float price = 99.50f;
char grade = 'A';

The declarations tell the compiler that these objects have different types.

             DATA TYPE
                 โ”‚
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚        โ”‚        โ”‚
        โ–ผ        โ–ผ        โ–ผ
       int     float     char
        โ”‚        โ”‚        โ”‚
        โ–ผ        โ–ผ        โ–ผ
       20      99.5       A
Core idea:

The compiler uses types to interpret values and check operations. This also affects calculations: dividing two integers follows different rules from dividing floating-point values.

4.2 Why Does C Need Data Types?

A program works with different kinds of information.

  • whole numbers
  • fractional values
  • characters
  • very large or very small numeric values
  • addresses
  • collections of related data

C needs a way to distinguish these different kinds of data.

int students = 60;
float temperature = 36.5f;
char section = 'A';

These objects represent different kinds of information and therefore use different types.

4.3 Major Categories of C Types
C TYPES
โ”‚
โ”œโ”€โ”€ Basic / Fundamental Types
โ”‚   โ”œโ”€โ”€ char
โ”‚   โ”œโ”€โ”€ signed integer types
โ”‚   โ”œโ”€โ”€ unsigned integer types
โ”‚   โ”œโ”€โ”€ _Bool
โ”‚   โ”œโ”€โ”€ float
โ”‚   โ”œโ”€โ”€ double
โ”‚   โ””โ”€โ”€ long double
โ”‚
โ”œโ”€โ”€ void
โ”‚
โ”œโ”€โ”€ Derived Types
โ”‚   โ”œโ”€โ”€ Arrays
โ”‚   โ”œโ”€โ”€ Pointers
โ”‚   โ””โ”€โ”€ Function types
โ”‚
โ”œโ”€โ”€ Structure Types
โ”‚
โ”œโ”€โ”€ Union Types
โ”‚
โ””โ”€โ”€ Enumeration Types

Start with the basic types in this lesson. Later lessons explain arrays, pointers, functions, structures, unions, and enumerations.

4.4 Fundamental Numeric and Character Types
Type Typical Use Example
char Character-sized integer type 'A'
short Short integer type 100
int General-purpose integer 500
long Integer type with at least as much range as int 100000L
long long Large integer values 9000000000LL
float Single-precision floating-point 3.14f
double Double-precision floating-point 3.14159
long double Extended floating-point type 3.14159L
Important:

Many sizes and ranges depend on the compiler and target system. Treat a size shown by your own program as a result for that system, not a rule for every computer.

4.5 The char Type

The char type is designed for character data and is also an integer type in C.

char grade = 'A';
char symbol = '#';

Character constants use single quotation marks.

'A'
'B'
'7'
'@'
Do not confuse:
'A'
"A"

'A' is a character constant. "A" is a string literal containing the character A followed by a terminating null character.

4.6 Integer Types

Integer types represent whole-number values.

int count = 100;
short smallNumber = 25;
long population = 1000000L;
long long distance = 9000000000LL;

C provides several integer types because programs may need different ranges and storage requirements.

Signed integer

Can represent negative and non-negative values within its implementation-defined range.

Unsigned integer

Represents non-negative values and generally provides a larger non-negative range for the same width.

4.7 Signed and Unsigned Integer Types
signed int temperature = -10;
unsigned int students = 500;

The unsigned keyword specifies that the type is non-negative.

Type Can represent negative values?
int Yes
signed int Yes
unsigned int No
Important:

Unsigned types do not store negative values. Their arithmetic wraps within the typeโ€™s range. Mixing signed and unsigned values can change comparisons or calculations, so check the conversion rules.

4.8 The float Type

float is a floating-point type used for values that may contain a fractional component.

float temperature = 36.5f;
float price = 99.99f;

The f suffix indicates a float floating constant.

3.14f

Without the suffix:

3.14

the floating constant has type double.

4.9 The double Type

double is a floating-point type that normally provides more precision than float.

double pi = 3.141592653589793;

Floating-point types can approximate a wide range of values, but they cannot represent every decimal value exactly. For example, 0.1 is not exact in common binary floating-point formats.

Placement point:

Do not assume that every decimal value can be represented exactly in binary floating-point.

4.10 long double

long double is an extended floating-point type. Its precision and representation are implementation-dependent.

long double value = 3.141592653589793238L;

The L suffix identifies a long double floating constant.

4.11 The _Bool Type

C provides the built-in integer type _Bool.

_Bool isPassed = 1;

In C99 through C17, the standard header <stdbool.h> provides the spelling bool and the true and false macros. In C23, bool, true, and false are keywords.

#include <stdbool.h>

bool isPassed = true;
Remember:

bool is provided by the standard header <stdbool.h> in C99 through C17. The underlying type is _Bool.

4.12 The void Type

void represents the absence of a value or type information in several C contexts.

A common example is a function that does not return a value:

void displayMessage(void)
{
    printf("Hello");
}

A pointer to void, written void *, is a separate concept and is useful for generic object pointers.

4.13 The sizeof Operator

The sizeof operator determines the size in bytes of a type or object.

#include <stdio.h>

int main(void)
{
    printf("%zu\n", sizeof(int));
    printf("%zu\n", sizeof(double));
    printf("%zu\n", sizeof(char));

    return 0;
}
sizeof(type)
     โ”‚
     โ–ผ
number of bytes
     โ”‚
     โ–ผ
depends on implementation
Important:

The result of sizeof has type size_t, which is why %zu is the appropriate printf conversion specifier in C99 and later.

4.14 Do Not Memorize Fixed Sizes

A common beginner mistake is memorizing:

int = 4 bytes
char = 1 byte
float = 4 bytes
double = 8 bytes

These are common on many modern systems, but C does not require every implementation to use exactly those sizes.

The correct way to discover the size on the current implementation is:

sizeof(type)
Special point:

C guarantees that sizeof(char) is exactly 1. A C byte is not required to contain exactly 8 bits; the number of bits in a byte is represented by CHAR_BIT.

4.15 Finding Integer Limits

The header <limits.h> provides macros describing limits of integer types on the current implementation.

#include <stdio.h>
#include <limits.h>

int main(void)
{
    printf("INT_MIN = %d\n", INT_MIN);
    printf("INT_MAX = %d\n", INT_MAX);
    printf("UINT_MAX = %u\n", UINT_MAX);

    return 0;
}

This is safer than assuming one universal numeric range.

4.16 Floating-Point Properties

The header <float.h> provides information about the characteristics of floating-point types.

#include <stdio.h>
#include <float.h>

int main(void)
{
    printf("FLT_DIG = %d\n", FLT_DIG);
    printf("DBL_DIG = %d\n", DBL_DIG);

    return 0;
}

For example, these values help you check how many decimal digits a floating-point type can preserve.

4.17 Type Specifiers and Modifiers

C provides keywords that combine with integer and floating types to describe different type forms.

Keyword Purpose
signed Specifies a signed integer type.
unsigned Specifies a non-negative integer type.
short Specifies a short integer type.
long Specifies a long integer or extended floating type.
short int a;
unsigned int b;
long int c;
long long int d;
4.18 Integer Type Relationships
Integer types

signed
โ”‚
โ”œโ”€โ”€ signed char
โ”œโ”€โ”€ short
โ”œโ”€โ”€ int
โ”œโ”€โ”€ long
โ””โ”€โ”€ long long

unsigned
โ”‚
โ”œโ”€โ”€ unsigned char
โ”œโ”€โ”€ unsigned short
โ”œโ”€โ”€ unsigned int
โ”œโ”€โ”€ unsigned long
โ””โ”€โ”€ unsigned long long

The compiler and system determine the exact sizes and ranges. C still sets minimum requirements and rules for how the standard integer types relate to one another.

4.19 Character Type Variants

C provides three character types:

char
signed char
unsigned char

Whether plain char behaves as signed or unsigned is implementation-defined.

Placement point:

Do not assume plain char is always signed or always unsigned.

4.20 Integer Constant Suffixes

Integer literals can use suffixes to influence their type.

100
100U
100L
100UL
100LL
100ULL
Literal Meaning
100 Integer constant without an explicit suffix
100U Unsigned integer constant
100L Long integer constant
100LL Long long integer constant
100ULL Unsigned long long integer constant
4.21 Floating-Point Constant Suffixes
3.14
3.14f
3.14L
Literal Type
3.14 double
3.14f float
3.14L long double
4.22 Data Types and Type Conversion

When different arithmetic types participate in an expression, C may convert values according to its conversion rules.

int a = 10;
double b = 2.5;

double result = a + b;

The integer value participates in the calculation after the appropriate conversion.

       10        +        2.5
        โ”‚                  โ”‚
        โ”‚                  โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
               โ–ผ
       common arithmetic
          conversion
               โ”‚
               โ–ผ
             12.5

Type conversion is covered in greater depth when expressions and operators are introduced.

4.23 Implicit and Explicit Conversion
Implicit conversion

C applies the conversion automatically according to its type rules.

double x = 10;
Explicit conversion

The programmer requests a conversion using a cast.

double x = (double)10;
4.24 Why Data Types Affect Results
int a = 5;
int b = 2;

printf("%d\n", a / b);

Because both operands are integers, the division is integer division and the result is 2.

Compare:

double result = 5.0 / 2.0;

Here the result is 2.5.

Key lesson:

Data types can affect not only storage but also the behavior of expressions and operations.

4.25 Derived Types โ€” Preview

C also supports derived and user-defined type constructs.

int numbers[5];

int *ptr;

struct Student
{
    int roll;
};

Arrays, pointers, structures, unions, enumerations and function types will be studied separately.

4.26 How Do You Choose a Data Type?
Requirement Possible Choice
General whole number int
Non-negative count Appropriate unsigned integer type when justified
Character-sized data char
Fractional value float or double
Higher floating-point precision double or long double, as appropriate
Boolean-style state _Bool or bool with <stdbool.h>
Programming principle:

Choose a type by asking what values you need, whether fractions are required, and what calculations you will perform. Check the typeโ€™s range instead of choosing it only because its size is small.

4.27 Complete Program โ€” Different Data Types
#include <stdio.h>
#include <stdbool.h>

int main(void)
{
    int age = 21;
    float height = 5.8f;
    double percentage = 87.4567;
    char grade = 'A';
    bool passed = true;

    printf("Age = %d\n", age);
    printf("Height = %.1f\n", height);
    printf("Percentage = %.4f\n", percentage);
    printf("Grade = %c\n", grade);
    printf("Passed = %d\n", passed);

    return 0;
}
Program
โ”‚
โ”œโ”€โ”€ int
โ”‚   โ””โ”€โ”€ age
โ”‚
โ”œโ”€โ”€ float
โ”‚   โ””โ”€โ”€ height
โ”‚
โ”œโ”€โ”€ double
โ”‚   โ””โ”€โ”€ percentage
โ”‚
โ”œโ”€โ”€ char
โ”‚   โ””โ”€โ”€ grade
โ”‚
โ”œโ”€โ”€ bool
โ”‚   โ””โ”€โ”€ passed
โ”‚
โ””โ”€โ”€ printf()
    โ””โ”€โ”€ displays values
4.28 Common Data Type Mistakes
  1. Assuming every C compiler uses exactly the same type sizes.
  2. Using int for a value that cannot fit in the required range.
  3. Expecting integer division to produce a fractional result.
  4. Confusing char with a string.
  5. Using the wrong printf() format specifier.
  6. Assuming plain char is always signed.
  7. Treating floating-point values as if they were always exact decimal numbers.
4.29 Common printf() Format Specifiers
Specifier Common Use
%d Signed decimal integer
%u Unsigned decimal integer
%c Character
%f Floating-point output
%zu size_t, commonly used with sizeof
Important:

Match each format specifier to its argument. A function that accepts a varying number of arguments, such as printf() cannot safely use a format specifier that expects the wrong argument type. A mismatch can cause undefined behaviour.

4.30 Portable Integer Types and Limits

C does not guarantee int, long and pointers have the same sizes on all machines. Use <stdint.h> for optional exact-width types such as int32_t, <inttypes.h> for portable format macros, and <limits.h> for properties such as INT_MAX. int32_t exists only if the implementation provides an exactly 32-bit signed integer type.

Complete C program:

#include <stdio.h>
#include <limits.h>
#include <stdint.h>
#include <inttypes.h>

int main(void)
{
    int32_t score = 1234;
    printf("Score: %" PRId32 "\n", score);
    printf("INT_MAX is at least 32767: %s\n",
           INT_MAX >= 32767 ? "yes" : "no");
    return 0;
}

Expected output:

Score: 1234
INT_MAX is at least 32767: yes

Step-by-step explanation:

  1. int32_t is a signed exact-width integer on supporting implementations.
  2. PRId32 supplies the matching printf conversion sequence.
  3. Limits come from headers rather than guessed machine-specific sizes.
Remember: Do not assume sizeof(int) == 4 or that char is always signed. For byte buffers, unsigned char is often appropriate.

4.31 const, volatile and restrict โ€” Different Qualifiers

const prevents modification through an expression with the const-qualified type. volatile tells the compiler that accesses to certain objects must follow the languageโ€™s observable-access rules; it does not make shared data thread-safe. restrict, introduced in C99, is a promise about how pointers access data, which can help optimisation. These qualifiers have different purposes.

Complete C program:

#include <stdio.h>

void addArrays(int n, int *restrict result,
               const int *restrict left, const int *restrict right)
{
    for (int i = 0; i < n; ++i)
        result[i] = left[i] + right[i];
}

int main(void)
{
    int a[3] = {1, 2, 3}, b[3] = {4, 5, 6}, out[3];
    addArrays(3, out, a, b);
    printf("%d %d %d\n", out[0], out[1], out[2]);
    return 0;
}

Expected output:

5 7 9

Step-by-step explanation:

  1. The source arrays are read through pointers to const int.
  2. The restrict-qualified pointers are used with nonoverlapping arrays.
  3. The destination receives pairwise sums.
Remember: Using overlapping objects in a way that violates a restrict contract can cause undefined behavior; do not use volatile to make threads safe.

4.32 Quick Revision

๐Ÿ“Œ char is used for character values.

๐Ÿ“Œ int is commonly used for integer values.

๐Ÿ“Œ float represents single-precision floating-point values.

๐Ÿ“Œ double represents double-precision floating-point values.

๐Ÿ“Œ void represents the absence of a value in certain contexts.

๐Ÿ“Œ sizeof reports size in bytes.

๐Ÿ“Œ Use sizeof() when you need the actual size on your system.

๐Ÿ“Œ Integer division discards the fractional part of the result.

4.33 Quick MCQs

Select an answer first, then click Check Answer. A correct choice becomes green. If the choice is wrong, it becomes red and the correct option is shown in green. The explanation appears below after checking.

1. Which data type is commonly used to store an integer?
2. Which operator gives the size of a type or object?
3. Which is a character constant?
4. What is the result of 5 / 2 when both operands are int?
5. Which type generally provides more precision than float?
PRACTICE

4.34 ๐ŸŽฏ Programming Problems

Try each program yourself first. Use ๐Ÿ’ป Solve It Yourself to write and run your C code. Open a hint only when needed, and use Show Program to study the official solution after attempting the problem.

๐Ÿ“ˆ Data Types Practice Progress
Solved 0 / 5
Completed with Solution 0
Total Score 0 / 100
Completion 0%
A problem counts as Solved when all test cases pass without opening the full solution. Problems completed after viewing the official solution are tracked separately.
1. Print Values of Different Data Types

Problem 1: Declare variables of type int, float, double and char, read their values, and print them.

Input: An integer, a float, a double and a character.

Output: Print all four values with clear labels.

2. Print Sizes Using sizeof

Problem 2: Write a program to print the size of char, int, float and double using sizeof.

Input: No input.

Output: Print the sizes in bytes on separate lines.

3. Average with Decimal Precision

Problem 3: Write a program to calculate the average of two integers and display the result with decimal precision.

Input: Two integers.

Output: Print the average rounded to two decimal places.

4. Integer Division vs Floating-Point Division

Problem 4: Write a program demonstrating the difference between integer division and floating-point division.

Input: Two integers a and b, where b is non-zero.

Output: Print integer division and floating-point division results.

5. Convert Integer to Double

Problem 5: Write a program that reads an integer and displays its value as a double.

Input: One integer.

Output: Print the converted value with two digits after the decimal point.

4.35 Key Takeaway

๐ŸŽฏ Don't simply memorize data types.

Understand three things:

1. What kind of value do I need?

2. What type is appropriate?

3. What happens when different types are used together?

These ideas become extremely important when we learn operators, expressions, arrays, pointers and functions.
PROGRAM TRACING

๐Ÿ”Ž Program Tracing โ€” Data Types

Trace how integer division differs from floating-point division after an explicit type conversion.

INTERVIEW PREPARATION

๐ŸŽค Data Types โ€” Interview Questions

1. What is a data type in C?
2. What are the main categories of C data types?
3. What is the difference between float and double?
4. What is the purpose of sizeof?
5. What is the difference between implicit and explicit type conversion?
6. Why does 5 / 2 produce 2 in an integer expression?
7. What is the purpose of signed and unsigned integer types?
PLACEMENT TIPS

๐Ÿ’ก Data Types โ€” Extra Tips

  • Do not memorize fixed byte sizes for every machine. Except for sizeof(char) == 1, sizes of fundamental types are implementation-dependent.
  • Know the correct format specifier for common types and remember that scanf uses %lf for double.
  • Be ready to explain why integer division can produce a different result from floating-point division.
  • Understand when a cast such as (double)a changes the type used by an expression.
  • In interviews, connect type + range/precision + operation behavior instead of memorizing only syntax.
EXTRA PRACTICE

โœ๏ธ Data Types โ€” Extra Practice Questions

  1. Predict the type and result of the expression 5 + 2.5.
  2. Explain why 5 / 2 and 5.0 / 2 produce different results.
  3. Write a short program that uses sizeof with five different types available in C.
  4. Compare char, int, float, and double with one suitable example value for each.
  5. Rewrite an integer-division expression so that it produces a floating-point result using an explicit cast.
โ† Previous Topic: Variables & Constants Next Topic: Input & Output โ†’