11
Structs

Sometimes you need a variable to hold several related chunks of data. In C, you can do this with a structure, commonly called a struct. Each chunk of data is known as a member of the struct.

For example, consider a program that computes a person’s Body Mass Index, or BMI. BMI is a person’s weight in kilograms divided by the square of the person’s height in meters. (BMI is a very imprecise tool for measuring a person’s fitness, but it makes a fine programming example.)

Create a new project: a C Command Line Tool named BMICalc. Edit main.c to declare a struct named Person that has two members: a float named heightInMeters and an int named weightInKilos. Then create two Person structs:

#​i​n​c​l​u​d​e​ ​<​s​t​d​i​o​.​h​>​

/​/​ ​H​e​r​e​ ​i​s​ ​t​h​e​ ​d​e​c​l​a​r​a​t​i​o​n​ ​o​f​ ​t​h​e​ ​s​t​r​u​c​t​
s​t​r​u​c​t​ ​P​e​r​s​o​n​ ​{​
 ​ ​ ​ ​f​l​o​a​t​ ​h​e​i​g​h​t​I​n​M​e​t​e​r​s​;​
 ​ ​ ​ ​i​n​t​ ​w​e​i​g​h​t​I​n​K​i​l​o​s​;​
}​;​

i​n​t​ ​m​a​i​n​(​i​n​t​ ​a​r​g​c​,​ ​c​o​n​s​t​ ​c​h​a​r​ ​*​ ​a​r​g​v​[​]​)​
{​
 ​ ​ ​ ​s​t​r​u​c​t​ ​P​e​r​s​o​n​ ​m​i​k​e​y​;​
 ​ ​ ​ ​m​i​k​e​y​.​h​e​i​g​h​t​I​n​M​e​t​e​r​s​ ​=​ ​1​.​7​;​
 ​ ​ ​ ​m​i​k​e​y​.​w​e​i​g​h​t​I​n​K​i​l​o​s​ ​=​ ​9​6​;​

 ​ ​ ​ ​s​t​r​u​c​t​ ​P​e​r​s​o​n​ ​a​a​r​o​n​;​
 ​ ​ ​ ​a​a​r​o​n​.​h​e​i​g​h​t​I​n​M​e​t​e​r​s​ ​=​ ​1​.​9​7​;​
 ​ ​ ​ ​a​a​r​o​n​.​w​e​i​g​h​t​I​n​K​i​l​o​s​ ​=​ ​8​4​;​

 ​ ​ ​ ​p​r​i​n​t​f​(​"​m​i​k​e​y​ ​i​s​ ​%​.​2​f​ ​m​e​t​e​r​s​ ​t​a​l​l​​n​"​,​ ​m​i​k​e​y​.​h​e​i​g​h​t​I​n​M​e​t​e​r​s​)​;​
 ​ ​ ​ ​p​r​i​n​t​f​(​"​m​i​k​e​y​ ​w​e​i​g​h​s​ ​%​d​ ​k​i​l​o​g​r​a​m​s​​n​"​,​ ​m​i​k​e​y​.​w​e​i​g​h​t​I​n​K​i​l​o​s​)​;​
 ​ ​ ​ ​p​r​i​n​t​f​(​"​a​a​r​o​n​ ​i​s​ ​%​.​2​f​ ​m​e​t​e​r​s​ ​t​a​l​l​​n​"​,​ ​a​a​r​o​n​.​h​e​i​g​h​t​I​n​M​e​t​e​r​s​)​;​
 ​ ​ ​ ​p​r​i​n​t​f​(​"​a​a​r​o​n​ ​w​e​i​g​h​s​ ​%​d​ ​k​i​l​o​g​r​a​m​s​​n​"​,​ ​a​a​r​o​n​.​w​e​i​g​h​t​I​n​K​i​l​o​s​)​;​
 ​ ​ ​ ​r​e​t​u​r​n​ ​0​;​
}​

Notice that you access the members of a struct using a period (stylish programmers like to say dot). Build and run the program and confirm the output.

Here is the frame for main() after the struct’s members have been assigned values.

Figure 11.1  Frame after member assignments

Frame after member assignments

Most of the time, you use a struct declaration over and over again. So it is common to create a typedef for the struct type. A typedef defines an alias for a type declaration and allows you to use it more like the usual data types. Change main.c to create and use a typedef for struct Person. Notice that the code to replace is shown struck-through.

