Struct Embedding
Part of the Object Oriented Programming section of Coddy's C journey — lesson 28 of 61.
In object-oriented languages like C++ or Java, inheritance allows a class to acquire properties from a parent class. C doesn't have built-in inheritance, but we can simulate it using a technique called composition — placing one struct inside another.
The idea is simple: if a Child needs all the properties of a Parent, we embed the Parent struct as a member of Child.
typedef struct {
int id;
char name[50];
} Parent;
typedef struct {
Parent parent; // Embedded struct
int grade;
} Child;Here, Child contains everything Parent has, plus its own grade field. This is composition — the child "has a" parent rather than "is a" parent, but the effect is similar to inheritance.
To access the parent's members through a child instance, you use the dot operator twice:
Child c;
c.parent.id = 101;
c.parent.name[0] = 'A';
c.grade = 5;This pattern forms the foundation for building type hierarchies in C. By embedding a base struct as the first member, we unlock powerful techniques that we'll explore in upcoming lessons.
Challenge
EasyLet's build a simple employee management system that demonstrates struct embedding—the foundation of inheritance in C.
You'll create a hierarchy where an Employee contains a Person. This mirrors how inheritance works: an employee "is a" person with additional job-related information. By embedding the Person struct inside Employee, you get all the person's properties plus the employee-specific fields.
You'll organize your code across three files:
types.h: Define both structs here with include guards. First, create aPersonstruct with two fields:name(a character array of 50 characters) andage(an integer). Then define anEmployeestruct that embedsPersonas its first member and adds anemployee_idfield (an integer).types.c: Implement a function calledprint_employeethat takes a pointer to anEmployeeand prints their information. Access the embedded person's data using the chained dot/arrow syntax you learned.main.c: Create anEmployeevariable, populate all its fields (including the embedded person's name and age), and use your print function to display the information.
You will receive three inputs: the employee's name (a string), their age (an integer), and their employee ID (an integer).
Your print_employee function should output the employee's information in this format:
Employee: Alice
Age: 28
ID: 1001Where Alice is the name, 28 is the age, and 1001 is the employee ID from your inputs.
Remember to access the embedded struct's members through the parent member—for example, to reach the name, you'll navigate through the person member first.
Cheat sheet
C doesn't have built-in inheritance, but you can simulate it using composition — embedding one struct inside another.
To create a parent-child relationship, embed the parent struct as a member of the child struct:
typedef struct {
int id;
char name[50];
} Parent;
typedef struct {
Parent parent; // Embedded struct
int grade;
} Child;The child struct contains all properties of the parent, plus its own additional fields. This represents a "has a" relationship.
To access members of the embedded struct, use the dot operator twice:
Child c;
c.parent.id = 101;
c.parent.name[0] = 'A';
c.grade = 5;When working with pointers, use the arrow operator to access the embedded struct's members:
Child *ptr = &c;
ptr->parent.id = 101;
ptr->grade = 5;Embedding the base struct as the first member is a common pattern that enables advanced techniques for building type hierarchies in C.
Try it yourself
#include <stdio.h>
#include <string.h>
#include "types.h"
int main() {
// Read input
char name[50];
int age;
int employee_id;
fgets(name, 50, stdin);
name[strcspn(name, "\n")] = '\0'; // Remove newline
scanf("%d", &age);
scanf("%d", &employee_id);
// TODO: Create an Employee variable
// TODO: Populate the embedded person's name and age
// Hint: Use strcpy for the name, access with employee.person.name
// TODO: Set the employee_id
// TODO: Call print_employee with a pointer to your employee
return 0;
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Modular Programming Basics
Header FilesInclude GuardsSource FilesStatic FunctionsRecap: Modular Calculator4Encapsulation
Opaque Pointers ConceptDefining Opaque StructsGetters and SettersValidation in SettersRecap: Secret Box2Objects and Methods
Structs as ObjectsThe 'Self' PointerConst CorrectnessPointer vs ValueHelper MethodsRecap: Point Manager5Project: Simple Bank Account
Project SetupImplementation of Account3Object Lifecycle
Constructor PatternDestructor PatternStack InitializationDeep CopyRecap: String Wrapper6Inheritance via Composition
Struct EmbeddingThe First Member RuleAccessing Parent MembersUpcastingRecap: Shape Hierarchy