Little-Endian vs Big-Endian in C Programming
In the C programming language, multi-byte integers are stored in memory across consecutive byte addresses using either little-endian or big-endian ordering, determined by the underlying hardware architecture. This article explains the fundamental differences between these two memory representations, illustrates how integer words are arranged in memory addresses, and demonstrates how to check or handle byte ordering in C code.
The Concept of Endianness
A standard 32-bit integer word consists of four bytes. For example,
the hexadecimal integer value 0x12345678 is made up of four
individual bytes: 0x12 (the Most Significant Byte, or MSB),
0x34, 0x56, and 0x78 (the Least
Significant Byte, or LSB).
Endianness defines the sequential order in which these bytes are mapped to increasing memory addresses. The C language standard does not mandate a specific byte order; instead, it delegates this choice to the target CPU architecture.
Big-Endian Representation
In big-endian representation, the Most Significant Byte is stored at the lowest (first) memory address, while the Least Significant Byte is stored at the highest address. This matches the standard left-to-right reading order of numbers.
Using the value 0x12345678 stored at base address
0x1000:
0x1000:0x12(MSB)0x1001:0x340x1002:0x560x1003:0x78(LSB)
Big-endian is commonly referred to as "network byte order" because Internet protocols (such as IP and TCP) standardize on this format. It was also historically common on architectures such as SPARC, Motorola 68000, and older PowerPC chips.
Little-Endian Representation
In little-endian representation, the Least Significant Byte is stored at the lowest (first) memory address, and the Most Significant Byte is stored at the highest address.
Using the same value 0x12345678 stored at base address
0x1000:
0x1000:0x78(LSB)0x1001:0x560x1002:0x340x1003:0x12(MSB)
Little-endian is the dominant layout in modern consumer computing, used by x86, x86-64, and the default configurations of ARM processors.
Detecting Endianness in C
Because C allows low-level memory inspection via pointers and type punning, you can determine the endianness of the current system at runtime by examining the byte stored at the base address of an integer:
#include <stdio.h>
#include <stdint.h>
int main(void) {
uint32_t value = 0x01;
uint8_t *byte_ptr = (uint8_t *)&value;
if (*byte_ptr == 0x01) {
printf("System is Little-Endian\n");
} else {
printf("System is Big-Endian\n");
}
return 0;
}In this code, if the first byte accessed via byte_ptr
contains 0x01, the least significant byte is stored first,
confirming a little-endian machine.
Practical Implications in C
Understanding endianness is critical in two main areas of C software development:
- Network Communication: Since network protocols
mandate big-endian ordering, systems running on little-endian
architectures must convert integer words using POSIX functions such as
htonl()(host to network long) andntohl()(network to host long) before sending and after receiving data. - Binary File Formats: When reading or writing raw
binary data (such as image files, audio, or database records) across
different architectures, endian-independent code must explicitly
serialize and deserialize integer fields rather than using direct
fread()orfwrite()operations into integer pointers.