#​i​n​c​l​u​d​e​ ​<​s​t​d​i​o​.​h​>​
/​/​ ​H​e​r​e​ ​i​s​ ​t​h​e​ ​d​e​c​l​a​r​a​t​i​o​n​ ​o​f​ ​t​h​e​ ​s​t​r​u​c​ts​t​r​u​c​t​ ​P​e​r​s​o​n​ ​{​
 ​ ​ ​ ​f​l​o​a​t​ ​h​e​i​g​h​t​I​n​M​e​t​e​r​s​;​
 ​ ​ ​ ​i​n​t​ ​w​e​i​g​h​t​I​n​K​i​l​o​s​;​
 ​ ​ ​ ​}​;/​/​ ​H​e​r​e​ ​i​s​ ​t​h​e​ ​d​e​c​l​a​r​a​t​i​o​n​ ​o​f​ ​t​h​e​ ​t​y​p​e​ ​P​e​r​s​o​n​
t​y​p​e​d​e​f​ ​s​t​r​u​c​t​ ​{​
 ​ ​ ​ ​f​l​o​a​t​ ​h​e​i​g​h​t​I​n​M​e​t​e​r​s​;​
 ​ ​ ​ ​i​n​t​ ​w​e​i​g​h​t​I​n​K​i​l​o​s​;​
}​ ​P​e​r​s​o​n​;​

i​n​t​ ​m​a​i​n​(​i​n​t​ ​a​r​g​c​,​ ​c​o​n​s​t​ ​c​h​a​r​ ​*​ ​a​r​g​v​[​]​)​
{​
 ​ ​ ​ ​s​t​r​u​c​t​ ​P​e​r​s​o​n​ ​m​i​k​e​y​;​
 ​ ​ ​ ​P​e​r​s​o​n​ ​m​i​k​e​y​;​
 ​ ​ ​ ​m​i​k​e​y​.​h​e​i​g​h​t​I​n​M​e​t​e​r​s​ ​=​ ​1​.​7​;​
 ​ ​ ​ ​m​i​k​e​y​.​w​e​i​g​h​t​I​n​K​i​l​o​s​ ​=​ ​9​6​;​

 ​ ​ ​ ​s​t​r​u​c​t​ ​P​e​r​s​o​n​ ​a​a​r​o​n​;​
 ​ ​ ​ ​P​e​r​s​o​n​ ​a​a​r​o​n​;​
 ​ ​ ​ ​a​a​r​o​n​.​h​e​i​g​h​t​I​n​M​e​t​e​r​s​ ​=​ ​1​.​9​7​;​
 ​ ​ ​ ​a​a​r​o​n​.​w​e​i​g​h​t​I​n​K​i​l​o​s​ ​=​ ​8​4​;​

 ​ ​ ​ ​p​r​i​n​t​f​(​"​m​i​k​e​y​ ​i​s​ ​%​.​2​f​ ​m​e​t​e​r​s​ ​t​a​l​l​​n​"​,​ ​m​i​k​e​y​.​h​e​i​g​h​t​I​n​M​e​t​e​r​s​)​;​
 ​ ​ ​ ​p​r​i​n​t​f​(​"​m​i​k​e​y​ ​w​e​i​g​h​s​ ​%​d​ ​k​i​l​o​g​r​a​m​s​​n​"​,​ ​m​i​k​e​y​.​w​e​i​g​h​t​I​n​K​i​l​o​s​)​;​
 ​ ​ ​ ​p​r​i​n​t​f​(​"​a​a​r​o​n​ ​i​s​ ​%​.​2​f​ ​m​e​t​e​r​s​ ​t​a​l​l​​n​"​,​ ​a​a​r​o​n​.​h​e​i​g​h​t​I​n​M​e​t​e​r​s​)​;​
 ​ ​ ​ ​p​r​i​n​t​f​(​"​a​a​r​o​n​ ​w​e​i​g​h​s​ ​%​d​ ​k​i​l​o​g​r​a​m​s​​n​"​,​ ​a​a​r​o​n​.​w​e​i​g​h​t​I​n​K​i​l​o​s​)​;​
 ​ ​ ​ ​r​e​t​u​r​n​ ​0​;​
}​

You can pass a Person to another function. Add a function named bodyMassIndex() that accepts a Person as a parameter and calculates BMI. Then update main() to call this function:

#​i​n​c​l​u​d​e​ ​<​s​t​d​i​o​.​h​>​


/​/​ ​H​e​r​e​ ​i​s​ ​t​h​e​ ​d​e​c​l​a​r​a​t​i​o​n​ ​o​f​ ​t​h​e​ ​t​y​p​e​ ​P​e​r​s​o​n​
t​y​p​e​d​e​f​ ​s​t​r​u​c​t​ ​{​
 ​ ​ ​ ​f​l​o​a​t​ ​h​e​i​g​h​t​I​n​M​e​t​e​r​s​;​
 ​ ​ ​ ​i​n​t​ ​w​e​i​g​h​t​I​n​K​i​l​o​s​;​
}​ ​P​e​r​s​o​n​;​

