{{Short description|C keyword for defining a structured data type}} {{lowercase}} In the C programming language, '''{{mono|struct}}''' (referring to a '''structure''') is the keyword used to define a composite, a.k.a. record, data type {{endash}} 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. {{clarify|reason=What does type of allocation strategy matches to?|date=January 2026}} 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 {{mono|sizeof}} 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.<ref>{{Cite web|url=https://stackoverflow.com/questions/2748995/struct-memory-layout-in-c|title=Struct memory layout in C|website=Stack Overflow}}</ref>
The C struct feature was derived from the same-named concept in ALGOL 68.<ref name="sigplan">{{cite journal | first = Dennis M.| last = Ritchie | authorlink = Dennis Ritchie | title = The Development of the C Language | date = March 1993 | journal = ACM SIGPLAN Notices | volume = 28 | issue = 3 | pages = 201–208 | url = http://www.bell-labs.com/usr/dmr/www/chist.html | doi = 10.1145/155360.155580 | quote = The scheme of type composition adopted by C owes considerable debt to Algol 68, although it did not, perhaps, emerge in a form that Algol's adherents would approve of. The central notion I captured from Algol was a type structure based on atomic types (including structures), composed into arrays, pointers (references), and functions (procedures). Algol 68's concept of unions and casts also had an influence that appeared later.| doi-access = free }}</ref>
== 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 ===
{{Main|Typedef}} Via the keyword <code>typedef</code>, a struct type can be referenced without using the <code>struct</code> keyword. However, some<ref>{{Cite web|url=https://www.kernel.org/doc/html/v4.10/process/coding-style.html#typedefs|title=Linux kernel coding style}}</ref> 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.<ref>{{cite book | first1 = Al | last1 = Kelley | first2 = Ira | last2 = Pohl | year = 2004 | url = https://archive.org/details/bookoncprogrammi00kell/page/418 | edition = Fourth | title = A Book On C: Programming in C | isbn = 0-201-18399-4 | pages = [https://archive.org/details/bookoncprogrammi00kell/page/418 418] | url-access = registration }}</ref> 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.<ref>{{cite web | url=https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.cbclx01/strin.htm | title=IBM Linux compilers. Initialization of structures and unions}}</ref> 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 ==
{{Main|Bit field}} 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),<ref>{{cite web |title=Structs - Crystal |url=https://crystal-lang.org/reference/1.19/syntax_and_semantics/structs.html |website=crystal-lang.org |access-date= 8 February 2026}}</ref> D,<ref>{{cite web |title=Structs, Unions - D Programming Language |url=https://dlang.org/spec/struct.html |website=dlang.org |access-date=8 July 2025}}</ref> Go, Julia,<ref>{{cite web |title=Types · The Julia Language |url=https://docs.julialang.org/en/v1/manual/types/#Composite-Types |website=docs.julialang.org |language=en}}</ref> Rust, Swift and Zig<ref>{{cite web |title=Structs {{!}} zig.guide |url=https://zig.guide/language-basics/structs/ |website=zig.guide |access-date=8 July 2025 |language=en |date=20 April 2024}}</ref> 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 {{endash}} 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.<ref>{{Cite web|url=http://yoda.arachsys.com/csharp/parameters.html|title=Parameter passing in C#}}</ref>
== See also == * {{Annotated link|Bit field}} * {{Annotated link|Flexible array member}} * {{Annotated link|Passive data structure}} * {{Annotated link|Union type}}
== References == {{reflist}}
Category:C (programming language)