Struct (C programming language)
Encyclopedia
A struct in C programming language is a structured (record
) type that aggregates a fixed set of labelled objects, possibly of different types, into a single object.
A
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.
The primary use of a struct is for the construction of complex
datatypes, but in practice they are sometimes used to circumvent standard C conventions to create a kind of primitive subtyping
. For example, common Internet protocols rely on the fact that C compilers insert padding between struct fields in predictable ways; thus the code
is often assumed to work as expected, if the operate_on_ifoo function only accesses fields x and y of its argument.
For non contiguous or out of order members list designated initializer style may be used
Omitted elements are initialised to 0. The disadvantage of designated initializer style is that this feature is not defined for C++ programming language, according to C++11 standard
s can be used as shortcuts, for example:
Different users have differing preferences; proponents usually claim:
Without typedef:
With typedef:
If neither typedef were used in defining a function that takes a pointer to a type of the above function pointer, the following code would have to be used. Although valid, it becomes increasingly hard to read quickly.
However, there are a handful of disadvantages in using them:
Record (computer science)
In computer science, a record is an instance of a product of primitive data types called a tuple. In C it is the compound data in a struct. Records are among the simplest data structures. A record is a value that contains other values, typically in fixed number and sequence and typically indexed...
) type that aggregates a fixed set of labelled objects, possibly of different types, into a single object.
A
struct
declaration consists of a list of fields, each of which can have any type. The total storage required for a struct object is the sum of the storage requirements of all the fields, plus any internal padding.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.
The primary use of a struct is for the construction of complex
datatypes, but in practice they are sometimes used to circumvent standard C conventions to create a kind of primitive subtyping
Subtype
In programming language theory, subtyping or subtype polymorphism is a form of type polymorphism in which a subtype is a datatype that is related to another datatype by some notion of substitutability, meaning that program constructs, typically subroutines or functions, written to operate on...
. For example, common Internet protocols rely on the fact that C compilers insert padding between struct fields in predictable ways; thus the code
is often assumed to work as expected, if the operate_on_ifoo function only accesses fields x and y of its argument.
Struct initialization
There are two ways to initialize a structure. The C89-style initializers are used when contiguous members may be given.For non contiguous or out of order members list designated initializer style may be used
Omitted elements are initialised to 0. The disadvantage of designated initializer style is that this feature is not defined for C++ programming language, according to C++11 standard
Assignment
The following assignment of a struct to another struct does what one might expect. It is not necessary to usememcpy
to make a duplicate of a struct type. The memory is already given and zeroed by just declaring a variable of that type regardless of member initialization. This should not be confused with the requirement of memory management when dealing with a pointer to a struct.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. 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).typedef
TypedefTypedef
typedef is a keyword in the C and C++ programming languages. The purpose of typedef is to assign alternative names to existing types, most often those whose standard declaration is cumbersome, potentially confusing, or likely to vary from one implementation to another.Under C convention , types...
s can be used as shortcuts, for example:
Different users have differing preferences; proponents usually claim:
- shorter to write
- can simplify more complex type definitions, such as 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:
If neither typedef were used in defining a function that takes a pointer to a type of the above function pointer, the following code would have to be used. Although valid, it becomes increasingly hard to read quickly.
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)
- 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
- C language union
- Composite data type