User-Defined Types
C provides three primary ways to create custom types: Structures, Unions, and Enumerations. These allow you to group related data into logical entities.
Structures: Grouping Heterogeneous Data
A struct is a block of memory that holds multiple variables (members) of different types.
struct Player {
char name[32];
int score;
float health;
};
Accessing Members: . vs ->
- use the Dot Operator (
.) for direct instances. - Use the Arrow Operator (
->) for pointers to instances.ptr->xis shorthand for(*ptr).x.
Memory Alignment and Padding
This is a critical systems concept. A struct’s size is not always the sum of its parts. Compilers insert “padding” bytes to ensure members are aligned with the CPU’s word boundaries for faster access.
struct Mixed {
char c; // 1 byte
// 3 bytes of padding inserted here!
int i; // 4 bytes
};
// sizeof(struct Mixed) is likely 8, not 5.
Optimization Tip: Reorder struct members from largest to smallest to minimize padding.
Unions: Shared Memory
A union is a special type where all members share the same starting memory address. The size of the union is the size of its largest member.
Use unions for:
- Type Punning: Interpreting the same bits in different ways.
- Mutually Exclusive Data: When an object can be “A” or “B”, but never both at once.
union Data {
int i;
float f;
} u;
u.i = 42;
// Now u.f also contains the bit pattern of 42 interpreted as a float.
Bit-fields: Power at the Bit Level
In embedded programming, we often need to packet data into specific bits to save space or match hardware registers.
struct Flags {
unsigned int is_active : 1; // 1 bit
unsigned int error_code : 3; // 3 bits
unsigned int reserved : 4; // 4 bits
};
// Total size: 1 byte (plus possible padding to int size)
Memory Layout
union Example {
char a;
int b;
};
// If sizeof(char) is 1 and sizeof(int) is 4,
// what is sizeof(union Example)?
// Answer: Enumerations (enum)
Enums provide a way to define integer constants with human-readable names, improving code clarity.
enum Status { IDLE, RUNNING, ERROR = -1 };
enum Status current = IDLE; // 'current' is effectively 0
Interactive Lab
Waiting for signal...