# `struct`

For putting many values with different data types together in a single variable.

## General syntax

```
struct TagName {
    Type member1;
    Type member2;
};
```

:::{wpd} struct
:id: struct (C programming language)
defines a composite data type – a named set of values that occupy a block of memory
:::

## Tagged `struct`

```c
struct Shape {
  int x, y;
  char *name;
}; // struct definition is similar to `enum`

struct Shape s = {.x = 0, .y = 0, .name = "banana"};
// Pay attention to `.`s
// Alternatively: {0, 0, "banana"} in short

int main() {
  s.x = 5;
  // Access elements with `.`

  struct Shape s2 = {};
  // Can be initialized similar to arrays
}
```

:::{activity} Comparing `struct`s
:label: comparing-structs
1. Define a `struct` named `Person` with two members:
   - `age`
   - `gender`
1. Create two variables using the `struct`: `p1`, `p2`.
1. Write a function called `are_equal(a, b)` that checks whether the two have the same data.
:::
<!-- equality does not work -->

:::{note}
As a convention, I use PascalCase for tags (and also `typedef`, `enum`, `union`, etc). It seems to be more common.

You will see also snake_case and `_t` suffix in other code. The most important is to stick to the conventions of a code base or project.
:::

## Anonymous `struct`

We can also declare a variable directly like an `enum`, but then reusing it becomes more difficult:

Above example using an anonymous `struct` and `typeof`:
```c
struct {
  int x, y;
  char *name;
} s = {.x = 0, .y = 0, .name = "banana"};

int main() {
  s.x = 5;
  typeof(s) s2 = {};
}
```

:::{tip}
Anonymous `struct` is useful if you plan not to use the `struct` for further variables.

Typically you can stick to the tagged version.
:::

## pass-by-?


::::{activity} Passing a `struct` to a function
 The code below stores same values in an array and a struct. Analyze the following code and its output. Why are `a` and `s` not the same in the end?

:::{literalinclude} ../code/struct_vs_arr_pass_by_address_or_value.c
:language: c
:::
Output
:::{literalinclude} ../code/struct_vs_arr_pass_by_address_or_value.txt
:language: text
::::
<!-- compared to arrays structs are passed by value -->

:::{tip}
Pay attention when you are passing large structs. Structs should be typically passed by address.
:::

:::{activity} Modifying `struct` members
Modify `set_first_element_to_zero_struct` so the struct is passed by address.
:::
<!--
void set_first_element_to_zero_struct(typeof(s) *s) { (*s).a = 0; }
-->

## Accessing members of a `struct` pointer using `->`

`->` is the arrow operator.

```c
struct Shape {
  int x, y;
  char *name;
};

struct Shape s;
typeof(s) *sp = &s;

int main() {
  (*sp).x = 1;  // ❌ this is silly
  sp->x = 1;  // ✅
}
```

:::{activity} 
Modify your code again to use the dereference operator.
:::

(self-referential-struct)=
## Self-referential `struct`

`struct` can point to itself. This is a superpower 💪:

:::{literalinclude} ../code/self_referential_struct_linked_list.c
:language: c
:::
:::{literalinclude} ../code/self_referential_struct_linked_list.txt
:language: text
:::

:::{commons-figure} https://commons.wikimedia.org/wiki/File:Singly-linked-list.svg
:figwidth: 35%
:align: right
A linked list. Each node contains data (e.g., 12) and a pointer to the next node.
:::

We can build dynamic linked lists using this superpower.

We will cover linked lists [in a future section](linked-list) more in detail.

:::{card} 🤔 Question to ponder
How can we create an endless string using the linked list above?
<!-- instead of nullptr, use &head , but requires predeclaration-->
:::