Definition of Structs
Explore the definition of structs in the D programming language and understand how they allow you to create new types by combining related variables. Learn to use structs to simplify function parameters, return multiple values, and organize complex data effectively in your programs.
We'll cover the following...
Chapter overview
Fundamental types are not suitable to represent higher-level concepts. For example, although a value of type int is suitable to represent the hour of the day, two int variables would be more suitable together to represent a point in time: one for the hour and the other for the minute.
Structs are the features that allow defining new types by combining already existing types. The new type is defined by the struct keyword. By this definition, structs are user-defined types. Most of the content of this chapter is directly applicable to classes as well, especially the concept of combining existing types to define a new type.
This chapter covers only the basic features of structs. You will see more of structs in the following lessons:
To understand how useful structs are, let’s define a function addDuration():
void addDuration(int startHour, int startMinute,
int durationHour, int durationMinute,
out int resultHour, out int resultMinute) {
resultHour = startHour + durationHour;
resultMinute = startMinute +
durationMinute; resultHour += resultMinute / 60;
resultMinute %= 60;
resultHour %= 24;
}
Note: We will ignore the
in,out, andunittestblocks in this chapter to keep the code samples short.
Although the function above clearly takes six parameters, it is conceptually taking only three bits of information for the starting time, the duration, and the result (when the three pairs of parameters are considered).
Structs definition
The struct keyword defines a new type by combining variables that are related in some way:
The code above defines a new type named TimeOfDay, which consists of two variables named hour and minute. That definition allows the new TimeOfDay type to be used in the program just like any other type. The following code demonstrates how similar its use is to a fundamental type:
The syntax of struct definition is the following:
struct TypeName {
// ... member variables and functions ...
}
The variables that a struct combines are called its members. According to this
definition, TimeOfDay has two members: hour and minute.
struct defines a type, not a variable
There is an important distinction here. The curly brackets of struct definitions may give the incorrect impression that the struct members start and end their lives inside that scope. This is not true.
Member definitions are not variable definitions:
The definition of a struct determines the types and the names of the members that the objects of that struct will have. Those member variables will be constructed as parts of TimeOfDay objects that take part in the program:
The variables of struct and class types are called objects.
Coding convenience
Being able to combine the concepts of hour and minute together as a new type is a great convenience. For example, the function above can be rewritten in a more meaningful way by taking three TimeOfDay parameters instead of the existing six int parameters:
void addDuration(TimeOfDay start, TimeOfDay duration, out TimeOfDay result) {
// ...
}
Note: It is not normal to add two variables that represent two points in time. For example, it is meaningless to add the lunchtime 12:00 to the breakfast time 7:30. It would make more sense to define another type, appropriately called
Duration, and to add objects of that type toTimeOfDayobjects. Despite this design flaw, we will continue using onlyTimeOfDayobjects in this chapter and introduceDurationin a later chapter.
As you know, functions return up-to a single value. That is precisely the reason why the earlier definition of addDuration() was taking two out parameters: It could not return the hour and minute information as a single value.
Structs remove this limitation as well. Since multiple values can be combined as a single struct type, functions can return an object of such a struct, effectively returning multiple values at once. addDuration() can now be defined as returning its result:
TimeOfDay addDuration(TimeOfDay start, TimeOfDay duration) {
TimeOfDay result;
// ...
return result;
}
Consequently, addDuration() now becomes a function that produces a value, as opposed to being a function that has side effects. As you know, producing results is preferred over having side effects.
Structs can be members of other structs. For example, the following struct has two TimeOfDay members:
In turn, Meeting can be a member of another struct. Assuming that there is also the Meal struct:
Accessing the members
Struct members are used like any other variable. The only difference is that the actual struct variable name and a dot must be specified before the name of the member:
start.hour = 10;
The line above assigns the value 10 to the hour member of the start object.
Let’s rewrite the addDuration() function with what we have seen so far:
Notice that the names of the variables are much shorter in this version of the function: start, duration, and result. Additionally, instead of using complex names like startHour, it is possible to access struct members through their respective struct variables as in start.hour.
Here is a code that uses the new addDuration() function. Given the start time and the duration, the following code calculates when a class period at a school would end:
Above, main() has been written only by what we have seen so far. We will make this code even shorter and cleaner soon.