Lesson 17 of 18

Structs

Structs

In HolyC, the class keyword serves the role of both struct and class from C/C++. All classes are plain data structures — there are no methods, constructors, or access modifiers. This lesson covers practical struct patterns: nested classes, passing structs to functions, and building composite data types.

Nested Classes

A class can contain another class as a member, creating hierarchical data structures:

class Address {
  U8 *city;
  U8 *state;
};

class Employee {
  U8 *name;
  I64 id;
  Address addr;
};

Employee e;
e.name = "Terry";
e.id = 1;
e.addr.city = "Las Vegas";
e.addr.state = "NV";

Print("%s (#%d) - %s, %s\n", e.name, e.id, e.addr.city, e.addr.state);
// Terry (#1) - Las Vegas, NV

Struct Pointers and Functions

Functions commonly accept struct pointers to avoid copying and to allow mutation:

class Vec2 {
  F64 x, y;
};

F64 Magnitude(Vec2 *v) {
  return Sqrt(v->x * v->x + v->y * v->y);
}

U0 Scale(Vec2 *v, F64 factor) {
  v->x = v->x * factor;
  v->y = v->y * factor;
}

Vec2 v;
v.x = 3.0;
v.y = 4.0;
Print("%.1f\n", Magnitude(&v));  // 5.0
Scale(&v, 2.0);
Print("%.1f %.1f\n", v.x, v.y);  // 6.0 8.0

Composing Structs

Build complex types by nesting classes. A Line is two Points:

class Point {
  I64 x, y;
};

class Line {
  Point start;
  Point end;
};

Line ln;
ln.start.x = 0;
ln.start.y = 0;
ln.end.x = 10;
ln.end.y = 5;

I64 dx = ln.end.x - ln.start.x;
I64 dy = ln.end.y - ln.start.y;
Print("dx=%d dy=%d\n", dx, dy);  // dx=10 dy=5

Your Task

Define a Point class with I64 x and I64 y members. Define a Rect class with two Point members: origin and size (where size.x is width and size.y is height).

Write a function I64 Area(Rect *r) that returns the area (width * height).

Create a rectangle with origin (2, 3) and size (10, 5), then print the area.

Expected output: 50

Aiwnios HolyC loading...
Loading...
Click "Run" to execute your code.