Skip to content

Chapter 3 of 21

Data Types and Variables

Choose integer, floating, character, boolean, and derived types safely.

24 minutes 10 quick checksBy Subha Prasad
Lesson 3 of 21Course navigation

Lesson content

Read, practise, then check your understanding

A type determines how bytes are interpreted, which operations are permitted, and how values are passed. C’s fundamental types include character, signed and unsigned integers, floating-point types, and _Bool. Arrays, pointers, functions, structures, unions, and enumerations build on them.

Integer types

The standard integer family is char, short, int, long, and long long, each except plain char having signed and unsigned forms. Their exact widths are implementation-defined, but the ordering guarantees each later type can represent at least as much range as the previous one.

Use <limits.h> for ranges and <stdint.h> when a fixed or minimum width matters:

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

int main(void) {
    int32_t temperature_milli_c = 23500;
    uint64_t packet_count = 9000;
    printf("%d, %llu\n", temperature_milli_c,
           (unsigned long long)packet_count);
}

Exact-width types such as int32_t exist only when the implementation supports them. Types like int_least32_t and uint_fast16_t provide portable alternatives.

Floating point and boolean

float, double, and long double trade storage and speed for precision and range. Decimal fractions are often not exactly representable in binary, so compare calculated floating values using a meaningful tolerance.

#include <math.h>
#include <stdbool.h>

bool nearly_equal(double a, double b) {
    return fabs(a - b) < 1e-9;
}

stdbool.h defines bool, true, and false for language editions before C23’s updates.

Declarations and initialization

Initialize variables before reading them. Automatic local variables otherwise hold indeterminate values.

int attempts = 0;
double average = 0.0;
char grade = 'A';

Character constants use single quotes; strings use double quotes. A char is an integer type large enough to hold one byte, not inherently a full Unicode character.

Conversions

Usual arithmetic conversions bring operands to compatible types. Mixing signed and unsigned values can produce surprising results because a negative signed operand may convert to a large unsigned value.

size_t length = 10;
int index = -1;

if (index >= 0 && (size_t)index < length) {
    /* index is valid */
}

Use explicit casts only after proving the conversion is valid; a cast can silence a warning without making a value safe.

sizeof and portable output

sizeof(type) and sizeof expression return the storage size in bytes as size_t. Use %zu to print it:

printf("int uses %zu bytes\n", sizeof(int));

Do not assume that a byte is eight bits, that int is 32 bits, or that pointers fit in an integer. Use standard types and limits that express the program’s real requirement.

Knowledge check

Answer every question correctly to complete this chapter.

Which operator reports the size of a type or object in bytes?
Which header defines fixed-width types such as int32_t?
Which standard type represents truth values before C23?
Which floating type has at least as much precision as float?
What value does an uninitialized automatic int contain?
Which header exposes integer limits such as INT_MAX?
What is size_t designed to represent?
Why can mixing negative int values with unsigned values be surprising?
Which printf conversion prints size_t?
What is plain char fundamentally in C?

0 of 10 checks passed

Your progress is saved on this device.