In the C programming language, (referring to a structure) is the keyword used to define a composite, a.k.a. record, data type a named set of values that occupy a block of memory. It allows for the different values to be accessed via a single identifier, often a pointer. A struct can contain other data types so is used for mixed-data-type records. For example, a bank customer struct might contain fields for the customer's name, address, telephone number, and balance.
A struct occupies a contiguous block of memory, usually delimited (sized) by word-length boundaries. It corresponds to the similarly named feature available in some assemblers for Intel processors. Being a block of contiguous memory, each field within a struct is located at a certain fixed offset from the start.
The operator results in the number of bytes needed to store a particular struct, just as it does for a primitive data type. The alignment of particular fields in the struct (with respect to word boundaries) is implementation-specific and may include padding. Modern compilers typically support the <code>#pragma pack</code> directive, which sets the size in bytes for alignment.
The C struct feature was derived from the same-named concept in ALGOL 68.
Declaration
The following simple example depicts declaring a struct named <code>MyStruct</code>, with two fields of types <code>Type1</code> and <code>Type2</code> respectively.
<syntaxhighlight lang="C">
struct MyStruct {
Type1 member1;
Type2 member2;
};
</syntaxhighlight>
The added name <code>MyStruct</code> is optional in some contexts.
Members may possibly be padded for memory alignment, and thus it is often recommended to order fields from largest to smallest size for efficient memory usage.
A function may directly return a struct, although this is often not efficient at run-time. Since C99, a struct may also end with a flexible array member.
Structs can be composed of other structs:
<syntaxhighlight lang="c">
struct Date {
int year;
int month;
int day;
};
struct Birthday {
char name[50];
struct Date dob;
};
</syntaxhighlight>
It is legal to declare an anonymous struct within a struct, but it cannot be named in C (as there is no notion of nested types, unlike C++ where nesting named structs is legal).
<syntaxhighlight lang="c">
struct Person {
char name[50];
int age;
struct {
char city[50];
int zip;
} addr;
};
</syntaxhighlight>
A struct containing a pointer to a struct of its own type is commonly used to build linked data structures:
<syntaxhighlight lang=C>
struct LinkedList {
void* item; // stores the current item
struct LinkedList* next; // stores the next list, or NULL if nothing next
};
</syntaxhighlight>
Circularly referencing between two structs must be done using a forward declaration and pointers:
<syntaxhighlight lang="c">
struct B;
struct A {
struct B* b;
};
struct B {
struct A* a;
};
</syntaxhighlight>
Typedef
Via the keyword <code>typedef</code>, a struct type can be referenced without using the <code>struct</code> keyword. However, some programming style guides advise against this, claiming that it can obfuscate the type.
For example:
<syntaxhighlight lang="C">
typedef struct MyStruct {
Type1 member1;
Type2 member2;
} Thing;
// struct MyStruct can now be referred to as 'Thing'
Thing thing;
</syntaxhighlight>
In C++ code, the type may be referred to as either <code>struct Thing</code> or <code>Thing</code> (without any need for <code>typedef</code>). <code>typedef</code> in C++ is also superseded by the <code>using</code> statement, which can alias types that have templates.
Initialization
Considering the struct declaration:
<syntaxhighlight lang="c">
struct Point {
int x;
int y;
};
</syntaxhighlight>
There are three ways to initialize a structure:
C89-style initializers are used when contiguous members may be given. For example:
<syntaxhighlight lang="c">
struct Point a = { 1, 2 };
</syntaxhighlight>
For non contiguous or out of order members list, the designated initializer style (introduced in C99) may be used. For example:
<syntaxhighlight lang="c">
struct Point a = { .x = 1, .b = 2 };
// May initialize fields out of order too
struct Point b = { .y = 4, .x = -3 };
</syntaxhighlight>
If an initializer is given or if the object is statically allocated, omitted elements are initialized to 0.
A third way of initializing a structure is to copy the value of an existing object of the same type. For example:
<syntaxhighlight lang="c">
struct Point b = a;
</syntaxhighlight>
Copy
The state of a struct can be copied to another instance. A compiler might use <code>memcpy()</code> to copy the bytes of the memory block.
<syntaxhighlight lang="c">
struct Point a = { 1, 3 };
struct Point b;
b = a;
</syntaxhighlight>
Bit fields
Structs may also use bit fields to allow fields to share the same storage units, but layouts are implementation-defined.
<syntaxhighlight lang="c">
struct Properties {
// three fields can be compactly packed in one byte
unsigned char visible : 1; // a occupies 1 bit
unsigned char color : 3; // b occupies 3 bits
unsigned char size : 4; // c occupies 4 bits
};
</syntaxhighlight>
Pointers
Pointers can be used to refer to a <code>struct</code> by its address. This is useful for passing a struct to a function to avoid the overhead of copying the struct. The <code>-></code> operator dereferences the pointer (left operand) and accesses the value of a struct member (right operand).
<syntaxhighlight lang="c">
struct Point p = { 3, 7 };
int x = p.x;
p.x = 10;
struct Point* pp = &p;
x = pp->x;
pp->x = 8;
</syntaxhighlight>
Functions may take a struct as a parameter by value, but this is expensive as it copies the entire struct. Meanwhile, passing it by pointer is often preferable as the size of a pointer is known (typically 4 or 8 bytes).
<syntaxhighlight lang="c">
- include <stdio.h>
// a larger struct which may carry a lot of data
struct Student {
char name[50];
unsigned int id;
unsigned int semester;
float gpa;
};
// passing by value
void print_student(struct Student s) {
printf("Name: %s, ID: %d, in semester %d, with GPA: %.2f\n", s.name, s.id, s.semester, s.gpa);
}
// passing by pointer
void print_student(struct Student* s) {
printf("Name: %s, ID: %d, in semester %d, with GPA: %.2f\n", s->name, s->id, s->semester, s->gpa);
}
</syntaxhighlight>
In other languages
Crystal (programming language), D, Go, Julia, Rust, Swift and Zig have structs.
C++
In C++, struct is essentially the same as for C, but also with methods. Further, a class is the same as a struct but with different default visibility: class members are private by default, whereas struct members are public by default.
.NET
.NET languages have a feature similar to struct in C called <code>struct</code> in C# and <code>Structure</code> in Visual Basic .NET). This construct provides many features of a class, but acts as a value type instead of a reference type. For example, when passing a .NET struct to a function, the value is copied so that changes to the input parameter do not affect the value passed in.
