Created: 2023-08-20 18:00
Status: #concept
Subject: Programming
Tags: C Object Data Structure TypeScript interface JavaScript Class

struct

A struct is a data structure in C that contains named members that may have different types.

  • the members inside the struct have their own Local Scope, so two different struct tags can have the same member names.

struct C Representation in Memory.png

Syntax

It is similar to type variableName with int, float, or double, but we use a struct Tag { ...members } instead.

  • the sizeof a structure depends on the members, allocated 1 by 1 and with enough space for all.
    • however, this size is not always accurate as the compiler may allocate more space to create a Computer Word (typically 8 Bytes).
  • the Tag is optional.

// Part represents a part in a warehouse with an ID 'number', 'id', and stock 'on_hand'
// we declare 2 variables 'part1' & 'part2' with the type Part
struct Part {
    int id;
    char name[NAME_LEN+1];
    int on_hand;
} part1, part2;

struct Part part3 = { 10, "Engine", 43 }; // using struct Tag to initialize

Initialization

struct {
    int id;
    char name[NAME_LEN+1];
    int on_hand;
} part1 = {528, "Disk drive", 10}, 
  part2 = {914, "Printer cable", 5},
  part3 = {.on_hand = 2}; // we can also initialize specified members

// each value, separated by commas, will be stored in each member - in order

Member Access

We use the Dot Operator ., similar to other Object-oriented programming languages.

  • the . operator has the same precedence as () or ->.
  • they are treated as Lvalues and can be assigned as Variables.

printf("Part id: %d", part1.id);
printf("Part name: %s", part1.name);
printf("Quantity on hand: %d", part1.on_hand);

part1.number = 258;
part1.on_hand++;

Copying Members & Assignment

Since we allocate a static amount of memory, we can assign them as if they were normal Variable C Data Types like int.

  • this only works for compatible types like structs with the same Tag, it will not work if the struct was declared separately.

struct {
  int a[10];
} a1, a2;

struct {
  int a[10];
} b;

a1 = a2; // valid
b = a1;  // invalid, not compatible

By extension of that, we can also directly assign structs into Function parameters.

void print_part(struct part p) // function definition
{
    printf("Part id: %d\n", p.id);
    printf("Part name: %s\n", p.name);
    printf("Quantity on hand: %d\n" p.on_hand);
}

print_part(part1); // function call

Custom Types with struct & typedef

Instead of using struct Tag to declare a struct variable, we can alias the struct Tag with typedef.

typedef struct node {
  int data;
  struct node *next;
} Node;

Node head = { 3, NULL };

Nested struct Types

A struct.member can also contain other struct types or C Arrays.

  • we access them normally with another . operator.
  • parent.member.nestedMember

Array of struct Types

struct dialog_code {
    char *country; // use a pointer to a string variable to not mutate
    int code;
};

const struct dialing_code country_codes[] =
{
    {"Argentina", 54}, {"Bangladesh", 880}, {"Brazil", 55}, {"China", 86},
    {"Colombia", 57}, {"Egypt", 20}, {"Ethiopia", 251}, {"Indonesia", 62}
};

struct part inventory[100];
// declaration of array containing a max of 100 'part' structs

print_part(inventory[i]);
// prints the members' values using the function print_part
// on part 'i' in the array 'inventory'

inventory[i].number = 883;
// accessing a member inside part 'i' inside the structs array 'inventory'

inventory[i].name[0] = '\0';
// accessing a char array member inside part 'i'
We can think of struct arrays as tables, where the struct.members are the columns while each struct tag arr[] element is a row.

struct SQL Table Analogy.png

References