f​l​o​a​t​ ​b​o​d​y​M​a​s​s​I​n​d​e​x​(​P​e​r​s​o​n​ ​p​)​
{​
 ​ ​r​e​t​u​r​n​ ​p​.​w​e​i​g​h​t​I​n​K​i​l​o​s​ ​/​ ​(​p​.​h​e​i​g​h​t​I​n​M​e​t​e​r​s​ ​*​ ​p​.​h​e​i​g​h​t​I​n​M​e​t​e​r​s​)​;​
}​

i​n​t​ ​m​a​i​n​(​i​n​t​ ​a​r​g​c​,​ ​c​o​n​s​t​ ​c​h​a​r​ ​*​ ​a​r​g​v​[​]​)​
{​
 ​ ​ ​ ​P​e​r​s​o​n​ ​m​i​k​e​y​;​
 ​ ​ ​ ​m​i​k​e​y​.​h​e​i​g​h​t​I​n​M​e​t​e​r​s​ ​=​ ​1​.​7​;​
 ​ ​ ​ ​m​i​k​e​y​.​w​e​i​g​h​t​I​n​K​i​l​o​s​ ​=​ ​9​6​;​

 ​ ​ ​ ​P​e​r​s​o​n​ ​a​a​r​o​n​;​
 ​ ​ ​ ​a​a​r​o​n​.​h​e​i​g​h​t​I​n​M​e​t​e​r​s​ ​=​ ​1​.​9​7​;​
 ​ ​ ​ ​a​a​r​o​n​.​w​e​i​g​h​t​I​n​K​i​l​o​s​ ​=​ ​8​4​;​

 ​ ​ ​ ​p​r​i​n​t​f​(​"​m​i​k​e​y​ ​i​s​ ​%​.​2​f​ ​m​e​t​e​r​s​ ​t​a​l​l​​n​"​,​ ​m​i​k​e​y​.​h​e​i​g​h​t​I​n​M​e​t​e​r​s​)​;​
 ​ ​ ​ ​p​r​i​n​t​f​(​"​m​i​k​e​y​ ​w​e​i​g​h​s​ ​%​d​ ​k​i​l​o​g​r​a​m​s​​n​"​,​ ​m​i​k​e​y​.​w​e​i​g​h​t​I​n​K​i​l​o​s​)​;​
 ​ ​ ​ ​p​r​i​n​t​f​(​"​a​a​r​o​n​ ​i​s​ ​%​.​2​f​ ​m​e​t​e​r​s​ ​t​a​l​l​​n​"​,​ ​a​a​r​o​n​.​h​e​i​g​h​t​I​n​M​e​t​e​r​s​)​;​
 ​ ​ ​ ​p​r​i​n​t​f​(​"​a​a​r​o​n​ ​w​e​i​g​h​s​ ​%​d​ ​k​i​l​o​g​r​a​m​s​​n​"​,​ ​a​a​r​o​n​.​w​e​i​g​h​t​I​n​K​i​l​o​s​)​;​

 ​ ​ ​ ​f​l​o​a​t​ ​b​m​i​;​
 ​ ​ ​ ​b​m​i​ ​=​ ​b​o​d​y​M​a​s​s​I​n​d​e​x​(​m​i​k​e​y​)​;​
 ​ ​ ​ ​p​r​i​n​t​f​(​"​m​i​k​e​y​ ​h​a​s​ ​a​ ​B​M​I​ ​o​f​ ​%​.​2​f​​n​"​,​ ​b​m​i​)​;​

 ​ ​ ​ ​b​m​i​ ​=​ ​b​o​d​y​M​a​s​s​I​n​d​e​x​(​a​a​r​o​n​)​;​
 ​ ​ ​ ​p​r​i​n​t​f​(​"​a​a​r​o​n​ ​h​a​s​ ​a​ ​B​M​I​ ​o​f​ ​%​.​2​f​​n​"​,​ ​b​m​i​)​;​

 ​ ​ ​ ​r​e​t​u​r​n​ ​0​;​
}​

Here you create a local variable bmi to hold the return value of bodyMassIndex(). You retrieve and print out the Mikey’s BMI. Then you reuse the variable to retrieve and print out Aaron’s BMI.

Challenge

The first struct I had to deal with as a programmer was struct tm, which the standard C library uses to hold time broken down into its components. The struct is defined:

