Structs
A struct is a data structure that can contain multiple fields. A struct can be used to group related data together. For example, the following struct can be used to represent a 2D point:
struct Point {
int x;
int y;
}
Bit-fields
It is also possible to declare a field with a bit-width. This is useful if you want to read data from a peripheral, such as a mouse. For example, the following struct can be used to read the position of a mouse, and the state of its left and right buttons:
struct MouseInput {
int y : 7;
int x : 7;
int left : 1;
int right : 1;
}
Note: When declaring a field with a bit-width, the compiler will automatically add bit-wise operations to get and set the value of the field. This means that the field will be slower to access than a normal field.
It is not recommended to use bit-fields unless you are reading data from a peripheral.
Bit offsets
Bit-fields are aligned by 16 bits. When declaring a bit-field, the compiler will automatically calculate the offset of the field. For example:
struct Example {
int a : 8 // Offset 0 with 8 bits
int b : 8 // Offset 8 with 8 bits
int c : 8 // Offset 16 with 8 bits
}
The bit-fields must be aligned by 16 bits. For example, the following struct is invalid because the last field is over the 16 bit boundary:
// Note: the following example will not compile
struct InvalidExample {
int a : 7 // This is valid, offset 0 with 7 bits
int b : 7 // This is valid, offset 7 with 7 bits
int c : 7 // This is invalid, offset 14 with 7 bits: [14 + 7 =] 21 > 16
}
When a normal field is introduced, the offset is reset to the 16 bit boundary. For example:
struct Example {
int a : 7 // Offset 0, 7 bits
int b : 7 // Offset 7, 7 bits
int c // Reset, Offset 16, 16 bits
int d : 7 // Offset 32, 7 bits
}
Initializing structs
Structs can be initialized by using curly braces ({
and }
) to specify the values of the fields. For example:
struct Point {
int x;
int y;
}
// Create a point with the x value 1 and the y value 2
Point point = { 1, 2 }
It is also possible to initialize structs by specifying the name of the fields. For example:
struct Point {
int x;
int y;
}
// Create a point with the y value 2 and the x value 1
// Note: the order of the fields does not matter when initializing a struct
Point point = { y: 2, x: 1 }
Accessing fields
The fields of a struct can be accessed by using the dot (.
) operator. For example:
struct Point {
int x;
int y;
}
Point point = { 1, 2 }
// Access the x field of the point
int x = point.x
Nested structs
Structs can be nested inside other structs. For example:
struct Point {
int x;
int y;
}
struct Rectangle {
Point topLeft;
Point bottomRight;
}
Rectangle rectangle = {
topLeft: { x: 1, y: 2 },
bottomRight: { x: 3, y: 4 }
}
// Access the x field of the top left point of the rectangle
int x = rectangle.topLeft.x