Initialization of structures and unions
An initializer for a structure is a brace-enclosed comma-separated list of values, and for a union, a brace-enclosed single value. The initializer is preceded by an equal sign (=).
C99 and C++ allow the initializer for an automatic member variable of a union or structure type to be a constant or non-constant expression.
The initializer for a static member variable of a union or structure type must be a constant expression or string literal. See Static data members (C++ only) for more information.
There are two ways to specify initializers for structures
and unions:
- With C89-style initializers, structure members must be initialized in the order declared, and only the first member of a union can be initialized.
- Using designated initializers, a C99 feature which allows you to name members to be initialized, structure members can be initialized in any order, and any (single) member of a union can be initialized. Designated initializers are described in detail in Designated initializers for aggregate types (C only).
Using C89-style initialization, the following example
shows how you would initialize the first union member birthday of
the union variable people:
union {
char birthday[9];
int age;
float weight;
} people = {"23/07/57"};
Using a designated
initializer in the same example, the following initializes the second
union member age :
union {
char birthday[9];
int age;
float weight;
} people = { .age = 14 };
The following definition shows a completely initialized
structure:
struct address {
int street_no;
char *street_name;
char *city;
char *prov;
char *postal_code;
};
static struct address perm_address =
{ 3, "Savona Dr.", "Dundas", "Ontario", "L4B 2A1"};
The
values of perm_address are: Member | Value |
---|---|
perm_address.street_no | 3 |
perm_address.street_name | address of string "Savona Dr." |
perm_address.city | address of string "Dundas" |
perm_address.prov | address of string "Ontario" |
perm_address.postal_code | address of string "L4B 2A1" |
Unnamed structure or union members do not participate
in initialization and have indeterminate value after initialization.
Therefore, in the following example, the bit field is not initialized,
and the initializer 3 is applied to member b:
struct {
int a;
int :10;
int b;
} w = { 2, 3 };
You do not have to initialize all members of
structure variables. If a structure variable does not have an initializer,
the initial values of the structure members depend on the storage
class associated with the structure variable:
- If a structure variable has static storage, its members are implicitly initialized to zero of the appropriate type.
- If a structure variable has automatic storage, its members have no default initialization.
If a structure variable is partially initialized, all
the uninitialized structure members are implicitly initialized to
zero no matter what the storage class of the structure variable is.
See the following example:
struct one {
int a;
int b;
int c;
};
void main(){
struct one z1; // Members in z1 do not have default initial values.
static struct one z2; // z2.a=0, z2.b=0, and z2.c=0.
struct one z3 = {1}; // z3.a=1, z3.b=0, and z3.c=0.
}
In this example, structure variable z1 has
automatic storage, and it does not have an initializer, so none of
the members in z1 have default initial values. Structure
variable z2 has static storage, and all its members
are implicitly initialized to zero. Structure variable z3 is
partially initialized, so all its uninitialized members are implicitly
initialized to zero.You do not have to initialize all members of a union. The default initializer for a union with static storage is the default for the first component. A union with automatic storage has no default initialization.
To initialize only the third and fourth members of the temp_address variable,
you could use a designated initializer list, as follows:
struct address {
int street_no;
char *street_name;
char *city;
char *prov;
char *postal_code;
};
struct address temp_address =
{ .city = "Hamilton", .prov = "Ontario" };