A struct in the C programming language (and many derivatives) is a composite data type (or record) declaration that defines a physically grouped list of variables to be placed under one name in a block of memory, allowing the different variables to be accessed via a single pointer, or the struct declared name which returns the same address. The struct data type can contain many other complex and simple data types in an association, so it is a natural type for organizing mixed-data-type records such as lists of hard-drive directory entries (file length, name, extension, physical (cylinder, disk, head indexes) address, etc.), or other mixed-type records (patient names, address, telephone... insurance codes, balance, etc.).
The C struct directly references a contiguous block of physical memory, usually delimited (sized) by word-length boundaries. It corresponds to the similarly named feature available in some assemblers for Intel processors. Language implementations that could utilize half-word or byte boundaries (giving denser packing, using less memory) were considered advanced in the mid-eighties. Being a block of contiguous memory, each field within a struct is located at a certain fixed offset from the start. As an illustration, many BASIC interpreters once fielded a string data struct organization with one value recording string length, one indexing (cursor value of) the previous line, one pointing to the string data.
Because the contents of a struct are stored in contiguous memory, the sizeof operator must be used to get the number of bytes needed to store a particular type of struct, just as it can be used for primitives. The alignment of particular fields in the struct (with respect to word boundaries) is implementation-specific and may include padding, although modern compilers typically support the #pragma pack directive, which changes the size in bytes used for alignment.[1]
In the C++ language, a struct is identical to a C++ class but a difference in the default visibility exists: class members are by default private, whereas struct members are by default public.
In other languages
The struct data type in C was derived from the ALGOL 68 struct data type.[2]
Like its C counterpart, the struct data type in C# (Structure in Visual Basic .NET) is similar to a class. The biggest difference between a struct and a class in these languages is that when a struct is passed as an argument to a function, any modifications to the struct in that function will not be reflected in the original variable (unless pass-by-reference is used).[3]
This differs from C++, where classes or structs can be statically allocated or dynamically allocated either on the stack (similar to C#) or on the heap, with an explicit pointer. In C++, the only difference between a struct and a class is that the members and base classes of a struct are public by default. (A class defined with the class keyword has private members and base classes by default.)
Golang also uses structs.[4][5]
Declaration
The general syntax for a struct declaration in C is:
Here tag_name is optional in some contexts.
Such a struct declaration may also appear in the context of a typedef declaration of a type alias or the declaration or definition of a variable:
Often, such entities are better declared separately, as in:
For example:
defines a type, referred to as struct account. To create a new variable of this type, we can write
which has an integer component, accessed by s.account_number, and a floating-point component, accessed by s.balance, as well as the first_name and last_name components. The structure s contains all four values, and all four fields may be changed independently.
A pointer to an instance of the "account" structure will point to the memory address of the first variable, "account_number". The total storage required for a struct object is the sum of the storage requirements of all the fields, plus any internal padding.
Struct initialization
There are three ways to initialize a structure. For the struct type
C89-style initializers are used when contiguous members may be given.[6]
For non contiguous or out of order members list, designated initializer style[7] may be used
If an initializer is given or if the object is statically allocated, omitted elements are initialized to 0.[8]
A third way of initializing a structure is to copy the value of an existing object of the same type
Assignment
The following assignment of a struct to another struct will copy as one might expect. Depending on the contents, a compiler might use memcpy() in order to perform this operation.
Pointers to struct
Pointers can be used to refer to a struct by its address. This is particularly useful for passing structs to a function by reference or to refer to another instance of the struct type as a field. The pointer can be dereferenced just like any other pointer in C, using the * operator. There is also a -> operator in C which dereferences the pointer to struct (left operand) and then accesses the value of a member of the struct (right operand).
C does not allow recursive declaration of struct; a struct can not contain a field that has the type of the struct itself. But pointers can be used to refer to an instance of it:
Here the instance el would contain a point with coordinates 3 and 7. Its next pointer would be a null pointer since the initializer for that field is omitted. The instance le in turn would have its own point and its next pointer would refer to el.
typedef
{{main|typedef}}
Typedefs can be used as shortcuts, for example:
Different users have differing preferences; proponents usually claim:
shorter to write
can simplify more complex type definitions
can be used to forward declare a struct type
As an example, consider a type that defines a pointer to a function that accepts pointers to struct types and returns a pointer to struct:
Without typedef:
With typedef:
A common naming convention for such a typedef is to append a "_t" (here point_t) to the struct tag name, but such names are reserved by POSIX so such a practice should be avoided. A much easier convention is to use just the same identifier for the tag name and the type name:
Without typedef a function that takes function pointer the following code would have to be used. Although valid, it becomes increasingly hard to read.
Here a second typedef for a function pointer type can be useful
Now with the two typedefs being used the complexity of the function signature is drastically reduced.
However, there are a handful of disadvantages in using them:
They pollute the main namespace (see below), however this is easily overcome with prefixing a library name to the type name.
Harder to figure out the aliased type (having to scan/grep through code), though most IDEs provide this lookup automatically.
Typedefs do not really "hide" anything in a struct or union — members are still accessible (account.balance). To really hide struct members, one needs to use 'incompletely-declared' structs.
See also
Bit field
Composite data type
Flexible array member
Passive data structure
Union type
References
1. ^[https://stackoverflow.com/questions/2748995/c-struct-memory-layout C struct memory layout? - Stack Overflow] 2. ^{{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 | ref = harv | 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.}} 3. ^Parameter passing in C# 4. ^https://yourbasic.org/golang/structs-explained/ 5. ^https://gobyexample.com/structs 6. ^{{cite book | first = Al | last = Kelley | first2 = Ira | last2 = Pohl | year = 2004 | url = http://users.soe.ucsc.edu/~pohl/abc4.html | edition = Fourth | title = A Book On C: Programming in C | isbn = 0-201-18399-4 | pages = 418 }} 7. ^{{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}} 8. ^{{cite web | url=http://c0x.coding-guidelines.com/6.7.8.html#1695 | title=The New C Standard, §6.7.8 Initialization}}