Structures

A structure groups related data under named fields: ecu.name = 'VCU'; ecu.address = 2016;.

Concept

A structure groups related data under named fields: ecu.name = 'VCU'; ecu.address = 2016;. Fields can hold any type, including other structs.

s.field = value or s = struct('name', 'VCU', 'voltage', 12.6) s.name, dynamic field s.(fieldName)

fieldnames(s), isfield(s, 'x'), isstruct(s) s = rmfield(s, 'x') Struct array

bus(1).name = 'VCU'; bus(2).name = 'BMS'; Collect a field [bus.voltage] (numeric), {bus.name} (text)

Note: struct('code', {'A', 'B'}) with cell values creates a struct *array* (one element per cell). To store a cell array in one field, wrap it: struct('names', {{'A', 'B'}}).

Why It Matters

Structs model records — an ECU, a test result, a vehicle configuration — making code readable (cfg.bitrate instead of cfg(3)). Measurement data imported from MAT files and JSON (jsondecode) arrives as structs.

Syntax

cfg.bitrate = 500e3; cfg.channel = 1;
names = {bus.name};              % cell array of all names
v = [bus.voltage];               % numeric vector of all voltages
low = bus(v < 12);               % filter a struct array

Example

15.1 Fields, dynamic fields, struct arrays and nesting

ecu.name = 'VCU';
ecu.address = hex2dec('7E0');
ecu.firmware = '2.4.1';
ecu.dtcs = {'P0A80'};
disp(ecu)
fprintf('fields: %s\n', strjoin(fieldnames(ecu)', ', '))
fprintf('isfield(ecu, ''address'') = %d, address = 0x%X\n', isfield(ecu, 'address'), ecu.address)

f = 'firmware';
fprintf('dynamic field ecu.(f) = %s\n', ecu.(f))

bus(1) = struct('name', 'VCU', 'voltage', 12.6);    % struct array
bus(2) = struct('name', 'BMS', 'voltage', 11.2);
bus(3) = struct('name', 'GW',  'voltage', 12.9);
v = [bus.voltage];                                  % collect a field from all elements
fprintf('voltages: %s, lowest: %s\n', mat2str(v), bus(v == min(v)).name)
low = bus([bus.voltage] < 12);
fprintf('ECUs below 12 V: %s\n', strjoin({low.name}, ', '))

ecu = rmfield(ecu, 'dtcs');
s = struct('code', {'P0A80', 'U0100'}, 'active', {true, false});   % cell values create a 1x2 struct array
fprintf('struct array size %s, second code %s, active flags %s\n', mat2str(size(s)), s(2).code, mat2str([s.active]))
nested.vehicle.vin = 'EHBAUREV250000001';
nested.vehicle.ecus = bus;
fprintf('nested access: %s has %d ECUs\n', nested.vehicle.vin, numel(nested.vehicle.ecus))

Expected Result

[bus.voltage] collected one field from every element into a vector, which made filtering the struct array a one-liner. (The layout of disp(ecu) differs slightly between MATLAB and Octave.)

name = VCU
    address = 2016
    firmware = 2.4.1
    dtcs =
    {
      [1,1] = P0A80
    }

fields: name, address, firmware, dtcs
isfield(ecu, 'address') = 1, address = 0x7E0
dynamic field ecu.(f) = 2.4.1
voltages: [12.6 11.2 12.9], lowest: BMS
ECUs below 12 V: BMS
struct array size [1 2], second code U0100, active flags [true false]
nested access: EHBAUREV250000001 has 3 ECUs

Common Mistakes

Misspelling a field name on assignment silently creates a new field.

The struct() cell-value rule creating an array when a single struct was intended.

Deeply nested structs that are hard to navigate.

Struct arrays whose elements have different field sets (not allowed).

Best Practices

Build structs in one place (a constructor-like function) so all fields exist.

Use struct arrays for records of the same shape; consider tables (MATLAB) for tabular data.

Use isfield before reading optional fields.

Interview Relevance

Medium: "struct vs cell array?", "what is a dynamic field name?", "how do you extract a field from a struct array?".

Practice Questions

Create a struct array of 4 sensors with name, unit and reading; print those above a threshold.

Sort a struct array by one field.

Write a function that returns default settings as a struct and merges user overrides.

Convert a struct to a cell array with struct2cell and back.

Quick Quiz

Q1. (Multiple choice) s.(f) where f = 'voltage' accesses: A) A field literally named f B) The field named by the text in f C) An error D) A function Answer: B.

Q2. (Predict the output) size(struct('code', {'P0A80', 'U0100'}, 'active', {true, false}))

Answer: 1 2 — a struct array (verified).

Q3. (True/False) [bus.voltage] works when voltage holds scalar numbers.

Answer: True (verified).

Q4. (Find the bug) cfg.bitrate = 500e3; ... if cfg.bitRate > 250e3 fails.

Answer: Field names are case-sensitive (bitrate vs bitRate).

Coding Challenge

Create a struct array of three ECUs (name, firmware, voltage), sort it by voltage (ascending) and print the names in that order.

ecus = struct('name', {'VCU', 'BMS', 'GW'}, 'firmware', {'2.4.1', '1.9.0', '3.2.0'}, 'voltage', {12.6, 11.2, 12.9});
[~, order] = sort([ecus.voltage]);
sorted = ecus(order);
fprintf('by voltage: %s\n', strjoin({sorted.name}, ' < '))