C COMPOSITE DATA

Master Structures, Enums & Typedefs

Introduction to Composite Data Types

Welcome to the world of C composite data types! In this comprehensive guide, we'll explore three fundamental concepts that allow you to create more complex and organized data structures in C programming:

  • Structures (struct) - Group related variables together
  • Enumerations (enum) - Define named constants
  • Type Definitions (typedef) - Create aliases for existing types
Why Use Composite Data Types?
These constructs help you write more organized, readable, and maintainable code by grouping related data together and creating meaningful names for your data types.

Structures (struct)

What is a Structure?

A structure is a user-defined data type that groups together variables of different types under a single name. Think of it as a blueprint for creating related data.

Basic Syntax

struct StructureName {
    datatype member1;
    datatype member2;
    // ... more members
};

Real Example: Course Structure

#include <stdio.h>
#include <string.h>

struct Course {
    int sln;
    char title[256];
    char instructor[250];
    int time;
};

void main() {
    struct Course ser222;
    
    ser222.sln = 1774;
    strcpy(ser222.title, "Data Structures & Algorithms");
    strcpy(ser222.instructor, "Acuna, Ruben");
    
    printf("Memory allocated for this structure is %d", sizeof(ser222));
}
Interactive Structure Memory Layout

Click the button to see how memory is allocated for the Course structure:

Important Notes:
• Structure members are stored in contiguous memory
• The total size may be larger due to padding/alignment
• Use dot notation (.) to access members

Enumerations (enum)

What is an Enumeration?

An enumeration defines a type that consists of a set of named constants. Each enum value is internally represented as an integer, making them efficient while providing meaningful names.

Basic Syntax

enum { value1, value2, value3 } EnumName;

Example 1: Boolean Enumeration

// Example 1:
enum { false, true } boolean;

void main() {
    enum boolean x = false;
    int counter = 5;
    
    if (x == true) counter++;
}

Example 2: Days of Week

// Example 2:
enum {
    Sun=0, Mon, Tue, Wed, Thu, Fri, Sat
} days;

enum days day = Mon;
Enum Value Explorer

See how enum values are automatically numbered:

Key Points:
• Enum values start at 0 by default
• You can explicitly assign values
• Each value is just an integer internally
• Not type-safe in C (unlike C++)

Type Definitions (typedef)

What is typedef?

The typedef keyword creates an alias (synonym) for an existing data type. This makes your code more readable and easier to maintain.

Basic Syntax

typedef existing_type new_name;

Example 1: Simple Type Alias

// example 1
typedef int boolean;

void main() {
    boolean x = 0;
    int counter = 5;
    
    if (x == 0) counter++;
}

Example 2: Better Alternative

// example 2
typedef char FlagType;

int main() {
    FlagType x = '\0';
}

Typedef with Structures

// Combining typedef with struct
typedef struct {
    int x, y;
    char symbol;
} Point;

// Now you can use Point directly
Point player = {10, 20, '@'};
Why use char instead of int for boolean?
Using char (1 byte) instead of int (typically 4 bytes) saves memory when you only need to represent simple true/false or flag values.

Practical Examples

Game Character System

#include <stdio.h>
#include <string.h>

// Enum for character classes
typedef enum {
    WARRIOR, MAGE, ARCHER, ROGUE
} CharacterClass;

// Enum for game states
typedef enum {
    MENU, PLAYING, PAUSED, GAME_OVER
} GameState;

// Structure for game character
typedef struct {
    char name[50];
    CharacterClass class;
    int health;
    int mana;
    int level;
    float experience;
} Character;

void displayCharacter(Character *c) {
    char *classes[] = {"Warrior", "Mage", "Archer", "Rogue"};
    
    printf("=== Character Info ===\n");
    printf("Name: %s\n", c->name);
    printf("Class: %s\n", classes[c->class]);
    printf("Level: %d\n", c->level);
    printf("Health: %d\n", c->health);
    printf("Mana: %d\n", c->mana);
}

int main() {
    Character player;
    GameState currentState = PLAYING;
    
    // Initialize character
    strcpy(player.name, "CodeWarrior");
    player.class = WARRIOR;
    player.health = 100;
    player.mana = 50;
    player.level = 1;
    player.experience = 0.0;
    
    displayCharacter(&player);
    
    printf("\nCharacter size: %zu bytes\n", sizeof(player));
    
    return 0;
}
Character Creation Simulator

Create your own character and see the memory layout:



Memory Management & Best Practices

Memory Layout of Structures

Understanding how structures are laid out in memory is crucial for efficient programming:

struct Example {
    char a;      // 1 byte
    int b;       // 4 bytes (typically)
    char c;      // 1 byte
    double d;    // 8 bytes
};

// Actual memory layout with padding:
// [a][pad][pad][pad][b][b][b][b][c][pad][pad][pad][pad][pad][pad][pad][d][d][d][d][d][d][d][d]

Best Practices

  • Use meaningful names: Make your code self-documenting
  • Order members by size: Place larger types first to minimize padding
  • Use typedef consistently: Create aliases for complex types
  • Initialize structures: Always initialize your structures to avoid garbage values
  • Use enums for constants: Replace magic numbers with meaningful enum values
Common Pitfalls to Avoid:
• Don't assume enum values without checking
• Remember that enums are just integers in C
• Be aware of structure padding
• Always check array bounds in structures
Memory Size Calculator

Compare different structure layouts and their memory usage: