Initializing structures is similar to initializing arrays—the elements are simply listed inside a pair of braces, with each element separated by a comma.
To initialize the date structure variable today to July 2, 2005, the statement
struct date today = { 7, 2, 2005 };
can be used. The statement
struct time this_time = { 3, 29, 55 };
defines the struct time variable this_time and sets its value to 3:29:55 a.m. As with other variables, if this_time is a local structure variable, it is initialized each time the function is entered. If the structure variable is made static (by placing the keyword static in front of it), it is only initialized once at the start of program execution. In either case, the initial values listed inside the curly braces must be constant expressions.
As with the initialization of an array, fewer values might be listed than are contained in the structure. So the statement
struct time time1 = { 12, 10 };
sets time1.hour to 12 and time1.minutes to 10 but gives no initial value to time1.seconds. In such a case, its default initial value is undefined.
You can also specify the member names in the initialization list. In that case, the gen- eral format is
.member = value
This method enables you to initialize the members in any order, or to only initialize specified members. For example,
struct time time1 = { .hour = 12, .minutes = 10 };
sets the time1 variable to the same initial values as shown in the previous example. The statement
struct date today = { .year = 2004 };
sets just the year member of the date structure variable today to 2004.
1. Compound Literals
You can assign one or more values to a structure in a single statement using what is know as compound literals. For example, assuming that today has been previously declared as a struct date variable, the assignment of the members of today as shown in
Program 9.1 can also be done in a single statement as follows:
today = (struct date) { 9, 25, 2004 };
Note that this statement can appear anywhere in the program; it is not a declaration statement. The type cast operator is used to tell the compiler the type of the expression, which in this case is struct date, and is followed by the list of values that are to be assigned to the members of the structure, in order. These values are listed in the same way as if you were initializing a structure variable.
You can also specify values using the .member notation like this:
today = (struct date) { .month = 9, .day = 25, .year = 2004 };
The advantage of using this approach is that the arguments can appear in any order. Without explicitly specifying the member names, they must be supplied in the order in which they are defined in the structure.
The following example shows the dateUpdate function from Program 9.4 rewritten to take advantage of compound literals:
// Function to calculate tomorrow’s date – using compound literals
struct date dateUpdate (struct date today)
{
struct date tomorrow;
int numberOfDays (struct date d);
if ( today.day != numberOfDays (today) )
tomorrow = (struct date) { today.month, today.day + 1, today.year };
else if ( today.month == 12 ) // end of year
tomorrow = (struct date) { 1, 1, today.year + 1 };
else // end of month
tomorrow = (struct date) { today.month + 1, 1, today.year };
return tomorrow;
}
Whether you decide to use compound literals in your programs is up to you. In this case, the use of compound literals makes the dateUpdate function easier to read.
Compound literals can be used in other places where a valid structure expression is allowed. This is a perfectly valid, albeit totally impractical example of such a use:
nextDay = dateUpdate ((struct date) { 5, 11, 2004} );
The dateUpdate function expects an argument of type struct date, which is precisely the type of compound literal that is supplied as the argument to the function.
Source: Kochan Stephen G. (2004), Programming in C: A Complete Introduction to the C Programming Language, Sams; Subsequent edition.