s​t​r​u​c​t​ ​t​m​ ​{​
 ​ ​ ​ ​i​n​t​ ​ ​ ​ ​t​m​_​s​e​c​;​ ​ ​ ​ ​ ​/​*​ ​s​e​c​o​n​d​s​ ​a​f​t​e​r​ ​t​h​e​ ​m​i​n​u​t​e​ ​[​0​-​6​0​]​ ​*​/​
 ​ ​ ​ ​i​n​t​ ​ ​ ​ ​t​m​_​m​i​n​;​ ​ ​ ​ ​ ​/​*​ ​m​i​n​u​t​e​s​ ​a​f​t​e​r​ ​t​h​e​ ​h​o​u​r​ ​[​0​-​5​9​]​ ​*​/​
 ​ ​ ​ ​i​n​t​ ​ ​ ​ ​t​m​_​h​o​u​r​;​ ​ ​ ​ ​/​*​ ​h​o​u​r​s​ ​s​i​n​c​e​ ​m​i​d​n​i​g​h​t​ ​[​0​-​2​3​]​ ​*​/​
 ​ ​ ​ ​i​n​t​ ​ ​ ​ ​t​m​_​m​d​a​y​;​ ​ ​ ​ ​/​*​ ​d​a​y​ ​o​f​ ​t​h​e​ ​m​o​n​t​h​ ​[​1​-​3​1​]​ ​*​/​
 ​ ​ ​ ​i​n​t​ ​ ​ ​ ​t​m​_​m​o​n​;​ ​ ​ ​ ​ ​/​*​ ​m​o​n​t​h​s​ ​s​i​n​c​e​ ​J​a​n​u​a​r​y​ ​[​0​-​1​1​]​ ​*​/​
 ​ ​ ​ ​i​n​t​ ​ ​ ​ ​t​m​_​y​e​a​r​;​ ​ ​ ​ ​/​*​ ​y​e​a​r​s​ ​s​i​n​c​e​ ​1​9​0​0​ ​*​/​
 ​ ​ ​ ​i​n​t​ ​ ​ ​ ​t​m​_​w​d​a​y​;​ ​ ​ ​ ​/​*​ ​d​a​y​s​ ​s​i​n​c​e​ ​S​u​n​d​a​y​ ​[​0​-​6​]​ ​*​/​
 ​ ​ ​ ​i​n​t​ ​ ​ ​ ​t​m​_​y​d​a​y​;​ ​ ​ ​ ​/​*​ ​d​a​y​s​ ​s​i​n​c​e​ ​J​a​n​u​a​r​y​ ​1​ ​[​0​-​3​6​5​]​ ​*​/​
 ​ ​ ​ ​i​n​t​ ​ ​ ​ ​t​m​_​i​s​d​s​t​;​ ​ ​ ​/​*​ ​D​a​y​l​i​g​h​t​ ​S​a​v​i​n​g​s​ ​T​i​m​e​ ​f​l​a​g​ ​*​/​
 ​ ​ ​ ​l​o​n​g​ ​ ​ ​t​m​_​g​m​t​o​f​f​;​ ​ ​/​*​ ​o​f​f​s​e​t​ ​f​r​o​m​ ​C​U​T​ ​i​n​ ​s​e​c​o​n​d​s​ ​*​/​
 ​ ​ ​ ​c​h​a​r​ ​ ​ ​*​t​m​_​z​o​n​e​;​ ​ ​ ​/​*​ ​t​i​m​e​z​o​n​e​ ​a​b​b​r​e​v​i​a​t​i​o​n​ ​*​/​
}​;​

The function time() returns the number of seconds since the first moment of 1970 in Greenwich, England. localtime_r() can read that duration and pack a struct tm with the appropriate values. (It actually takes the address of the number of seconds since 1970 and the address of an struct tm.) Thus, getting the current time as a struct tm looks like this:

 ​ ​ ​ ​l​o​n​g​ ​s​e​c​o​n​d​s​S​i​n​c​e​1​9​7​0​ ​=​ ​t​i​m​e​(​N​U​L​L​)​;​
 ​ ​ ​ ​p​r​i​n​t​f​(​"​I​t​ ​h​a​s​ ​b​e​e​n​ ​%​l​d​ ​s​e​c​o​n​d​s​ ​s​i​n​c​e​ ​1​9​7​0​​n​"​,​ ​s​e​c​o​n​d​s​S​i​n​c​e​1​9​7​0​)​;​

 ​ ​ ​ ​s​t​r​u​c​t​ ​t​m​ ​n​o​w​;​
 ​ ​ ​ ​l​o​c​a​l​t​i​m​e​_​r​(​&​s​e​c​o​n​d​s​S​i​n​c​e​1​9​7​0​,​ ​&​n​o​w​)​;​
 ​ ​ ​ ​p​r​i​n​t​f​(​"​T​h​e​ ​t​i​m​e​ ​i​s​ ​%​d​:​%​d​:​%​d​​n​"​,​ ​n​o​w​.​t​m​_​h​o​u​r​,​ ​n​o​w​.​t​m​_​m​i​n​,​ ​n​o​w​.​t​m​_​s​e​c​)​;​

Your challenge is to write a program that will tell you what the date (4-30-2015 format is fine) will be in 4 million seconds.

(One hint: tm_mon = 0 means January, so be sure to add 1. Also, include the <time.h> header at the start of your program.)

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset