#include // malloc, free #include // puts // structs, unions and enums is how you create new types in C // sizeof is an operator, not a function, part of the C language // a basic struct declares a type in C, we can make recursive structs to create recursive types struct A { struct A * inner; const char * text; }; // use a typedef along with the struct name, allows you to use the alias later and omit `struct` // however, you still need `struct` prefix when using the struct type recursively typedef struct B { struct B * inner; const char * text; } B; // forward declare the typedef, and you get to use the alias recursively typedef struct C C; struct C { C * inner; const char * text; }; // omit the struct name, and you can't use the struct type recursively typedef struct { const char * text; } D; // here's an unnamed struct as well, but this time with an instance globally created struct { const char * text; } e = { "This is the E!" }; // these are constructor functions // they have to be heap allocated struct A * newA () { struct A * a = malloc(sizeof(struct A)); struct A * aa = malloc(sizeof(struct A)); a->text = "This is the A!"; aa->text = "This is the internal A!"; a->inner = aa; return a; } B * newB () { B * b = malloc(sizeof(B)); B * bb = malloc(sizeof(B)); b->text = "This is the B!"; bb->text = "This is the internal B!"; b->inner = bb; return b; } C * newC () { C * c = malloc(sizeof(C)); C * cc = malloc(sizeof(C)); c->text = "This is the C!"; cc->text = "This is the internal C!"; c->inner = cc; return c; } int main () { struct A * a = newA(); puts(a->text); puts(a->inner->text); free(a); B * b = newB(); puts(b->text); puts(b->inner->text); free(b); C * c = newC(); puts(c->text); puts(c->inner->text); free(c); D d = { "This is the D!" }; puts(d.text); puts(e.text); return 0; }